Skip to content

Commit c4182df

Browse files
committed
feat(tests): add executeJs basic and decryptAndCombine tests
1 parent ef926e4 commit c4182df

File tree

7 files changed

+364
-89
lines changed

7 files changed

+364
-89
lines changed

packages/e2e/src/e2e.spec.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1+
import { createCustomAuthContext } from './helper/auth-contexts';
12
import {
2-
createCustomAuthContext,
3-
createPkpAuthContext,
4-
} from './helper/auth-contexts';
5-
import {
6-
createExecuteJsTest,
7-
createPkpSignTest,
8-
createPkpEncryptDecryptTest,
93
createEncryptDecryptFlowTest,
10-
createPkpPermissionsManagerFlowTest,
114
createEoaNativeAuthFlowTest,
5+
createExecuteJsDecryptAndCombineTest,
6+
createExecuteJsBasicTest,
7+
createPaymentDelegationFlowTest,
8+
createPaymentManagerFlowTest,
9+
createPkpEncryptDecryptTest,
10+
createPkpPermissionsManagerFlowTest,
11+
createPkpSignTest,
1212
createViemSignMessageTest,
1313
createViemSignTransactionTest,
1414
createViemSignTypedDataTest,
1515
createViewPKPsByAddressTest,
1616
createViewPKPsByAuthDataTest,
17-
createPaymentManagerFlowTest,
18-
createPaymentDelegationFlowTest,
1917
} from './helper/tests';
2018
import { init } from './init';
2119
import { AuthContext } from './types';
@@ -56,7 +54,12 @@ describe('all', () => {
5654
it('pkpSign', () =>
5755
createPkpSignTest(ctx, () => ctx.aliceEoaAuthContext)());
5856
it('executeJs', () =>
59-
createExecuteJsTest(ctx, () => ctx.aliceEoaAuthContext)());
57+
createExecuteJsBasicTest(ctx, () => ctx.aliceEoaAuthContext)());
58+
it('executeJs decryptAndCombine', () =>
59+
createExecuteJsDecryptAndCombineTest(
60+
ctx,
61+
() => ctx.aliceEoaAuthContext
62+
)());
6063
it('viewPKPsByAddress', () => createViewPKPsByAddressTest(ctx)());
6164
it('viewPKPsByAuthData', () =>
6265
createViewPKPsByAuthDataTest(ctx, () => ctx.aliceEoaAuthContext)());
@@ -96,7 +99,7 @@ describe('all', () => {
9699
it('pkpSign', () =>
97100
createPkpSignTest(ctx, () => ctx.alicePkpAuthContext)());
98101
it('executeJs', () =>
99-
createExecuteJsTest(ctx, () => ctx.alicePkpAuthContext)());
102+
createExecuteJsBasicTest(ctx, () => ctx.alicePkpAuthContext)());
100103
it('viewPKPsByAddress', () => createViewPKPsByAddressTest(ctx)());
101104
it('viewPKPsByAuthData', () =>
102105
createViewPKPsByAuthDataTest(ctx, () => ctx.alicePkpAuthContext)());
@@ -137,7 +140,7 @@ describe('all', () => {
137140
ctx.eveViemAccountPkp.pubkey
138141
)());
139142
it('executeJs', () =>
140-
createExecuteJsTest(
143+
createExecuteJsBasicTest(
141144
ctx,
142145
() => eveCustomAuthContext,
143146
ctx.eveViemAccountPkp.pubkey

packages/e2e/src/helper/tests/execute-js.ts renamed to packages/e2e/src/helper/tests/executeJs/basic.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
import { init } from '../../init';
1+
import { init } from '../../../init';
2+
import { AuthContext } from '../../../types';
23

3-
export const createExecuteJsTest = (
4-
ctx: Awaited<ReturnType<typeof init>>,
5-
getAuthContext: () => any,
4+
type ExecuteJsContext = Pick<
5+
Awaited<ReturnType<typeof init>>,
6+
'litClient' | 'aliceViemAccountPkp'
7+
>;
8+
9+
export const createExecuteJsBasicTest = (
10+
ctx: ExecuteJsContext,
11+
getAuthContext: () => AuthContext,
612
pubkey?: string
713
) => {
814
return async () => {
@@ -22,14 +28,21 @@ export const createExecuteJsTest = (
2228
});
2329
})();`;
2430

31+
const defaultPubkey = ctx.aliceViemAccountPkp?.pubkey;
32+
const targetPubkey = pubkey ?? defaultPubkey;
33+
34+
if (!targetPubkey) {
35+
throw new Error('Missing PKP public key for executeJs test');
36+
}
37+
2538
const result = await ctx.litClient.executeJs({
2639
code: litActionCode,
2740
authContext: getAuthContext(),
2841
jsParams: {
2942
message: 'Test message from e2e executeJs',
3043
sigName: 'e2e-test-sig',
3144
toSign: 'Test message from e2e executeJs',
32-
publicKey: pubkey || ctx.aliceViemAccountPkp.pubkey,
45+
publicKey: targetPubkey,
3346
},
3447
});
3548

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import { AuthContext, LitClientInstance } from '../../../types';
2+
3+
type ExecuteJsContext = {
4+
litClient: LitClientInstance;
5+
aliceEoaAuthContext: AuthContext;
6+
};
7+
8+
export const decryptAndCombineLitAction = `
9+
(async () => {
10+
const results = {
11+
step1_getCurrentCid: null,
12+
step2_generateEntropy: null,
13+
step3_encrypt: null,
14+
step4_decrypt: null,
15+
step5_verify: null,
16+
};
17+
18+
try {
19+
// Step 1: Get current action IPFS CID
20+
const currentCid = Lit.Auth.actionIpfsIdStack[0];
21+
results.step1_getCurrentCid = {
22+
success: true,
23+
cid: currentCid,
24+
};
25+
26+
// Step 2: Generate entropy (32 random bytes)
27+
const entropyHex = await Lit.Actions.runOnce(
28+
{ waitForResponse: true, name: "generateEntropy" },
29+
async () => {
30+
return ethers.utils.hexlify(ethers.utils.randomBytes(32));
31+
}
32+
);
33+
const entropy = ethers.utils.arrayify(entropyHex);
34+
results.step2_generateEntropy = {
35+
success: true,
36+
entropyPreview: entropyHex.substring(0, 20) + "...",
37+
entropyLength: entropy.length,
38+
};
39+
40+
// Step 3: Encrypt with access control locked to current IPFS CID
41+
const accessControlConditions = [
42+
{
43+
contractAddress: "",
44+
standardContractType: "",
45+
chain: "ethereum",
46+
method: "",
47+
parameters: [":currentActionIpfsId"],
48+
returnValueTest: {
49+
comparator: "=",
50+
value: currentCid,
51+
},
52+
},
53+
];
54+
55+
let encryptResult = await Lit.Actions.runOnce(
56+
{ waitForResponse: true, name: "encrypt" },
57+
async () => {
58+
return JSON.stringify(
59+
await Lit.Actions.encrypt({
60+
accessControlConditions,
61+
to_encrypt: ethers.utils.toUtf8Bytes(entropyHex),
62+
})
63+
);
64+
}
65+
);
66+
encryptResult = JSON.parse(encryptResult);
67+
68+
// Convert ciphertext to base64 for transmission
69+
let ciphertextStr;
70+
if (encryptResult.ciphertext instanceof Uint8Array) {
71+
const binaryStr = Array.from(encryptResult.ciphertext)
72+
.map((byte) => String.fromCharCode(byte))
73+
.join("");
74+
ciphertextStr = btoa(binaryStr);
75+
} else {
76+
ciphertextStr = encryptResult.ciphertext;
77+
}
78+
79+
// Convert dataToEncryptHash to hex
80+
let dataHashStr;
81+
if (encryptResult.dataToEncryptHash instanceof Uint8Array) {
82+
dataHashStr = ethers.utils.hexlify(encryptResult.dataToEncryptHash);
83+
} else {
84+
dataHashStr = encryptResult.dataToEncryptHash;
85+
}
86+
87+
results.step3_encrypt = {
88+
success: true,
89+
ciphertextLength: ciphertextStr.length,
90+
ciphertextPreview: ciphertextStr.substring(0, 30) + "...",
91+
dataToEncryptHash: dataHashStr,
92+
};
93+
94+
// Step 4: Decrypt using decryptAndCombine
95+
const decryptResult = await Lit.Actions.decryptAndCombine({
96+
accessControlConditions,
97+
ciphertext: encryptResult.ciphertext,
98+
dataToEncryptHash: encryptResult.dataToEncryptHash,
99+
authSig: null,
100+
chain: "ethereum",
101+
});
102+
103+
// Convert decrypted result to hex for comparison
104+
let decryptedHex;
105+
if (decryptResult instanceof Uint8Array) {
106+
decryptedHex = ethers.utils.hexlify(decryptResult);
107+
} else if (typeof decryptResult === "string") {
108+
decryptedHex = decryptResult;
109+
} else {
110+
decryptedHex = "unknown format";
111+
}
112+
113+
results.step4_decrypt = {
114+
success: true,
115+
decryptedDataPreview: decryptedHex.substring(0, 20) + "...",
116+
decryptedLength: decryptResult.length,
117+
};
118+
119+
// Step 5: Verify original matches decrypted
120+
const matches = entropyHex === decryptedHex;
121+
results.step5_verify = {
122+
success: true,
123+
matches,
124+
originalPreview: entropyHex.substring(0, 20) + "...",
125+
decryptedPreview: decryptedHex.substring(0, 20) + "...",
126+
};
127+
128+
Lit.Actions.setResponse({
129+
response: JSON.stringify(
130+
{
131+
success: true,
132+
currentCid,
133+
results,
134+
},
135+
null,
136+
2
137+
),
138+
});
139+
} catch (error) {
140+
Lit.Actions.setResponse({
141+
response: JSON.stringify(
142+
{
143+
success: false,
144+
error: error.message,
145+
results,
146+
},
147+
null,
148+
2
149+
),
150+
});
151+
}
152+
})();`;
153+
154+
export const createExecuteJsDecryptAndCombineTest = (
155+
ctx: ExecuteJsContext,
156+
getAuthContext: () => AuthContext = () => ctx.aliceEoaAuthContext
157+
) => {
158+
return async () => {
159+
const result = await ctx.litClient.executeJs({
160+
code: decryptAndCombineLitAction,
161+
authContext: getAuthContext(),
162+
jsParams: {},
163+
});
164+
165+
if (typeof result.response !== 'string') {
166+
throw new Error('Expected executeJs response to be a string payload');
167+
}
168+
169+
const parsed = JSON.parse(result.response);
170+
171+
expect(parsed.success).toBe(true);
172+
expect(parsed.currentCid).toBeDefined();
173+
expect(parsed.results?.step1_getCurrentCid?.success).toBe(true);
174+
expect(parsed.results?.step2_generateEntropy?.entropyLength).toBe(32);
175+
expect(parsed.results?.step3_encrypt?.success).toBe(true);
176+
expect(parsed.results?.step4_decrypt?.success).toBe(true);
177+
expect(parsed.results?.step5_verify?.matches).toBe(true);
178+
};
179+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export { createExecuteJsBasicTest } from './basic';
2+
export {
3+
createExecuteJsDecryptAndCombineTest,
4+
decryptAndCombineLitAction,
5+
} from './decrypt-and-combine';

packages/e2e/src/helper/tests/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Endpoint tests
22
export { createPkpSignTest } from './pkp-sign';
3-
export { createExecuteJsTest } from './execute-js';
3+
export {
4+
createExecuteJsBasicTest,
5+
createExecuteJsDecryptAndCombineTest,
6+
} from './executeJs';
47
export { createViewPKPsByAddressTest } from './view-pkps-by-address';
58
export { createViewPKPsByAuthDataTest } from './view-pkps-by-auth-data';
69
export { createPkpEncryptDecryptTest } from './pkp-encrypt-decrypt';

0 commit comments

Comments
 (0)