@account-kit/wallet-client 0.1.0-alpha.10 → 0.1.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/client/actions/requestAccount.js +2 -2
- package/dist/esm/client/actions/requestAccount.js.map +1 -1
- package/dist/esm/client/actions/signSignatureRequest.d.ts +3 -3
- package/dist/esm/client/actions/signSignatureRequest.js.map +1 -1
- package/dist/esm/client/client.e2e-test.js +40 -1
- package/dist/esm/client/client.e2e-test.js.map +1 -1
- package/dist/esm/isomorphic/actions/createSession.js +2 -2
- package/dist/esm/isomorphic/actions/createSession.js.map +1 -1
- package/dist/esm/isomorphic/actions/getCallsStatus.js +2 -2
- package/dist/esm/isomorphic/actions/getCallsStatus.js.map +1 -1
- package/dist/esm/isomorphic/actions/prepareSign.js +2 -2
- package/dist/esm/isomorphic/actions/prepareSign.js.map +1 -1
- package/dist/esm/isomorphic/actions/sendPreparedCalls.js +37 -10
- package/dist/esm/isomorphic/actions/sendPreparedCalls.js.map +1 -1
- package/dist/esm/isomorphic/utils/createAccount.d.ts +2 -2
- package/dist/esm/isomorphic/utils/createAccount.js +1 -1
- package/dist/esm/isomorphic/utils/createAccount.js.map +1 -1
- package/dist/esm/isomorphic/utils/decodeSignature.d.ts +2 -2
- package/dist/esm/isomorphic/utils/decodeSignature.js +2 -2
- package/dist/esm/isomorphic/utils/decodeSignature.js.map +1 -1
- package/dist/esm/isomorphic/utils/parsePermissionsContext.d.ts +2 -2
- package/dist/esm/isomorphic/utils/parsePermissionsContext.js +1 -1
- package/dist/esm/isomorphic/utils/parsePermissionsContext.js.map +1 -1
- package/dist/esm/isomorphic/utils/supportsFeature.d.ts +2 -2
- package/dist/esm/isomorphic/utils/supportsFeature.js.map +1 -1
- package/dist/types/client/actions/signSignatureRequest.d.ts +3 -3
- package/dist/types/client/actions/signSignatureRequest.d.ts.map +1 -1
- package/dist/types/isomorphic/actions/prepareSign.d.ts.map +1 -1
- package/dist/types/isomorphic/actions/sendPreparedCalls.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/createAccount.d.ts +2 -2
- package/dist/types/isomorphic/utils/createAccount.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/decodeSignature.d.ts +2 -2
- package/dist/types/isomorphic/utils/decodeSignature.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts +2 -2
- package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts.map +1 -1
- package/dist/types/isomorphic/utils/supportsFeature.d.ts +2 -2
- package/dist/types/isomorphic/utils/supportsFeature.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/client/actions/requestAccount.ts +2 -2
- package/src/client/actions/signSignatureRequest.ts +8 -8
- package/src/client/client.e2e-test.ts +270 -191
- package/src/isomorphic/actions/createSession.ts +2 -2
- package/src/isomorphic/actions/getCallsStatus.ts +2 -2
- package/src/isomorphic/actions/prepareSign.ts +2 -5
- package/src/isomorphic/actions/sendPreparedCalls.ts +46 -9
- package/src/isomorphic/utils/createAccount.ts +2 -2
- package/src/isomorphic/utils/decodeSignature.ts +6 -6
- package/src/isomorphic/utils/parsePermissionsContext.ts +2 -2
- package/src/isomorphic/utils/supportsFeature.ts +3 -3
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { LocalAccountSigner } from "@aa-sdk/core";
|
|
2
2
|
import { alchemy, arbitrumSepolia } from "@account-kit/infra";
|
|
3
3
|
import { describe, expect, it } from "bun:test";
|
|
4
|
-
import { createPublicClient, zeroAddress, type Address } from "viem";
|
|
5
|
-
import { createSmartWalletClient } from "./index.js";
|
|
4
|
+
import { createPublicClient, zeroAddress, type Address, type Hex } from "viem";
|
|
5
|
+
import { createSmartWalletClient, type SmartWalletClient } from "./index.js";
|
|
6
|
+
import { sleep } from "bun";
|
|
6
7
|
|
|
7
8
|
describe("Client E2E Tests", () => {
|
|
8
9
|
const transport = alchemy(
|
|
@@ -119,105 +120,129 @@ describe("Client E2E Tests", () => {
|
|
|
119
120
|
expect(isValid).toBeTrue();
|
|
120
121
|
});
|
|
121
122
|
|
|
122
|
-
it(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const preparedCalls = await _client.prepareCalls({
|
|
141
|
-
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
142
|
-
from: account.address,
|
|
143
|
-
capabilities: {
|
|
144
|
-
paymasterService: {
|
|
145
|
-
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
123
|
+
it(
|
|
124
|
+
"should successfully send a UO with paymaster using 7702",
|
|
125
|
+
async () => {
|
|
126
|
+
const _signer = LocalAccountSigner.privateKeyToAccountSigner(
|
|
127
|
+
"0x49daf21e92c997093e9ffdf7e7ddbf8970e9eadc5d4847d0f690db25d5128e1f",
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const _client = createSmartWalletClient({
|
|
131
|
+
transport,
|
|
132
|
+
chain: arbitrumSepolia,
|
|
133
|
+
mode: "local",
|
|
134
|
+
signer: _signer,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const account = await _client.requestAccount({
|
|
138
|
+
creationHint: {
|
|
139
|
+
accountType: "7702",
|
|
146
140
|
},
|
|
147
|
-
}
|
|
148
|
-
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const preparedCalls = await _client.prepareCalls({
|
|
144
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
145
|
+
from: account.address,
|
|
146
|
+
capabilities: {
|
|
147
|
+
paymasterService: {
|
|
148
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
});
|
|
149
152
|
|
|
150
|
-
|
|
153
|
+
const signedCalls = await _client.signPreparedCalls(preparedCalls);
|
|
151
154
|
|
|
152
|
-
|
|
155
|
+
const result = await _client.sendPreparedCalls(signedCalls);
|
|
153
156
|
|
|
154
|
-
|
|
155
|
-
});
|
|
157
|
+
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
156
158
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
paymasterService: {
|
|
164
|
-
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
});
|
|
159
|
+
await waitForUserOpSuccess(client, result.preparedCallIds[0]);
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
timeout: 45_000,
|
|
163
|
+
},
|
|
164
|
+
);
|
|
168
165
|
|
|
169
|
-
|
|
166
|
+
it(
|
|
167
|
+
"should successfully send a UO with paymaster",
|
|
168
|
+
async () => {
|
|
169
|
+
const account = await client.requestAccount();
|
|
170
|
+
const preparedCalls = await client.prepareCalls({
|
|
171
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
172
|
+
from: account.address,
|
|
173
|
+
capabilities: {
|
|
174
|
+
paymasterService: {
|
|
175
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
});
|
|
170
179
|
|
|
171
|
-
|
|
180
|
+
const signedCalls = await client.signPreparedCalls(preparedCalls);
|
|
172
181
|
|
|
173
|
-
|
|
174
|
-
});
|
|
182
|
+
const result = await client.sendPreparedCalls(signedCalls);
|
|
175
183
|
|
|
176
|
-
|
|
177
|
-
const account = await client.requestAccount();
|
|
184
|
+
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
178
185
|
|
|
179
|
-
|
|
186
|
+
await waitForUserOpSuccess(client, result.preparedCallIds[0]);
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
timeout: 45_000,
|
|
190
|
+
},
|
|
191
|
+
);
|
|
180
192
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
publicKey: await sessionKey.getAddress(),
|
|
186
|
-
type: "secp256k1",
|
|
187
|
-
},
|
|
188
|
-
permissions: [{ type: "root" }],
|
|
189
|
-
});
|
|
193
|
+
it(
|
|
194
|
+
"should successfully create a session with grantPermissions and send a UO",
|
|
195
|
+
async () => {
|
|
196
|
+
const account = await client.requestAccount();
|
|
190
197
|
|
|
191
|
-
|
|
192
|
-
transport,
|
|
193
|
-
chain: arbitrumSepolia,
|
|
194
|
-
mode: "local",
|
|
195
|
-
signer: sessionKey,
|
|
196
|
-
});
|
|
198
|
+
const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
|
|
197
199
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
const permissions = await client.grantPermissions({
|
|
201
|
+
account: account.address,
|
|
202
|
+
expirySec: Math.floor(Date.now() / 1000) + 60 * 60,
|
|
203
|
+
key: {
|
|
204
|
+
publicKey: await sessionKey.getAddress(),
|
|
205
|
+
type: "secp256k1",
|
|
204
206
|
},
|
|
205
|
-
permissions,
|
|
206
|
-
}
|
|
207
|
-
|
|
207
|
+
permissions: [{ type: "root" }],
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const sessionKeyClient = createSmartWalletClient({
|
|
211
|
+
transport,
|
|
212
|
+
chain: arbitrumSepolia,
|
|
213
|
+
mode: "local",
|
|
214
|
+
signer: sessionKey,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const preparedCalls = await sessionKeyClient.prepareCalls({
|
|
218
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
219
|
+
from: account.address,
|
|
220
|
+
capabilities: {
|
|
221
|
+
paymasterService: {
|
|
222
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
223
|
+
},
|
|
224
|
+
permissions,
|
|
225
|
+
},
|
|
226
|
+
});
|
|
208
227
|
|
|
209
|
-
|
|
210
|
-
|
|
228
|
+
const signedCalls =
|
|
229
|
+
await sessionKeyClient.signPreparedCalls(preparedCalls);
|
|
211
230
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
231
|
+
const result = await sessionKeyClient.sendPreparedCalls({
|
|
232
|
+
...signedCalls,
|
|
233
|
+
capabilities: {
|
|
234
|
+
permissions,
|
|
235
|
+
},
|
|
236
|
+
});
|
|
218
237
|
|
|
219
|
-
|
|
220
|
-
|
|
238
|
+
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
239
|
+
|
|
240
|
+
await waitForUserOpSuccess(client, result.preparedCallIds[0]);
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
timeout: 45_000,
|
|
244
|
+
},
|
|
245
|
+
);
|
|
221
246
|
});
|
|
222
247
|
|
|
223
248
|
describe("Remote Mode Tests", () => {
|
|
@@ -326,138 +351,170 @@ describe("Client E2E Tests", () => {
|
|
|
326
351
|
expect(isValid).toBeTrue();
|
|
327
352
|
});
|
|
328
353
|
|
|
329
|
-
it(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
354
|
+
it(
|
|
355
|
+
"should successfully send a UO with paymaster",
|
|
356
|
+
async () => {
|
|
357
|
+
const account = await client.requestAccount();
|
|
358
|
+
const preparedCalls = await client.prepareCalls({
|
|
359
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
360
|
+
from: account.address,
|
|
361
|
+
capabilities: {
|
|
362
|
+
paymasterService: {
|
|
363
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
364
|
+
},
|
|
337
365
|
},
|
|
338
|
-
}
|
|
339
|
-
});
|
|
366
|
+
});
|
|
340
367
|
|
|
341
|
-
|
|
368
|
+
const signedCalls = await client.signPreparedCalls(preparedCalls);
|
|
342
369
|
|
|
343
|
-
|
|
370
|
+
const result = await client.sendPreparedCalls(signedCalls);
|
|
344
371
|
|
|
345
|
-
|
|
346
|
-
});
|
|
372
|
+
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
347
373
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
374
|
+
await waitForUserOpSuccess(client, result.preparedCallIds[0]);
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
timeout: 45_000,
|
|
378
|
+
},
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
it(
|
|
382
|
+
"should successfully drop and replace a UO with repeat calls",
|
|
383
|
+
async () => {
|
|
384
|
+
const account = await client.requestAccount();
|
|
385
|
+
const preparedCalls = await client.prepareCalls({
|
|
386
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
387
|
+
from: account.address,
|
|
388
|
+
capabilities: {
|
|
389
|
+
paymasterService: {
|
|
390
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
391
|
+
},
|
|
356
392
|
},
|
|
357
|
-
}
|
|
358
|
-
});
|
|
393
|
+
});
|
|
359
394
|
|
|
360
|
-
|
|
361
|
-
|
|
395
|
+
const signedCalls = await client.signPreparedCalls(preparedCalls);
|
|
396
|
+
const result = await client.sendPreparedCalls(signedCalls);
|
|
362
397
|
|
|
363
|
-
|
|
398
|
+
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
364
399
|
|
|
365
|
-
|
|
366
|
-
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
367
|
-
from: account.address,
|
|
368
|
-
capabilities: {
|
|
369
|
-
paymasterService: {
|
|
370
|
-
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
});
|
|
374
|
-
const signedCalls2 = await client.signPreparedCalls(prepareCalls2);
|
|
375
|
-
const result2 = await client.sendPreparedCalls(signedCalls2);
|
|
400
|
+
await waitForUserOpSuccess(client, result.preparedCallIds[0]);
|
|
376
401
|
|
|
377
|
-
|
|
378
|
-
|
|
402
|
+
const prepareCalls2 = await client.prepareCalls({
|
|
403
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
404
|
+
from: account.address,
|
|
405
|
+
capabilities: {
|
|
406
|
+
paymasterService: {
|
|
407
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
});
|
|
411
|
+
const signedCalls2 = await client.signPreparedCalls(prepareCalls2);
|
|
412
|
+
const result2 = await client.sendPreparedCalls(signedCalls2);
|
|
379
413
|
|
|
380
|
-
|
|
381
|
-
const _signer = LocalAccountSigner.privateKeyToAccountSigner(
|
|
382
|
-
"0x00d35c6d307b5cddeb70aeed96ee27a551fee58bf1a43858477e6c11f9172ba8",
|
|
383
|
-
);
|
|
414
|
+
expect(result2.preparedCallIds).toBeArrayOfSize(1);
|
|
384
415
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
416
|
+
await waitForUserOpSuccess(client, result2.preparedCallIds[0]);
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
timeout: 90_000,
|
|
420
|
+
},
|
|
421
|
+
);
|
|
391
422
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
423
|
+
it(
|
|
424
|
+
"should successfully send a UO with paymaster using 7702",
|
|
425
|
+
async () => {
|
|
426
|
+
const _signer = LocalAccountSigner.privateKeyToAccountSigner(
|
|
427
|
+
"0x00d35c6d307b5cddeb70aeed96ee27a551fee58bf1a43858477e6c11f9172ba8",
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
const _client = createSmartWalletClient({
|
|
431
|
+
transport,
|
|
432
|
+
chain: arbitrumSepolia,
|
|
433
|
+
mode: "remote",
|
|
434
|
+
signer: _signer,
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
const account = await _client.requestAccount({
|
|
438
|
+
creationHint: {
|
|
439
|
+
accountType: "7702",
|
|
405
440
|
},
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
441
|
+
});
|
|
442
|
+
expect(account.address).toBe(await _signer.getAddress());
|
|
443
|
+
|
|
444
|
+
const preparedCalls = await _client.prepareCalls({
|
|
445
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
446
|
+
from: account.address,
|
|
447
|
+
capabilities: {
|
|
448
|
+
paymasterService: {
|
|
449
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
});
|
|
410
453
|
|
|
411
|
-
|
|
454
|
+
const signedCalls = await _client.signPreparedCalls(preparedCalls);
|
|
412
455
|
|
|
413
|
-
|
|
414
|
-
});
|
|
456
|
+
const result = await _client.sendPreparedCalls(signedCalls);
|
|
415
457
|
|
|
416
|
-
|
|
417
|
-
const account = await client.requestAccount();
|
|
458
|
+
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
418
459
|
|
|
419
|
-
|
|
460
|
+
await waitForUserOpSuccess(client, result.preparedCallIds[0]);
|
|
461
|
+
},
|
|
462
|
+
{ timeout: 45_000 },
|
|
463
|
+
);
|
|
420
464
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
publicKey: await sessionKey.getAddress(),
|
|
426
|
-
type: "secp256k1",
|
|
427
|
-
},
|
|
428
|
-
permissions: [{ type: "root" }],
|
|
429
|
-
});
|
|
465
|
+
it(
|
|
466
|
+
"should successfully create a session with grantPermissions and send a UO",
|
|
467
|
+
async () => {
|
|
468
|
+
const account = await client.requestAccount();
|
|
430
469
|
|
|
431
|
-
|
|
432
|
-
transport,
|
|
433
|
-
chain: arbitrumSepolia,
|
|
434
|
-
mode: "remote",
|
|
435
|
-
signer: sessionKey,
|
|
436
|
-
});
|
|
470
|
+
const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
|
|
437
471
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
472
|
+
const permissions = await client.grantPermissions({
|
|
473
|
+
account: account.address,
|
|
474
|
+
expirySec: Math.floor(Date.now() / 1000) + 60 * 60,
|
|
475
|
+
key: {
|
|
476
|
+
publicKey: await sessionKey.getAddress(),
|
|
477
|
+
type: "secp256k1",
|
|
444
478
|
},
|
|
445
|
-
permissions,
|
|
446
|
-
}
|
|
447
|
-
|
|
479
|
+
permissions: [{ type: "root" }],
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
const sessionKeyClient = createSmartWalletClient({
|
|
483
|
+
transport,
|
|
484
|
+
chain: arbitrumSepolia,
|
|
485
|
+
mode: "remote",
|
|
486
|
+
signer: sessionKey,
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
const preparedCalls = await sessionKeyClient.prepareCalls({
|
|
490
|
+
calls: [{ to: zeroAddress, value: "0x0" }],
|
|
491
|
+
from: account.address,
|
|
492
|
+
capabilities: {
|
|
493
|
+
paymasterService: {
|
|
494
|
+
policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
|
|
495
|
+
},
|
|
496
|
+
permissions,
|
|
497
|
+
},
|
|
498
|
+
});
|
|
448
499
|
|
|
449
|
-
|
|
450
|
-
|
|
500
|
+
const signedCalls =
|
|
501
|
+
await sessionKeyClient.signPreparedCalls(preparedCalls);
|
|
451
502
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
503
|
+
const result = await sessionKeyClient.sendPreparedCalls({
|
|
504
|
+
...signedCalls,
|
|
505
|
+
capabilities: {
|
|
506
|
+
permissions,
|
|
507
|
+
},
|
|
508
|
+
});
|
|
458
509
|
|
|
459
|
-
|
|
460
|
-
|
|
510
|
+
expect(result.preparedCallIds).toBeArrayOfSize(1);
|
|
511
|
+
|
|
512
|
+
await waitForUserOpSuccess(client, result.preparedCallIds[0]);
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
timeout: 45_000,
|
|
516
|
+
},
|
|
517
|
+
);
|
|
461
518
|
});
|
|
462
519
|
|
|
463
520
|
const givenTypedData = {
|
|
@@ -493,3 +550,25 @@ describe("Client E2E Tests", () => {
|
|
|
493
550
|
},
|
|
494
551
|
} as const;
|
|
495
552
|
});
|
|
553
|
+
|
|
554
|
+
const waitForUserOpSuccess = async (
|
|
555
|
+
client: SmartWalletClient,
|
|
556
|
+
preparedCallId: Hex,
|
|
557
|
+
) => {
|
|
558
|
+
const maxTimeoutMs = 1000 * 30;
|
|
559
|
+
const deadline = Date.now() + maxTimeoutMs;
|
|
560
|
+
while (Date.now() < deadline) {
|
|
561
|
+
const status = (await client.getCallsStatus(preparedCallId)).status;
|
|
562
|
+
if (status === 200) {
|
|
563
|
+
// Success.
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
if (status !== 100) {
|
|
567
|
+
// Error.
|
|
568
|
+
throw new Error(`Get call status failed with status ${status}.`);
|
|
569
|
+
}
|
|
570
|
+
// Pending.
|
|
571
|
+
await sleep(5000);
|
|
572
|
+
}
|
|
573
|
+
throw new Error("Timed out waiting for successful call status.");
|
|
574
|
+
};
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "viem";
|
|
22
22
|
import { InvalidRequestError } from "ox/RpcResponse";
|
|
23
23
|
import {
|
|
24
|
-
|
|
24
|
+
Permission,
|
|
25
25
|
isGlobalValidation,
|
|
26
26
|
} from "@alchemy/wallet-api-types/capabilities";
|
|
27
27
|
import type {
|
|
@@ -144,7 +144,7 @@ export async function createSession(
|
|
|
144
144
|
})
|
|
145
145
|
.addPermissions({
|
|
146
146
|
permissions: params.permissions.map((permission) =>
|
|
147
|
-
Value.Encode(
|
|
147
|
+
Value.Encode(Permission, permission),
|
|
148
148
|
),
|
|
149
149
|
})
|
|
150
150
|
.compileDeferred();
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
type wallet_getCallsStatus,
|
|
20
20
|
type WalletServerViemRpcSchema,
|
|
21
21
|
} from "@alchemy/wallet-api-types/rpc";
|
|
22
|
-
import {
|
|
22
|
+
import { CallId } from "@alchemy/wallet-api-types";
|
|
23
23
|
import { castToHex } from "../../utils.js";
|
|
24
24
|
|
|
25
25
|
export type GetCallsStatusParams = Static<
|
|
@@ -43,7 +43,7 @@ export async function getCallsStatus(
|
|
|
43
43
|
if (!client.chain) {
|
|
44
44
|
throw new ChainNotFoundError();
|
|
45
45
|
}
|
|
46
|
-
const { chainId, hash } = Value.Decode(
|
|
46
|
+
const { chainId, hash } = Value.Decode(CallId, callId);
|
|
47
47
|
|
|
48
48
|
const baseResp = {
|
|
49
49
|
id: callId,
|
|
@@ -15,10 +15,7 @@ import type {
|
|
|
15
15
|
wallet_prepareSign,
|
|
16
16
|
WalletServerViemRpcSchema,
|
|
17
17
|
} from "@alchemy/wallet-api-types/rpc";
|
|
18
|
-
import {
|
|
19
|
-
TypeSignableMessage,
|
|
20
|
-
jsonSafeTypedData,
|
|
21
|
-
} from "@alchemy/wallet-api-types";
|
|
18
|
+
import { SignableMessage, jsonSafeTypedData } from "@alchemy/wallet-api-types";
|
|
22
19
|
import { createAccount } from "../utils/createAccount.js";
|
|
23
20
|
import { createDummySigner } from "../utils/createDummySigner.js";
|
|
24
21
|
import { Value } from "@sinclair/typebox/value";
|
|
@@ -74,7 +71,7 @@ export async function prepareSign(
|
|
|
74
71
|
chainId: toHex(client.chain.id),
|
|
75
72
|
signatureRequest: {
|
|
76
73
|
type: signatureRequest.type,
|
|
77
|
-
data: Value.Encode(
|
|
74
|
+
data: Value.Encode(SignableMessage, signatureRequest.data),
|
|
78
75
|
},
|
|
79
76
|
};
|
|
80
77
|
} else {
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
ChainNotFoundError,
|
|
10
10
|
concat,
|
|
11
11
|
concatHex,
|
|
12
|
+
getContract,
|
|
12
13
|
numberToHex,
|
|
13
14
|
parseSignature,
|
|
14
15
|
toHex,
|
|
@@ -22,7 +23,7 @@ import type {
|
|
|
22
23
|
WalletServerViemRpcSchema,
|
|
23
24
|
} from "@alchemy/wallet-api-types/rpc";
|
|
24
25
|
import { decodePermissionsContext } from "@alchemy/wallet-api-types/capabilities";
|
|
25
|
-
import {
|
|
26
|
+
import { CallId } from "@alchemy/wallet-api-types";
|
|
26
27
|
import { isSupportedDelegationAddress7702 } from "../utils/7702.js";
|
|
27
28
|
import { InvalidRequestError } from "ox/RpcResponse";
|
|
28
29
|
import { assertNever } from "../../utils.js";
|
|
@@ -146,6 +147,47 @@ export async function sendPreparedCalls(
|
|
|
146
147
|
});
|
|
147
148
|
}
|
|
148
149
|
|
|
150
|
+
const deferredActionData: Hex | undefined = deferredAction
|
|
151
|
+
? await (async () => {
|
|
152
|
+
// determine whether the data should be appended to the signature.
|
|
153
|
+
// logic ported from @account-kit/smart-contracts `modularAccountV2Base.ts`
|
|
154
|
+
|
|
155
|
+
const deferredActionNonce = BigInt(
|
|
156
|
+
`0x${deferredAction.slice(4, 68)}`,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const entryPoint = getEntryPoint(client.chain, {
|
|
160
|
+
version: "0.7.0",
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const entryPointContract = getContract({
|
|
164
|
+
address: entryPoint.address,
|
|
165
|
+
abi: entryPoint.abi,
|
|
166
|
+
client,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Set these values if the deferred action has not been consumed. We check this with the EP
|
|
170
|
+
const nextNonceForDeferredAction: bigint =
|
|
171
|
+
(await entryPointContract.read.getNonce([
|
|
172
|
+
userOp.data.sender,
|
|
173
|
+
deferredActionNonce >> 64n,
|
|
174
|
+
])) as bigint;
|
|
175
|
+
|
|
176
|
+
if (deferredActionNonce === nextNonceForDeferredAction) {
|
|
177
|
+
return `0x${deferredAction.slice(68)}`;
|
|
178
|
+
} else if (deferredActionNonce > nextNonceForDeferredAction) {
|
|
179
|
+
// if nonce is greater than the next nonce, its invalid, so we throw
|
|
180
|
+
throw new InvalidRequestError({
|
|
181
|
+
message: "Invalid session nonce",
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// In this case, the deferred action has already been consumed, so no data should be appended to the signature.
|
|
186
|
+
// The signer entity should already be accounted for in `userOp.nonce`.
|
|
187
|
+
return undefined;
|
|
188
|
+
})()
|
|
189
|
+
: undefined;
|
|
190
|
+
|
|
149
191
|
const factoryType = counterfactualInfo?.factoryType;
|
|
150
192
|
|
|
151
193
|
// build signature based on account type
|
|
@@ -166,13 +208,8 @@ export async function sendPreparedCalls(
|
|
|
166
208
|
case "MAv2.0.0-sma-b":
|
|
167
209
|
// For sma-b, we need to handle deferred actions if needed and prepend the "Reserved
|
|
168
210
|
// Signature Segment" and "SignatureType.EOA" bytes
|
|
169
|
-
return
|
|
170
|
-
? concatHex([
|
|
171
|
-
`0x${deferredAction.slice(68)}`, // Cuts off stuff prepended to the digest (nonce, etc.).
|
|
172
|
-
"0xFF",
|
|
173
|
-
"0x00",
|
|
174
|
-
uoSigHex,
|
|
175
|
-
])
|
|
211
|
+
return deferredActionData != null
|
|
212
|
+
? concatHex([deferredActionData, "0xFF", "0x00", uoSigHex])
|
|
176
213
|
: concat(["0xFF", "0x00", uoSigHex]);
|
|
177
214
|
case "LightAccountV2.0.0-MultiOwner":
|
|
178
215
|
// for LAv2-MultiOwner, we need to prepend the "SignatureType.EOA" byte
|
|
@@ -225,7 +262,7 @@ export async function sendPreparedCalls(
|
|
|
225
262
|
|
|
226
263
|
return {
|
|
227
264
|
preparedCallIds: hashes.map((hash) =>
|
|
228
|
-
Value.Encode(
|
|
265
|
+
Value.Encode(CallId, {
|
|
229
266
|
chainId: toHex(client.chain.id),
|
|
230
267
|
hash,
|
|
231
268
|
}),
|