Skip to content

Commit ca57a26

Browse files
committed
feat(auth,auth-services,network,lit-client):
**Auth Flow Hardening** 1. (feat) DiscordAuthenticator - it now forces you to support the real Discord client id wheever you hit a non-default login server, so the hashed `authMethodId` lines up with what the Lit nodes compute 2. (fix) WebAuthnAuthenticator - Refuse "successful" jobs that returns no payload. Make the service path fail loudly instad of handing back undefined data. **Auth Service** 1. (fix) add network-scoped queue names, so multi-network deploytments stops overwriting each other's BullMQ jobs. 2. (fix) initSystemContext - dropped the silent `naga-dev` default and demand an explict `NETWORK`, preventing workers from accidentally botting against the wrong network. 3. (chore) remove unsued route **Networks * Lit Client** 1. (refactor): stop hard-coding `authServiceBaseUrl` - the SDK will rely on runtime config so staging URLs don't leak into other envs. 2. (fix): Remove Strict Auth Data and make it Partial<AuthData> 3. (chore) add tracing the `mintWithAuth`
1 parent a833c7a commit ca57a26

File tree

27 files changed

+268
-188
lines changed

27 files changed

+268
-188
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"license": "MIT",
55
"scripts": {
66
"sync:contracts": "nx run contracts:sync",
7-
"reset": "rimraf dist pnpm-lock.yaml node_modules tmp yarn-error.log yarn.lock package-lock.json learn-debug.log .nx lit-auth-storage pkp-tokens lit-auth-local ./e2e/dist ./e2e/node_modules",
7+
"reset": "rimraf .nx dist node_modules packages/**/node_modules tmp",
88
"build": "nx run-many --parallel=false --target=build --all --exclude=wrapped-keys,wrapped-keys-lit-actions",
99
"gen:local-network-context": "dotenvx run --env-file=.env -- node --conditions=import --import tsx packages/networks/src/networks/vNaga/shared/scripts/generate-abi-signatures.ts",
1010
"prettier": "npx nx format:write --all",

packages/auth-services/src/_setup/initSystemContext.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import {
44
ViemAccountAuthenticator,
55
} from '@lit-protocol/auth';
66
import { createLitClient } from '@lit-protocol/lit-client';
7-
import { nagaDev, nagaTest, nagaStaging } from '@lit-protocol/networks';
7+
import { nagaDev, nagaTest } from '@lit-protocol/networks';
88
import { Hex } from 'viem';
99
import { privateKeyToAccount } from 'viem/accounts';
1010
import { env } from '../env';
1111
import { AuthData } from '@lit-protocol/schemas';
12+
import { getChildLogger } from '@lit-protocol/logger';
13+
14+
const _logger = getChildLogger({ name: 'initSystemContext' });
1215

1316
declare global {
1417
var systemContext: {
@@ -29,12 +32,13 @@ export async function initSystemContext({
2932
}) {
3033
console.log('🔥 [initSystemContext] Initializing system context...');
3134

32-
let networkModule: any;
35+
let networkModule: typeof nagaDev | typeof nagaTest;
3336
if (env.NETWORK === 'naga-dev') networkModule = nagaDev;
3437
else if (env.NETWORK === 'naga-test') networkModule = nagaTest;
35-
else if (env.NETWORK === 'naga-staging') networkModule = nagaStaging;
3638
else throw new Error(`Unsupported network: ${env.NETWORK}`);
3739

40+
_logger.info({ env: env.NETWORK }, 'Using env.NETWORK');
41+
3842
const overrideRpc = rpcUrl || env.LIT_TXSENDER_RPC_URL;
3943

4044
// Apply runtime override if rpcUrl provided
@@ -52,11 +56,10 @@ export async function initSystemContext({
5256
typeof effectiveModule.getRpcUrl === 'function'
5357
? effectiveModule.getRpcUrl()
5458
: 'n/a';
55-
console.log(
56-
'[initSystemContext] RPC (base → effective):',
57-
baseRpc,
58-
'→',
59-
effRpc
59+
60+
_logger.info(
61+
{ baseRpc, effRpc },
62+
'[initSystemContext] RPC (base → effective):'
6063
);
6164
} catch {
6265
throw new Error(
@@ -73,7 +76,7 @@ export async function initSystemContext({
7376
const authManager = createAuthManager({
7477
storage: storagePlugins.localStorageNode({
7578
appName: appName,
76-
networkName: 'naga-dev',
79+
networkName: env.NETWORK,
7780
storagePath: `./lit-auth-worker-storage-${appName}`,
7881
}),
7982
});
@@ -93,13 +96,12 @@ export async function initSystemContext({
9396
statement: `${appName} is running..`,
9497
domain: 'worker.litprotocol.com',
9598
resources: [['pkp-signing', '*']],
96-
capabilityAuthSigs: [],
9799
expiration: new Date(Date.now() + 1000 * 60 * 10).toISOString(),
98100
},
99101
litClient: litClient,
100102
});
101103
},
102104
authData,
103105
};
104-
console.log('🔥 [initSystemContext] System context initialized');
106+
_logger.info('🔥 [initSystemContext] System context initialized');
105107
}

packages/auth-services/src/auth-server/src/routes/auth/webauthn/webauthn.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/auth-services/src/auth-server/src/routes/pkp.express.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { Express } from 'express';
22
import { addJob } from '../../../queue-manager/src/bullmqSetup';
33
import { randomUUID } from 'node:crypto';
4+
import { getChildLogger } from '@lit-protocol/logger';
5+
6+
const logger = getChildLogger({ name: 'registerPkpRoutes' });
47

58
export const registerPkpRoutes = (app: Express) => {
69
app.post('/pkp/mint', async (req, res) => {
710
const reqId = randomUUID();
811
try {
12+
logger.info({ reqId, body: req.body }, `[API] pkp/mint incoming request`);
13+
914
const job = await addJob('pkpMint', { requestBody: req.body });
1015
return res
1116
.status(202)

packages/auth-services/src/env.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Compatibility env shim for existing imports
22
export const env = {
3-
NETWORK: process.env['NETWORK'] || 'naga-dev',
3+
NETWORK: process.env['NETWORK'],
44
LIT_TXSENDER_RPC_URL: process.env['LIT_TXSENDER_RPC_URL'] || '',
55
LIT_TXSENDER_PRIVATE_KEY: process.env['LIT_TXSENDER_PRIVATE_KEY'] || '',
66
REDIS_URL: process.env['REDIS_URL'] || 'redis://localhost:6379',

packages/auth-services/src/queue-manager/src/bullmqSetup.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import { ConnectionOptions, Queue } from 'bullmq';
22
import { env } from '../../env';
33
import { parseRedisUrl } from './helper/redisUrlParser';
44
import { JobName } from './jobRegistry';
5+
import { getChildLogger } from '@lit-protocol/logger';
56

6-
export const mainQueueName = 'pkpAuthServiceQueue';
7+
const logger = getChildLogger({ name: 'BullMQ' });
8+
9+
const queueSuffix = env.NETWORK ? `-${env.NETWORK}` : '';
10+
export const mainQueueName = `pkpAuthServiceQueue${queueSuffix}`;
711

812
let bullmqConnectionOptions: ConnectionOptions = parseRedisUrl(env.REDIS_URL);
913

@@ -23,6 +27,14 @@ let mainAppQueueInstance: Queue | null = null;
2327

2428
export const getMainAppQueue = (): Queue => {
2529
if (!mainAppQueueInstance) {
30+
logger.info(
31+
{
32+
queue: mainQueueName,
33+
network: env.NETWORK,
34+
redis: bullmqConnectionOptions,
35+
},
36+
'Initialising BullMQ Queue...'
37+
);
2638
mainAppQueueInstance = new Queue(mainQueueName, {
2739
connection: bullmqConnectionOptions,
2840
defaultJobOptions: {
@@ -52,6 +64,14 @@ export const getMainAppQueue = (): Queue => {
5264
)}`
5365
);
5466
}
67+
68+
logger.info(
69+
{
70+
queue: mainQueueName,
71+
network: env.NETWORK,
72+
},
73+
'Reusing existing BullMQ Queue instance'
74+
);
5575
return mainAppQueueInstance;
5676
};
5777

@@ -63,12 +83,26 @@ export const addJob = async (
6383
*/
6484
jobData: { requestBody: any }
6585
) => {
86+
logger.info(
87+
{
88+
queue: mainQueueName,
89+
network: env.NETWORK,
90+
jobName,
91+
},
92+
'Adding job to BullMQ queue'
93+
);
6694
const job = await getMainAppQueue().add(jobName, jobData, {
6795
jobId: crypto.randomUUID(),
6896
});
6997

70-
console.log(
71-
`[BullMQ] Job ${job.id} added to queue ${getMainAppQueue().name}`
98+
logger.info(
99+
{
100+
queue: mainQueueName,
101+
network: env.NETWORK,
102+
jobName,
103+
jobId: job.id,
104+
},
105+
'Job added to BullMQ queue'
72106
);
73107

74108
return job;
@@ -99,6 +133,27 @@ export const getJobStatus = async (
99133

100134
const state = await job.getState();
101135

136+
let returnValue: unknown = undefined;
137+
138+
if (state === 'completed') {
139+
returnValue = job.returnvalue;
140+
141+
if (returnValue == null) {
142+
try {
143+
const { returnvalue: rawReturnValue } = job.asJSON();
144+
returnValue =
145+
typeof rawReturnValue === 'string' && rawReturnValue.length > 0
146+
? JSON.parse(rawReturnValue)
147+
: rawReturnValue;
148+
} catch (err) {
149+
console.warn(
150+
`[BullMQ] Unable to read return value for completed job ${job.id}:`,
151+
err
152+
);
153+
}
154+
}
155+
}
156+
102157
const responsePayload = {
103158
jobId: job.id,
104159
name: job.name,
@@ -107,7 +162,7 @@ export const getJobStatus = async (
107162
timestamp: job.timestamp, // Creation time
108163
processedOn: job.processedOn,
109164
finishedOn: job.finishedOn,
110-
returnValue: job.returnvalue, // Contains result if completed (already stringified by handler)
165+
returnValue,
111166
failedReason: job.failedReason, // Contains error message if failed
112167
};
113168

packages/auth-services/src/queue-manager/src/genericWorker.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getChildLogger } from '@lit-protocol/logger';
22
import { Worker } from 'bullmq';
33
import { getBullmqConnectionOptions, mainQueueName } from './bullmqSetup';
44
import { JobName, jobRegistry } from './jobRegistry';
5+
import { env } from '../../env';
56

67
const logger = getChildLogger({
78
name: 'generic-bullmq-worker',
@@ -10,11 +11,23 @@ const logger = getChildLogger({
1011
export function createGenericWorker() {
1112
logger.info('Initialising Generic BullMQ Worker...');
1213

14+
logger.info(
15+
{
16+
queue: mainQueueName,
17+
network: env.NETWORK,
18+
pid: process.pid,
19+
},
20+
'Generic BullMQ Worker started'
21+
);
22+
1323
const worker = new Worker(
1424
mainQueueName,
1525
async (job) => {
1626
logger.info(
1727
{
28+
queue: mainQueueName,
29+
network: env.NETWORK,
30+
pid: process.pid,
1831
jobId: job.id,
1932
jobName: job.name,
2033
},

packages/auth-services/src/queue-manager/src/handlers/pkpMint/pkpMint.handler.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import {
2-
AuthData,
3-
MintPKPRequest,
4-
MintPKPRequestSchema,
5-
} from '@lit-protocol/schemas';
6-
import { Optional } from '@lit-protocol/types';
1+
import { MintPKPRequest } from '@lit-protocol/schemas';
2+
import { getChildLogger } from '@lit-protocol/logger';
73

84
/**
95
* Handles PKP minting tasks.
@@ -14,20 +10,26 @@ export async function handlePkpMintTask(jobData: {
1410
requestBody: MintPKPRequest;
1511
reqId?: string;
1612
}): Promise<any> {
17-
const result = await globalThis.systemContext.litClient.mintWithAuth({
13+
const mintParams = {
1814
account: globalThis.systemContext.account,
1915
authData: {
2016
authMethodId: jobData.requestBody.authMethodId,
2117
authMethodType: jobData.requestBody.authMethodType,
2218
publicKey: jobData.requestBody.pubkey,
2319
},
2420
scopes: jobData.requestBody.scopes,
25-
});
21+
};
22+
23+
const result = await globalThis.systemContext.litClient.mintWithAuth(
24+
mintParams
25+
);
2626

2727
console.log(
2828
`[PkpMintHandler] PKP Minting successful. Token ID: ${result.data.tokenId.toString()}`
2929
);
3030

31+
logger.info({ result }, '[PkpMintHandler] raw mint result:');
32+
3133
const processedResult = {
3234
hash: result._raw.hash,
3335
data: {

packages/auth/src/lib/authenticators/ViemAccountAuthenticator.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from '@lit-protocol/constants';
1010
import { getChildLogger } from '@lit-protocol/logger';
1111
import { AuthData } from '@lit-protocol/schemas';
12-
import { AuthMethod, AuthSig, EthBlockhashInfo } from '@lit-protocol/types';
12+
import { AuthMethod, AuthSig } from '@lit-protocol/types';
1313
import {
1414
Account,
1515
getAddress,
@@ -18,36 +18,12 @@ import {
1818
PrivateKeyAccount,
1919
stringToBytes,
2020
} from 'viem';
21+
import { fetchBlockchainData } from './helper/fetchBlockchainData';
2122

2223
const _logger = getChildLogger({
2324
module: 'ViemAccountAuthenticator',
2425
});
2526

26-
const fetchBlockchainData = async () => {
27-
try {
28-
const resp = await fetch(
29-
'https://block-indexer.litgateway.com/get_most_recent_valid_block'
30-
);
31-
if (!resp.ok) {
32-
throw new Error(`Primary fetch failed with status: ${resp.status}`); // Or a custom error
33-
}
34-
35-
const blockHashBody: EthBlockhashInfo = await resp.json();
36-
const { blockhash, timestamp } = blockHashBody;
37-
38-
if (!blockhash || !timestamp) {
39-
throw new Error('Invalid data from primary blockhash source');
40-
}
41-
42-
return blockhash;
43-
} catch (error) {
44-
if (error instanceof Error) {
45-
throw new Error(error.message);
46-
}
47-
throw new Error(String(error));
48-
}
49-
};
50-
5127
export class ViemAccountAuthenticator {
5228
public readonly type = 'account';
5329

packages/auth/src/lib/authenticators/WalletClientAuthenticator.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,10 @@ import {
99
} from '@lit-protocol/constants';
1010
import { getChildLogger } from '@lit-protocol/logger';
1111
import { AuthData } from '@lit-protocol/schemas';
12-
import { AuthMethod, AuthSig, EthBlockhashInfo } from '@lit-protocol/types';
12+
import { AuthMethod, AuthSig } from '@lit-protocol/types';
1313
import { GetWalletClientReturnType } from '@wagmi/core';
1414
import { getAddress, Hex, keccak256, stringToBytes, WalletClient } from 'viem';
15-
16-
const fetchBlockchainData = async () => {
17-
try {
18-
const resp = await fetch(
19-
'https://block-indexer.litgateway.com/get_most_recent_valid_block'
20-
);
21-
if (!resp.ok) {
22-
throw new Error(`Primary fetch failed with status: ${resp.status}`); // Or a custom error
23-
}
24-
25-
const blockHashBody: EthBlockhashInfo = await resp.json();
26-
const { blockhash, timestamp } = blockHashBody;
27-
28-
if (!blockhash || !timestamp) {
29-
throw new Error('Invalid data from primary blockhash source');
30-
}
31-
32-
return blockhash;
33-
} catch (error) {
34-
if (error instanceof Error) {
35-
throw new Error(error.message);
36-
}
37-
throw new Error(String(error));
38-
}
39-
};
15+
import { fetchBlockchainData } from './helper/fetchBlockchainData';
4016

4117
const _logger = getChildLogger({
4218
module: 'WalletClientAuthenticator',

0 commit comments

Comments
 (0)