@alchemy/smart-accounts 0.0.0-alpha.2 → 0.0.0-alpha.21

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 (147) hide show
  1. package/dist/esm/index.d.ts +4 -3
  2. package/dist/esm/index.js +3 -3
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/light-account/accounts/account.d.ts +9 -4
  5. package/dist/esm/light-account/accounts/account.js +29 -18
  6. package/dist/esm/light-account/accounts/account.js.map +1 -1
  7. package/dist/esm/light-account/accounts/base.d.ts +4 -4
  8. package/dist/esm/light-account/accounts/base.js +51 -24
  9. package/dist/esm/light-account/accounts/base.js.map +1 -1
  10. package/dist/esm/light-account/accounts/multi-owner-account.d.ts +9 -4
  11. package/dist/esm/light-account/accounts/multi-owner-account.js +23 -14
  12. package/dist/esm/light-account/accounts/multi-owner-account.js.map +1 -1
  13. package/dist/esm/light-account/decorators/multiOwner.js +2 -1
  14. package/dist/esm/light-account/decorators/multiOwner.js.map +1 -1
  15. package/dist/esm/light-account/decorators/singleOwner.js +1 -1
  16. package/dist/esm/light-account/decorators/singleOwner.js.map +1 -1
  17. package/dist/esm/light-account/lightAccountStaticImpl.d.ts +3 -1
  18. package/dist/esm/light-account/lightAccountStaticImpl.js +57 -7
  19. package/dist/esm/light-account/lightAccountStaticImpl.js.map +1 -1
  20. package/dist/esm/light-account/predictAddress.d.ts +40 -2
  21. package/dist/esm/light-account/predictAddress.js +83 -3
  22. package/dist/esm/light-account/predictAddress.js.map +1 -1
  23. package/dist/esm/light-account/registry.d.ts +3411 -1
  24. package/dist/esm/light-account/registry.js +33 -1
  25. package/dist/esm/light-account/registry.js.map +1 -1
  26. package/dist/esm/light-account/utils.js +1 -1
  27. package/dist/esm/light-account/utils.js.map +1 -1
  28. package/dist/esm/ma-v1/accounts/base.d.ts +4 -4
  29. package/dist/esm/ma-v1/accounts/base.js +1 -1
  30. package/dist/esm/ma-v1/accounts/base.js.map +1 -1
  31. package/dist/esm/ma-v1/accounts/multi-owner-account.d.ts +9 -4
  32. package/dist/esm/ma-v1/accounts/multi-owner-account.js +26 -14
  33. package/dist/esm/ma-v1/accounts/multi-owner-account.js.map +1 -1
  34. package/dist/esm/ma-v1/decorators/multiOwner.js +2 -1
  35. package/dist/esm/ma-v1/decorators/multiOwner.js.map +1 -1
  36. package/dist/esm/ma-v1/predictAddress.d.ts +20 -1
  37. package/dist/esm/ma-v1/predictAddress.js +37 -1
  38. package/dist/esm/ma-v1/predictAddress.js.map +1 -1
  39. package/dist/esm/ma-v2/accounts/account.d.ts +10 -7
  40. package/dist/esm/ma-v2/accounts/account.js +24 -43
  41. package/dist/esm/ma-v2/accounts/account.js.map +1 -1
  42. package/dist/esm/ma-v2/accounts/base.d.ts +5 -5
  43. package/dist/esm/ma-v2/accounts/base.js +18 -60
  44. package/dist/esm/ma-v2/accounts/base.js.map +1 -1
  45. package/dist/esm/ma-v2/mav2StaticImpl.d.ts +1 -15
  46. package/dist/esm/ma-v2/mav2StaticImpl.js +0 -33
  47. package/dist/esm/ma-v2/mav2StaticImpl.js.map +1 -1
  48. package/dist/esm/ma-v2/predictAddress.d.ts +22 -6
  49. package/dist/esm/ma-v2/predictAddress.js +46 -12
  50. package/dist/esm/ma-v2/predictAddress.js.map +1 -1
  51. package/dist/esm/ma-v2/utils/account.d.ts +0 -3
  52. package/dist/esm/ma-v2/utils/account.js +2 -4
  53. package/dist/esm/ma-v2/utils/account.js.map +1 -1
  54. package/dist/esm/ma-v2/utils/signature.d.ts +1 -12
  55. package/dist/esm/ma-v2/utils/signature.js +1 -34
  56. package/dist/esm/ma-v2/utils/signature.js.map +1 -1
  57. package/dist/esm/types.d.ts +8 -1
  58. package/dist/esm/types.js.map +1 -1
  59. package/dist/esm/utils.d.ts +32 -2
  60. package/dist/esm/utils.js +75 -5
  61. package/dist/esm/utils.js.map +1 -1
  62. package/dist/esm/version.d.ts +1 -1
  63. package/dist/esm/version.js +1 -1
  64. package/dist/esm/version.js.map +1 -1
  65. package/dist/types/index.d.ts +4 -3
  66. package/dist/types/index.d.ts.map +1 -1
  67. package/dist/types/light-account/accounts/account.d.ts +9 -4
  68. package/dist/types/light-account/accounts/account.d.ts.map +1 -1
  69. package/dist/types/light-account/accounts/base.d.ts +4 -4
  70. package/dist/types/light-account/accounts/base.d.ts.map +1 -1
  71. package/dist/types/light-account/accounts/multi-owner-account.d.ts +9 -4
  72. package/dist/types/light-account/accounts/multi-owner-account.d.ts.map +1 -1
  73. package/dist/types/light-account/decorators/multiOwner.d.ts.map +1 -1
  74. package/dist/types/light-account/decorators/singleOwner.d.ts.map +1 -1
  75. package/dist/types/light-account/lightAccountStaticImpl.d.ts +3 -1
  76. package/dist/types/light-account/lightAccountStaticImpl.d.ts.map +1 -1
  77. package/dist/types/light-account/predictAddress.d.ts +40 -2
  78. package/dist/types/light-account/predictAddress.d.ts.map +1 -1
  79. package/dist/types/light-account/registry.d.ts +3411 -1
  80. package/dist/types/light-account/registry.d.ts.map +1 -1
  81. package/dist/types/ma-v1/accounts/base.d.ts +4 -4
  82. package/dist/types/ma-v1/accounts/base.d.ts.map +1 -1
  83. package/dist/types/ma-v1/accounts/multi-owner-account.d.ts +9 -4
  84. package/dist/types/ma-v1/accounts/multi-owner-account.d.ts.map +1 -1
  85. package/dist/types/ma-v1/decorators/multiOwner.d.ts.map +1 -1
  86. package/dist/types/ma-v1/predictAddress.d.ts +20 -1
  87. package/dist/types/ma-v1/predictAddress.d.ts.map +1 -1
  88. package/dist/types/ma-v2/accounts/account.d.ts +10 -7
  89. package/dist/types/ma-v2/accounts/account.d.ts.map +1 -1
  90. package/dist/types/ma-v2/accounts/base.d.ts +5 -5
  91. package/dist/types/ma-v2/accounts/base.d.ts.map +1 -1
  92. package/dist/types/ma-v2/mav2StaticImpl.d.ts +1 -15
  93. package/dist/types/ma-v2/mav2StaticImpl.d.ts.map +1 -1
  94. package/dist/types/ma-v2/predictAddress.d.ts +22 -6
  95. package/dist/types/ma-v2/predictAddress.d.ts.map +1 -1
  96. package/dist/types/ma-v2/utils/account.d.ts +0 -3
  97. package/dist/types/ma-v2/utils/account.d.ts.map +1 -1
  98. package/dist/types/ma-v2/utils/signature.d.ts +1 -12
  99. package/dist/types/ma-v2/utils/signature.d.ts.map +1 -1
  100. package/dist/types/types.d.ts +8 -1
  101. package/dist/types/types.d.ts.map +1 -1
  102. package/dist/types/utils.d.ts +32 -2
  103. package/dist/types/utils.d.ts.map +1 -1
  104. package/dist/types/version.d.ts +1 -1
  105. package/dist/types/version.d.ts.map +1 -1
  106. package/package.json +5 -6
  107. package/src/index.ts +4 -3
  108. package/src/light-account/accounts/account.ts +42 -26
  109. package/src/light-account/accounts/base.ts +66 -27
  110. package/src/light-account/accounts/multi-owner-account.ts +33 -16
  111. package/src/light-account/decorators/multiOwner.ts +4 -1
  112. package/src/light-account/decorators/singleOwner.ts +3 -1
  113. package/src/light-account/lightAccountStaticImpl.ts +84 -11
  114. package/src/light-account/predictAddress.ts +124 -3
  115. package/src/light-account/registry.ts +47 -1
  116. package/src/light-account/utils.ts +1 -1
  117. package/src/ma-v1/accounts/base.ts +8 -5
  118. package/src/ma-v1/accounts/multi-owner-account.ts +37 -18
  119. package/src/ma-v1/decorators/multiOwner.ts +4 -1
  120. package/src/ma-v1/predictAddress.ts +59 -2
  121. package/src/ma-v2/accounts/account.ts +42 -55
  122. package/src/ma-v2/accounts/base.ts +24 -88
  123. package/src/ma-v2/mav2StaticImpl.ts +1 -52
  124. package/src/ma-v2/predictAddress.ts +68 -30
  125. package/src/ma-v2/utils/account.ts +4 -4
  126. package/src/ma-v2/utils/signature.ts +2 -51
  127. package/src/types.ts +15 -1
  128. package/src/utils.ts +119 -6
  129. package/src/version.ts +1 -1
  130. package/dist/esm/ma-v2/abis/webAuthnFactoryAbi.d.ts +0 -330
  131. package/dist/esm/ma-v2/abis/webAuthnFactoryAbi.js +0 -260
  132. package/dist/esm/ma-v2/abis/webAuthnFactoryAbi.js.map +0 -1
  133. package/dist/esm/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.d.ts +0 -287
  134. package/dist/esm/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.js +0 -374
  135. package/dist/esm/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.js.map +0 -1
  136. package/dist/esm/ma-v2/modules/webauthn-validation/module.d.ts +0 -11
  137. package/dist/esm/ma-v2/modules/webauthn-validation/module.js +0 -16
  138. package/dist/esm/ma-v2/modules/webauthn-validation/module.js.map +0 -1
  139. package/dist/types/ma-v2/abis/webAuthnFactoryAbi.d.ts +0 -331
  140. package/dist/types/ma-v2/abis/webAuthnFactoryAbi.d.ts.map +0 -1
  141. package/dist/types/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.d.ts +0 -288
  142. package/dist/types/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.d.ts.map +0 -1
  143. package/dist/types/ma-v2/modules/webauthn-validation/module.d.ts +0 -12
  144. package/dist/types/ma-v2/modules/webauthn-validation/module.d.ts.map +0 -1
  145. package/src/ma-v2/abis/webAuthnFactoryAbi.ts +0 -259
  146. package/src/ma-v2/modules/webauthn-validation/abis/webauthnValidationAbi.ts +0 -373
  147. package/src/ma-v2/modules/webauthn-validation/module.ts +0 -28
@@ -19,14 +19,10 @@ import {
19
19
  import {
20
20
  entryPoint07Abi,
21
21
  type SmartAccountImplementation,
22
- type SmartAccount,
23
22
  entryPoint07Address,
24
23
  getUserOperationHash,
25
24
  toSmartAccount,
26
- type WebAuthnAccount,
27
25
  type ToSmartAccountParameters,
28
- estimateUserOperationGas,
29
- type UserOperation,
30
26
  } from "viem/account-abstraction";
31
27
  import {
32
28
  getCode,
@@ -42,7 +38,10 @@ import {
42
38
  type ValidationDataView,
43
39
  } from "../types.js";
44
40
  import { modularAccountAbi } from "../abis/modularAccountAbi.js";
45
- import type { SignatureRequest } from "../../types.js";
41
+ import type {
42
+ SignatureRequest,
43
+ SmartAccountWithDecodeCalls,
44
+ } from "../../types.js";
46
45
  import {
47
46
  decodeFunctionData,
48
47
  getAction,
@@ -58,14 +57,13 @@ import {
58
57
  import { parseDeferredAction } from "../utils/deferredActions.js";
59
58
  import {
60
59
  pack1271Signature,
61
- toWebAuthnSignature,
62
60
  toReplaySafeTypedData,
63
61
  packUOSignature,
64
62
  } from "../utils/signature.js";
65
- import { chainHas7212 } from "../../utils.js";
66
63
  import { InvalidDeferredActionNonceError } from "../../errors/InvalidDeferredActionNonceError.js";
67
64
  import { InvalidNonceKeyError } from "../../errors/InvalidNonceKeyError.js";
68
65
  import { InvalidEntityIdError } from "../../errors/InvalidEntityIdError.js";
66
+ import { is7702Delegated } from "../../utils.js";
69
67
 
70
68
  export type ValidationDataParams =
71
69
  | {
@@ -81,7 +79,7 @@ export type BaseModularAccountV2Implementation = SmartAccountImplementation<
81
79
  typeof entryPoint07Abi,
82
80
  "0.7",
83
81
  {
84
- source: "ModularAccountV2";
82
+ smartAccountType: "ModularAccountV2";
85
83
  signerEntity: SignerEntity;
86
84
  encodeCallData: (callData: Hex) => Promise<Hex>;
87
85
  getExecutionData: (selector: Hex) => Promise<ExecutionDataView>;
@@ -95,13 +93,13 @@ export type BaseModularAccountV2Implementation = SmartAccountImplementation<
95
93
  >;
96
94
 
97
95
  export type ModularAccountV2Base =
98
- SmartAccount<BaseModularAccountV2Implementation>;
96
+ SmartAccountWithDecodeCalls<BaseModularAccountV2Implementation>;
99
97
 
100
98
  export type ToModularAccountV2BaseParams<
101
99
  TTransport extends Transport = Transport,
102
100
  > = {
103
101
  client: Client<TTransport, Chain, JsonRpcAccount | LocalAccount | undefined>;
104
- owner: JsonRpcAccount | LocalAccount | WebAuthnAccount;
102
+ owner: JsonRpcAccount | LocalAccount;
105
103
  accountAddress: Address;
106
104
  getFactoryArgs: () => Promise<{
107
105
  factory?: Address | undefined;
@@ -144,10 +142,18 @@ export async function toModularAccountV2Base<
144
142
  throw new InvalidEntityIdError(entityId);
145
143
  }
146
144
 
145
+ let isDeployed = false;
146
+
147
147
  const isAccountDeployed: () => Promise<boolean> = async () => {
148
+ if (isDeployed) {
149
+ return true;
150
+ }
148
151
  const action = getAction(client, getCode, "getCode");
149
152
  const code = await action({ address: accountAddress });
150
- return code != null && code !== "0x";
153
+ isDeployed = authorization
154
+ ? is7702Delegated(authorization.address, code)
155
+ : !!code;
156
+ return isDeployed;
151
157
  };
152
158
 
153
159
  // These default values signal that we should not use the set deferred action nonce
@@ -294,17 +300,12 @@ export async function toModularAccountV2Base<
294
300
  data: toReplaySafeTypedData({
295
301
  chainId: client.chain.id,
296
302
  hash,
297
- ...(owner.type === "webAuthn"
298
- ? {
299
- address: DefaultModuleAddress.WEBAUTHN_VALIDATION,
303
+ ...(entityId === DEFAULT_OWNER_ENTITY_ID
304
+ ? { address: accountAddress }
305
+ : {
306
+ address: DefaultModuleAddress.SINGLE_SIGNER_VALIDATION,
300
307
  salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
301
- }
302
- : entityId === DEFAULT_OWNER_ENTITY_ID
303
- ? { address: accountAddress }
304
- : {
305
- address: DefaultModuleAddress.SINGLE_SIGNER_VALIDATION,
306
- salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
307
- }),
308
+ }),
308
309
  }),
309
310
  };
310
311
  };
@@ -312,8 +313,7 @@ export async function toModularAccountV2Base<
312
313
  const formatSignature = async (signature: Hex): Promise<Hex> => {
313
314
  return pack1271Signature({
314
315
  entityId,
315
- validationSignaturePrefix:
316
- owner.type === "webAuthn" ? null : SignaturePrefix.EOA,
316
+ validationSignaturePrefix: SignaturePrefix.EOA,
317
317
  validationSignature: signature,
318
318
  });
319
319
  };
@@ -409,10 +409,6 @@ export async function toModularAccountV2Base<
409
409
  },
410
410
 
411
411
  async getStubSignature() {
412
- if (owner.type === "webAuthn") {
413
- return "0xff000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000001949fc7c88032b9fcb5f6efc7a7b8c63668eae9871b765e23123bb473ff57aa831a7c0d9276168ebcc29f2875a0239cffdf2a9cd1c2007c5c77c071db9264df1d000000000000000000000000000000000000000000000000000000000000002549960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2273496a396e6164474850596759334b7156384f7a4a666c726275504b474f716d59576f4d57516869467773222c226f726967696e223a2268747470733a2f2f7369676e2e636f696e626173652e636f6d222c2263726f73734f726967696e223a66616c73657d00000000000000000000000000000000000000000000";
414
- }
415
-
416
412
  const sig = packUOSignature({
417
413
  validationSignature:
418
414
  "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c",
@@ -426,13 +422,6 @@ export async function toModularAccountV2Base<
426
422
  data: message,
427
423
  });
428
424
 
429
- if (owner.type === "webAuthn") {
430
- const validationSignature = toWebAuthnSignature(
431
- await owner.sign({ hash: hashTypedData(data) }),
432
- );
433
- return formatSignature(validationSignature);
434
- }
435
-
436
425
  const action = getAction(client, signTypedData, "signTypedData");
437
426
 
438
427
  const signature = await action({
@@ -456,15 +445,6 @@ export async function toModularAccountV2Base<
456
445
  data: td as TypedDataDefinition, // TODO(v5): Try harder to satisfy this w/o casting.
457
446
  });
458
447
 
459
- if (owner.type === "webAuthn") {
460
- const validationSignature = toWebAuthnSignature(
461
- await owner.sign({ hash: hashTypedData(data) }),
462
- );
463
- return isDeferredAction
464
- ? validationSignature
465
- : formatSignature(validationSignature);
466
- }
467
-
468
448
  const action = getAction(client, signTypedData, "signTypedData");
469
449
 
470
450
  const signature = await action({
@@ -488,21 +468,6 @@ export async function toModularAccountV2Base<
488
468
  },
489
469
  });
490
470
 
491
- if (owner.type === "webAuthn") {
492
- const validationSignature = toWebAuthnSignature(
493
- await owner.sign({
494
- hash: hashMessage({ raw: hash }),
495
- }),
496
- );
497
-
498
- const signature = deferredActionData
499
- ? concatHex([deferredActionData, validationSignature])
500
- : validationSignature;
501
- deferredActionData = undefined; // clear once used
502
- hasAssociatedExecHooks = false; // set to falsy value once used
503
- return concatHex(["0xff", signature]);
504
- }
505
-
506
471
  const signMessageAction = getAction(client, signMessage, "signMessage");
507
472
 
508
473
  const validationSignature = await signMessageAction({
@@ -524,37 +489,8 @@ export async function toModularAccountV2Base<
524
489
  return signature;
525
490
  },
526
491
 
527
- userOperation: {
528
- estimateGas: async (uo) => {
529
- if (owner.type !== "webAuthn") {
530
- // Uses the default gas estimator.
531
- // Note that we get 7702 support automatically from Viem.
532
- return undefined;
533
- }
534
-
535
- const estimateGasAction = getAction(
536
- client,
537
- estimateUserOperationGas,
538
- "estimateUserOperationGas",
539
- );
540
-
541
- const estimate = await estimateGasAction({
542
- ...(uo as UserOperation<typeof entryPoint.version>),
543
- entryPointAddress: entryPoint.address,
544
- });
545
-
546
- const buffer = (await chainHas7212(client)) ? 10000n : 300000n;
547
-
548
- // TODO(v4): iterate numbers. Aim to have ~1000 gas buffer to account for longer authenticatorDatas and clientDataJSONs.
549
- return {
550
- ...estimate,
551
- verificationGasLimit: estimate.verificationGasLimit + buffer,
552
- };
553
- },
554
- },
555
-
556
492
  extend: {
557
- source: "ModularAccountV2" as const,
493
+ smartAccountType: "ModularAccountV2" as const,
558
494
  signerEntity: {
559
495
  entityId,
560
496
  isGlobalValidation,
@@ -1,14 +1,11 @@
1
- import { encodeFunctionData, type Address, type Hex } from "viem";
1
+ import { encodeFunctionData, type Address } from "viem";
2
2
  import { entryPoint07Abi, entryPoint07Address } from "viem/account-abstraction";
3
3
  import { lowerAddress } from "@alchemy/common";
4
4
  import type { StaticSmartAccountImplementation } from "../types.js";
5
5
  import { semiModularAccountBytecodeAbi } from "./abis/semiModularAccountBytecodeAbi.js";
6
6
  import { accountFactoryAbi } from "./abis/accountFactoryAbi.js";
7
- import { webAuthnFactoryAbi } from "./abis/webAuthnFactoryAbi.js";
8
7
  import { DefaultAddress as DefaultMAV2Address } from "./utils/account.js";
9
8
  import { predictModularAccountV2Address } from "./predictAddress.js";
10
- import { modularAccountAbi } from "./abis/modularAccountAbi.js";
11
- import { parsePublicKey } from "webauthn-p256";
12
9
 
13
10
  export type SemiModularAccountV2FactoryArgs = {
14
11
  owner: Address;
@@ -84,51 +81,3 @@ export const semiModularAccount7702StaticImpl: SemiModularAccount7702StaticImpl
84
81
  ...semiModularAccountBase,
85
82
  delegationAddress: lowerAddress(DefaultMAV2Address.SMAV2_7702),
86
83
  };
87
-
88
- export type WebAuthnModularAccountV2FactoryArgs = {
89
- ownerPublicKey: Hex;
90
- salt: bigint;
91
- entityId: number;
92
- };
93
-
94
- export type WebAuthnModularAccountV2StaticImpl =
95
- StaticSmartAccountImplementation<
96
- false,
97
- "0.7",
98
- WebAuthnModularAccountV2FactoryArgs,
99
- typeof entryPoint07Abi,
100
- typeof modularAccountAbi,
101
- typeof webAuthnFactoryAbi
102
- >;
103
-
104
- /**
105
- * Static implementation logic for WebAuthnModularAccountV2.
106
- *
107
- * TODO(v5): update JSDoc format when doc-gen supports structs or records.
108
- */
109
- export const webAuthnModularAccountV2StaticImpl: WebAuthnModularAccountV2StaticImpl =
110
- {
111
- entryPoint,
112
- accountAbi: modularAccountAbi,
113
- accountImplementation: lowerAddress(DefaultMAV2Address.MAV2),
114
- factoryAddress: lowerAddress(DefaultMAV2Address.MAV2_FACTORY_WEBAUTHN),
115
- factoryAbi: webAuthnFactoryAbi,
116
- getFactoryData: (args: WebAuthnModularAccountV2FactoryArgs) => {
117
- const { x, y } = parsePublicKey(args.ownerPublicKey);
118
- return encodeFunctionData({
119
- abi: webAuthnFactoryAbi,
120
- functionName: "createWebAuthnAccount",
121
- args: [x, y, args.salt, args.entityId],
122
- });
123
- },
124
- predictAccountAddress: (args: WebAuthnModularAccountV2FactoryArgs) => {
125
- return predictModularAccountV2Address({
126
- factoryAddress: DefaultMAV2Address.MAV2_FACTORY_WEBAUTHN,
127
- implementationAddress: DefaultMAV2Address.MAV2,
128
- type: "WebAuthn",
129
- salt: args.salt,
130
- ownerPublicKey: args.ownerPublicKey,
131
- entityId: args.entityId,
132
- });
133
- },
134
- };
@@ -1,13 +1,22 @@
1
1
  import { assertNever } from "@alchemy/common";
2
2
  import {
3
3
  concatHex,
4
+ decodeFunctionData,
4
5
  encodePacked,
5
6
  getContractAddress,
7
+ isAddressEqual,
6
8
  keccak256,
7
9
  type Address,
10
+ type Client,
8
11
  type Hex,
9
12
  } from "viem";
10
- import { parsePublicKey } from "webauthn-p256";
13
+ import {
14
+ entryPoint07Address,
15
+ type EntryPointVersion,
16
+ } from "viem/account-abstraction";
17
+ import { accountFactoryAbi } from "./abis/accountFactoryAbi.js";
18
+ import { DefaultAddress } from "./utils/account.js";
19
+ import { getSenderFromFactoryData } from "../utils.js";
11
20
 
12
21
  export type PredictModularAccountV2AddressParams = {
13
22
  factoryAddress: Address;
@@ -23,15 +32,10 @@ export type PredictModularAccountV2AddressParams = {
23
32
  type: "SMA";
24
33
  ownerAddress: Address;
25
34
  }
26
- | {
27
- type: "WebAuthn";
28
- ownerPublicKey: Hex;
29
- entityId: number;
30
- }
31
35
  );
32
36
 
33
37
  /**
34
- * Predicts the address of a modular account V2 based on the provided parameters, which include factory address, salt, and implementation address. This function supports different types of accounts including "SMA", "MA", and "WebAuthn".
38
+ * Predicts the address of a modular account V2 based on the provided parameters, which include factory address, salt, and implementation address. This function supports different types of accounts including "SMA" and "MA".
35
39
  *
36
40
  * @example
37
41
  * ```ts
@@ -80,16 +84,6 @@ export function predictModularAccountV2Address(
80
84
  ),
81
85
  initcode: getProxyBytecode(implementationAddress),
82
86
  };
83
- case "WebAuthn":
84
- const { x, y } = parsePublicKey(params.ownerPublicKey);
85
- return {
86
- combinedSalt: getCombinedSaltWebAuthn(
87
- { x, y },
88
- salt,
89
- params.entityId,
90
- ),
91
- initcode: getProxyBytecode(implementationAddress),
92
- };
93
87
  default:
94
88
  return assertNever(params, "Unexpected MAv2 type");
95
89
  }
@@ -116,19 +110,6 @@ function getCombinedSaltK1(
116
110
  );
117
111
  }
118
112
 
119
- function getCombinedSaltWebAuthn(
120
- ownerPublicKey: { x: bigint; y: bigint },
121
- salt: bigint,
122
- entityId: number,
123
- ): Hex {
124
- return keccak256(
125
- encodePacked(
126
- ["uint256", "uint256", "uint256", "uint32"],
127
- [ownerPublicKey.x, ownerPublicKey.y, salt, entityId],
128
- ),
129
- );
130
- }
131
-
132
113
  function getProxyBytecode(implementationAddress: Address): Hex {
133
114
  return concatHex([
134
115
  "0x603d3d8160223d3973",
@@ -147,3 +128,60 @@ function getProxyBytecodeWithImmutableArgs(
147
128
  2,
148
129
  )}`;
149
130
  }
131
+
132
+ export type GetModularAccountV2AddressFromFactoryDataParams = {
133
+ client: Client;
134
+ factoryAddress: Address;
135
+ factoryData: Hex;
136
+ implementationAddress: Address;
137
+ entryPoint?: {
138
+ version: EntryPointVersion;
139
+ address: Address;
140
+ };
141
+ };
142
+
143
+ /**
144
+ * Gets the modular account v2 address from factory data.
145
+ * If the factory is a known default (SMA), decodes the args and predicts without RPC.
146
+ * Otherwise falls back to calling the entry point's getSenderAddress.
147
+ *
148
+ * @param {GetModularAccountV2AddressFromFactoryDataParams} params - The parameters
149
+ * @returns {Promise<Address>} The account address
150
+ */
151
+ export async function getModularAccountV2AddressFromFactoryData({
152
+ client,
153
+ factoryAddress,
154
+ factoryData,
155
+ implementationAddress,
156
+ entryPoint = {
157
+ version: "0.7",
158
+ address: entryPoint07Address,
159
+ },
160
+ }: GetModularAccountV2AddressFromFactoryDataParams): Promise<Address> {
161
+ // Try SMA factory
162
+ if (isAddressEqual(factoryAddress, DefaultAddress.MAV2_FACTORY)) {
163
+ try {
164
+ const decoded = decodeFunctionData({
165
+ abi: accountFactoryAbi,
166
+ data: factoryData,
167
+ });
168
+ if (decoded.functionName === "createSemiModularAccount") {
169
+ const [decodedOwner, decodedSalt] = decoded.args;
170
+ return predictModularAccountV2Address({
171
+ factoryAddress,
172
+ implementationAddress,
173
+ salt: decodedSalt,
174
+ type: "SMA",
175
+ ownerAddress: decodedOwner,
176
+ });
177
+ }
178
+ } catch {
179
+ // Decode failed, fall through to RPC
180
+ }
181
+ }
182
+ return getSenderFromFactoryData(client, {
183
+ factory: factoryAddress,
184
+ factoryData,
185
+ entryPoint,
186
+ });
187
+ }
@@ -16,11 +16,9 @@ import type { ModularAccountV2Base } from "../accounts/base.js";
16
16
  */
17
17
  export const DefaultAddress = {
18
18
  MAV2_FACTORY: "0x00000000000017c61b5bEe81050EC8eFc9c6fecd",
19
- MAV2_FACTORY_WEBAUTHN: "0x55010E571dCf07e254994bfc88b9C1C8FAe31960",
20
19
  SMAV2_BYTECODE: "0x000000000000c5A9089039570Dd36455b5C07383",
21
20
  SMAV2_STORAGE: "0x0000000000006E2f9d80CaEc0Da6500f005EB25A",
22
21
  SMAV2_7702: "0x69007702764179f14F51cdce752f4f775d74E139",
23
- MAV2: "0x00000000000002377B26b1EdA7b0BC371C60DD4f",
24
22
  } satisfies Record<string, Address>;
25
23
 
26
24
  /**
@@ -28,7 +26,6 @@ export const DefaultAddress = {
28
26
  */
29
27
  export const DefaultModuleAddress = {
30
28
  SINGLE_SIGNER_VALIDATION: "0x00000000000099DE0BF6fA90dEB851E2A2df7d83",
31
- WEBAUTHN_VALIDATION: "0x0000000000001D9d34E07D9834274dF9ae575217",
32
29
  TIME_RANGE: "0x00000000000082B8e2012be914dFA4f62A0573eA",
33
30
  PAYMASTER_GUARD: "0x0000000000001aA7A7F7E29abe0be06c72FD42A1",
34
31
  NATIVE_TOKEN_LIMIT: "0x00000000000001e541f0D090868FBe24b59Fbe06",
@@ -133,5 +130,8 @@ export function serializeModuleEntity(config: ModuleEntity): Hex {
133
130
  export function isModularAccountV2(
134
131
  account: SmartAccount,
135
132
  ): account is ModularAccountV2Base {
136
- return "source" in account && account.source === "ModularAccountV2";
133
+ return (
134
+ "smartAccountType" in account &&
135
+ account.smartAccountType === "ModularAccountV2"
136
+ );
137
137
  }
@@ -1,13 +1,5 @@
1
- import {
2
- concatHex,
3
- encodeAbiParameters,
4
- toHex,
5
- type Address,
6
- type Hash,
7
- type Hex,
8
- } from "viem";
1
+ import { concatHex, toHex, type Address, type Hash, type Hex } from "viem";
9
2
  import { SignaturePrefix } from "../types.js";
10
- import { Signature, type WebAuthnP256 } from "ox";
11
3
 
12
4
  export type PackUOSignatureParams = {
13
5
  // orderedHookData: HookData[];
@@ -30,7 +22,7 @@ export const packUOSignature = ({
30
22
  // TODO(v4): direct call validation 1271
31
23
  export type Pack1271SignatureParams = {
32
24
  entityId: number;
33
- validationSignaturePrefix: SignaturePrefix | null;
25
+ validationSignaturePrefix: SignaturePrefix;
34
26
  validationSignature: Hex;
35
27
  };
36
28
 
@@ -86,44 +78,3 @@ export function toReplaySafeTypedData({
86
78
  primaryType: "ReplaySafeHash" as const,
87
79
  };
88
80
  }
89
- /**
90
- * Wraps a P256 signature with the webauthn metadata.
91
- *
92
- * @param {ToWebAuthnSignatureParams} params - The parameters for wrapping a P256 signature with the webauthn metadata.
93
- * @returns {object} The wrapped P256 signature.
94
- */
95
- export function toWebAuthnSignature({
96
- webauthn,
97
- signature,
98
- }: {
99
- webauthn: WebAuthnP256.SignMetadata;
100
- signature: Hex;
101
- }) {
102
- const { r, s } = Signature.fromHex(signature);
103
- return encodeAbiParameters(
104
- [
105
- {
106
- name: "params",
107
- type: "tuple",
108
- components: [
109
- { name: "authenticatorData", type: "bytes" },
110
- { name: "clientDataJSON", type: "string" },
111
- { name: "challengeIndex", type: "uint256" },
112
- { name: "typeIndex", type: "uint256" },
113
- { name: "r", type: "uint256" },
114
- { name: "s", type: "uint256" },
115
- ],
116
- },
117
- ],
118
- [
119
- {
120
- authenticatorData: webauthn.authenticatorData,
121
- clientDataJSON: webauthn.clientDataJSON,
122
- challengeIndex: BigInt(webauthn.challengeIndex),
123
- typeIndex: BigInt(webauthn.typeIndex),
124
- r,
125
- s,
126
- },
127
- ],
128
- );
129
- }
package/src/types.ts CHANGED
@@ -6,7 +6,11 @@ import type {
6
6
  SignableMessage,
7
7
  TypedDataDefinition,
8
8
  } from "viem";
9
- import type { EntryPointVersion, SmartAccount } from "viem/account-abstraction";
9
+ import type {
10
+ EntryPointVersion,
11
+ SmartAccount,
12
+ SmartAccountImplementation,
13
+ } from "viem/account-abstraction";
10
14
 
11
15
  export type GetAccountParameter<
12
16
  TAccount extends SmartAccount | undefined = SmartAccount | undefined,
@@ -16,6 +20,16 @@ export type GetAccountParameter<
16
20
  ? { account: TAccountOverride }
17
21
  : { account?: TAccountOverride };
18
22
 
23
+ /**
24
+ * Helper type that converts a SmartAccount type to have a required `decodeCalls` function.
25
+ * This is useful for account implementations that always provide the `decodeCalls` functionality.
26
+ */
27
+ export type SmartAccountWithDecodeCalls<
28
+ TImplementation extends SmartAccountImplementation,
29
+ > = SmartAccount<TImplementation> & {
30
+ decodeCalls: NonNullable<SmartAccount<TImplementation>["decodeCalls"]>;
31
+ };
32
+
19
33
  export type SignatureRequest =
20
34
  | {
21
35
  type: "personal_sign";