Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@ alice-auth-manager-data
alice-auth-manager-data
!/packages/contracts/dist/
!/packages/contracts/dist/dev
.secret
.secret
debug
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,28 @@ pnpm run test:target packages/e2e/src/tickets/delegation.spec.ts

Append additional Jest flags after the path if you need finer filtering.

### Debugging node requests (curl dumps)

When running in Node.js (e2e tests, scripts, etc), you can persist generated curl commands to `./debug/` (this directory is gitignored). This lets you replay the exact request without re-running the full flow.

```bash
# enable writing curl commands to disk
export LIT_DEBUG_CURL=1

# optional: change output directory (defaults to ./debug)
export LIT_DEBUG_CURL_DIR=./debug
```

After your run, copy the correlation id (for example `X-Request-Id` from node calls, or `x-correlation-id` / the `Request(<id>)` value from Wrapped Keys errors) and print the stored curl command:

```bash
pnpm debug:curl -- <X-Request-Id>
```

If you only have a prefix/substring, `pnpm debug:curl` will try to match it (and will list matches if more than one file fits).

More details: `docs/guides/debugging-node-requests.mdx`.

## QA Starter Kit workflow

When you need to validate SDK integrations against backend or node features, lean on the [QA Starter Kit](https://github.com/LIT-Protocol/QA-kit). That repo installs published packages, so it mirrors how downstream teams will consume the SDK.
Expand Down
5 changes: 3 additions & 2 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@
"group": "Guides",
"pages": [
"guides/lit-action-sign-as-action",
"guides/server-sessions"
"guides/server-sessions",
"guides/debugging-node-requests"
]
},
{
Expand Down Expand Up @@ -246,4 +247,4 @@
"discord": "https://litgateway.com/discord"
}
}
}
}
39 changes: 39 additions & 0 deletions docs/guides/debugging-node-requests.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "Debugging Node Requests"
description: "Dump curl commands by request id so you can replay calls without re-running full flows."
---

# Overview

When debugging a failing Lit node call, it helps to replay the exact HTTP request without re-running an entire end-to-end flow. The SDK can generate a `curl` command for each request and (optionally) write it to disk keyed by the request correlation id (for example `X-Request-Id` or `x-correlation-id`).

# Enable curl dumps (Node.js only)

Set `LIT_DEBUG_CURL=1` in your environment when running in Node.js (tests, scripts, backends, etc). This is disabled by default and does not write anything in browser builds.

```bash
export LIT_DEBUG_CURL=1
```

Optional: override the output directory (defaults to `./debug`, relative to `process.cwd()`):

```bash
export LIT_DEBUG_CURL_DIR=./debug
```

After you run whatever code triggers requests, you should see files created under `./debug/` named by request id.

# Retrieve a curl command by request id

Once you have the correlation id (for example `X-Request-Id` from node calls, or `x-correlation-id` from Wrapped Keys service calls), you can print the stored curl command and paste it directly into a terminal:

```bash
pnpm debug:curl -- <X-Request-Id>
```

If you only have a prefix/substring, `pnpm debug:curl` will try to match it (and will list matches if more than one file fits).

# Security notes

- The generated curl command includes request headers and body, which may contain signatures or other sensitive data.
- The default `./debug` directory is gitignored in this repo; keep these files local and do not share them.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"scripts": {
"sync:contracts": "nx run contracts:sync",
"sync:docs-changelog": "node tools/sync-docs-changelog.js",
"debug:curl": "node tools/debug-curl.js",
"sync:wk": "node packages/wrapped-keys-lit-actions/sync-actions-to-ipfs.js",
"sync:check": "sh -c 'if [ -n \"$PKG\" ]; then pnpm syncpack list-mismatches --types prod,dev,peer --filter \"$PKG\"; else pnpm syncpack list-mismatches --types prod,dev,peer; fi'",
"sync:fix": "sh -c 'if [ -n \"$PKG\" ]; then pnpm syncpack fix-mismatches --types prod,dev,peer --filter \"$PKG\"; else pnpm syncpack fix-mismatches --types prod,dev,peer; fi'",
Expand Down
1 change: 1 addition & 0 deletions packages/access-control-conditions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"main": "./src/index.js",
"typings": "./src/index.d.ts",
"dependencies": {
"@lit-protocol/logger": "workspace:*",
"ethers": "5.7.2",
"zod": "3.24.3",
"@ethersproject/providers": "5.7.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/artillery/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Usage via root scripts remains the same, now pointing to `packages/artillery`.

# 🚀 Run Artillery tests

- LOG_LEVEL= `debug` | `info` | `silent` | `debug2` (raw console.log)
- LOG_LEVEL= `debug` | `info` | `silent` | `debug_text` (console-style text output, not JSON; `debug2` is a deprecated alias)
- NETWORK= `naga-dev` | `naga-staging`

## Setup Commands
Expand Down
1 change: 1 addition & 0 deletions packages/auth-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"main": "./src/index.js",
"typings": "./src/index.d.ts",
"dependencies": {
"@lit-protocol/logger": "workspace:*",
"@wagmi/core": "2.22.1",
"ethers": "5.7.2",
"siwe": "2.3.2",
Expand Down
5 changes: 4 additions & 1 deletion packages/auth-helpers/src/lib/auth-config-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import {
} from './resources'; // Corrected path: from ../lib/auth-config-builder.ts to ../lib/resources/

import { z } from 'zod';
import { getChildLogger } from '@lit-protocol/logger';

const logger = getChildLogger({ module: 'auth-config-builder' });

// Infer the AuthConfig type from the Zod schema
type AuthConfig = z.infer<typeof AuthConfigSchema>;
Expand Down Expand Up @@ -163,7 +166,7 @@ export const createAuthConfigBuilder = (): IAuthConfigBuilder => {
return parsedConfig;
} catch (e) {
if (e instanceof z.ZodError) {
console.error('AuthConfig validation failed:', e.errors);
logger.error({ errors: e.errors }, 'AuthConfig validation failed');
}
throw new Error(`Failed to build AuthConfig: ${(e as Error).message}`);
}
Expand Down
1 change: 1 addition & 0 deletions packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"universal"
],
"dependencies": {
"@lit-protocol/logger": "workspace:*",
"@noble/hashes": "1.8.0",
"@noble/curves": "1.8.1",
"@simplewebauthn/browser": "7.2.0",
Expand Down
45 changes: 24 additions & 21 deletions packages/auth/src/lib/authenticators/helper/pollResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
* ```
*/

import { getChildLogger } from '@lit-protocol/logger';

const logger = getChildLogger({ module: 'auth.pollResponse' });

/**
* Defines the parameters for the pollResponse function.
* @template TResponse The expected type of the JSON response from the URL.
Expand Down Expand Up @@ -82,7 +86,7 @@ export async function pollResponse<TResponse>({
}: PollResponseParams<TResponse>): Promise<TResponse> {
for (let i = 0; i < maxRetries; i++) {
try {
console.log(
logger.debug(
`${errorMessageContext}: Polling attempt ${
i + 1
}/${maxRetries} for ${url}`
Expand All @@ -96,27 +100,28 @@ export async function pollResponse<TResponse>({
);
}
// Log other non-ok statuses but continue retrying unless it's a client error type that won't resolve on its own.
console.error(
logger.warn(
{ status: response.status, url },
`${errorMessageContext}: Polling attempt ${
i + 1
} failed with HTTP status: ${
response.status
} for URL ${url}. Retrying...`
} failed with HTTP status. Retrying...`
);
// Optionally, specific handling for other critical HTTP errors could be added here to throw immediately.
} else {
const data = (await response.json()) as TResponse;
console.log(
`${errorMessageContext}: Polling attempt ${
i + 1
}/${maxRetries} - current status/data:`,
data
logger.debug(
{
attempt: i + 1,
maxRetries,
data,
},
`${errorMessageContext}: Polling attempt - current status/data`
);

if (isErrorCondition?.(data)) {
console.error(
`${errorMessageContext}: Error condition met during polling.`,
data
logger.error(
{ data },
`${errorMessageContext}: Error condition met during polling`
);
// Attempt to get more specific error details if available
const errorDetails =
Expand All @@ -133,21 +138,19 @@ export async function pollResponse<TResponse>({
}

if (isCompleteCondition(data)) {
console.log(
`${errorMessageContext}: Completion condition met successfully.`,
data
logger.info(
{ data },
`${errorMessageContext}: Completion condition met successfully`
);
return data;
}
// If neither error nor complete, continue polling after delay.
}
} catch (error: any) {
const message = error instanceof Error ? error.message : String(error);
console.error(
`${errorMessageContext}: Error during polling attempt ${
i + 1
}/${maxRetries} for ${url}:`,
message
logger.warn(
{ error, attempt: i + 1, maxRetries, url },
`${errorMessageContext}: Error during polling attempt`
);
// If it's the last attempt, or a critical error (like 404 or an explicit error condition from isErrorCondition), rethrow.
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { AuthData } from '@lit-protocol/schemas';
import { AuthMethod, StytchToken } from '@lit-protocol/types';
import { AuthMethodTypeStringMap } from '../../../../types';
import { totpAuthFactorParser } from '../../parsers';
import { getChildLogger } from '@lit-protocol/logger';

const _logger = getChildLogger({ module: 'StytchTotp2FAAuthenticator' });

/**
* Configuration for the Stytch TOTP authenticate method.
Expand Down Expand Up @@ -114,7 +117,7 @@ export class StytchTotp2FAAuthenticator {
}
accessToken = verifyData.accessToken;
} catch (e: any) {
console.error('Error verifying TOTP via auth service:', e);
_logger.error({ e }, 'Error verifying TOTP via auth service');
throw e;
}

Expand Down Expand Up @@ -146,7 +149,7 @@ export class StytchTotp2FAAuthenticator {
authMethodId: generatedAuthMethodId,
});
} catch (e) {
console.error('Error processing Stytch TOTP token:', e);
_logger.error({ e }, 'Error processing Stytch TOTP token');
reject(e);
}
});
Expand Down Expand Up @@ -243,7 +246,7 @@ export class StytchTotp2FAAuthenticator {

const createData = await createResponse.json();

console.log('createData', createData);
_logger.debug({ createData }, 'TOTP registration create response');

if (
!createData.totpRegistrationId ||
Expand All @@ -262,7 +265,10 @@ export class StytchTotp2FAAuthenticator {
recoveryCodes: createData.recoveryCodes || [],
};
} catch (e: any) {
console.error('Error initiating TOTP registration via auth service:', e);
_logger.error(
{ e },
'Error initiating TOTP registration via auth service'
);
throw e;
}
}
Expand Down Expand Up @@ -304,14 +310,17 @@ export class StytchTotp2FAAuthenticator {
);
}

console.log('verifyData', verifyData);
_logger.debug({ verifyData }, 'TOTP registration verify response');

return {
accessToken: verifyData.accessToken,
totpId: verifyData.totpId || '',
};
} catch (e: any) {
console.error('Error verifying TOTP registration via auth service:', e);
_logger.error(
{ e },
'Error verifying TOTP registration via auth service'
);
throw e;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { AuthData } from '@lit-protocol/schemas';
import { AuthMethod, StytchToken } from '@lit-protocol/types';
import { AuthMethodTypeStringMap } from '../../../types';
import { emailOtpAuthFactorParser } from '../parsers';
import { getChildLogger } from '@lit-protocol/logger';

const _logger = getChildLogger({ module: 'StytchEmailOtpAuthenticator' });

/**
* Configuration for initiating the Stytch Email OTP sending process.
Expand Down Expand Up @@ -74,7 +77,7 @@ export class StytchEmailOtpAuthenticator {
methodId: responseData.methodId,
};
} catch (e: any) {
console.error('Error in sendOtp:', e);
_logger.error({ e }, 'Error in sendOtp');
throw e; // Re-throw the error to be handled by the caller
}
}
Expand Down Expand Up @@ -116,7 +119,7 @@ export class StytchEmailOtpAuthenticator {
accessToken = verifyData.accessToken;
userId = verifyData.userId;
} catch (e: any) {
console.error('Error verifying OTP via auth service:', e);
_logger.error({ e }, 'Error verifying OTP via auth service');
throw e; // Re-throw the error
}

Expand Down Expand Up @@ -158,7 +161,7 @@ export class StytchEmailOtpAuthenticator {
},
});
} catch (e) {
console.error('Error processing Stytch token:', e);
_logger.error({ e }, 'Error processing Stytch token');
reject(e);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { AuthData } from '@lit-protocol/schemas';
import { AuthMethod, StytchToken } from '@lit-protocol/types';
import { AuthMethodTypeStringMap } from '../../../types';
import { smsOtpAuthFactorParser } from '../parsers';
import { getChildLogger } from '@lit-protocol/logger';

const _logger = getChildLogger({ module: 'StytchSmsOtpAuthenticator' });

/**
* Configuration for initiating the Stytch SMS OTP sending process.
Expand Down Expand Up @@ -70,7 +73,7 @@ export class StytchSmsOtpAuthenticator {
}
return { methodId: responseData.methodId };
} catch (e: any) {
console.error('Error in StytchSmsOtpAuthenticator sendOtp:', e);
_logger.error({ e }, 'Error in StytchSmsOtpAuthenticator sendOtp');
throw e;
}
}
Expand Down Expand Up @@ -114,7 +117,7 @@ export class StytchSmsOtpAuthenticator {
accessToken = verifyData.accessToken;
userId = verifyData.userId;
} catch (e: any) {
console.error('Error verifying SMS OTP via auth service:', e);
_logger.error({ e }, 'Error verifying SMS OTP via auth service');
throw e;
}

Expand Down Expand Up @@ -151,7 +154,7 @@ export class StytchSmsOtpAuthenticator {
},
});
} catch (e) {
console.error('Error processing Stytch SMS token:', e);
_logger.error({ e }, 'Error processing Stytch SMS token');
reject(e);
}
});
Expand Down
Loading
Loading