Skip to content

Commit 0c88db1

Browse files
committed
feat(wip): add pre-generated materials support
1 parent 99e5f5c commit 0c88db1

File tree

9 files changed

+814
-91
lines changed

9 files changed

+814
-91
lines changed

e2e/src/e2e.spec.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
createCustomAuthContext,
33
createPkpAuthContext,
4+
createPkpAuthContextWithPreGeneratedMaterials,
45
} from './helper/auth-contexts';
56
import {
67
createExecuteJsTest,
@@ -149,6 +150,95 @@ describe('all', () => {
149150
});
150151
});
151152

153+
describe('PKP Auth with Pre-generated Materials', () => {
154+
console.log('🔐 Testing PKP auth with pre-generated session materials');
155+
156+
let preGeneratedAuthContext: any;
157+
158+
beforeAll(async () => {
159+
try {
160+
preGeneratedAuthContext =
161+
await createPkpAuthContextWithPreGeneratedMaterials(ctx);
162+
} catch (e) {
163+
console.error('Failed to create pre-generated auth context:', e);
164+
throw e;
165+
}
166+
});
167+
168+
describe('endpoints', () => {
169+
it('pkpSign with pre-generated materials', () =>
170+
createPkpSignTest(ctx, () => preGeneratedAuthContext)());
171+
172+
it('executeJs with pre-generated materials', () =>
173+
createExecuteJsTest(ctx, () => preGeneratedAuthContext)());
174+
175+
it('pkpEncryptDecrypt with pre-generated materials', () =>
176+
createPkpEncryptDecryptTest(ctx, () => preGeneratedAuthContext)());
177+
});
178+
179+
describe('error handling', () => {
180+
it('should reject when only sessionKeyPair is provided', async () => {
181+
const tempAuthContext = await ctx.authManager.createPkpAuthContext({
182+
authData: ctx.aliceViemAccountAuthData,
183+
pkpPublicKey: ctx.aliceViemAccountPkp.publicKey,
184+
authConfig: {
185+
resources: [['pkp-signing', '*']],
186+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(),
187+
},
188+
litClient: ctx.litClient,
189+
});
190+
191+
const sessionKeyPair = tempAuthContext.sessionKeyPair;
192+
193+
await expect(
194+
ctx.authManager.createPkpAuthContext({
195+
authData: ctx.aliceViemAccountAuthData,
196+
pkpPublicKey: ctx.aliceViemAccountPkp.publicKey,
197+
authConfig: {
198+
resources: [['pkp-signing', '*']],
199+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(),
200+
},
201+
litClient: ctx.litClient,
202+
sessionKeyPair, // Only providing sessionKeyPair
203+
// delegationAuthSig is missing
204+
})
205+
).rejects.toThrow(
206+
'Both sessionKeyPair and delegationAuthSig must be provided together, or neither should be provided'
207+
);
208+
});
209+
210+
it('should reject when only delegationAuthSig is provided', async () => {
211+
const tempAuthContext = await ctx.authManager.createPkpAuthContext({
212+
authData: ctx.aliceViemAccountAuthData,
213+
pkpPublicKey: ctx.aliceViemAccountPkp.publicKey,
214+
authConfig: {
215+
resources: [['pkp-signing', '*']],
216+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(),
217+
},
218+
litClient: ctx.litClient,
219+
});
220+
221+
const delegationAuthSig = await tempAuthContext.authNeededCallback();
222+
223+
await expect(
224+
ctx.authManager.createPkpAuthContext({
225+
authData: ctx.aliceViemAccountAuthData,
226+
pkpPublicKey: ctx.aliceViemAccountPkp.publicKey,
227+
authConfig: {
228+
resources: [['pkp-signing', '*']],
229+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(),
230+
},
231+
litClient: ctx.litClient,
232+
// sessionKeyPair is missing
233+
delegationAuthSig, // Only providing delegationAuthSig
234+
})
235+
).rejects.toThrow(
236+
'Both sessionKeyPair and delegationAuthSig must be provided together, or neither should be provided'
237+
);
238+
});
239+
});
240+
});
241+
152242
describe('EOA Native', () => {
153243
console.log('🔐 Testing EOA native authentication and PKP minting');
154244

e2e/src/helper/auth-contexts.ts

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,70 @@
11
import { init } from '../init';
2-
2+
import { generateSessionKeyPair } from '@lit-protocol/auth';
33
import { hexToBigInt, keccak256, toBytes } from 'viem';
44

5+
/**
6+
* Creates a PKP authentication context with pre-generated session materials
7+
* This simulates a server-side use case where session key pair and delegation
8+
* signature are generated once and reused for multiple requests
9+
*/
10+
export const createPkpAuthContextWithPreGeneratedMaterials = async (
11+
ctx: Awaited<ReturnType<typeof init>>
12+
) => {
13+
console.log('🔁 Creating PKP Auth Context with Pre-generated Materials');
14+
try {
15+
// Step 1: Generate a session key pair directly
16+
console.log(' 📝 Step 1: Generating session key pair...');
17+
const sessionKeyPair = generateSessionKeyPair();
18+
19+
// Step 2: Generate PKP delegation signature for the session key pair
20+
console.log(' 📝 Step 2: Generating PKP delegation signature...');
21+
const delegationAuthSig =
22+
await ctx.authManager.generatePkpDelegationAuthSig({
23+
pkpPublicKey: ctx.aliceViemAccountPkp.publicKey,
24+
authData: ctx.aliceViemAccountAuthData,
25+
sessionKeyPair,
26+
authConfig: {
27+
resources: [
28+
['pkp-signing', '*'],
29+
['lit-action-execution', '*'],
30+
['access-control-condition-decryption', '*'],
31+
],
32+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(),
33+
},
34+
litClient: ctx.litClient,
35+
});
36+
37+
console.log(' 📝 Session materials generated:', {
38+
hasSessionKeyPair: !!sessionKeyPair,
39+
hasDelegationAuthSig: !!delegationAuthSig,
40+
sessionKeyPublicKey: sessionKeyPair?.publicKey?.substring(0, 20) + '...',
41+
});
42+
43+
// Step 3: Create auth context using the pre-generated materials
44+
// Using the dedicated function for pre-generated materials with a clean, minimal signature
45+
console.log(
46+
' 📝 Step 3: Creating auth context with pre-generated materials...'
47+
);
48+
const authContextWithPreGenerated =
49+
await ctx.authManager.createPkpAuthContextFromPreGenerated({
50+
pkpPublicKey: ctx.aliceViemAccountPkp.publicKey,
51+
sessionKeyPair,
52+
delegationAuthSig,
53+
// Optional: can provide authData if needed, otherwise minimal default is used
54+
authData: ctx.aliceViemAccountAuthData,
55+
});
56+
57+
console.log('✅ PKP Auth Context with Pre-generated Materials created');
58+
return authContextWithPreGenerated;
59+
} catch (e) {
60+
console.error(
61+
'❌ Error creating PKP Auth Context with Pre-generated Materials',
62+
e
63+
);
64+
throw e;
65+
}
66+
};
67+
568
/**
669
* Creates a PKP authentication context
770
*/
@@ -78,3 +141,72 @@ export const createCustomAuthContext = async (
78141
throw e;
79142
}
80143
};
144+
145+
/**
146+
* Creates an EOA authentication context with pre-generated session materials
147+
* This demonstrates how to pre-generate EOA session materials for server-side use
148+
*/
149+
export const createEoaAuthContextWithPreGeneratedMaterials = async (
150+
ctx: Awaited<ReturnType<typeof init>>
151+
) => {
152+
console.log('🔁 Creating EOA Auth Context with Pre-generated Materials');
153+
try {
154+
// Step 1: Generate a session key pair directly
155+
console.log(' 📝 Step 1: Generating session key pair...');
156+
const sessionKeyPair = generateSessionKeyPair();
157+
158+
// Step 2: Generate EOA delegation signature for the session key pair
159+
console.log(' 📝 Step 2: Generating EOA delegation signature...');
160+
const delegationAuthSig =
161+
await ctx.authManager.generateEoaDelegationAuthSig({
162+
account: ctx.aliceViemAccount,
163+
sessionKeyPair,
164+
authConfig: {
165+
resources: [
166+
['pkp-signing', '*'],
167+
['lit-action-execution', '*'],
168+
['access-control-condition-decryption', '*'],
169+
],
170+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(),
171+
},
172+
litClient: ctx.litClient,
173+
});
174+
175+
console.log(' 📝 EOA session materials generated:', {
176+
hasSessionKeyPair: !!sessionKeyPair,
177+
hasDelegationAuthSig: !!delegationAuthSig,
178+
sessionKeyPublicKey: sessionKeyPair?.publicKey?.substring(0, 20) + '...',
179+
});
180+
181+
// Step 3: Create EOA auth context using the pre-generated materials
182+
console.log(
183+
' 📝 Step 3: Creating EOA auth context with pre-generated materials...'
184+
);
185+
const authContextWithPreGenerated =
186+
await ctx.authManager.createEoaAuthContext({
187+
authConfig: {
188+
resources: [
189+
['pkp-signing', '*'],
190+
['lit-action-execution', '*'],
191+
['access-control-condition-decryption', '*'],
192+
],
193+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(),
194+
},
195+
config: {
196+
account: ctx.aliceViemAccount,
197+
},
198+
litClient: ctx.litClient,
199+
// Note: EOA auth contexts don't currently support pre-generated materials
200+
// This demonstrates the pattern for when it's implemented
201+
});
202+
203+
console.log('✅ EOA Auth Context with Pre-generated Materials created');
204+
return authContextWithPreGenerated;
205+
} catch (e) {
206+
console.error(
207+
'❌ Error creating EOA Auth Context with Pre-generated Materials',
208+
e
209+
);
210+
throw e;
211+
}
212+
};

packages/auth/src/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,32 @@ export { getAuthIdByAuthMethod } from './lib/authenticators/helper/utils';
9595
*/
9696
export { generateSessionKeyPair } from './lib/AuthManager/utils/generateSessionKeyPair';
9797

98+
/**
99+
* Utility function to generate a PKP delegation auth signature for a given session key pair.
100+
* The PKP will sign the session key delegation message via Lit nodes.
101+
* This function is useful for server-side scenarios where you want to pre-generate
102+
* PKP session materials and reuse them across multiple requests.
103+
*/
104+
export { generatePkpDelegationAuthSig } from './lib/AuthManager/authAdapters/generatePkpDelegationAuthSig';
105+
106+
/**
107+
* Utility function to generate an EOA delegation auth signature for a given session key pair.
108+
* The EOA wallet will sign the session key delegation message directly.
109+
* This function is useful for server-side scenarios where you want to pre-generate
110+
* EOA session materials and reuse them across multiple requests.
111+
*/
112+
export { generateEoaDelegationAuthSig } from './lib/AuthManager/authAdapters/generateEoaDelegationAuthSig';
113+
114+
/**
115+
* Utility function to create a PKP auth context from pre-generated session materials.
116+
* This is a streamlined API for server-side scenarios where session materials
117+
* are generated once and reused across multiple requests.
118+
*
119+
* This function only requires the essential parameters (pkpPublicKey, sessionKeyPair, delegationAuthSig)
120+
* and extracts auth config information from the delegation signature automatically.
121+
*/
122+
export { getPkpAuthContextFromPreGeneratedAdapter } from './lib/AuthManager/authAdapters/getPkpAuthContextFromPreGeneratedAdapter';
123+
98124
// ============================== Authenticators ==============================
99125
export {
100126
DiscordAuthenticator,

packages/auth/src/lib/AuthManager/auth-manager.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getChildLogger } from '@lit-protocol/logger';
22
import { AuthData, HexPrefixedSchema } from '@lit-protocol/schemas';
3-
// import { AuthSig, SessionKeyPair } from '@lit-protocol/types';
3+
import { AuthSig, SessionKeyPair } from '@lit-protocol/types';
44
import { z } from 'zod';
55
import { AuthConfigV2 } from '../authenticators/types';
66
import type { LitAuthStorageProvider } from '../storage/types';
@@ -11,7 +11,9 @@ import {
1111
import { getPkpAuthContextAdapter } from './authAdapters/getPkpAuthContextAdapter';
1212
import { AuthConfigSchema } from './authContexts/BaseAuthContextType';
1313
import { getCustomAuthContextAdapter } from './authAdapters/getCustomAuthContextAdapter';
14-
import { hexToBigInt, keccak256, toBytes } from 'viem';
14+
import { generatePkpDelegationAuthSig } from './authAdapters/generatePkpDelegationAuthSig';
15+
import { generateEoaDelegationAuthSig } from './authAdapters/generateEoaDelegationAuthSig';
16+
import { getPkpAuthContextFromPreGeneratedAdapter } from './authAdapters/getPkpAuthContextFromPreGeneratedAdapter';
1517

1618
export interface AuthManagerParams {
1719
storage: LitAuthStorageProvider;
@@ -77,12 +79,20 @@ export const createAuthManager = (authManagerParams: AuthManagerParams) => {
7779
cache?: {
7880
delegationAuthSig?: boolean;
7981
};
80-
// Optional pre-generated auth materials for server-side usage
81-
// sessionKeyPair?: SessionKeyPair;
82-
// delegationAuthSig?: AuthSig;
8382
}) => {
8483
return getPkpAuthContextAdapter(authManagerParams, params);
8584
},
85+
createPkpAuthContextFromPreGenerated: (params: {
86+
pkpPublicKey: z.infer<typeof HexPrefixedSchema>;
87+
sessionKeyPair: SessionKeyPair;
88+
delegationAuthSig: AuthSig;
89+
authData?: AuthData;
90+
}) => {
91+
return getPkpAuthContextFromPreGeneratedAdapter(
92+
authManagerParams,
93+
params
94+
);
95+
},
8696
createCustomAuthContext: (params: {
8797
// authData: AuthData;
8898
pkpPublicKey: z.infer<typeof HexPrefixedSchema>;
@@ -104,5 +114,22 @@ export const createAuthManager = (authManagerParams: AuthManagerParams) => {
104114

105115
return getCustomAuthContextAdapter(authManagerParams, params);
106116
},
117+
generatePkpDelegationAuthSig: (params: {
118+
pkpPublicKey: z.infer<typeof HexPrefixedSchema>;
119+
authData: AuthData;
120+
sessionKeyPair: SessionKeyPair;
121+
authConfig: AuthConfigV2;
122+
litClient: BaseAuthContext<any>['litClient'];
123+
}) => {
124+
return generatePkpDelegationAuthSig(authManagerParams, params);
125+
},
126+
generateEoaDelegationAuthSig: (params: {
127+
account: any; // ExpectedAccountOrWalletClient type
128+
sessionKeyPair: SessionKeyPair;
129+
authConfig: AuthConfigV2;
130+
litClient: BaseAuthContext<any>['litClient'];
131+
}) => {
132+
return generateEoaDelegationAuthSig(authManagerParams, params);
133+
},
107134
};
108135
};

0 commit comments

Comments
 (0)