Skip to content

Commit e18c696

Browse files
committed
refactor(e2e): refactor init.ts to include better logic to get or create account, moved the pkpAuthContext creation into the init.ts, and added a demo to showcase using PKP EOA Auth Method to add a permitted address via the PKP Viem Account
1 parent 5bf5189 commit e18c696

File tree

4 files changed

+341
-140
lines changed

4 files changed

+341
-140
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Run this command for this demo:
2+
// LOG_LEVEL=silent NETWORK=naga-dev bun run ./e2e/src/demo/add-permitted-address-demo.ts
3+
4+
//
5+
// This test if a PKP EOA Auth Method could add a permitted address via the PKPViemAccount
6+
//
7+
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
8+
import { nonceManager } from 'viem';
9+
import { fundAccount } from '../helper/fundAccount';
10+
import { createLitClient } from '@lit-protocol/lit-client';
11+
import {
12+
createAuthManager,
13+
storagePlugins,
14+
ViemAccountAuthenticator,
15+
} from '@lit-protocol/auth';
16+
17+
// -- Configurations
18+
const { nagaLocal } = await import('@lit-protocol/networks');
19+
const LOCAL_NETWORK_FUNDING_AMOUNT = '1';
20+
21+
// -- Master account to fund the alice(test) account
22+
const localMasterAccount = privateKeyToAccount(
23+
process.env['LOCAL_MASTER_ACCOUNT'] as `0x${string}`,
24+
{
25+
nonceManager: nonceManager,
26+
}
27+
);
28+
29+
// -- EOA Test account via Viem
30+
const aliceViemAccount = privateKeyToAccount(generatePrivateKey());
31+
32+
// -- Using the authenticator to get the Auth Data
33+
const aliceViemAccountAuthData = await ViemAccountAuthenticator.authenticate(
34+
aliceViemAccount
35+
);
36+
37+
console.log("✅ aliceViemAccountAuthData:", aliceViemAccountAuthData);
38+
39+
try {
40+
await fundAccount(aliceViemAccount, localMasterAccount, nagaLocal, {
41+
ifLessThan: LOCAL_NETWORK_FUNDING_AMOUNT,
42+
thenFundWith: LOCAL_NETWORK_FUNDING_AMOUNT,
43+
});
44+
console.log("✅ Account Funded.")
45+
} catch (e) {
46+
throw new Error("❌ Failed to fund account.")
47+
}
48+
49+
/**
50+
* ====================================
51+
* Initialise the LitClient
52+
* ====================================
53+
*/
54+
const litClient = await createLitClient({ network: nagaLocal });
55+
console.log("✅ Created Lit Client")
56+
57+
/**
58+
* ====================================
59+
* Initialise the AuthManager
60+
* ====================================
61+
*/
62+
const authManager = createAuthManager({
63+
storage: storagePlugins.localStorageNode({
64+
appName: 'my-local-testing-app',
65+
networkName: 'local-test',
66+
storagePath: './lit-auth-local',
67+
}),
68+
});
69+
console.log("✅ Created Auth Manager")
70+
71+
// Minting a new PKP
72+
const tx = await litClient.mintWithAuth({
73+
account: aliceViemAccount,
74+
authData: aliceViemAccountAuthData,
75+
scopes: ['sign-anything'],
76+
});
77+
console.log("✅ TX 1 done");
78+
console.log("ℹ️ tx:", tx)
79+
80+
const pkpInfo = tx.data;
81+
console.log("✅ pkpInfo:", pkpInfo);
82+
83+
const pkpPermissionsManagerForAliceViemAccount = await litClient.getPKPPermissionsManager({
84+
pkpIdentifier: {
85+
tokenId: pkpInfo.tokenId,
86+
},
87+
account: aliceViemAccount,
88+
});
89+
90+
console.log("✅ pkpPermissionsManagerForAliceViemAccount:", await pkpPermissionsManagerForAliceViemAccount.getPermissionsContext());
91+
92+
// check is address permitted
93+
const aliceViemAccountIsPermitted = await pkpPermissionsManagerForAliceViemAccount.isPermittedAddress({
94+
address: aliceViemAccount.address,
95+
});
96+
97+
console.log(`❗️ ${aliceViemAccount.address} is ${aliceViemAccountIsPermitted ? 'permitted' : 'NOT permitted'}`);
98+
99+
// check if pkp address is permitted
100+
const pkpIsPermitted = await pkpPermissionsManagerForAliceViemAccount.isPermittedAddress({
101+
address: pkpInfo.ethAddress,
102+
});
103+
104+
console.log(`❗️ ${pkpInfo.ethAddress} is ${pkpIsPermitted ? 'permitted' : 'NOT permitted'}`);
105+
106+
107+
const authContext = await authManager.createPkpAuthContext({
108+
authData: aliceViemAccountAuthData,
109+
pkpPublicKey: pkpInfo.pubkey,
110+
authConfig: {
111+
capabilityAuthSigs: [],
112+
expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(),
113+
statement: "",
114+
domain: "",
115+
resources: [
116+
["pkp-signing", "*"],
117+
["lit-action-execution", "*"],
118+
],
119+
},
120+
litClient,
121+
});
122+
123+
console.log("authContext:", authContext);
124+
125+
const pkpViemAccount = await litClient.getPkpViemAccount({
126+
pkpPublicKey: pkpInfo.pubkey,
127+
authContext: authContext,
128+
chainConfig: nagaLocal.getChainConfig(),
129+
});
130+
131+
await fundAccount(pkpViemAccount, localMasterAccount, nagaLocal, {
132+
ifLessThan: LOCAL_NETWORK_FUNDING_AMOUNT,
133+
thenFundWith: LOCAL_NETWORK_FUNDING_AMOUNT,
134+
});
135+
136+
const pkpViemAccountPermissionsManager = await litClient.getPKPPermissionsManager({
137+
pkpIdentifier: {
138+
tokenId: pkpInfo.tokenId,
139+
},
140+
account: pkpViemAccount,
141+
});
142+
143+
try {
144+
const tx2 = await pkpViemAccountPermissionsManager.addPermittedAddress({
145+
address: "0x1234567890123456789012345678901234567890",
146+
scopes: ["sign-anything"],
147+
});
148+
console.log('tx2:', tx2)
149+
} catch (e) {
150+
throw new Error(e);
151+
}
152+
153+
console.log("✅ pkpViemAccountPermissionsManager:", await pkpViemAccountPermissionsManager.getPermissionsContext());
154+
155+
process.exit();

e2e/src/e2e.spec.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe('all', () => {
3232
ctx = await init();
3333

3434
// Create PKP and custom auth contexts using helper functions
35-
alicePkpAuthContext = await createPkpAuthContext(ctx);
35+
// alicePkpAuthContext = await createPkpAuthContext(ctx);
3636
aliceCustomAuthContext = await createCustomAuthContext(ctx);
3737
} catch (e) {
3838
console.error(e);
@@ -83,29 +83,29 @@ describe('all', () => {
8383
console.log('🔐 Testing using Programmable Key Pair authentication');
8484

8585
describe('endpoints', () => {
86-
it('pkpSign', () => createPkpSignTest(ctx, () => alicePkpAuthContext)());
86+
it('pkpSign', () => createPkpSignTest(ctx, () => ctx.alicePkpAuthContext)());
8787
it('executeJs', () =>
88-
createExecuteJsTest(ctx, () => alicePkpAuthContext)());
88+
createExecuteJsTest(ctx, () => ctx.alicePkpAuthContext)());
8989
it('viewPKPsByAddress', () =>
90-
createViewPKPsByAddressTest(ctx, () => alicePkpAuthContext)());
90+
createViewPKPsByAddressTest(ctx, () => ctx.alicePkpAuthContext)());
9191
it('viewPKPsByAuthData', () =>
92-
createViewPKPsByAuthDataTest(ctx, () => alicePkpAuthContext)());
92+
createViewPKPsByAuthDataTest(ctx, () => ctx.alicePkpAuthContext)());
9393
it('pkpEncryptDecrypt', () =>
94-
createPkpEncryptDecryptTest(ctx, () => alicePkpAuthContext)());
94+
createPkpEncryptDecryptTest(ctx, () => ctx.alicePkpAuthContext)());
9595
it('encryptDecryptFlow', () =>
96-
createEncryptDecryptFlowTest(ctx, () => alicePkpAuthContext)());
96+
createEncryptDecryptFlowTest(ctx, () => ctx.alicePkpAuthContext)());
9797
it('pkpPermissionsManagerFlow', () =>
98-
createPkpPermissionsManagerFlowTest(ctx, () => alicePkpAuthContext)());
98+
createPkpPermissionsManagerFlowTest(ctx, () => ctx.alicePkpAuthContext)());
9999
});
100100

101101
describe('integrations', () => {
102102
describe('pkp viem account', () => {
103103
it('sign message', () =>
104-
createViemSignMessageTest(ctx, () => alicePkpAuthContext)());
104+
createViemSignMessageTest(ctx, () => ctx.alicePkpAuthContext)());
105105
it('sign transaction', () =>
106-
createViemSignTransactionTest(ctx, () => alicePkpAuthContext)());
106+
createViemSignTransactionTest(ctx, () => ctx.alicePkpAuthContext)());
107107
it('sign typed data', () =>
108-
createViemSignTypedDataTest(ctx, () => alicePkpAuthContext)());
108+
createViemSignTypedDataTest(ctx, () => ctx.alicePkpAuthContext)());
109109
});
110110
});
111111
});

e2e/src/helper/pkp-utils.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* PKP Utilities
3+
*
4+
* This module provides utility functions for managing Programmable Key Pairs (PKPs)
5+
* in the Lit Protocol ecosystem. It handles the common pattern of checking for
6+
* existing PKPs and creating new ones when necessary.
7+
*
8+
* Usage:
9+
* import { getOrCreatePkp } from './helper/pkp-utils';
10+
* const pkp = await getOrCreatePkp(litClient, authData, account, storagePath, networkName);
11+
*/
12+
13+
import { storagePlugins } from '@lit-protocol/auth';
14+
15+
// Configuration constants
16+
const PAGINATION_LIMIT = 5;
17+
const APP_NAME = 'my-app';
18+
const PKP_SCOPES = ['sign-anything'];
19+
20+
/**
21+
* Gets an existing PKP or creates a new one if none exists
22+
*
23+
* @param litClient - The Lit Protocol client instance
24+
* @param authData - Authentication data for the account
25+
* @param account - The account to associate with the PKP
26+
* @param storagePath - Local storage path for PKP tokens
27+
* @param networkName - Name of the network being used
28+
* @returns Promise<PKP> - The existing or newly created PKP
29+
*/
30+
export const getOrCreatePkp = async (
31+
litClient: any,
32+
authData: any,
33+
account: any,
34+
storagePath: string,
35+
networkName: string
36+
) => {
37+
// Check for existing PKPs
38+
const { pkps } = await litClient.viewPKPsByAuthData({
39+
authData,
40+
pagination: {
41+
limit: PAGINATION_LIMIT,
42+
},
43+
storageProvider: storagePlugins.localStorageNode({
44+
appName: APP_NAME,
45+
networkName,
46+
storagePath,
47+
}),
48+
});
49+
50+
// If PKP exists, return it
51+
if (pkps && pkps[0]) {
52+
return pkps[0];
53+
}
54+
55+
// Otherwise mint new PKP
56+
const mintResult = await litClient.mintWithAuth({
57+
authData,
58+
account,
59+
scopes: PKP_SCOPES,
60+
});
61+
62+
// Query again to get the newly minted PKP in the expected format
63+
const { pkps: newPkps } = await litClient.viewPKPsByAuthData({
64+
authData,
65+
pagination: {
66+
limit: PAGINATION_LIMIT,
67+
},
68+
storageProvider: storagePlugins.localStorageNode({
69+
appName: APP_NAME,
70+
networkName,
71+
storagePath,
72+
}),
73+
});
74+
75+
return newPkps[0];
76+
};

0 commit comments

Comments
 (0)