@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.
Files changed (49) hide show
  1. package/dist/esm/client/actions/requestAccount.js +2 -2
  2. package/dist/esm/client/actions/requestAccount.js.map +1 -1
  3. package/dist/esm/client/actions/signSignatureRequest.d.ts +3 -3
  4. package/dist/esm/client/actions/signSignatureRequest.js.map +1 -1
  5. package/dist/esm/client/client.e2e-test.js +40 -1
  6. package/dist/esm/client/client.e2e-test.js.map +1 -1
  7. package/dist/esm/isomorphic/actions/createSession.js +2 -2
  8. package/dist/esm/isomorphic/actions/createSession.js.map +1 -1
  9. package/dist/esm/isomorphic/actions/getCallsStatus.js +2 -2
  10. package/dist/esm/isomorphic/actions/getCallsStatus.js.map +1 -1
  11. package/dist/esm/isomorphic/actions/prepareSign.js +2 -2
  12. package/dist/esm/isomorphic/actions/prepareSign.js.map +1 -1
  13. package/dist/esm/isomorphic/actions/sendPreparedCalls.js +37 -10
  14. package/dist/esm/isomorphic/actions/sendPreparedCalls.js.map +1 -1
  15. package/dist/esm/isomorphic/utils/createAccount.d.ts +2 -2
  16. package/dist/esm/isomorphic/utils/createAccount.js +1 -1
  17. package/dist/esm/isomorphic/utils/createAccount.js.map +1 -1
  18. package/dist/esm/isomorphic/utils/decodeSignature.d.ts +2 -2
  19. package/dist/esm/isomorphic/utils/decodeSignature.js +2 -2
  20. package/dist/esm/isomorphic/utils/decodeSignature.js.map +1 -1
  21. package/dist/esm/isomorphic/utils/parsePermissionsContext.d.ts +2 -2
  22. package/dist/esm/isomorphic/utils/parsePermissionsContext.js +1 -1
  23. package/dist/esm/isomorphic/utils/parsePermissionsContext.js.map +1 -1
  24. package/dist/esm/isomorphic/utils/supportsFeature.d.ts +2 -2
  25. package/dist/esm/isomorphic/utils/supportsFeature.js.map +1 -1
  26. package/dist/types/client/actions/signSignatureRequest.d.ts +3 -3
  27. package/dist/types/client/actions/signSignatureRequest.d.ts.map +1 -1
  28. package/dist/types/isomorphic/actions/prepareSign.d.ts.map +1 -1
  29. package/dist/types/isomorphic/actions/sendPreparedCalls.d.ts.map +1 -1
  30. package/dist/types/isomorphic/utils/createAccount.d.ts +2 -2
  31. package/dist/types/isomorphic/utils/createAccount.d.ts.map +1 -1
  32. package/dist/types/isomorphic/utils/decodeSignature.d.ts +2 -2
  33. package/dist/types/isomorphic/utils/decodeSignature.d.ts.map +1 -1
  34. package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts +2 -2
  35. package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts.map +1 -1
  36. package/dist/types/isomorphic/utils/supportsFeature.d.ts +2 -2
  37. package/dist/types/isomorphic/utils/supportsFeature.d.ts.map +1 -1
  38. package/package.json +3 -3
  39. package/src/client/actions/requestAccount.ts +2 -2
  40. package/src/client/actions/signSignatureRequest.ts +8 -8
  41. package/src/client/client.e2e-test.ts +270 -191
  42. package/src/isomorphic/actions/createSession.ts +2 -2
  43. package/src/isomorphic/actions/getCallsStatus.ts +2 -2
  44. package/src/isomorphic/actions/prepareSign.ts +2 -5
  45. package/src/isomorphic/actions/sendPreparedCalls.ts +46 -9
  46. package/src/isomorphic/utils/createAccount.ts +2 -2
  47. package/src/isomorphic/utils/decodeSignature.ts +6 -6
  48. package/src/isomorphic/utils/parsePermissionsContext.ts +2 -2
  49. 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("should successfully send a UO with paymaster using 7702", async () => {
123
- const _signer = LocalAccountSigner.privateKeyToAccountSigner(
124
- "0x49daf21e92c997093e9ffdf7e7ddbf8970e9eadc5d4847d0f690db25d5128e1f",
125
- );
126
-
127
- const _client = createSmartWalletClient({
128
- transport,
129
- chain: arbitrumSepolia,
130
- mode: "local",
131
- signer: _signer,
132
- });
133
-
134
- const account = await _client.requestAccount({
135
- creationHint: {
136
- accountType: "7702",
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
- const signedCalls = await _client.signPreparedCalls(preparedCalls);
153
+ const signedCalls = await _client.signPreparedCalls(preparedCalls);
151
154
 
152
- const result = await _client.sendPreparedCalls(signedCalls);
155
+ const result = await _client.sendPreparedCalls(signedCalls);
153
156
 
154
- expect(result.preparedCallIds).toBeArrayOfSize(1);
155
- });
157
+ expect(result.preparedCallIds).toBeArrayOfSize(1);
156
158
 
157
- it("should successfully send a UO with paymaster", async () => {
158
- const account = await client.requestAccount();
159
- const preparedCalls = await client.prepareCalls({
160
- calls: [{ to: zeroAddress, value: "0x0" }],
161
- from: account.address,
162
- capabilities: {
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
- const signedCalls = await client.signPreparedCalls(preparedCalls);
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
- const result = await client.sendPreparedCalls(signedCalls);
180
+ const signedCalls = await client.signPreparedCalls(preparedCalls);
172
181
 
173
- expect(result.preparedCallIds).toBeArrayOfSize(1);
174
- });
182
+ const result = await client.sendPreparedCalls(signedCalls);
175
183
 
176
- it("should successfully create a session with grantPermissions and send a UO", async () => {
177
- const account = await client.requestAccount();
184
+ expect(result.preparedCallIds).toBeArrayOfSize(1);
178
185
 
179
- const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
186
+ await waitForUserOpSuccess(client, result.preparedCallIds[0]);
187
+ },
188
+ {
189
+ timeout: 45_000,
190
+ },
191
+ );
180
192
 
181
- const permissions = await client.grantPermissions({
182
- account: account.address,
183
- expirySec: Math.floor(Date.now() / 1000) + 60 * 60,
184
- key: {
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
- const sessionKeyClient = createSmartWalletClient({
192
- transport,
193
- chain: arbitrumSepolia,
194
- mode: "local",
195
- signer: sessionKey,
196
- });
198
+ const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
197
199
 
198
- const preparedCalls = await sessionKeyClient.prepareCalls({
199
- calls: [{ to: zeroAddress, value: "0x0" }],
200
- from: account.address,
201
- capabilities: {
202
- paymasterService: {
203
- policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
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
- const signedCalls =
210
- await sessionKeyClient.signPreparedCalls(preparedCalls);
228
+ const signedCalls =
229
+ await sessionKeyClient.signPreparedCalls(preparedCalls);
211
230
 
212
- const result = await sessionKeyClient.sendPreparedCalls({
213
- ...signedCalls,
214
- capabilities: {
215
- permissions,
216
- },
217
- });
231
+ const result = await sessionKeyClient.sendPreparedCalls({
232
+ ...signedCalls,
233
+ capabilities: {
234
+ permissions,
235
+ },
236
+ });
218
237
 
219
- expect(result.preparedCallIds).toBeArrayOfSize(1);
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("should successfully send a UO with paymaster", async () => {
330
- const account = await client.requestAccount();
331
- const preparedCalls = await client.prepareCalls({
332
- calls: [{ to: zeroAddress, value: "0x0" }],
333
- from: account.address,
334
- capabilities: {
335
- paymasterService: {
336
- policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
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
- const signedCalls = await client.signPreparedCalls(preparedCalls);
368
+ const signedCalls = await client.signPreparedCalls(preparedCalls);
342
369
 
343
- const result = await client.sendPreparedCalls(signedCalls);
370
+ const result = await client.sendPreparedCalls(signedCalls);
344
371
 
345
- expect(result.preparedCallIds).toBeArrayOfSize(1);
346
- });
372
+ expect(result.preparedCallIds).toBeArrayOfSize(1);
347
373
 
348
- it("should successfully drop and replace a UO with repeat calls", async () => {
349
- const account = await client.requestAccount();
350
- const preparedCalls = await client.prepareCalls({
351
- calls: [{ to: zeroAddress, value: "0x0" }],
352
- from: account.address,
353
- capabilities: {
354
- paymasterService: {
355
- policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
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
- const signedCalls = await client.signPreparedCalls(preparedCalls);
361
- const result = await client.sendPreparedCalls(signedCalls);
395
+ const signedCalls = await client.signPreparedCalls(preparedCalls);
396
+ const result = await client.sendPreparedCalls(signedCalls);
362
397
 
363
- expect(result.preparedCallIds).toBeArrayOfSize(1);
398
+ expect(result.preparedCallIds).toBeArrayOfSize(1);
364
399
 
365
- const prepareCalls2 = await client.prepareCalls({
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
- expect(result2.preparedCallIds).toBeArrayOfSize(1);
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
- it("should successfully send a UO with paymaster using 7702", async () => {
381
- const _signer = LocalAccountSigner.privateKeyToAccountSigner(
382
- "0x00d35c6d307b5cddeb70aeed96ee27a551fee58bf1a43858477e6c11f9172ba8",
383
- );
414
+ expect(result2.preparedCallIds).toBeArrayOfSize(1);
384
415
 
385
- const _client = createSmartWalletClient({
386
- transport,
387
- chain: arbitrumSepolia,
388
- mode: "remote",
389
- signer: _signer,
390
- });
416
+ await waitForUserOpSuccess(client, result2.preparedCallIds[0]);
417
+ },
418
+ {
419
+ timeout: 90_000,
420
+ },
421
+ );
391
422
 
392
- const account = await _client.requestAccount({
393
- creationHint: {
394
- accountType: "7702",
395
- },
396
- });
397
- expect(account.address).toBe(await _signer.getAddress());
398
-
399
- const preparedCalls = await _client.prepareCalls({
400
- calls: [{ to: zeroAddress, value: "0x0" }],
401
- from: account.address,
402
- capabilities: {
403
- paymasterService: {
404
- policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
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
- const signedCalls = await _client.signPreparedCalls(preparedCalls);
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
- const result = await _client.sendPreparedCalls(signedCalls);
454
+ const signedCalls = await _client.signPreparedCalls(preparedCalls);
412
455
 
413
- expect(result.preparedCallIds).toBeArrayOfSize(1);
414
- });
456
+ const result = await _client.sendPreparedCalls(signedCalls);
415
457
 
416
- it("should successfully create a session with grantPermissions and send a UO", async () => {
417
- const account = await client.requestAccount();
458
+ expect(result.preparedCallIds).toBeArrayOfSize(1);
418
459
 
419
- const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
460
+ await waitForUserOpSuccess(client, result.preparedCallIds[0]);
461
+ },
462
+ { timeout: 45_000 },
463
+ );
420
464
 
421
- const permissions = await client.grantPermissions({
422
- account: account.address,
423
- expirySec: Math.floor(Date.now() / 1000) + 60 * 60,
424
- key: {
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
- const sessionKeyClient = createSmartWalletClient({
432
- transport,
433
- chain: arbitrumSepolia,
434
- mode: "remote",
435
- signer: sessionKey,
436
- });
470
+ const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
437
471
 
438
- const preparedCalls = await sessionKeyClient.prepareCalls({
439
- calls: [{ to: zeroAddress, value: "0x0" }],
440
- from: account.address,
441
- capabilities: {
442
- paymasterService: {
443
- policyId: process.env.TEST_PAYMASTER_POLICY_ID!,
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
- const signedCalls =
450
- await sessionKeyClient.signPreparedCalls(preparedCalls);
500
+ const signedCalls =
501
+ await sessionKeyClient.signPreparedCalls(preparedCalls);
451
502
 
452
- const result = await sessionKeyClient.sendPreparedCalls({
453
- ...signedCalls,
454
- capabilities: {
455
- permissions,
456
- },
457
- });
503
+ const result = await sessionKeyClient.sendPreparedCalls({
504
+ ...signedCalls,
505
+ capabilities: {
506
+ permissions,
507
+ },
508
+ });
458
509
 
459
- expect(result.preparedCallIds).toBeArrayOfSize(1);
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
- TypePermission,
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(TypePermission, permission),
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 { TypeCallId } from "@alchemy/wallet-api-types";
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(TypeCallId, callId);
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(TypeSignableMessage, signatureRequest.data),
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 { TypeCallId } from "@alchemy/wallet-api-types";
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 deferredAction != null
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(TypeCallId, {
265
+ Value.Encode(CallId, {
229
266
  chainId: toHex(client.chain.id),
230
267
  hash,
231
268
  }),