@alchemy/smart-accounts 5.0.0-beta.2 → 5.0.0-beta.3

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 (38) hide show
  1. package/dist/esm/index.d.ts +3 -0
  2. package/dist/esm/index.js +3 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/light-account/accounts/calldataCodec.d.ts +17 -0
  5. package/dist/esm/light-account/accounts/calldataCodec.js +20 -0
  6. package/dist/esm/light-account/accounts/calldataCodec.js.map +1 -1
  7. package/dist/esm/ma-v1/accounts/base.js +5 -49
  8. package/dist/esm/ma-v1/accounts/base.js.map +1 -1
  9. package/dist/esm/ma-v1/accounts/calldataCodec.d.ts +20 -0
  10. package/dist/esm/ma-v1/accounts/calldataCodec.js +73 -0
  11. package/dist/esm/ma-v1/accounts/calldataCodec.js.map +1 -0
  12. package/dist/esm/ma-v2/accounts/base.js +6 -53
  13. package/dist/esm/ma-v2/accounts/base.js.map +1 -1
  14. package/dist/esm/ma-v2/accounts/calldataCodec.d.ts +20 -0
  15. package/dist/esm/ma-v2/accounts/calldataCodec.js +81 -0
  16. package/dist/esm/ma-v2/accounts/calldataCodec.js.map +1 -0
  17. package/dist/esm/version.d.ts +1 -1
  18. package/dist/esm/version.js +1 -1
  19. package/dist/esm/version.js.map +1 -1
  20. package/dist/types/index.d.ts +3 -0
  21. package/dist/types/index.d.ts.map +1 -1
  22. package/dist/types/light-account/accounts/calldataCodec.d.ts +17 -0
  23. package/dist/types/light-account/accounts/calldataCodec.d.ts.map +1 -1
  24. package/dist/types/ma-v1/accounts/base.d.ts.map +1 -1
  25. package/dist/types/ma-v1/accounts/calldataCodec.d.ts +21 -0
  26. package/dist/types/ma-v1/accounts/calldataCodec.d.ts.map +1 -0
  27. package/dist/types/ma-v2/accounts/base.d.ts.map +1 -1
  28. package/dist/types/ma-v2/accounts/calldataCodec.d.ts +21 -0
  29. package/dist/types/ma-v2/accounts/calldataCodec.d.ts.map +1 -0
  30. package/dist/types/version.d.ts +1 -1
  31. package/package.json +4 -4
  32. package/src/index.ts +15 -0
  33. package/src/light-account/accounts/calldataCodec.ts +21 -0
  34. package/src/ma-v1/accounts/base.ts +3 -54
  35. package/src/ma-v1/accounts/calldataCodec.ts +85 -0
  36. package/src/ma-v2/accounts/base.ts +5 -67
  37. package/src/ma-v2/accounts/calldataCodec.ts +94 -0
  38. package/src/version.ts +1 -1
@@ -8,7 +8,6 @@ import {
8
8
  type Transport,
9
9
  concat,
10
10
  concatHex,
11
- encodeFunctionData,
12
11
  hashMessage,
13
12
  hashTypedData,
14
13
  type TypedDataDefinition,
@@ -42,12 +41,7 @@ import type {
42
41
  SignatureRequest,
43
42
  SmartAccountWithDecodeCalls,
44
43
  } from "../../types.js";
45
- import {
46
- decodeFunctionData,
47
- getAction,
48
- isAddressEqual,
49
- sliceHex,
50
- } from "viem/utils";
44
+ import { getAction, isAddressEqual } from "viem/utils";
51
45
  import {
52
46
  DEFAULT_OWNER_ENTITY_ID,
53
47
  DefaultModuleAddress,
@@ -64,6 +58,7 @@ import { InvalidDeferredActionNonceError } from "../../errors/InvalidDeferredAct
64
58
  import { InvalidNonceKeyError } from "../../errors/InvalidNonceKeyError.js";
65
59
  import { InvalidEntityIdError } from "../../errors/InvalidEntityIdError.js";
66
60
  import { is7702Delegated } from "../../utils.js";
61
+ import { encodeCallsMAv2, decodeCallsMAv2 } from "./calldataCodec.js";
67
62
 
68
63
  export type ValidationDataParams =
69
64
  | {
@@ -336,76 +331,19 @@ export async function toModularAccountV2Base<
336
331
  if (isAddressEqual(call.to, accountAddress)) {
337
332
  // If the call is to the account itself, we need to avoid wrapping it in an `execute` call.
338
333
 
339
- if (call.data === undefined) {
334
+ if (call.data == null) {
340
335
  throw new BaseError("Data is required for an account self-call.");
341
336
  }
342
337
 
343
338
  return encodeCallData(call.data);
344
339
  }
345
-
346
- return encodeCallData(
347
- encodeFunctionData({
348
- abi: modularAccountAbi,
349
- functionName: "execute",
350
- args: [call.to, call.value ?? 0n, call.data ?? "0x"],
351
- }),
352
- );
353
340
  }
354
341
 
355
- return encodeCallData(
356
- encodeFunctionData({
357
- abi: modularAccountAbi,
358
- functionName: "executeBatch",
359
- args: [
360
- calls.map((call) => ({
361
- target: call.to,
362
- data: call.data ?? "0x",
363
- value: call.value ?? 0n,
364
- })),
365
- ],
366
- }),
367
- );
342
+ return encodeCallData(encodeCallsMAv2(calls));
368
343
  },
369
344
 
370
345
  async decodeCalls(data) {
371
- // Inverse of `encodeCalls`.
372
- // Trim the EXECUTE_USER_OP_SELECTOR if it is present.
373
- const trimmedData = data
374
- .toLowerCase()
375
- .startsWith(EXECUTE_USER_OP_SELECTOR.toLowerCase())
376
- ? sliceHex(data, 4)
377
- : data;
378
-
379
- const decoded = decodeFunctionData({
380
- abi: modularAccountAbi,
381
- data: trimmedData,
382
- });
383
-
384
- if (decoded.functionName === "execute") {
385
- return [
386
- {
387
- to: decoded.args[0],
388
- value: decoded.args[1],
389
- data: decoded.args[2],
390
- },
391
- ];
392
- }
393
-
394
- if (decoded.functionName === "executeBatch") {
395
- return decoded.args[0].map((call) => ({
396
- to: call.target,
397
- value: call.value,
398
- data: call.data,
399
- }));
400
- }
401
-
402
- // If the data is not for an `execute` or `executeBatch` call, we treat it as a single call to the account itself.
403
- return [
404
- {
405
- to: accountAddress,
406
- data,
407
- },
408
- ];
346
+ return decodeCallsMAv2(data, accountAddress);
409
347
  },
410
348
 
411
349
  async getStubSignature() {
@@ -0,0 +1,94 @@
1
+ import {
2
+ decodeFunctionData,
3
+ encodeFunctionData,
4
+ type Address,
5
+ type Call,
6
+ type Hex,
7
+ } from "viem";
8
+ import { sliceHex } from "viem/utils";
9
+ import { modularAccountAbi } from "../abis/modularAccountAbi.js";
10
+ import { EXECUTE_USER_OP_SELECTOR } from "../utils/account.js";
11
+ import { BaseError } from "@alchemy/common";
12
+
13
+ /**
14
+ * Encodes an array of calls into ModularAccountV2 calldata for `execute` or `executeBatch`.
15
+ * Used internally by the ModularAccountV2 SmartAccount implementation. Typically not needed
16
+ * directly unless you have an advanced use case.
17
+ *
18
+ * @param {Call[]} calls The calls to encode.
19
+ * @returns {Hex} The encoded calldata.
20
+ */
21
+ export function encodeCallsMAv2(calls: readonly Call[]): Hex {
22
+ if (!calls.length) {
23
+ throw new BaseError("No calls to encode.");
24
+ }
25
+
26
+ if (calls.length === 1) {
27
+ return encodeFunctionData({
28
+ abi: modularAccountAbi,
29
+ functionName: "execute",
30
+ args: [calls[0].to, calls[0].value ?? 0n, calls[0].data ?? "0x"],
31
+ });
32
+ }
33
+
34
+ return encodeFunctionData({
35
+ abi: modularAccountAbi,
36
+ functionName: "executeBatch",
37
+ args: [
38
+ calls.map((call) => ({
39
+ target: call.to,
40
+ data: call.data ?? "0x",
41
+ value: call.value ?? 0n,
42
+ })),
43
+ ],
44
+ });
45
+ }
46
+
47
+ /**
48
+ * Decodes ModularAccountV2 calldata back into an array of calls. Strips the `EXECUTE_USER_OP_SELECTOR` prefix if present.
49
+ * Used internally by the ModularAccountV2 SmartAccount implementation. Typically not needed
50
+ * directly unless you have an advanced use case.
51
+ *
52
+ * @param {Hex} data The calldata to decode.
53
+ * @param {Address} accountAddress The account address, used as the `to` for unrecognized selectors.
54
+ * @returns {Call[]} The decoded calls.
55
+ */
56
+ export function decodeCallsMAv2(data: Hex, accountAddress: Address): Call[] {
57
+ // Strip the EXECUTE_USER_OP_SELECTOR prefix if present.
58
+ const trimmedData = data
59
+ .toLowerCase()
60
+ .startsWith(EXECUTE_USER_OP_SELECTOR.toLowerCase())
61
+ ? sliceHex(data, 4)
62
+ : data;
63
+
64
+ const decoded = decodeFunctionData({
65
+ abi: modularAccountAbi,
66
+ data: trimmedData,
67
+ });
68
+
69
+ if (decoded.functionName === "execute") {
70
+ return [
71
+ {
72
+ to: decoded.args[0],
73
+ value: decoded.args[1],
74
+ data: decoded.args[2],
75
+ },
76
+ ];
77
+ }
78
+
79
+ if (decoded.functionName === "executeBatch") {
80
+ return decoded.args[0].map((call) => ({
81
+ to: call.target,
82
+ value: call.value,
83
+ data: call.data,
84
+ }));
85
+ }
86
+
87
+ // If the data is not for an `execute` or `executeBatch` call, treat it as a single call to the account itself.
88
+ return [
89
+ {
90
+ to: accountAddress,
91
+ data,
92
+ },
93
+ ];
94
+ }
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "5.0.0-beta.2";
3
+ export const VERSION = "5.0.0-beta.3";