@account-kit/smart-contracts 4.33.0 → 4.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/src/light-account/accounts/account.js +1 -1
- package/dist/esm/src/light-account/accounts/account.js.map +1 -1
- package/dist/esm/src/light-account/accounts/multiOwner.js +18 -17
- package/dist/esm/src/light-account/accounts/multiOwner.js.map +1 -1
- package/dist/esm/src/light-account/accounts/predictAddress.d.ts +8 -2
- package/dist/esm/src/light-account/accounts/predictAddress.js +31 -5
- package/dist/esm/src/light-account/accounts/predictAddress.js.map +1 -1
- package/dist/esm/src/ma-v2/account/modularAccountV2.d.ts +1 -0
- package/dist/esm/src/ma-v2/account/modularAccountV2.js +14 -14
- package/dist/esm/src/ma-v2/account/modularAccountV2.js.map +1 -1
- package/dist/esm/src/ma-v2/account/predictAddress.d.ts +21 -0
- package/dist/esm/src/ma-v2/account/predictAddress.js +46 -0
- package/dist/esm/src/ma-v2/account/predictAddress.js.map +1 -0
- package/dist/types/src/light-account/accounts/multiOwner.d.ts.map +1 -1
- package/dist/types/src/light-account/accounts/predictAddress.d.ts +8 -2
- package/dist/types/src/light-account/accounts/predictAddress.d.ts.map +1 -1
- package/dist/types/src/ma-v2/account/modularAccountV2.d.ts +1 -0
- package/dist/types/src/ma-v2/account/modularAccountV2.d.ts.map +1 -1
- package/dist/types/src/ma-v2/account/predictAddress.d.ts +22 -0
- package/dist/types/src/ma-v2/account/predictAddress.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/light-account/accounts/account.ts +1 -1
- package/src/light-account/accounts/multiOwner.ts +20 -19
- package/src/light-account/accounts/predictAddress.ts +56 -9
- package/src/ma-v2/account/modularAccountV2.ts +19 -15
- package/src/ma-v2/account/predictAddress.ts +123 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../../../../src/light-account/accounts/account.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,aAAa,GAId,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,SAAS,EACT,kBAAkB,GAInB,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAKjF,OAAO,EACL,sBAAsB,EACtB,oCAAoC,EACpC,0BAA0B,EAC1B,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,sBAAsB,GAGvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAiDjE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EACvC,SAAS,EACT,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,GAAG,0BAA0B,EAAE,EACtC,UAAU,GAAG,aAAa,CAAC,KAAK,EAAE;IAChC,OAAO,EAAE,sBAAsB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;SACrD,iBAAwB;CAC5B,CAAC,EACF,cAAc,EACd,cAAc,GAAG,oCAAoC,CAAC,KAAK,EAAE,OAAO,CAAC,EACrE,IAAI,EAAE,KAAK,GAAG,EAAE,GACS;IACzB,MAAM,MAAM,GAAG,mBAAmB,CAAC;QACjC,SAAS;QACT,KAAK;KACN,CAAC,CAAC;IAEH,MAAM,UAAU,GACd,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACjE,MAAM,UAAU,GACd,OAAO,KAAK,QAAQ;QAClB,CAAC,CAAC,yBAAyB;QAC3B,CAAC,CAAC,yBAAyB,CAAC;IAEhC,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAEhD,MAAM,IAAI,GAAG,oCAAoC,CAAC,GAAG,CACnD,cAAc,CAAC,WAAW,EAAa,CACxC;QACC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,KAAK,CAAC;IAEV,MAAM,kBAAkB,GAAG,KAAK,IAAI,EAAE;QACpC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE9B,OAAO,SAAS,CAAC;YACf,cAAc;YACd,kBAAkB,CAAC;gBACjB,GAAG,EAAE,UAAU;gBACf,YAAY,EAAE,eAAe;gBAC7B,IAAI,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC;aAC5B,CAAC;SACH,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,OAAO,GACX,cAAc;QACd,0BAA0B,CAAC;YACzB,cAAc;YACd,IAAI;YACJ,aAAa;
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../../../../src/light-account/accounts/account.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createBundlerClient,\n getEntryPoint,\n type Address,\n type EntryPointDef,\n type SmartAccountSigner,\n} from \"@aa-sdk/core\";\nimport {\n concatHex,\n encodeFunctionData,\n type Chain,\n type Hex,\n type Transport,\n} from \"viem\";\nimport { LightAccountAbi_v1 } from \"../abis/LightAccountAbi_v1.js\";\nimport { LightAccountAbi_v2 } from \"../abis/LightAccountAbi_v2.js\";\nimport { LightAccountFactoryAbi_v1 } from \"../abis/LightAccountFactoryAbi_v1.js\";\nimport { LightAccountFactoryAbi_v2 } from \"../abis/LightAccountFactoryAbi_v2.js\";\nimport type {\n LightAccountEntryPointVersion,\n LightAccountVersion,\n} from \"../types.js\";\nimport {\n AccountVersionRegistry,\n LightAccountUnsupported1271Factories,\n defaultLightAccountVersion,\n getDefaultLightAccountFactoryAddress,\n} from \"../utils.js\";\nimport {\n createLightAccountBase,\n type CreateLightAccountBaseParams,\n type LightAccountBase,\n} from \"./base.js\";\nimport { predictLightAccountAddress } from \"./predictAddress.js\";\n\nexport type LightAccount<\n TSigner extends SmartAccountSigner = SmartAccountSigner,\n TLightAccountVersion extends LightAccountVersion<\"LightAccount\"> = LightAccountVersion<\"LightAccount\">\n> = LightAccountBase<TSigner, \"LightAccount\", TLightAccountVersion> & {\n encodeTransferOwnership: (newOwner: Address) => Hex;\n getOwnerAddress: () => Promise<Address>;\n};\n\n// [!region CreateLightAccountParams]\nexport type CreateLightAccountParams<\n TTransport extends Transport = Transport,\n TSigner extends SmartAccountSigner = SmartAccountSigner,\n TLightAccountVersion extends LightAccountVersion<\"LightAccount\"> = LightAccountVersion<\"LightAccount\">\n> = Omit<\n CreateLightAccountBaseParams<\n \"LightAccount\",\n TLightAccountVersion,\n TTransport,\n TSigner\n >,\n | \"getAccountInitCode\"\n | \"entryPoint\"\n | \"version\"\n | \"abi\"\n | \"accountAddress\"\n | \"type\"\n> & {\n salt?: bigint;\n initCode?: Hex;\n accountAddress?: Address;\n factoryAddress?: Address;\n version?: TLightAccountVersion;\n entryPoint?: EntryPointDef<\n LightAccountEntryPointVersion<\"LightAccount\", TLightAccountVersion>,\n Chain\n >;\n};\n// [!endregion CreateLightAccountParams]\n\nexport async function createLightAccount<\n TTransport extends Transport = Transport,\n TSigner extends SmartAccountSigner = SmartAccountSigner,\n TLightAccountVersion extends LightAccountVersion<\"LightAccount\"> = \"v2.0.0\"\n>(\n config: CreateLightAccountParams<TTransport, TSigner, TLightAccountVersion>\n): Promise<LightAccount<TSigner, TLightAccountVersion>>;\n\n/**\n * Creates a light account based on the provided parameters such as transport, chain, signer, init code, and more. Ensures that an account is configured and returned with various capabilities, such as transferring ownership and retrieving the owner's address.\n *\n * @example\n * ```ts\n * import { createLightAccount } from \"@account-kit/smart-contracts\";\n * import { LocalAccountSigner } from \"@aa-sdk/core\";\n * import { sepolia } from \"viem/chains\";\n * import { http, generatePrivateKey } from \"viem\"\n *\n * const account = await createLightAccount({\n * chain: sepolia,\n * transport: http(\"RPC_URL\"),\n * signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey())\n * });\n * ```\n *\n * @param {CreateLightAccountParams} config The parameters for creating a light account\n * @returns {Promise<LightAccount>} A promise that resolves to a `LightAccount` object containing the created account information and methods\n */\nexport async function createLightAccount({\n transport,\n chain,\n signer,\n initCode,\n version = defaultLightAccountVersion(),\n entryPoint = getEntryPoint(chain, {\n version: AccountVersionRegistry[\"LightAccount\"][version]\n .entryPointVersion as any,\n }),\n accountAddress,\n factoryAddress = getDefaultLightAccountFactoryAddress(chain, version),\n salt: salt_ = 0n,\n}: CreateLightAccountParams): Promise<LightAccount> {\n const client = createBundlerClient({\n transport,\n chain,\n });\n\n const accountAbi =\n version === \"v2.0.0\" ? LightAccountAbi_v2 : LightAccountAbi_v1;\n const factoryAbi =\n version === \"v2.0.0\"\n ? LightAccountFactoryAbi_v1\n : LightAccountFactoryAbi_v2;\n\n const signerAddress = await signer.getAddress();\n\n const salt = LightAccountUnsupported1271Factories.has(\n factoryAddress.toLowerCase() as Address\n )\n ? 0n\n : salt_;\n\n const getAccountInitCode = async () => {\n if (initCode) return initCode;\n\n return concatHex([\n factoryAddress,\n encodeFunctionData({\n abi: factoryAbi,\n functionName: \"createAccount\",\n args: [signerAddress, salt],\n }),\n ]);\n };\n\n const address =\n accountAddress ??\n predictLightAccountAddress({\n factoryAddress,\n salt,\n ownerAddress: signerAddress,\n version,\n });\n\n const account = await createLightAccountBase<\n \"LightAccount\",\n LightAccountVersion<\"LightAccount\">,\n Transport,\n SmartAccountSigner\n >({\n transport,\n chain,\n signer,\n abi: accountAbi,\n type: \"LightAccount\",\n version,\n entryPoint,\n accountAddress: address,\n getAccountInitCode,\n });\n\n return {\n ...account,\n\n encodeTransferOwnership: (newOwner: Address) => {\n return encodeFunctionData({\n abi: accountAbi,\n functionName: \"transferOwnership\",\n args: [newOwner],\n });\n },\n async getOwnerAddress(): Promise<Address> {\n const callResult = await client.readContract({\n address,\n abi: accountAbi,\n functionName: \"owner\",\n });\n\n if (callResult == null) {\n throw new Error(\"could not get on-chain owner\");\n }\n\n return callResult;\n },\n };\n}\n"]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { createBundlerClient,
|
|
1
|
+
import { createBundlerClient, getEntryPoint, } from "@aa-sdk/core";
|
|
2
2
|
import { concatHex, encodeFunctionData, hexToBigInt, } from "viem";
|
|
3
3
|
import { MultiOwnerLightAccountAbi } from "../abis/MultiOwnerLightAccountAbi.js";
|
|
4
4
|
import { MultiOwnerLightAccountFactoryAbi } from "../abis/MultiOwnerLightAccountFactoryAbi.js";
|
|
5
5
|
import { defaultLightAccountVersion, getDefaultMultiOwnerLightAccountFactoryAddress, } from "../utils.js";
|
|
6
6
|
import { createLightAccountBase, } from "./base.js";
|
|
7
|
+
import { predictMultiOwnerLightAccountAddress } from "./predictAddress.js";
|
|
7
8
|
/**
|
|
8
9
|
* Creates a multi-owner light account using the provided parameters, including transport, chain, signer, initialization code, version, account address, factory address, salt, and owners. Ensures the owners list is deduplicated, ordered, and valid.
|
|
9
10
|
*
|
|
@@ -31,19 +32,19 @@ export async function createMultiOwnerLightAccount({ transport, chain, signer, i
|
|
|
31
32
|
transport,
|
|
32
33
|
chain,
|
|
33
34
|
});
|
|
35
|
+
// NOTE: the current signer connected will be one of the owners as well
|
|
36
|
+
const ownerAddress = await signer.getAddress();
|
|
37
|
+
// owners need to be dedupe + ordered in ascending order and not == to zero address
|
|
38
|
+
const owners_ = Array.from(new Set([...owners, ownerAddress]))
|
|
39
|
+
.filter((x) => hexToBigInt(x) !== 0n)
|
|
40
|
+
.sort((a, b) => {
|
|
41
|
+
const bigintA = hexToBigInt(a);
|
|
42
|
+
const bigintB = hexToBigInt(b);
|
|
43
|
+
return bigintA < bigintB ? -1 : bigintA > bigintB ? 1 : 0;
|
|
44
|
+
});
|
|
34
45
|
const getAccountInitCode = async () => {
|
|
35
46
|
if (initCode)
|
|
36
47
|
return initCode;
|
|
37
|
-
// NOTE: the current signer connected will be one of the owners as well
|
|
38
|
-
const ownerAddress = await signer.getAddress();
|
|
39
|
-
// owners need to be dedupe + ordered in ascending order and not == to zero address
|
|
40
|
-
const owners_ = Array.from(new Set([...owners, ownerAddress]))
|
|
41
|
-
.filter((x) => hexToBigInt(x) !== 0n)
|
|
42
|
-
.sort((a, b) => {
|
|
43
|
-
const bigintA = hexToBigInt(a);
|
|
44
|
-
const bigintB = hexToBigInt(b);
|
|
45
|
-
return bigintA < bigintB ? -1 : bigintA > bigintB ? 1 : 0;
|
|
46
|
-
});
|
|
47
48
|
return concatHex([
|
|
48
49
|
factoryAddress,
|
|
49
50
|
encodeFunctionData({
|
|
@@ -53,12 +54,12 @@ export async function createMultiOwnerLightAccount({ transport, chain, signer, i
|
|
|
53
54
|
}),
|
|
54
55
|
]);
|
|
55
56
|
};
|
|
56
|
-
const address =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
const address = accountAddress ??
|
|
58
|
+
predictMultiOwnerLightAccountAddress({
|
|
59
|
+
factoryAddress,
|
|
60
|
+
salt: salt_,
|
|
61
|
+
ownerAddresses: owners_,
|
|
62
|
+
});
|
|
62
63
|
const account = await createLightAccountBase({
|
|
63
64
|
transport,
|
|
64
65
|
chain,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multiOwner.js","sourceRoot":"","sources":["../../../../../src/light-account/accounts/multiOwner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"multiOwner.js","sourceRoot":"","sources":["../../../../../src/light-account/accounts/multiOwner.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createBundlerClient,\n getEntryPoint,\n type EntryPointDef,\n type SmartAccountSigner,\n} from \"@aa-sdk/core\";\nimport {\n concatHex,\n encodeFunctionData,\n hexToBigInt,\n type Address,\n type Chain,\n type Hex,\n type Transport,\n} from \"viem\";\nimport { MultiOwnerLightAccountAbi } from \"../abis/MultiOwnerLightAccountAbi.js\";\nimport { MultiOwnerLightAccountFactoryAbi } from \"../abis/MultiOwnerLightAccountFactoryAbi.js\";\nimport type {\n LightAccountEntryPointVersion,\n LightAccountVersion,\n} from \"../types.js\";\nimport {\n defaultLightAccountVersion,\n getDefaultMultiOwnerLightAccountFactoryAddress,\n} from \"../utils.js\";\nimport {\n createLightAccountBase,\n type CreateLightAccountBaseParams,\n type LightAccountBase,\n} from \"./base.js\";\nimport { predictMultiOwnerLightAccountAddress } from \"./predictAddress.js\";\n\nexport type MultiOwnerLightAccount<\n TSigner extends SmartAccountSigner = SmartAccountSigner,\n TLightAccountVersion extends LightAccountVersion<\"MultiOwnerLightAccount\"> = LightAccountVersion<\"MultiOwnerLightAccount\">\n> = LightAccountBase<\n TSigner,\n \"MultiOwnerLightAccount\",\n TLightAccountVersion\n> & {\n encodeUpdateOwners: (\n ownersToAdd: Address[],\n ownersToRemove: Address[]\n ) => Hex;\n getOwnerAddresses: () => Promise<readonly Address[]>;\n};\n\nexport type CreateMultiOwnerLightAccountParams<\n TTransport extends Transport = Transport,\n TSigner extends SmartAccountSigner = SmartAccountSigner,\n TLightAccountVersion extends LightAccountVersion<\"MultiOwnerLightAccount\"> = LightAccountVersion<\"MultiOwnerLightAccount\">\n> = Omit<\n CreateLightAccountBaseParams<\n \"MultiOwnerLightAccount\",\n TLightAccountVersion,\n TTransport,\n TSigner\n >,\n | \"getAccountInitCode\"\n | \"entryPoint\"\n | \"version\"\n | \"abi\"\n | \"accountAddress\"\n | \"type\"\n> & {\n salt?: bigint;\n initCode?: Hex;\n accountAddress?: Address;\n factoryAddress?: Address;\n version?: TLightAccountVersion;\n entryPoint?: EntryPointDef<\n LightAccountEntryPointVersion<\n \"MultiOwnerLightAccount\",\n TLightAccountVersion\n >,\n Chain\n >;\n owners?: Address[];\n};\n\nexport async function createMultiOwnerLightAccount<\n TTransport extends Transport = Transport,\n TSigner extends SmartAccountSigner = SmartAccountSigner,\n TLightAccountVersion extends LightAccountVersion<\"MultiOwnerLightAccount\"> = LightAccountVersion<\"MultiOwnerLightAccount\">\n>(\n config: CreateMultiOwnerLightAccountParams<\n TTransport,\n TSigner,\n TLightAccountVersion\n >\n): Promise<MultiOwnerLightAccount<TSigner, TLightAccountVersion>>;\n\n/**\n * Creates a multi-owner light account using the provided parameters, including transport, chain, signer, initialization code, version, account address, factory address, salt, and owners. Ensures the owners list is deduplicated, ordered, and valid.\n *\n * @example\n * ```ts\n * import { createMultiOwnerLightAccount } from \"@account-kit/smart-contracts\";\n * import { LocalAccountSigner } from \"@aa-sdk/core\";\n * import { sepolia } from \"viem/chains\";\n * import { http, generatePrivateKey } from \"viem\"\n *\n * const account = await createMultiOwnerLightAccount({\n * chain: sepolia,\n * transport: http(\"RPC_URL\"),\n * signer: LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey())\n * });\n * ```\n *\n * @param {CreateMultiOwnerLightAccountParams} config The parameters for creating a multi-owner light account\n * @returns {Promise<MultiOwnerLightAccount>} A promise that resolves to a `MultiOwnerLightAccount` object containing the created account information and methods\n */\nexport async function createMultiOwnerLightAccount({\n transport,\n chain,\n signer,\n initCode,\n version = defaultLightAccountVersion(),\n entryPoint = getEntryPoint(chain, {\n version: \"0.7.0\",\n }),\n accountAddress,\n factoryAddress = getDefaultMultiOwnerLightAccountFactoryAddress(\n chain,\n version\n ),\n salt: salt_ = 0n,\n owners = [],\n}: CreateMultiOwnerLightAccountParams): Promise<MultiOwnerLightAccount> {\n const client = createBundlerClient({\n transport,\n chain,\n });\n\n // NOTE: the current signer connected will be one of the owners as well\n const ownerAddress = await signer.getAddress();\n // owners need to be dedupe + ordered in ascending order and not == to zero address\n const owners_ = Array.from(new Set([...owners, ownerAddress]))\n .filter((x) => hexToBigInt(x) !== 0n)\n .sort((a, b) => {\n const bigintA = hexToBigInt(a);\n const bigintB = hexToBigInt(b);\n\n return bigintA < bigintB ? -1 : bigintA > bigintB ? 1 : 0;\n });\n\n const getAccountInitCode = async () => {\n if (initCode) return initCode;\n\n return concatHex([\n factoryAddress,\n encodeFunctionData({\n abi: MultiOwnerLightAccountFactoryAbi,\n functionName: \"createAccount\",\n args: [owners_, salt_],\n }),\n ]);\n };\n\n const address =\n accountAddress ??\n predictMultiOwnerLightAccountAddress({\n factoryAddress,\n salt: salt_,\n ownerAddresses: owners_,\n });\n\n const account = await createLightAccountBase<\n \"MultiOwnerLightAccount\",\n LightAccountVersion<\"MultiOwnerLightAccount\">,\n Transport,\n SmartAccountSigner\n >({\n transport,\n chain,\n signer,\n abi: MultiOwnerLightAccountAbi,\n version,\n type: \"MultiOwnerLightAccount\",\n entryPoint,\n accountAddress: address,\n getAccountInitCode,\n });\n\n return {\n ...account,\n encodeUpdateOwners: (ownersToAdd: Address[], ownersToRemove: Address[]) => {\n return encodeFunctionData({\n abi: MultiOwnerLightAccountAbi,\n functionName: \"updateOwners\",\n args: [ownersToAdd, ownersToRemove],\n });\n },\n async getOwnerAddresses(): Promise<readonly Address[]> {\n const callResult = await client.readContract({\n address,\n abi: MultiOwnerLightAccountAbi,\n functionName: \"owners\",\n });\n\n if (callResult == null) {\n throw new Error(\"could not get on-chain owners\");\n }\n\n if (!callResult.includes(await signer.getAddress())) {\n throw new Error(\"on-chain owners does not include the current signer\");\n }\n\n return callResult;\n },\n };\n}\n"]}
|
|
@@ -3,7 +3,13 @@ import type { LightAccountVersionConfigs } from "../types";
|
|
|
3
3
|
export type PredictLightAccountAddressParams = {
|
|
4
4
|
factoryAddress: Address;
|
|
5
5
|
salt: bigint;
|
|
6
|
-
|
|
6
|
+
ownerAddress: Address;
|
|
7
7
|
version: keyof LightAccountVersionConfigs["LightAccount"];
|
|
8
8
|
};
|
|
9
|
-
export declare function predictLightAccountAddress({ factoryAddress, salt,
|
|
9
|
+
export declare function predictLightAccountAddress({ factoryAddress, salt, ownerAddress, version, }: PredictLightAccountAddressParams): Address;
|
|
10
|
+
export type PredictMultiOwnerLightAccountAddressParams = {
|
|
11
|
+
factoryAddress: Address;
|
|
12
|
+
salt: bigint;
|
|
13
|
+
ownerAddresses: Address[];
|
|
14
|
+
};
|
|
15
|
+
export declare function predictMultiOwnerLightAccountAddress({ factoryAddress, salt, ownerAddresses, }: PredictMultiOwnerLightAccountAddressParams): Address;
|
|
@@ -2,7 +2,7 @@ import { encodeAbiParameters, encodeDeployData, keccak256, getContractAddress, t
|
|
|
2
2
|
import { OZ_ERC1967Proxy_ConstructorAbi } from "../abis/OZ_ERC1967Proxy.js";
|
|
3
3
|
import { AccountVersionRegistry } from "../utils.js";
|
|
4
4
|
import { LightAccountAbi_v1 } from "../abis/LightAccountAbi_v1.js";
|
|
5
|
-
export function predictLightAccountAddress({ factoryAddress, salt,
|
|
5
|
+
export function predictLightAccountAddress({ factoryAddress, salt, ownerAddress, version, }) {
|
|
6
6
|
const implementationAddress =
|
|
7
7
|
// If we aren't using the default factory address, we compute the implementation address from the factory's `create` deployment.
|
|
8
8
|
// This is accurate for both LA v1 and v2 factories. If we are using the default factory address, we use the implementation address from the registry.
|
|
@@ -31,16 +31,15 @@ export function predictLightAccountAddress({ factoryAddress, salt, signerAddress
|
|
|
31
31
|
encodeFunctionData({
|
|
32
32
|
abi: LightAccountAbi_v1,
|
|
33
33
|
functionName: "initialize",
|
|
34
|
-
args: [
|
|
34
|
+
args: [ownerAddress],
|
|
35
35
|
}),
|
|
36
36
|
],
|
|
37
37
|
}),
|
|
38
38
|
});
|
|
39
39
|
case "v2.0.0":
|
|
40
40
|
// Logic ported from LA factory v2.0.0
|
|
41
|
-
const combinedSalt = keccak256(encodeAbiParameters([{ type: "address" }, { type: "uint256" }], [
|
|
42
|
-
|
|
43
|
-
const initCode = `0x603d3d8160223d3973${implementationAddress.slice(2)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;
|
|
41
|
+
const combinedSalt = keccak256(encodeAbiParameters([{ type: "address" }, { type: "uint256" }], [ownerAddress, salt]));
|
|
42
|
+
const initCode = getLAv2ProxyBytecode(implementationAddress);
|
|
44
43
|
return getContractAddress({
|
|
45
44
|
from: factoryAddress,
|
|
46
45
|
opcode: "CREATE2",
|
|
@@ -51,6 +50,33 @@ export function predictLightAccountAddress({ factoryAddress, salt, signerAddress
|
|
|
51
50
|
assertNeverLightAccountVersion(version);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
53
|
+
// Note: assumes the owner addresses are already deduped, sorted in ascending order, and have the signer address included.
|
|
54
|
+
export function predictMultiOwnerLightAccountAddress({ factoryAddress, salt, ownerAddresses, }) {
|
|
55
|
+
const implementationAddress =
|
|
56
|
+
// If we aren't using the default factory address, we compute the implementation address from the factory's `create` deployment.
|
|
57
|
+
// This is accurate for both LA v1 and v2 factories. If we are using the default factory address, we use the implementation address from the registry.
|
|
58
|
+
factoryAddress !==
|
|
59
|
+
AccountVersionRegistry.MultiOwnerLightAccount["v2.0.0"].addresses.default
|
|
60
|
+
.factory
|
|
61
|
+
? getContractAddress({
|
|
62
|
+
from: factoryAddress,
|
|
63
|
+
nonce: 1n,
|
|
64
|
+
})
|
|
65
|
+
: AccountVersionRegistry.MultiOwnerLightAccount["v2.0.0"].addresses
|
|
66
|
+
.default.impl;
|
|
67
|
+
const combinedSalt = keccak256(encodeAbiParameters([{ type: "address[]" }, { type: "uint256" }], [ownerAddresses, salt]));
|
|
68
|
+
const initCode = getLAv2ProxyBytecode(implementationAddress);
|
|
69
|
+
return getContractAddress({
|
|
70
|
+
from: factoryAddress,
|
|
71
|
+
opcode: "CREATE2",
|
|
72
|
+
salt: combinedSalt,
|
|
73
|
+
bytecode: initCode,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Bytecode from https://github.com/Vectorized/solady/blob/c6e5238e5f3b621789c59e1a443f43b6606394b2/src/utils/LibClone.sol#L721
|
|
77
|
+
function getLAv2ProxyBytecode(implementationAddress) {
|
|
78
|
+
return `0x603d3d8160223d3973${implementationAddress.slice(2)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;
|
|
79
|
+
}
|
|
54
80
|
function assertNeverLightAccountVersion(version) {
|
|
55
81
|
throw new Error(`Unknown light account version: ${version}`);
|
|
56
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predictAddress.js","sourceRoot":"","sources":["../../../../../src/light-account/accounts/predictAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAGlB,KAAK,EACL,kBAAkB,GACnB,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AASnE,MAAM,UAAU,0BAA0B,CAAC,EACzC,cAAc,EACd,IAAI,EACJ,
|
|
1
|
+
{"version":3,"file":"predictAddress.js","sourceRoot":"","sources":["../../../../../src/light-account/accounts/predictAddress.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n encodeAbiParameters,\n encodeDeployData,\n keccak256,\n getContractAddress,\n type Address,\n type Hex,\n toHex,\n encodeFunctionData,\n} from \"viem\";\nimport type { LightAccountVersionConfigs } from \"../types\";\nimport { OZ_ERC1967Proxy_ConstructorAbi } from \"../abis/OZ_ERC1967Proxy.js\";\nimport { AccountVersionRegistry } from \"../utils.js\";\nimport { LightAccountAbi_v1 } from \"../abis/LightAccountAbi_v1.js\";\n\nexport type PredictLightAccountAddressParams = {\n factoryAddress: Address;\n salt: bigint;\n ownerAddress: Address;\n version: keyof LightAccountVersionConfigs[\"LightAccount\"];\n};\n\nexport function predictLightAccountAddress({\n factoryAddress,\n salt,\n ownerAddress,\n version,\n}: PredictLightAccountAddressParams): Address {\n const implementationAddress =\n // If we aren't using the default factory address, we compute the implementation address from the factory's `create` deployment.\n // This is accurate for both LA v1 and v2 factories. If we are using the default factory address, we use the implementation address from the registry.\n factoryAddress !==\n AccountVersionRegistry.LightAccount[version].addresses.default.factory\n ? getContractAddress({\n from: factoryAddress,\n nonce: 1n,\n })\n : AccountVersionRegistry.LightAccount[version].addresses.default.impl;\n\n switch (version) {\n case \"v1.0.1\":\n case \"v1.0.2\":\n case \"v1.1.0\":\n // Same proxy initcode for all LA v1 factories\n const LAv1_proxy_bytecode: Hex =\n \"0x60406080815261042c908138038061001681610218565b93843982019181818403126102135780516001600160a01b038116808203610213576020838101516001600160401b0394919391858211610213570186601f820112156102135780519061007161006c83610253565b610218565b918083528583019886828401011161021357888661008f930161026e565b813b156101b9577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916841790556000927fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8480a28051158015906101b2575b61010b575b855160e790816103458239f35b855194606086019081118682101761019e578697849283926101889952602788527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c87890152660819985a5b195960ca1b8a8901525190845af4913d15610194573d9061017a61006c83610253565b91825281943d92013e610291565b508038808080806100fe565b5060609250610291565b634e487b7160e01b84526041600452602484fd5b50826100f9565b855162461bcd60e51b815260048101859052602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b600080fd5b6040519190601f01601f191682016001600160401b0381118382101761023d57604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b03811161023d57601f01601f191660200190565b60005b8381106102815750506000910152565b8181015183820152602001610271565b919290156102f357508151156102a5575090565b3b156102ae5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156103065750805190602001fd5b6044604051809262461bcd60e51b825260206004830152610336815180928160248601526020868601910161026e565b601f01601f19168101030190fdfe60806040523615605f5773ffffffffffffffffffffffffffffffffffffffff7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54166000808092368280378136915af43d82803e15605b573d90f35b3d90fd5b73ffffffffffffffffffffffffffffffffffffffff7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54166000808092368280378136915af43d82803e15605b573d90f3fea26469706673582212205da2750cd2b0cadfd354d8a1ca4752ed7f22214c8069d852f7dc6b8e9e5ee66964736f6c63430008150033\";\n\n return getContractAddress({\n from: factoryAddress,\n opcode: \"CREATE2\",\n salt: toHex(salt, { size: 32 }),\n bytecode: encodeDeployData({\n bytecode: LAv1_proxy_bytecode,\n abi: OZ_ERC1967Proxy_ConstructorAbi,\n args: [\n implementationAddress,\n encodeFunctionData({\n abi: LightAccountAbi_v1,\n functionName: \"initialize\",\n args: [ownerAddress],\n }),\n ],\n }),\n });\n\n case \"v2.0.0\":\n // Logic ported from LA factory v2.0.0\n const combinedSalt = keccak256(\n encodeAbiParameters(\n [{ type: \"address\" }, { type: \"uint256\" }],\n [ownerAddress, salt]\n )\n );\n\n const initCode: Hex = getLAv2ProxyBytecode(implementationAddress);\n\n return getContractAddress({\n from: factoryAddress,\n opcode: \"CREATE2\",\n salt: combinedSalt,\n bytecode: initCode,\n });\n\n default:\n assertNeverLightAccountVersion(version);\n }\n}\n\nexport type PredictMultiOwnerLightAccountAddressParams = {\n factoryAddress: Address;\n salt: bigint;\n ownerAddresses: Address[];\n // There's just one version of the MultiOwnerLightAccount for now, so skip requiring the version as a parameter.\n};\n\n// Note: assumes the owner addresses are already deduped, sorted in ascending order, and have the signer address included.\nexport function predictMultiOwnerLightAccountAddress({\n factoryAddress,\n salt,\n ownerAddresses,\n}: PredictMultiOwnerLightAccountAddressParams): Address {\n const implementationAddress =\n // If we aren't using the default factory address, we compute the implementation address from the factory's `create` deployment.\n // This is accurate for both LA v1 and v2 factories. If we are using the default factory address, we use the implementation address from the registry.\n factoryAddress !==\n AccountVersionRegistry.MultiOwnerLightAccount[\"v2.0.0\"].addresses.default\n .factory\n ? getContractAddress({\n from: factoryAddress,\n nonce: 1n,\n })\n : AccountVersionRegistry.MultiOwnerLightAccount[\"v2.0.0\"].addresses\n .default.impl;\n\n const combinedSalt = keccak256(\n encodeAbiParameters(\n [{ type: \"address[]\" }, { type: \"uint256\" }],\n [ownerAddresses, salt]\n )\n );\n\n const initCode: Hex = getLAv2ProxyBytecode(implementationAddress);\n\n return getContractAddress({\n from: factoryAddress,\n opcode: \"CREATE2\",\n salt: combinedSalt,\n bytecode: initCode,\n });\n}\n\n// Bytecode from https://github.com/Vectorized/solady/blob/c6e5238e5f3b621789c59e1a443f43b6606394b2/src/utils/LibClone.sol#L721\n\nfunction getLAv2ProxyBytecode(implementationAddress: Address): Hex {\n return `0x603d3d8160223d3973${implementationAddress.slice(\n 2\n )}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;\n}\n\nfunction assertNeverLightAccountVersion(version: never): never {\n throw new Error(`Unknown light account version: ${version}`);\n}\n"]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getEntryPoint, EntityIdOverrideError, InvalidModularAccountV2Mode, } from "@aa-sdk/core";
|
|
2
2
|
import { concatHex, encodeFunctionData, } from "viem";
|
|
3
3
|
import { accountFactoryAbi } from "../abis/accountFactoryAbi.js";
|
|
4
|
-
import { getDefaultMAV2FactoryAddress } from "../utils.js";
|
|
4
|
+
import { getDefaultMAV2FactoryAddress, getDefaultSMAV2BytecodeAddress, } from "../utils.js";
|
|
5
5
|
import { createMAv2Base, } from "./common/modularAccountV2Base.js";
|
|
6
6
|
import { DEFAULT_OWNER_ENTITY_ID } from "../utils.js";
|
|
7
|
+
import { predictModularAccountV2Address } from "./predictAddress.js";
|
|
7
8
|
/**
|
|
8
9
|
* Creates a ModularAccount V2 account, with the mode depending on the provided "mode" field.
|
|
9
10
|
* Possible modes include: "default", which is SMA Bytecode, and "7702", which is SMA 7702.
|
|
@@ -41,10 +42,6 @@ export async function createModularAccountV2(config) {
|
|
|
41
42
|
isGlobalValidation: true,
|
|
42
43
|
entityId: DEFAULT_OWNER_ENTITY_ID,
|
|
43
44
|
}, signerEntity: { entityId = DEFAULT_OWNER_ENTITY_ID } = {}, deferredAction, } = config;
|
|
44
|
-
const client = createBundlerClient({
|
|
45
|
-
transport,
|
|
46
|
-
chain,
|
|
47
|
-
});
|
|
48
45
|
const accountFunctions = await (async () => {
|
|
49
46
|
switch (config.mode) {
|
|
50
47
|
case "7702": {
|
|
@@ -67,7 +64,8 @@ export async function createModularAccountV2(config) {
|
|
|
67
64
|
}
|
|
68
65
|
case "default":
|
|
69
66
|
case undefined: {
|
|
70
|
-
const { salt = 0n, factoryAddress = getDefaultMAV2FactoryAddress(chain), initCode, } = config;
|
|
67
|
+
const { salt = 0n, factoryAddress = getDefaultMAV2FactoryAddress(chain), implementationAddress = getDefaultSMAV2BytecodeAddress(chain), initCode, } = config;
|
|
68
|
+
const signerAddress = await signer.getAddress();
|
|
71
69
|
const getAccountInitCode = async () => {
|
|
72
70
|
if (initCode) {
|
|
73
71
|
return initCode;
|
|
@@ -77,16 +75,18 @@ export async function createModularAccountV2(config) {
|
|
|
77
75
|
encodeFunctionData({
|
|
78
76
|
abi: accountFactoryAbi,
|
|
79
77
|
functionName: "createSemiModularAccount",
|
|
80
|
-
args: [
|
|
78
|
+
args: [signerAddress, salt],
|
|
81
79
|
}),
|
|
82
80
|
]);
|
|
83
81
|
};
|
|
84
|
-
const accountAddress =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
const accountAddress = _accountAddress ??
|
|
83
|
+
predictModularAccountV2Address({
|
|
84
|
+
factoryAddress,
|
|
85
|
+
implementationAddress,
|
|
86
|
+
salt,
|
|
87
|
+
type: "SMA",
|
|
88
|
+
ownerAddress: signerAddress,
|
|
89
|
+
});
|
|
90
90
|
return {
|
|
91
91
|
getAccountInitCode,
|
|
92
92
|
accountAddress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modularAccountV2.js","sourceRoot":"","sources":["../../../../../src/ma-v2/account/modularAccountV2.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"modularAccountV2.js","sourceRoot":"","sources":["../../../../../src/ma-v2/account/modularAccountV2.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n EntryPointDef,\n SmartAccountSigner,\n ToSmartContractAccountParams,\n} from \"@aa-sdk/core\";\nimport {\n getEntryPoint,\n EntityIdOverrideError,\n InvalidModularAccountV2Mode,\n} from \"@aa-sdk/core\";\nimport {\n concatHex,\n encodeFunctionData,\n type Address,\n type Chain,\n type Hex,\n type Transport,\n} from \"viem\";\nimport { accountFactoryAbi } from \"../abis/accountFactoryAbi.js\";\nimport {\n getDefaultMAV2FactoryAddress,\n getDefaultSMAV2BytecodeAddress,\n} from \"../utils.js\";\nimport {\n type SignerEntity,\n type ModularAccountV2,\n createMAv2Base,\n} from \"./common/modularAccountV2Base.js\";\nimport { DEFAULT_OWNER_ENTITY_ID } from \"../utils.js\";\nimport { predictModularAccountV2Address } from \"./predictAddress.js\";\n\nexport type CreateModularAccountV2Params<\n TTransport extends Transport = Transport,\n TSigner extends SmartAccountSigner = SmartAccountSigner\n> = (Pick<\n ToSmartContractAccountParams<\"ModularAccountV2\", TTransport, Chain, \"0.7.0\">,\n \"transport\" | \"chain\" | \"accountAddress\"\n> & {\n signer: TSigner;\n entryPoint?: EntryPointDef<\"0.7.0\", Chain>;\n deferredAction?: Hex;\n signerEntity?: SignerEntity;\n}) &\n (\n | {\n mode?: \"default\";\n salt?: bigint;\n factoryAddress?: Address;\n implementationAddress?: Address;\n initCode?: Hex;\n }\n | {\n mode: \"7702\";\n }\n );\n\nexport async function createModularAccountV2<\n TTransport extends Transport = Transport,\n TSigner extends SmartAccountSigner = SmartAccountSigner\n>(\n config: CreateModularAccountV2Params<TTransport, TSigner>\n): Promise<ModularAccountV2<TSigner>>;\n\n/**\n * Creates a ModularAccount V2 account, with the mode depending on the provided \"mode\" field.\n * Possible modes include: \"default\", which is SMA Bytecode, and \"7702\", which is SMA 7702.\n * Handles nonce generation, transaction encoding, and mode variant-specific behavior like initcode construction.\n *\n * @example\n * ```ts twoslash\n * import { createModularAccountV2 } from \"@account-kit/smart-contracts\";\n * import { LocalAccountSigner } from \"@aa-sdk/core\";\n * import { alchemy, sepolia } from \"@account-kit/infra\";\n *\n * const MNEMONIC = \"...\";\n * const RPC_URL = \"...\";\n *\n * const signer = LocalAccountSigner.mnemonicToAccountSigner(MNEMONIC);\n *\n * const chain = sepolia;\n *\n * const transport = alchemy({ rpcUrl: RPC_URL });\n *\n *\n * const modularAccountV2 = await createModularAccountV2({\n * mode: \"default\", // or \"7702\"\n * chain,\n * signer,\n * transport,\n * });\n * ```\n *\n * @param {CreateModularAccountV2Params} config Configuration parameters for creating a Modular Account V2.\n * @returns {Promise<ModularAccountV2>} A promise that resolves to an `ModularAccountV2` providing methods for nonce retrieval, transaction execution, and more.\n */\nexport async function createModularAccountV2(\n config: CreateModularAccountV2Params\n): Promise<ModularAccountV2> {\n const {\n transport,\n chain,\n signer,\n accountAddress: _accountAddress,\n entryPoint = getEntryPoint(chain, { version: \"0.7.0\" }),\n signerEntity = {\n isGlobalValidation: true,\n entityId: DEFAULT_OWNER_ENTITY_ID,\n },\n signerEntity: { entityId = DEFAULT_OWNER_ENTITY_ID } = {},\n deferredAction,\n } = config;\n\n const accountFunctions = await (async () => {\n switch (config.mode) {\n case \"7702\": {\n const getAccountInitCode = async (): Promise<Hex> => {\n return \"0x\";\n };\n const signerAddress = await signer.getAddress();\n const accountAddress = _accountAddress ?? signerAddress;\n if (\n entityId === DEFAULT_OWNER_ENTITY_ID &&\n signerAddress !== accountAddress\n ) {\n throw new EntityIdOverrideError();\n }\n\n const implementation: Address =\n \"0x69007702764179f14F51cdce752f4f775d74E139\";\n\n const getImplementationAddress = async () => implementation;\n\n return {\n getAccountInitCode,\n accountAddress,\n getImplementationAddress,\n };\n }\n case \"default\":\n case undefined: {\n const {\n salt = 0n,\n factoryAddress = getDefaultMAV2FactoryAddress(chain),\n implementationAddress = getDefaultSMAV2BytecodeAddress(chain),\n initCode,\n } = config;\n\n const signerAddress = await signer.getAddress();\n\n const getAccountInitCode = async () => {\n if (initCode) {\n return initCode;\n }\n\n return concatHex([\n factoryAddress,\n encodeFunctionData({\n abi: accountFactoryAbi,\n functionName: \"createSemiModularAccount\",\n args: [signerAddress, salt],\n }),\n ]);\n };\n\n const accountAddress =\n _accountAddress ??\n predictModularAccountV2Address({\n factoryAddress,\n implementationAddress,\n salt,\n type: \"SMA\",\n ownerAddress: signerAddress,\n });\n\n return {\n getAccountInitCode,\n accountAddress,\n };\n }\n default:\n assertNever(config);\n }\n })();\n\n return createMAv2Base({\n source: \"ModularAccountV2\",\n transport,\n chain,\n signer,\n entryPoint,\n signerEntity,\n deferredAction,\n ...accountFunctions,\n });\n}\n\n// If we add more valid modes, the switch case branch's mode will no longer be `never`, which will cause a compile time error here and ensure we handle the new type.\nfunction assertNever(_valid: never): never {\n throw new InvalidModularAccountV2Mode();\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Address } from "viem";
|
|
2
|
+
export type PredictModularAccountV2AddressParams = {
|
|
3
|
+
factoryAddress: Address;
|
|
4
|
+
implementationAddress: Address;
|
|
5
|
+
salt: bigint;
|
|
6
|
+
} & ({
|
|
7
|
+
type: "MA";
|
|
8
|
+
ownerAddress: Address;
|
|
9
|
+
entityId: number;
|
|
10
|
+
} | {
|
|
11
|
+
type: "SMA";
|
|
12
|
+
ownerAddress: Address;
|
|
13
|
+
} | {
|
|
14
|
+
type: "WebAuthn";
|
|
15
|
+
ownerPublicKey: {
|
|
16
|
+
x: bigint;
|
|
17
|
+
y: bigint;
|
|
18
|
+
};
|
|
19
|
+
entityId: number;
|
|
20
|
+
});
|
|
21
|
+
export declare function predictModularAccountV2Address(params: PredictModularAccountV2AddressParams): Address;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { encodePacked, getContractAddress, keccak256, } from "viem";
|
|
2
|
+
export function predictModularAccountV2Address(params) {
|
|
3
|
+
const { factoryAddress, salt, implementationAddress } = params;
|
|
4
|
+
let combinedSalt;
|
|
5
|
+
let initcode;
|
|
6
|
+
// Note: prediction for MA and WebAuthn is currently untested, because they are not supported as an account type yet.
|
|
7
|
+
// Prior to using this prediction logic, ensure that the counterfactual computation is correct by updating `predictAddress.test.ts` to include a test for MA and WebAuthn.
|
|
8
|
+
switch (params.type) {
|
|
9
|
+
case "SMA":
|
|
10
|
+
// MAv2 factory uses max uint32 for SMA entityId
|
|
11
|
+
combinedSalt = getCombinedSaltK1(params.ownerAddress, salt, 0xffffffff);
|
|
12
|
+
const immutableArgs = params.ownerAddress;
|
|
13
|
+
initcode = getProxyBytecodeWithImmutableArgs(implementationAddress, immutableArgs);
|
|
14
|
+
break;
|
|
15
|
+
case "MA":
|
|
16
|
+
combinedSalt = getCombinedSaltK1(params.ownerAddress, salt, params.entityId);
|
|
17
|
+
initcode = getProxyBytecode(implementationAddress);
|
|
18
|
+
break;
|
|
19
|
+
case "WebAuthn":
|
|
20
|
+
const { ownerPublicKey: { x, y }, } = params;
|
|
21
|
+
combinedSalt = keccak256(encodePacked(["uint256", "uint256", "uint256", "uint32"], [x, y, salt, params.entityId]));
|
|
22
|
+
initcode = getProxyBytecode(implementationAddress);
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
return assertNeverModularAccountV2Type(params);
|
|
26
|
+
}
|
|
27
|
+
return getContractAddress({
|
|
28
|
+
from: factoryAddress,
|
|
29
|
+
opcode: "CREATE2",
|
|
30
|
+
salt: combinedSalt,
|
|
31
|
+
bytecode: initcode,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function getCombinedSaltK1(ownerAddress, salt, entityId) {
|
|
35
|
+
return keccak256(encodePacked(["address", "uint256", "uint32"], [ownerAddress, salt, entityId]));
|
|
36
|
+
}
|
|
37
|
+
function getProxyBytecode(implementationAddress) {
|
|
38
|
+
return `0x603d3d8160223d3973${implementationAddress.slice(2)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;
|
|
39
|
+
}
|
|
40
|
+
function getProxyBytecodeWithImmutableArgs(implementationAddress, immutableArgs) {
|
|
41
|
+
return `0x6100513d8160233d3973${implementationAddress.slice(2)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3${immutableArgs.slice(2)}`;
|
|
42
|
+
}
|
|
43
|
+
function assertNeverModularAccountV2Type(_) {
|
|
44
|
+
throw new Error("Unknown modular account type in predictModularAccountV2Address");
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=predictAddress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predictAddress.js","sourceRoot":"","sources":["../../../../../src/ma-v2/account/predictAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,SAAS,GAGV,MAAM,MAAM,CAAC;AA0Bd,MAAM,UAAU,8BAA8B,CAC5C,MAA4C;IAE5C,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAAC;IAE/D,IAAI,YAAiB,CAAC;IACtB,IAAI,QAAa,CAAC;IAElB,qHAAqH;IACrH,0KAA0K;IAC1K,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,KAAK;YACR,gDAAgD;YAChD,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YACxE,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC;YAC1C,QAAQ,GAAG,iCAAiC,CAC1C,qBAAqB,EACrB,aAAa,CACd,CAAC;YACF,MAAM;QACR,KAAK,IAAI;YACP,YAAY,GAAG,iBAAiB,CAC9B,MAAM,CAAC,YAAY,EACnB,IAAI,EACJ,MAAM,CAAC,QAAQ,CAChB,CAAC;YAEF,QAAQ,GAAG,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;YACnD,MAAM;QACR,KAAK,UAAU;YACb,MAAM,EACJ,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GACzB,GAAG,MAAM,CAAC;YAEX,YAAY,GAAG,SAAS,CACtB,YAAY,CACV,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAC3C,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAC9B,CACF,CAAC;YAEF,QAAQ,GAAG,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;YAEnD,MAAM;QACR;YACE,OAAO,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,kBAAkB,CAAC;QACxB,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,QAAQ;KACnB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CACxB,YAAqB,EACrB,IAAY,EACZ,QAAgB;IAEhB,OAAO,SAAS,CACd,YAAY,CACV,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAChC,CAAC,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,CAC/B,CACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,qBAA8B;IACtD,OAAO,uBAAuB,qBAAqB,CAAC,KAAK,CACvD,CAAC,CACF,sIAAsI,CAAC;AAC1I,CAAC;AAED,SAAS,iCAAiC,CACxC,qBAA8B,EAC9B,aAAkB;IAElB,OAAO,yBAAyB,qBAAqB,CAAC,KAAK,CACzD,CAAC,CACF,uIAAuI,aAAa,CAAC,KAAK,CACzJ,CAAC,CACF,EAAE,CAAC;AACN,CAAC;AAED,SAAS,+BAA+B,CAAC,CAAQ;IAC/C,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;AACJ,CAAC","sourcesContent":["import {\n encodePacked,\n getContractAddress,\n keccak256,\n type Address,\n type Hex,\n} from \"viem\";\n\nexport type PredictModularAccountV2AddressParams = {\n factoryAddress: Address;\n implementationAddress: Address; // Should be the implementation address of the account type you are predicting the address for.\n salt: bigint;\n} & (\n | {\n type: \"MA\";\n ownerAddress: Address;\n entityId: number;\n }\n | {\n type: \"SMA\";\n ownerAddress: Address;\n }\n | {\n type: \"WebAuthn\";\n ownerPublicKey: {\n x: bigint;\n y: bigint;\n };\n entityId: number;\n }\n);\n\nexport function predictModularAccountV2Address(\n params: PredictModularAccountV2AddressParams\n): Address {\n const { factoryAddress, salt, implementationAddress } = params;\n\n let combinedSalt: Hex;\n let initcode: Hex;\n\n // Note: prediction for MA and WebAuthn is currently untested, because they are not supported as an account type yet.\n // Prior to using this prediction logic, ensure that the counterfactual computation is correct by updating `predictAddress.test.ts` to include a test for MA and WebAuthn.\n switch (params.type) {\n case \"SMA\":\n // MAv2 factory uses max uint32 for SMA entityId\n combinedSalt = getCombinedSaltK1(params.ownerAddress, salt, 0xffffffff);\n const immutableArgs = params.ownerAddress;\n initcode = getProxyBytecodeWithImmutableArgs(\n implementationAddress,\n immutableArgs\n );\n break;\n case \"MA\":\n combinedSalt = getCombinedSaltK1(\n params.ownerAddress,\n salt,\n params.entityId\n );\n\n initcode = getProxyBytecode(implementationAddress);\n break;\n case \"WebAuthn\":\n const {\n ownerPublicKey: { x, y },\n } = params;\n\n combinedSalt = keccak256(\n encodePacked(\n [\"uint256\", \"uint256\", \"uint256\", \"uint32\"],\n [x, y, salt, params.entityId]\n )\n );\n\n initcode = getProxyBytecode(implementationAddress);\n\n break;\n default:\n return assertNeverModularAccountV2Type(params);\n }\n\n return getContractAddress({\n from: factoryAddress,\n opcode: \"CREATE2\",\n salt: combinedSalt,\n bytecode: initcode,\n });\n}\n\nfunction getCombinedSaltK1(\n ownerAddress: Address,\n salt: bigint,\n entityId: number\n): Hex {\n return keccak256(\n encodePacked(\n [\"address\", \"uint256\", \"uint32\"],\n [ownerAddress, salt, entityId]\n )\n );\n}\n\nfunction getProxyBytecode(implementationAddress: Address): Hex {\n return `0x603d3d8160223d3973${implementationAddress.slice(\n 2\n )}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;\n}\n\nfunction getProxyBytecodeWithImmutableArgs(\n implementationAddress: Address,\n immutableArgs: Hex\n): Hex {\n return `0x6100513d8160233d3973${implementationAddress.slice(\n 2\n )}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3${immutableArgs.slice(\n 2\n )}`;\n}\n\nfunction assertNeverModularAccountV2Type(_: never): never {\n throw new Error(\n \"Unknown modular account type in predictModularAccountV2Address\"\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multiOwner.d.ts","sourceRoot":"","sources":["../../../../../src/light-account/accounts/multiOwner.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"multiOwner.d.ts","sourceRoot":"","sources":["../../../../../src/light-account/accounts/multiOwner.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,GAAG,EACR,KAAK,SAAS,EACf,MAAM,MAAM,CAAC;AAGd,OAAO,KAAK,EACV,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAGnB,MAAM,MAAM,sBAAsB,CAChC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB,EACvD,oBAAoB,SAAS,mBAAmB,CAAC,wBAAwB,CAAC,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,IACxH,gBAAgB,CAClB,OAAO,EACP,wBAAwB,EACxB,oBAAoB,CACrB,GAAG;IACF,kBAAkB,EAAE,CAClB,WAAW,EAAE,OAAO,EAAE,EACtB,cAAc,EAAE,OAAO,EAAE,KACtB,GAAG,CAAC;IACT,iBAAiB,EAAE,MAAM,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,kCAAkC,CAC5C,UAAU,SAAS,SAAS,GAAG,SAAS,EACxC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB,EACvD,oBAAoB,SAAS,mBAAmB,CAAC,wBAAwB,CAAC,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,IACxH,IAAI,CACN,4BAA4B,CAC1B,wBAAwB,EACxB,oBAAoB,EACpB,UAAU,EACV,OAAO,CACR,EACC,oBAAoB,GACpB,YAAY,GACZ,SAAS,GACT,KAAK,GACL,gBAAgB,GAChB,MAAM,CACT,GAAG;IACF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,UAAU,CAAC,EAAE,aAAa,CACxB,6BAA6B,CAC3B,wBAAwB,EACxB,oBAAoB,CACrB,EACD,KAAK,CACN,CAAC;IACF,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB,CAAC;AAEF,wBAAsB,4BAA4B,CAChD,UAAU,SAAS,SAAS,GAAG,SAAS,EACxC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB,EACvD,oBAAoB,SAAS,mBAAmB,CAAC,wBAAwB,CAAC,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,EAE1H,MAAM,EAAE,kCAAkC,CACxC,UAAU,EACV,OAAO,EACP,oBAAoB,CACrB,GACA,OAAO,CAAC,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC"}
|
|
@@ -3,8 +3,14 @@ import type { LightAccountVersionConfigs } from "../types";
|
|
|
3
3
|
export type PredictLightAccountAddressParams = {
|
|
4
4
|
factoryAddress: Address;
|
|
5
5
|
salt: bigint;
|
|
6
|
-
|
|
6
|
+
ownerAddress: Address;
|
|
7
7
|
version: keyof LightAccountVersionConfigs["LightAccount"];
|
|
8
8
|
};
|
|
9
|
-
export declare function predictLightAccountAddress({ factoryAddress, salt,
|
|
9
|
+
export declare function predictLightAccountAddress({ factoryAddress, salt, ownerAddress, version, }: PredictLightAccountAddressParams): Address;
|
|
10
|
+
export type PredictMultiOwnerLightAccountAddressParams = {
|
|
11
|
+
factoryAddress: Address;
|
|
12
|
+
salt: bigint;
|
|
13
|
+
ownerAddresses: Address[];
|
|
14
|
+
};
|
|
15
|
+
export declare function predictMultiOwnerLightAccountAddress({ factoryAddress, salt, ownerAddresses, }: PredictMultiOwnerLightAccountAddressParams): Address;
|
|
10
16
|
//# sourceMappingURL=predictAddress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predictAddress.d.ts","sourceRoot":"","sources":["../../../../../src/light-account/accounts/predictAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,OAAO,EAIb,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAK3D,MAAM,MAAM,gCAAgC,GAAG;IAC7C,cAAc,EAAE,OAAO,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,
|
|
1
|
+
{"version":3,"file":"predictAddress.d.ts","sourceRoot":"","sources":["../../../../../src/light-account/accounts/predictAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,OAAO,EAIb,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAK3D,MAAM,MAAM,gCAAgC,GAAG;IAC7C,cAAc,EAAE,OAAO,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,0BAA0B,CAAC,cAAc,CAAC,CAAC;CAC3D,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,EACzC,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,OAAO,GACR,EAAE,gCAAgC,GAAG,OAAO,CA2D5C;AAED,MAAM,MAAM,0CAA0C,GAAG;IACvD,cAAc,EAAE,OAAO,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,EAAE,CAAC;CAE3B,CAAC;AAGF,wBAAgB,oCAAoC,CAAC,EACnD,cAAc,EACd,IAAI,EACJ,cAAc,GACf,EAAE,0CAA0C,GAAG,OAAO,CA6BtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modularAccountV2.d.ts","sourceRoot":"","sources":["../../../../../src/ma-v2/account/modularAccountV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,4BAA4B,EAC7B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"modularAccountV2.d.ts","sourceRoot":"","sources":["../../../../../src/ma-v2/account/modularAccountV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AAMtB,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,GAAG,EACR,KAAK,SAAS,EACf,MAAM,MAAM,CAAC;AAMd,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAEtB,MAAM,kCAAkC,CAAC;AAI1C,MAAM,MAAM,4BAA4B,CACtC,UAAU,SAAS,SAAS,GAAG,SAAS,EACxC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB,IACrD,CAAC,IAAI,CACP,4BAA4B,CAAC,kBAAkB,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,EAC5E,WAAW,GAAG,OAAO,GAAG,gBAAgB,CACzC,GAAG;IACF,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,cAAc,CAAC,EAAE,GAAG,CAAC;IACrB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC,GACA,CACI;IACE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CACJ,CAAC;AAEJ,wBAAsB,sBAAsB,CAC1C,UAAU,SAAS,SAAS,GAAG,SAAS,EACxC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB,EAEvD,MAAM,EAAE,4BAA4B,CAAC,UAAU,EAAE,OAAO,CAAC,GACxD,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Address } from "viem";
|
|
2
|
+
export type PredictModularAccountV2AddressParams = {
|
|
3
|
+
factoryAddress: Address;
|
|
4
|
+
implementationAddress: Address;
|
|
5
|
+
salt: bigint;
|
|
6
|
+
} & ({
|
|
7
|
+
type: "MA";
|
|
8
|
+
ownerAddress: Address;
|
|
9
|
+
entityId: number;
|
|
10
|
+
} | {
|
|
11
|
+
type: "SMA";
|
|
12
|
+
ownerAddress: Address;
|
|
13
|
+
} | {
|
|
14
|
+
type: "WebAuthn";
|
|
15
|
+
ownerPublicKey: {
|
|
16
|
+
x: bigint;
|
|
17
|
+
y: bigint;
|
|
18
|
+
};
|
|
19
|
+
entityId: number;
|
|
20
|
+
});
|
|
21
|
+
export declare function predictModularAccountV2Address(params: PredictModularAccountV2AddressParams): Address;
|
|
22
|
+
//# sourceMappingURL=predictAddress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predictAddress.d.ts","sourceRoot":"","sources":["../../../../../src/ma-v2/account/predictAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EAEb,MAAM,MAAM,CAAC;AAEd,MAAM,MAAM,oCAAoC,GAAG;IACjD,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,CACA;IACE,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;CACvB,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE;QACd,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;CAClB,CACJ,CAAC;AAEF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,oCAAoC,GAC3C,OAAO,CAoDT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@account-kit/smart-contracts",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.34.1",
|
|
4
4
|
"description": "aa-sdk compatible interfaces for Alchemy Smart Accounts",
|
|
5
5
|
"author": "Alchemy",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"test:run": "vitest run"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@account-kit/plugingen": "^4.
|
|
55
|
+
"@account-kit/plugingen": "^4.34.1",
|
|
56
56
|
"change-case": "^5.1.2",
|
|
57
57
|
"dedent": "^1.5.1",
|
|
58
58
|
"dotenv": "^16.3.1",
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"url": "https://github.com/alchemyplatform/aa-sdk/issues"
|
|
73
73
|
},
|
|
74
74
|
"homepage": "https://github.com/alchemyplatform/aa-sdk#readme",
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "2d78b5cc399d24717cc1a225e8f3e8fb9e2422f8",
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@aa-sdk/core": "^4.
|
|
78
|
-
"@account-kit/infra": "^4.
|
|
77
|
+
"@aa-sdk/core": "^4.34.1",
|
|
78
|
+
"@account-kit/infra": "^4.34.1"
|
|
79
79
|
},
|
|
80
80
|
"peerDependencies": {
|
|
81
81
|
"viem": "^2.29.2"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createBundlerClient,
|
|
3
|
-
getAccountAddress,
|
|
4
3
|
getEntryPoint,
|
|
5
4
|
type EntryPointDef,
|
|
6
5
|
type SmartAccountSigner,
|
|
@@ -29,6 +28,7 @@ import {
|
|
|
29
28
|
type CreateLightAccountBaseParams,
|
|
30
29
|
type LightAccountBase,
|
|
31
30
|
} from "./base.js";
|
|
31
|
+
import { predictMultiOwnerLightAccountAddress } from "./predictAddress.js";
|
|
32
32
|
|
|
33
33
|
export type MultiOwnerLightAccount<
|
|
34
34
|
TSigner extends SmartAccountSigner = SmartAccountSigner,
|
|
@@ -132,20 +132,20 @@ export async function createMultiOwnerLightAccount({
|
|
|
132
132
|
chain,
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
// NOTE: the current signer connected will be one of the owners as well
|
|
136
|
+
const ownerAddress = await signer.getAddress();
|
|
137
|
+
// owners need to be dedupe + ordered in ascending order and not == to zero address
|
|
138
|
+
const owners_ = Array.from(new Set([...owners, ownerAddress]))
|
|
139
|
+
.filter((x) => hexToBigInt(x) !== 0n)
|
|
140
|
+
.sort((a, b) => {
|
|
141
|
+
const bigintA = hexToBigInt(a);
|
|
142
|
+
const bigintB = hexToBigInt(b);
|
|
137
143
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// owners need to be dedupe + ordered in ascending order and not == to zero address
|
|
141
|
-
const owners_ = Array.from(new Set([...owners, ownerAddress]))
|
|
142
|
-
.filter((x) => hexToBigInt(x) !== 0n)
|
|
143
|
-
.sort((a, b) => {
|
|
144
|
-
const bigintA = hexToBigInt(a);
|
|
145
|
-
const bigintB = hexToBigInt(b);
|
|
144
|
+
return bigintA < bigintB ? -1 : bigintA > bigintB ? 1 : 0;
|
|
145
|
+
});
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
const getAccountInitCode = async () => {
|
|
148
|
+
if (initCode) return initCode;
|
|
149
149
|
|
|
150
150
|
return concatHex([
|
|
151
151
|
factoryAddress,
|
|
@@ -157,12 +157,13 @@ export async function createMultiOwnerLightAccount({
|
|
|
157
157
|
]);
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
const address =
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
160
|
+
const address =
|
|
161
|
+
accountAddress ??
|
|
162
|
+
predictMultiOwnerLightAccountAddress({
|
|
163
|
+
factoryAddress,
|
|
164
|
+
salt: salt_,
|
|
165
|
+
ownerAddresses: owners_,
|
|
166
|
+
});
|
|
166
167
|
|
|
167
168
|
const account = await createLightAccountBase<
|
|
168
169
|
"MultiOwnerLightAccount",
|
|
@@ -16,14 +16,14 @@ import { LightAccountAbi_v1 } from "../abis/LightAccountAbi_v1.js";
|
|
|
16
16
|
export type PredictLightAccountAddressParams = {
|
|
17
17
|
factoryAddress: Address;
|
|
18
18
|
salt: bigint;
|
|
19
|
-
|
|
19
|
+
ownerAddress: Address;
|
|
20
20
|
version: keyof LightAccountVersionConfigs["LightAccount"];
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
export function predictLightAccountAddress({
|
|
24
24
|
factoryAddress,
|
|
25
25
|
salt,
|
|
26
|
-
|
|
26
|
+
ownerAddress,
|
|
27
27
|
version,
|
|
28
28
|
}: PredictLightAccountAddressParams): Address {
|
|
29
29
|
const implementationAddress =
|
|
@@ -57,7 +57,7 @@ export function predictLightAccountAddress({
|
|
|
57
57
|
encodeFunctionData({
|
|
58
58
|
abi: LightAccountAbi_v1,
|
|
59
59
|
functionName: "initialize",
|
|
60
|
-
args: [
|
|
60
|
+
args: [ownerAddress],
|
|
61
61
|
}),
|
|
62
62
|
],
|
|
63
63
|
}),
|
|
@@ -68,15 +68,11 @@ export function predictLightAccountAddress({
|
|
|
68
68
|
const combinedSalt = keccak256(
|
|
69
69
|
encodeAbiParameters(
|
|
70
70
|
[{ type: "address" }, { type: "uint256" }],
|
|
71
|
-
[
|
|
71
|
+
[ownerAddress, salt]
|
|
72
72
|
)
|
|
73
73
|
);
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const initCode: Hex = `0x603d3d8160223d3973${implementationAddress.slice(
|
|
78
|
-
2
|
|
79
|
-
)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;
|
|
75
|
+
const initCode: Hex = getLAv2ProxyBytecode(implementationAddress);
|
|
80
76
|
|
|
81
77
|
return getContractAddress({
|
|
82
78
|
from: factoryAddress,
|
|
@@ -90,6 +86,57 @@ export function predictLightAccountAddress({
|
|
|
90
86
|
}
|
|
91
87
|
}
|
|
92
88
|
|
|
89
|
+
export type PredictMultiOwnerLightAccountAddressParams = {
|
|
90
|
+
factoryAddress: Address;
|
|
91
|
+
salt: bigint;
|
|
92
|
+
ownerAddresses: Address[];
|
|
93
|
+
// There's just one version of the MultiOwnerLightAccount for now, so skip requiring the version as a parameter.
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Note: assumes the owner addresses are already deduped, sorted in ascending order, and have the signer address included.
|
|
97
|
+
export function predictMultiOwnerLightAccountAddress({
|
|
98
|
+
factoryAddress,
|
|
99
|
+
salt,
|
|
100
|
+
ownerAddresses,
|
|
101
|
+
}: PredictMultiOwnerLightAccountAddressParams): Address {
|
|
102
|
+
const implementationAddress =
|
|
103
|
+
// If we aren't using the default factory address, we compute the implementation address from the factory's `create` deployment.
|
|
104
|
+
// This is accurate for both LA v1 and v2 factories. If we are using the default factory address, we use the implementation address from the registry.
|
|
105
|
+
factoryAddress !==
|
|
106
|
+
AccountVersionRegistry.MultiOwnerLightAccount["v2.0.0"].addresses.default
|
|
107
|
+
.factory
|
|
108
|
+
? getContractAddress({
|
|
109
|
+
from: factoryAddress,
|
|
110
|
+
nonce: 1n,
|
|
111
|
+
})
|
|
112
|
+
: AccountVersionRegistry.MultiOwnerLightAccount["v2.0.0"].addresses
|
|
113
|
+
.default.impl;
|
|
114
|
+
|
|
115
|
+
const combinedSalt = keccak256(
|
|
116
|
+
encodeAbiParameters(
|
|
117
|
+
[{ type: "address[]" }, { type: "uint256" }],
|
|
118
|
+
[ownerAddresses, salt]
|
|
119
|
+
)
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const initCode: Hex = getLAv2ProxyBytecode(implementationAddress);
|
|
123
|
+
|
|
124
|
+
return getContractAddress({
|
|
125
|
+
from: factoryAddress,
|
|
126
|
+
opcode: "CREATE2",
|
|
127
|
+
salt: combinedSalt,
|
|
128
|
+
bytecode: initCode,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Bytecode from https://github.com/Vectorized/solady/blob/c6e5238e5f3b621789c59e1a443f43b6606394b2/src/utils/LibClone.sol#L721
|
|
133
|
+
|
|
134
|
+
function getLAv2ProxyBytecode(implementationAddress: Address): Hex {
|
|
135
|
+
return `0x603d3d8160223d3973${implementationAddress.slice(
|
|
136
|
+
2
|
|
137
|
+
)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;
|
|
138
|
+
}
|
|
139
|
+
|
|
93
140
|
function assertNeverLightAccountVersion(version: never): never {
|
|
94
141
|
throw new Error(`Unknown light account version: ${version}`);
|
|
95
142
|
}
|
|
@@ -4,9 +4,7 @@ import type {
|
|
|
4
4
|
ToSmartContractAccountParams,
|
|
5
5
|
} from "@aa-sdk/core";
|
|
6
6
|
import {
|
|
7
|
-
createBundlerClient,
|
|
8
7
|
getEntryPoint,
|
|
9
|
-
getAccountAddress,
|
|
10
8
|
EntityIdOverrideError,
|
|
11
9
|
InvalidModularAccountV2Mode,
|
|
12
10
|
} from "@aa-sdk/core";
|
|
@@ -19,13 +17,17 @@ import {
|
|
|
19
17
|
type Transport,
|
|
20
18
|
} from "viem";
|
|
21
19
|
import { accountFactoryAbi } from "../abis/accountFactoryAbi.js";
|
|
22
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
getDefaultMAV2FactoryAddress,
|
|
22
|
+
getDefaultSMAV2BytecodeAddress,
|
|
23
|
+
} from "../utils.js";
|
|
23
24
|
import {
|
|
24
25
|
type SignerEntity,
|
|
25
26
|
type ModularAccountV2,
|
|
26
27
|
createMAv2Base,
|
|
27
28
|
} from "./common/modularAccountV2Base.js";
|
|
28
29
|
import { DEFAULT_OWNER_ENTITY_ID } from "../utils.js";
|
|
30
|
+
import { predictModularAccountV2Address } from "./predictAddress.js";
|
|
29
31
|
|
|
30
32
|
export type CreateModularAccountV2Params<
|
|
31
33
|
TTransport extends Transport = Transport,
|
|
@@ -44,6 +46,7 @@ export type CreateModularAccountV2Params<
|
|
|
44
46
|
mode?: "default";
|
|
45
47
|
salt?: bigint;
|
|
46
48
|
factoryAddress?: Address;
|
|
49
|
+
implementationAddress?: Address;
|
|
47
50
|
initCode?: Hex;
|
|
48
51
|
}
|
|
49
52
|
| {
|
|
@@ -107,11 +110,6 @@ export async function createModularAccountV2(
|
|
|
107
110
|
deferredAction,
|
|
108
111
|
} = config;
|
|
109
112
|
|
|
110
|
-
const client = createBundlerClient({
|
|
111
|
-
transport,
|
|
112
|
-
chain,
|
|
113
|
-
});
|
|
114
|
-
|
|
115
113
|
const accountFunctions = await (async () => {
|
|
116
114
|
switch (config.mode) {
|
|
117
115
|
case "7702": {
|
|
@@ -143,9 +141,12 @@ export async function createModularAccountV2(
|
|
|
143
141
|
const {
|
|
144
142
|
salt = 0n,
|
|
145
143
|
factoryAddress = getDefaultMAV2FactoryAddress(chain),
|
|
144
|
+
implementationAddress = getDefaultSMAV2BytecodeAddress(chain),
|
|
146
145
|
initCode,
|
|
147
146
|
} = config;
|
|
148
147
|
|
|
148
|
+
const signerAddress = await signer.getAddress();
|
|
149
|
+
|
|
149
150
|
const getAccountInitCode = async () => {
|
|
150
151
|
if (initCode) {
|
|
151
152
|
return initCode;
|
|
@@ -156,17 +157,20 @@ export async function createModularAccountV2(
|
|
|
156
157
|
encodeFunctionData({
|
|
157
158
|
abi: accountFactoryAbi,
|
|
158
159
|
functionName: "createSemiModularAccount",
|
|
159
|
-
args: [
|
|
160
|
+
args: [signerAddress, salt],
|
|
160
161
|
}),
|
|
161
162
|
]);
|
|
162
163
|
};
|
|
163
164
|
|
|
164
|
-
const accountAddress =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
const accountAddress =
|
|
166
|
+
_accountAddress ??
|
|
167
|
+
predictModularAccountV2Address({
|
|
168
|
+
factoryAddress,
|
|
169
|
+
implementationAddress,
|
|
170
|
+
salt,
|
|
171
|
+
type: "SMA",
|
|
172
|
+
ownerAddress: signerAddress,
|
|
173
|
+
});
|
|
170
174
|
|
|
171
175
|
return {
|
|
172
176
|
getAccountInitCode,
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {
|
|
2
|
+
encodePacked,
|
|
3
|
+
getContractAddress,
|
|
4
|
+
keccak256,
|
|
5
|
+
type Address,
|
|
6
|
+
type Hex,
|
|
7
|
+
} from "viem";
|
|
8
|
+
|
|
9
|
+
export type PredictModularAccountV2AddressParams = {
|
|
10
|
+
factoryAddress: Address;
|
|
11
|
+
implementationAddress: Address; // Should be the implementation address of the account type you are predicting the address for.
|
|
12
|
+
salt: bigint;
|
|
13
|
+
} & (
|
|
14
|
+
| {
|
|
15
|
+
type: "MA";
|
|
16
|
+
ownerAddress: Address;
|
|
17
|
+
entityId: number;
|
|
18
|
+
}
|
|
19
|
+
| {
|
|
20
|
+
type: "SMA";
|
|
21
|
+
ownerAddress: Address;
|
|
22
|
+
}
|
|
23
|
+
| {
|
|
24
|
+
type: "WebAuthn";
|
|
25
|
+
ownerPublicKey: {
|
|
26
|
+
x: bigint;
|
|
27
|
+
y: bigint;
|
|
28
|
+
};
|
|
29
|
+
entityId: number;
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export function predictModularAccountV2Address(
|
|
34
|
+
params: PredictModularAccountV2AddressParams
|
|
35
|
+
): Address {
|
|
36
|
+
const { factoryAddress, salt, implementationAddress } = params;
|
|
37
|
+
|
|
38
|
+
let combinedSalt: Hex;
|
|
39
|
+
let initcode: Hex;
|
|
40
|
+
|
|
41
|
+
// Note: prediction for MA and WebAuthn is currently untested, because they are not supported as an account type yet.
|
|
42
|
+
// Prior to using this prediction logic, ensure that the counterfactual computation is correct by updating `predictAddress.test.ts` to include a test for MA and WebAuthn.
|
|
43
|
+
switch (params.type) {
|
|
44
|
+
case "SMA":
|
|
45
|
+
// MAv2 factory uses max uint32 for SMA entityId
|
|
46
|
+
combinedSalt = getCombinedSaltK1(params.ownerAddress, salt, 0xffffffff);
|
|
47
|
+
const immutableArgs = params.ownerAddress;
|
|
48
|
+
initcode = getProxyBytecodeWithImmutableArgs(
|
|
49
|
+
implementationAddress,
|
|
50
|
+
immutableArgs
|
|
51
|
+
);
|
|
52
|
+
break;
|
|
53
|
+
case "MA":
|
|
54
|
+
combinedSalt = getCombinedSaltK1(
|
|
55
|
+
params.ownerAddress,
|
|
56
|
+
salt,
|
|
57
|
+
params.entityId
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
initcode = getProxyBytecode(implementationAddress);
|
|
61
|
+
break;
|
|
62
|
+
case "WebAuthn":
|
|
63
|
+
const {
|
|
64
|
+
ownerPublicKey: { x, y },
|
|
65
|
+
} = params;
|
|
66
|
+
|
|
67
|
+
combinedSalt = keccak256(
|
|
68
|
+
encodePacked(
|
|
69
|
+
["uint256", "uint256", "uint256", "uint32"],
|
|
70
|
+
[x, y, salt, params.entityId]
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
initcode = getProxyBytecode(implementationAddress);
|
|
75
|
+
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
return assertNeverModularAccountV2Type(params);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return getContractAddress({
|
|
82
|
+
from: factoryAddress,
|
|
83
|
+
opcode: "CREATE2",
|
|
84
|
+
salt: combinedSalt,
|
|
85
|
+
bytecode: initcode,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getCombinedSaltK1(
|
|
90
|
+
ownerAddress: Address,
|
|
91
|
+
salt: bigint,
|
|
92
|
+
entityId: number
|
|
93
|
+
): Hex {
|
|
94
|
+
return keccak256(
|
|
95
|
+
encodePacked(
|
|
96
|
+
["address", "uint256", "uint32"],
|
|
97
|
+
[ownerAddress, salt, entityId]
|
|
98
|
+
)
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getProxyBytecode(implementationAddress: Address): Hex {
|
|
103
|
+
return `0x603d3d8160223d3973${implementationAddress.slice(
|
|
104
|
+
2
|
|
105
|
+
)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function getProxyBytecodeWithImmutableArgs(
|
|
109
|
+
implementationAddress: Address,
|
|
110
|
+
immutableArgs: Hex
|
|
111
|
+
): Hex {
|
|
112
|
+
return `0x6100513d8160233d3973${implementationAddress.slice(
|
|
113
|
+
2
|
|
114
|
+
)}60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3${immutableArgs.slice(
|
|
115
|
+
2
|
|
116
|
+
)}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function assertNeverModularAccountV2Type(_: never): never {
|
|
120
|
+
throw new Error(
|
|
121
|
+
"Unknown modular account type in predictModularAccountV2Address"
|
|
122
|
+
);
|
|
123
|
+
}
|