@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
@@ -13,10 +13,14 @@ import { LightAccountAbi_v1 } from "../abis/LightAccountAbi_v1.js";
13
13
  import { LightAccountAbi_v2 } from "../abis/LightAccountAbi_v2.js";
14
14
  import { LightAccountFactoryAbi_v1 } from "../abis/LightAccountFactoryAbi_v1.js";
15
15
  import { LightAccountFactoryAbi_v2 } from "../abis/LightAccountFactoryAbi_v2.js";
16
- import { predictLightAccountAddress } from "../predictAddress.js";
16
+ import {
17
+ getLightAccountAddressFromFactoryData,
18
+ predictLightAccountAddress,
19
+ } from "../predictAddress.js";
17
20
  import {
18
21
  type LightAccountVersion,
19
22
  AccountVersionRegistry,
23
+ isLightAccountVersion2,
20
24
  } from "../registry.js";
21
25
  import {
22
26
  LightAccountUnsupported1271Factories,
@@ -41,11 +45,13 @@ export type ToLightAccountParams<
41
45
  > = {
42
46
  client: Client<Transport, Chain, JsonRpcAccount | LocalAccount | undefined>;
43
47
  owner: JsonRpcAccount | LocalAccount;
44
- salt?: bigint;
45
48
  accountAddress?: Address;
46
- factoryAddress?: Address;
49
+ factory?: Address;
47
50
  version?: TLightAccountVersion;
48
- };
51
+ } & (
52
+ | { salt?: bigint; factoryData?: never }
53
+ | { salt?: never; factoryData?: Hex }
54
+ );
49
55
 
50
56
  /**
51
57
  * Creates a light account.
@@ -62,7 +68,8 @@ export async function toLightAccount<
62
68
  salt: salt_ = 0n,
63
69
  accountAddress: accountAddress_,
64
70
  version = defaultLightAccountVersion() as TLightAccountVersion,
65
- factoryAddress = AccountVersionRegistry.LightAccount[version].factoryAddress,
71
+ factory = AccountVersionRegistry.LightAccount[version].factoryAddress,
72
+ factoryData: factoryData_,
66
73
  }: ToLightAccountParams<TLightAccountVersion>): Promise<
67
74
  LightAccount<TLightAccountVersion>
68
75
  > {
@@ -71,39 +78,48 @@ export async function toLightAccount<
71
78
  hasAccountAddress: !!accountAddress_,
72
79
  });
73
80
 
74
- const accountAbi =
75
- version === "v2.0.0" ? LightAccountAbi_v2 : LightAccountAbi_v1;
76
- const factoryAbi =
77
- version === "v2.0.0"
78
- ? LightAccountFactoryAbi_v2
79
- : LightAccountFactoryAbi_v1;
81
+ const accountAbi = isLightAccountVersion2(version)
82
+ ? LightAccountAbi_v2
83
+ : LightAccountAbi_v1;
84
+ const factoryAbi = isLightAccountVersion2(version)
85
+ ? LightAccountFactoryAbi_v2
86
+ : LightAccountFactoryAbi_v1;
80
87
 
81
- const salt = LightAccountUnsupported1271Factories.has(
82
- lowerAddress(factoryAddress),
83
- )
88
+ const salt = LightAccountUnsupported1271Factories.has(lowerAddress(factory))
84
89
  ? 0n
85
90
  : salt_;
86
91
 
87
92
  const accountAddress =
88
93
  accountAddress_ ??
89
- predictLightAccountAddress({
90
- factoryAddress,
91
- salt,
92
- ownerAddress: owner.address,
93
- version,
94
- });
94
+ (factoryData_
95
+ ? await getLightAccountAddressFromFactoryData({
96
+ client,
97
+ factoryAddress: factory,
98
+ factoryData: factoryData_,
99
+ entryPoint:
100
+ AccountVersionRegistry["LightAccount"][version].entryPoint,
101
+ version,
102
+ })
103
+ : predictLightAccountAddress({
104
+ factoryAddress: factory,
105
+ salt,
106
+ ownerAddress: owner.address,
107
+ version,
108
+ }));
95
109
 
96
110
  LOGGER.debug("toLightAccount:address-resolved", { accountAddress });
97
111
 
98
112
  const getFactoryArgs = async () => {
99
- const factoryData = encodeFunctionData({
100
- abi: factoryAbi,
101
- functionName: "createAccount",
102
- args: [owner.address, salt],
103
- });
113
+ const factoryData =
114
+ factoryData_ ??
115
+ encodeFunctionData({
116
+ abi: factoryAbi,
117
+ functionName: "createAccount",
118
+ args: [owner.address, salt],
119
+ });
104
120
 
105
121
  return {
106
- factory: factoryAddress,
122
+ factory,
107
123
  factoryData,
108
124
  };
109
125
  };
@@ -1,5 +1,4 @@
1
1
  import {
2
- concat,
3
2
  concatHex,
4
3
  encodeFunctionData,
5
4
  fromHex,
@@ -18,8 +17,8 @@ import {
18
17
  } from "viem";
19
18
  import {
20
19
  getUserOperationHash,
20
+ getUserOperationTypedData,
21
21
  toSmartAccount,
22
- type SmartAccount,
23
22
  type SmartAccountImplementation,
24
23
  } from "viem/account-abstraction";
25
24
  import { getStorageAt, signMessage, signTypedData } from "viem/actions";
@@ -29,7 +28,7 @@ import type {
29
28
  LightAccountVersion,
30
29
  } from "../registry.js";
31
30
  import { EIP1967_PROXY_IMPL_STORAGE_SLOT } from "../utils.js";
32
- import { AccountVersionRegistry } from "../registry.js";
31
+ import { AccountVersionRegistry, isLightAccountVersion2 } from "../registry.js";
33
32
  import {
34
33
  encodeCallsLA as encodeCalls,
35
34
  decodeCallsLA as decodeCalls,
@@ -38,6 +37,7 @@ import { BaseError, lowerAddress } from "@alchemy/common";
38
37
  import type {
39
38
  SignatureRequest,
40
39
  StaticSmartAccountImplementation,
40
+ SmartAccountWithDecodeCalls,
41
41
  } from "../../types.js";
42
42
  import { getAction } from "viem/utils";
43
43
 
@@ -59,7 +59,7 @@ export type BaseLightAccountImplementation<
59
59
  >["version"],
60
60
  {
61
61
  getLightAccountVersion: () => TLightAccountVersion;
62
- source: TLightAccountType;
62
+ smartAccountType: TLightAccountType;
63
63
  encodeUpgradeToAndCall: (params: {
64
64
  upgradeToAddress: Address;
65
65
  upgradeToInitData: Hex;
@@ -74,7 +74,7 @@ export type LightAccountBase<
74
74
  TLightAccountType extends LightAccountType = LightAccountType,
75
75
  TLightAccountVersion extends
76
76
  LightAccountVersion<TLightAccountType> = LightAccountVersion<TLightAccountType>,
77
- > = SmartAccount<
77
+ > = SmartAccountWithDecodeCalls<
78
78
  BaseLightAccountImplementation<TLightAccountType, TLightAccountVersion>
79
79
  >;
80
80
 
@@ -203,6 +203,8 @@ export async function toLightAccountBase<
203
203
  data: get1271Wrapper(messageHash, "1"),
204
204
  };
205
205
  case "v2.0.0":
206
+ case "v2.1.0":
207
+ case "v2.2.0":
206
208
  return {
207
209
  type: "eth_signTypedData_v4",
208
210
  data: get1271Wrapper(messageHash, "2"),
@@ -215,8 +217,10 @@ export async function toLightAccountBase<
215
217
  };
216
218
 
217
219
  const formatSignature = async (signature: Hex): Promise<Hex> => {
218
- return version === "v2.0.0"
219
- ? concat([SignaturePrefix.EOA, signature])
220
+ return isLightAccountVersion2(
221
+ version as LightAccountVersion<"LightAccount">,
222
+ )
223
+ ? concatHex([SignaturePrefix.EOA, signature])
220
224
  : signature;
221
225
  };
222
226
 
@@ -251,7 +255,9 @@ export async function toLightAccountBase<
251
255
  case "v1.1.0":
252
256
  return signature;
253
257
  case "v2.0.0":
254
- return concat([SignaturePrefix.EOA, signature]);
258
+ case "v2.1.0":
259
+ case "v2.2.0":
260
+ return concatHex([SignaturePrefix.EOA, signature]);
255
261
  default:
256
262
  throw new BaseError(`Unknown version ${type} of ${String(version)}`);
257
263
  }
@@ -307,30 +313,63 @@ export async function toLightAccountBase<
307
313
 
308
314
  async signUserOperation(parameters) {
309
315
  const { chainId = client.chain.id, ...userOperation } = parameters;
310
- const userOpHash = getUserOperationHash({
311
- chainId,
312
- entryPointAddress: entryPoint.address,
313
- entryPointVersion: entryPoint.version,
314
- userOperation: {
315
- ...userOperation,
316
- sender: accountAddress,
317
- },
318
- });
319
-
320
- const signMessageAction = getAction(client, signMessage, "signMessage");
316
+ let signature: Hex;
321
317
 
322
- const signature = await signMessageAction({
323
- account: owner,
324
- message: { raw: userOpHash },
325
- });
318
+ switch (version) {
319
+ case "v1.0.1":
320
+ case "v1.0.2":
321
+ case "v1.1.0":
322
+ case "v2.0.0":
323
+ const userOpHash = getUserOperationHash({
324
+ chainId,
325
+ entryPointAddress: entryPoint.address,
326
+ entryPointVersion: entryPoint.version,
327
+ userOperation: {
328
+ ...userOperation,
329
+ sender: accountAddress,
330
+ },
331
+ });
332
+
333
+ const signMessageAction = getAction(
334
+ client,
335
+ signMessage,
336
+ "signMessage",
337
+ );
338
+
339
+ signature = await signMessageAction({
340
+ account: owner,
341
+ message: { raw: userOpHash },
342
+ });
343
+ break;
344
+ case "v2.1.0":
345
+ case "v2.2.0":
346
+ const signTypedDataAction = getAction(
347
+ client,
348
+ signTypedData,
349
+ "signTypedData",
350
+ );
351
+
352
+ signature = await signTypedDataAction({
353
+ account: owner,
354
+ ...getUserOperationTypedData({
355
+ chainId,
356
+ entryPointAddress: entryPoint.address,
357
+ userOperation: {
358
+ ...userOperation,
359
+ sender: accountAddress,
360
+ },
361
+ }),
362
+ });
363
+ break;
364
+ default:
365
+ throw new BaseError(`Unknown version ${type} of ${String(version)}`);
366
+ }
326
367
 
327
- return version === "v2.0.0"
328
- ? concatHex([SignaturePrefix.EOA, signature])
329
- : signature;
368
+ return formatSignature(signature);
330
369
  },
331
370
 
332
371
  extend: {
333
- source: type,
372
+ smartAccountType: type,
334
373
  getLightAccountVersion: () => version,
335
374
  encodeUpgradeToAndCall,
336
375
  prepareSignature,
@@ -13,7 +13,10 @@ import {
13
13
  import { readContract } from "viem/actions";
14
14
  import { MultiOwnerLightAccountAbi } from "../abis/MultiOwnerLightAccountAbi.js";
15
15
  import { MultiOwnerLightAccountFactoryAbi } from "../abis/MultiOwnerLightAccountFactoryAbi.js";
16
- import { predictMultiOwnerLightAccountAddress } from "../predictAddress.js";
16
+ import {
17
+ getMultiOwnerLightAccountAddressFromFactoryData,
18
+ predictMultiOwnerLightAccountAddress,
19
+ } from "../predictAddress.js";
17
20
  import { toLightAccountBase, type LightAccountBase } from "./base.js";
18
21
  import { BaseError, lowerAddress } from "@alchemy/common";
19
22
  import { getAction } from "viem/utils";
@@ -33,10 +36,12 @@ export type MultiOwnerLightAccount = LightAccountBase<
33
36
  export type ToMultiOwnerLightAccountParams = {
34
37
  client: Client<Transport, Chain, JsonRpcAccount | LocalAccount | undefined>;
35
38
  owners: [OneOf<JsonRpcAccount | LocalAccount>, ...{ address: Address }[]];
36
- salt?: bigint;
37
39
  accountAddress?: Address;
38
- factoryAddress?: Address;
39
- };
40
+ factory?: Address;
41
+ } & (
42
+ | { salt?: bigint; factoryData?: never }
43
+ | { salt?: never; factoryData?: Hex }
44
+ );
40
45
 
41
46
  /**
42
47
  * Creates a multi-owner light account.
@@ -49,8 +54,9 @@ export async function toMultiOwnerLightAccount({
49
54
  salt = 0n,
50
55
  owners,
51
56
  accountAddress: accountAddress_,
52
- factoryAddress = AccountVersionRegistry.MultiOwnerLightAccount["v2.0.0"]
57
+ factory = AccountVersionRegistry.MultiOwnerLightAccount["v2.0.0"]
53
58
  .factoryAddress,
59
+ factoryData: factoryData_,
54
60
  }: ToMultiOwnerLightAccountParams): Promise<MultiOwnerLightAccount> {
55
61
  const signer = owners[0];
56
62
 
@@ -66,21 +72,32 @@ export async function toMultiOwnerLightAccount({
66
72
 
67
73
  const accountAddress =
68
74
  accountAddress_ ??
69
- predictMultiOwnerLightAccountAddress({
70
- factoryAddress,
71
- salt,
72
- ownerAddresses: sortedOwners,
73
- });
75
+ (factoryData_
76
+ ? await getMultiOwnerLightAccountAddressFromFactoryData({
77
+ client,
78
+ factoryAddress: factory,
79
+ factoryData: factoryData_,
80
+ entryPoint:
81
+ AccountVersionRegistry["MultiOwnerLightAccount"]["v2.0.0"]
82
+ .entryPoint,
83
+ })
84
+ : predictMultiOwnerLightAccountAddress({
85
+ factoryAddress: factory,
86
+ salt,
87
+ ownerAddresses: sortedOwners,
88
+ }));
74
89
 
75
90
  const getFactoryArgs = async () => {
76
- const factoryData = encodeFunctionData({
77
- abi: MultiOwnerLightAccountFactoryAbi,
78
- functionName: "createAccount",
79
- args: [sortedOwners, salt],
80
- });
91
+ const factoryData =
92
+ factoryData_ ??
93
+ encodeFunctionData({
94
+ abi: MultiOwnerLightAccountFactoryAbi,
95
+ functionName: "createAccount",
96
+ args: [sortedOwners, salt],
97
+ });
81
98
 
82
99
  return {
83
- factory: factoryAddress,
100
+ factory,
84
101
  factoryData,
85
102
  };
86
103
  };
@@ -21,7 +21,10 @@ export type MultiOwnerLightAccountActions<
21
21
  function isMultiOwnerLightAccount(
22
22
  account: SmartAccount,
23
23
  ): account is MultiOwnerLightAccount {
24
- return "source" in account && account.source === "MultiOwnerLightAccount";
24
+ return (
25
+ "smartAccountType" in account &&
26
+ account.smartAccountType === "MultiOwnerLightAccount"
27
+ );
25
28
  }
26
29
 
27
30
  /**
@@ -16,7 +16,9 @@ export type LightAccountActions<
16
16
  };
17
17
 
18
18
  function isLightAccount(account: SmartAccount): account is LightAccount {
19
- return "source" in account && account.source === "LightAccount";
19
+ return (
20
+ "smartAccountType" in account && account.smartAccountType === "LightAccount"
21
+ );
20
22
  }
21
23
 
22
24
  /**
@@ -4,6 +4,10 @@ import {
4
4
  entryPoint07Abi,
5
5
  entryPoint06Address,
6
6
  entryPoint07Address,
7
+ entryPoint08Abi,
8
+ entryPoint08Address,
9
+ entryPoint09Abi,
10
+ entryPoint09Address,
7
11
  } from "viem/account-abstraction";
8
12
  import { LightAccountAbi_v1 } from "./abis/LightAccountAbi_v1.js";
9
13
  import { LightAccountFactoryAbi_v1 } from "./abis/LightAccountFactoryAbi_v1.js";
@@ -96,15 +100,6 @@ export const lightAccountStaticImplV1_1_0: LightAccountV1StaticImpl = {
96
100
  },
97
101
  };
98
102
 
99
- // Shared type and fields for all light account v2 implementations
100
- const lightAccountV2Base = {
101
- entryPoint: {
102
- abi: entryPoint07Abi,
103
- address: entryPoint07Address,
104
- version: "0.7",
105
- },
106
- } satisfies Partial<StaticSmartAccountImplementation<false, "0.7">>;
107
-
108
103
  export const lightAccountStaticImplV2_0_0: StaticSmartAccountImplementation<
109
104
  false,
110
105
  "0.7",
@@ -113,7 +108,11 @@ export const lightAccountStaticImplV2_0_0: StaticSmartAccountImplementation<
113
108
  typeof LightAccountAbi_v2,
114
109
  typeof LightAccountFactoryAbi_v2
115
110
  > = {
116
- ...lightAccountV2Base,
111
+ entryPoint: {
112
+ abi: entryPoint07Abi,
113
+ address: entryPoint07Address,
114
+ version: "0.7",
115
+ },
117
116
  accountAbi: LightAccountAbi_v2,
118
117
  accountImplementation: lowerAddress(
119
118
  "0x8E8e658E22B12ada97B402fF0b044D6A325013C7",
@@ -149,7 +148,11 @@ export const multiOwnerLightAccountStaticImplV2_0_0: StaticSmartAccountImplement
149
148
  typeof MultiOwnerLightAccountAbi,
150
149
  typeof MultiOwnerLightAccountFactoryAbi
151
150
  > = {
152
- ...lightAccountV2Base,
151
+ entryPoint: {
152
+ abi: entryPoint07Abi,
153
+ address: entryPoint07Address,
154
+ version: "0.7",
155
+ },
153
156
  accountAbi: MultiOwnerLightAccountAbi,
154
157
  accountImplementation: lowerAddress(
155
158
  "0xd2c27F9eE8E4355f71915ffD5568cB3433b6823D",
@@ -170,3 +173,73 @@ export const multiOwnerLightAccountStaticImplV2_0_0: StaticSmartAccountImplement
170
173
  });
171
174
  },
172
175
  };
176
+
177
+ export const lightAccountStaticImplV2_1_0: StaticSmartAccountImplementation<
178
+ false,
179
+ "0.8",
180
+ LightAccountFactoryArgs,
181
+ typeof entryPoint08Abi,
182
+ typeof LightAccountAbi_v2,
183
+ typeof LightAccountFactoryAbi_v2
184
+ > = {
185
+ entryPoint: {
186
+ abi: entryPoint08Abi,
187
+ address: entryPoint08Address,
188
+ version: "0.8",
189
+ },
190
+ accountAbi: LightAccountAbi_v2,
191
+ accountImplementation: lowerAddress(
192
+ "0x2c53D0bD33A60db8881c7b049Df6fd762A1f059C",
193
+ ),
194
+ factoryAbi: LightAccountFactoryAbi_v2,
195
+ factoryAddress: lowerAddress("0x000000000000B1c70Df4DC2CcF86372714e14154"),
196
+ getFactoryData: (factoryArgs) => {
197
+ return encodeFunctionData({
198
+ abi: LightAccountFactoryAbi_v2,
199
+ functionName: "createAccount",
200
+ args: [factoryArgs.owner, factoryArgs.salt],
201
+ });
202
+ },
203
+ predictAccountAddress: (factoryArgs) => {
204
+ return predictLightAccountAddress({
205
+ salt: factoryArgs.salt,
206
+ ownerAddress: factoryArgs.owner,
207
+ version: "v2.1.0",
208
+ });
209
+ },
210
+ };
211
+
212
+ export const lightAccountStaticImplV2_2_0: StaticSmartAccountImplementation<
213
+ false,
214
+ "0.9",
215
+ LightAccountFactoryArgs,
216
+ typeof entryPoint09Abi,
217
+ typeof LightAccountAbi_v2,
218
+ typeof LightAccountFactoryAbi_v2
219
+ > = {
220
+ entryPoint: {
221
+ abi: entryPoint09Abi,
222
+ address: entryPoint09Address,
223
+ version: "0.9",
224
+ },
225
+ accountAbi: LightAccountAbi_v2,
226
+ accountImplementation: lowerAddress(
227
+ "0x05FF1bF6Ac15d4990Ea77Ae60394629bcB16640d",
228
+ ),
229
+ factoryAbi: LightAccountFactoryAbi_v2,
230
+ factoryAddress: lowerAddress("0x0000000000003805C662f84E42E446C96a446e82"),
231
+ getFactoryData: (factoryArgs) => {
232
+ return encodeFunctionData({
233
+ abi: LightAccountFactoryAbi_v2,
234
+ functionName: "createAccount",
235
+ args: [factoryArgs.owner, factoryArgs.salt],
236
+ });
237
+ },
238
+ predictAccountAddress: (factoryArgs) => {
239
+ return predictLightAccountAddress({
240
+ salt: factoryArgs.salt,
241
+ ownerAddress: factoryArgs.owner,
242
+ version: "v2.2.0",
243
+ });
244
+ },
245
+ };
@@ -1,18 +1,29 @@
1
1
  import {
2
2
  concatHex,
3
+ decodeFunctionData,
3
4
  encodeAbiParameters,
4
5
  encodeDeployData,
5
6
  encodeFunctionData,
6
7
  getContractAddress,
8
+ isAddressEqual,
7
9
  keccak256,
8
10
  toHex,
9
11
  type Address,
12
+ type Client,
10
13
  type Hex,
11
14
  } from "viem";
15
+ import type { EntryPointVersion } from "viem/account-abstraction";
12
16
  import { LightAccountAbi_v1 } from "./abis/LightAccountAbi_v1.js";
17
+ import { LightAccountFactoryAbi_v1 } from "./abis/LightAccountFactoryAbi_v1.js";
18
+ import { LightAccountFactoryAbi_v2 } from "./abis/LightAccountFactoryAbi_v2.js";
19
+ import { MultiOwnerLightAccountFactoryAbi } from "./abis/MultiOwnerLightAccountFactoryAbi.js";
13
20
  import { OZ_ERC1967Proxy_ConstructorAbi } from "./abis/OZ_ERC1967Proxy.js";
14
- import { AccountVersionRegistry } from "./registry.js";
21
+ import {
22
+ AccountVersionRegistry,
23
+ type LightAccountVersion,
24
+ } from "./registry.js";
15
25
  import { BaseError, lowerAddress } from "@alchemy/common";
26
+ import { getSenderFromFactoryData } from "../utils.js";
16
27
 
17
28
  export type PredictLightAccountAddressParams = {
18
29
  version: keyof typeof AccountVersionRegistry.LightAccount;
@@ -73,7 +84,9 @@ export function predictLightAccountAddress({
73
84
  });
74
85
 
75
86
  case "v2.0.0":
76
- // Logic ported from LA factory v2.0.0
87
+ case "v2.1.0":
88
+ case "v2.2.0":
89
+ // Logic ported from LA factory v2
77
90
  const combinedSalt = keccak256(
78
91
  encodeAbiParameters(
79
92
  [{ type: "address" }, { type: "uint256" }],
@@ -89,7 +102,6 @@ export function predictLightAccountAddress({
89
102
  salt: combinedSalt,
90
103
  bytecode: initCode,
91
104
  });
92
-
93
105
  default:
94
106
  assertNeverLightAccountVersion(version);
95
107
  }
@@ -172,3 +184,112 @@ function getLAv2ProxyBytecode(implementationAddress: Address): Hex {
172
184
  function assertNeverLightAccountVersion(version: never): never {
173
185
  throw new BaseError(`Unknown light account version: ${version}`);
174
186
  }
187
+
188
+ export type GetLightAccountAddressFromFactoryDataParams = {
189
+ client: Client;
190
+ factoryAddress: Address;
191
+ factoryData: Hex;
192
+ entryPoint: {
193
+ version: EntryPointVersion;
194
+ address: Address;
195
+ };
196
+ version: LightAccountVersion<"LightAccount">;
197
+ };
198
+
199
+ /**
200
+ * Gets the light account address from factory data.
201
+ * If the factory is a known default, decodes the args and predicts without RPC.
202
+ * Otherwise falls back to calling the entry point's getSenderAddress.
203
+ *
204
+ * @param {GetLightAccountAddressFromFactoryDataParams} params - The parameters
205
+ * @returns {Promise<Address>} The account address
206
+ */
207
+ export async function getLightAccountAddressFromFactoryData({
208
+ client,
209
+ factoryAddress,
210
+ factoryData,
211
+ entryPoint,
212
+ version,
213
+ }: GetLightAccountAddressFromFactoryDataParams): Promise<Address> {
214
+ const defaultFactory =
215
+ AccountVersionRegistry["LightAccount"][version].factoryAddress;
216
+ if (isAddressEqual(factoryAddress, defaultFactory)) {
217
+ const factoryAbi =
218
+ version === "v2.0.0"
219
+ ? LightAccountFactoryAbi_v2
220
+ : LightAccountFactoryAbi_v1;
221
+ try {
222
+ const decoded = decodeFunctionData({
223
+ abi: factoryAbi,
224
+ data: factoryData,
225
+ });
226
+ if (decoded.functionName === "createAccount") {
227
+ const [decodedOwner, decodedSalt] = decoded.args;
228
+ return predictLightAccountAddress({
229
+ factoryAddress,
230
+ salt: decodedSalt,
231
+ ownerAddress: decodedOwner,
232
+ version,
233
+ });
234
+ }
235
+ } catch {
236
+ // Decode failed, fall through to RPC
237
+ }
238
+ }
239
+ return getSenderFromFactoryData(client, {
240
+ factory: factoryAddress,
241
+ factoryData,
242
+ entryPoint,
243
+ });
244
+ }
245
+
246
+ export type GetMultiOwnerLightAccountAddressFromFactoryDataParams = {
247
+ client: Client;
248
+ factoryAddress: Address;
249
+ factoryData: Hex;
250
+ entryPoint: {
251
+ version: EntryPointVersion;
252
+ address: Address;
253
+ };
254
+ };
255
+
256
+ /**
257
+ * Gets the multi-owner light account address from factory data.
258
+ * If the factory is a known default, decodes the args and predicts without RPC.
259
+ * Otherwise falls back to calling the entry point's getSenderAddress.
260
+ *
261
+ * @param {GetMultiOwnerLightAccountAddressFromFactoryDataParams} params - The parameters
262
+ * @returns {Promise<Address>} The account address
263
+ */
264
+ export async function getMultiOwnerLightAccountAddressFromFactoryData({
265
+ client,
266
+ factoryAddress,
267
+ factoryData,
268
+ entryPoint,
269
+ }: GetMultiOwnerLightAccountAddressFromFactoryDataParams): Promise<Address> {
270
+ const defaultFactory =
271
+ AccountVersionRegistry["MultiOwnerLightAccount"]["v2.0.0"].factoryAddress;
272
+ if (isAddressEqual(factoryAddress, defaultFactory)) {
273
+ try {
274
+ const decoded = decodeFunctionData({
275
+ abi: MultiOwnerLightAccountFactoryAbi,
276
+ data: factoryData,
277
+ });
278
+ if (decoded.functionName === "createAccount") {
279
+ const [decodedOwners, decodedSalt] = decoded.args;
280
+ return predictMultiOwnerLightAccountAddress({
281
+ factoryAddress,
282
+ salt: decodedSalt,
283
+ ownerAddresses: [...decodedOwners],
284
+ });
285
+ }
286
+ } catch {
287
+ // Decode failed, fall through to RPC
288
+ }
289
+ }
290
+ return getSenderFromFactoryData(client, {
291
+ factory: factoryAddress,
292
+ factoryData,
293
+ entryPoint,
294
+ });
295
+ }