From 557b679205f2b5219894dff243f334ad495396ff Mon Sep 17 00:00:00 2001 From: howydev <132113803+howydev@users.noreply.github.com> Date: Wed, 26 Mar 2025 16:23:54 -0400 Subject: [PATCH 1/6] feat: add entity id and nonce reader --- .../src/ma-v2/abis/entityIdAndNonceReader.ts | 23 +++ .../src/ma-v2/actions/DeferralActions.ts | 77 ++++++++-- .../src/ma-v2/client/client.test.ts | 132 +++++++++++++++++- .../smart-contracts/src/ma-v2/index.ts | 1 + .../smart-contracts/src/ma-v2/utils.ts | 26 ++++ 5 files changed, 247 insertions(+), 12 deletions(-) create mode 100644 account-kit/smart-contracts/src/ma-v2/abis/entityIdAndNonceReader.ts diff --git a/account-kit/smart-contracts/src/ma-v2/abis/entityIdAndNonceReader.ts b/account-kit/smart-contracts/src/ma-v2/abis/entityIdAndNonceReader.ts new file mode 100644 index 0000000000..4905f7a0ae --- /dev/null +++ b/account-kit/smart-contracts/src/ma-v2/abis/entityIdAndNonceReader.ts @@ -0,0 +1,23 @@ +export const entityIdAndNonceReaderAbi = [ + { + type: "constructor", + inputs: [ + { + name: "account", + type: "address", + internalType: "contract IModularAccountView", + }, + { + name: "ep", + type: "address", + internalType: "contract IEntryPoint", + }, + { + name: "nonce", + type: "uint192", + internalType: "uint192", + }, + ], + stateMutability: "nonpayable", + }, +]; diff --git a/account-kit/smart-contracts/src/ma-v2/actions/DeferralActions.ts b/account-kit/smart-contracts/src/ma-v2/actions/DeferralActions.ts index 9508800fba..8c15277d4a 100644 --- a/account-kit/smart-contracts/src/ma-v2/actions/DeferralActions.ts +++ b/account-kit/smart-contracts/src/ma-v2/actions/DeferralActions.ts @@ -15,7 +15,11 @@ import { encodePacked, size, toHex, + encodeDeployData, + hexToNumber, } from "viem"; +import { entityIdAndNonceReaderBytecode, buildFullNonce } from "../utils.js"; +import { entityIdAndNonceReaderAbi } from "../abis/entityIdAndNonceReader.js"; import type { ModularAccountV2Client } from "../client/client.js"; export type DeferredActionTypedData = { @@ -62,6 +66,12 @@ export type BuildUserOperationWithDeferredActionParams = { nonceOverride: bigint; }; +export type EntityIdAndNonceParams = { + entityId: number; + nonce: bigint; + isGlobalValidation: boolean; +}; + export type DeferralActions = { createDeferredActionTypedDataObject: ( args: CreateDeferredActionTypedDataParams @@ -70,6 +80,9 @@ export type DeferralActions = { buildUserOperationWithDeferredAction: ( args: BuildUserOperationWithDeferredActionParams ) => Promise; + getEntityIdAndNonce: ( + args: EntityIdAndNonceParams + ) => Promise<{ nonce: bigint; entityId: number }>; }; /** @@ -86,15 +99,14 @@ export const deferralActions: ( deadline, entityId, isGlobalValidation, - nonceKeyOverride, + nonceKeyOverride = 0n, }: CreateDeferredActionTypedDataParams): Promise => { if (!client.account) { throw new AccountNotFoundError(); } - const baseNonceKey = nonceKeyOverride || 0n; - if (baseNonceKey > maxUint152) { - throw new InvalidNonceKeyError(baseNonceKey); + if (nonceKeyOverride > maxUint152) { + throw new InvalidNonceKeyError(nonceKeyOverride); } const entryPoint = client.account.getEntryPoint(); @@ -108,12 +120,12 @@ export const deferralActions: ( client: client, }); - // 2 = deferred action flags 0b10 - // 1 = isGlobal validation flag 0b01 - const fullNonceKey: bigint = - ((baseNonceKey << 40n) + (BigInt(entityId) << 8n)) | - 2n | - (isGlobalValidation ? 1n : 0n); + const fullNonceKey: bigint = buildFullNonce({ + nonce: nonceKeyOverride, + entityId, + isGlobalValidation, + isDeferredAction: true, + }); const nonceOverride = (await entryPointContract.read.getNonce([ client.account.address, @@ -224,9 +236,54 @@ export const deferralActions: ( return unsignedUo; }; + const getEntityIdAndNonce = async ({ + entityId, + nonce, + isGlobalValidation, + }: EntityIdAndNonceParams) => { + if (!client.account) { + throw new AccountNotFoundError(); + } + + if (nonce > maxUint152) { + throw new InvalidNonceKeyError(nonce); + } + + const entryPoint = client.account.getEntryPoint(); + if (entryPoint === undefined) { + throw new EntryPointNotFoundError(client.chain, "0.7.0"); + } + + const bytecode = encodeDeployData({ + abi: entityIdAndNonceReaderAbi, + bytecode: entityIdAndNonceReaderBytecode, + args: [ + client.account.address, + entryPoint.address, + buildFullNonce({ + nonce, + entityId, + isGlobalValidation, + isDeferredAction: true, + }), + ], + }); + + const { data } = await client.call({ data: bytecode }); + if (!data) { + throw new Error("No data returned from contract call"); + } + + return { + nonce: BigInt(data), + entityId: hexToNumber(`0x${data.slice(40, 48)}`), + }; + }; + return { createDeferredActionTypedDataObject, buildDeferredActionDigest, buildUserOperationWithDeferredAction, + getEntityIdAndNonce, }; }; diff --git a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts index 10e2d15776..fbee114805 100644 --- a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts +++ b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts @@ -16,12 +16,14 @@ import { hashMessage, hashTypedData, fromHex, + prepareEncodeFunctionData, isAddress, concat, testActions, - type TestActions, concatHex, + type TestActions, type Hex, + type ContractFunctionName, } from "viem"; import { HookType } from "../actions/common/types.js"; import { @@ -37,6 +39,7 @@ import { AllowlistModule, NativeTokenLimitModule, semiModularAccountBytecodeAbi, + buildFullNonce, } from "@account-kit/smart-contracts/experimental"; import { createLightAccountClient, @@ -58,7 +61,7 @@ import { alchemyGasAndPaymasterAndDataMiddleware, } from "@account-kit/infra"; import { getMAV2UpgradeToData } from "@account-kit/smart-contracts"; -import { deferralActions } from "../actions/DeferralActions.js"; +import { deferralActions } from "../actions/deferralActions.js"; import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; // Note: These tests maintain a shared state to not break the local-running rundler by desyncing the chain. @@ -1345,6 +1348,128 @@ describe("MA v2 Tests", async () => { client.setAutomine(true); }); + it("tests entity id and nonce selection", async () => { + let newClient = (await givenConnectedProvider({ signer, salt: 1n })) + .extend(deferralActions) + .extend(installValidationActions); + + await setBalance(client, { + address: newClient.getAddress(), + value: parseEther("2"), + }); + + const entryPoint = newClient.account.getEntryPoint(); + const entryPointContract = getContract({ + address: entryPoint.address, + abi: entryPoint.abi, + client, + }); + + // entity id and nonce selection for undeployed account + for (let startEntityId = 0; startEntityId < 5; startEntityId++) { + for (let startNonce = 0n; startNonce < 5n; startNonce++) { + const { entityId, nonce } = await newClient.getEntityIdAndNonce({ + entityId: startEntityId, + nonce: startNonce, + isGlobalValidation: true, + }); + + const expectedEntityId: number = Math.max(1, startEntityId); + + // account not deployed, expect to get 1 when we pass in 0 + assert(entityId === expectedEntityId); + assert( + nonce === + (await entryPointContract.read.getNonce([ + newClient.account.address, + buildFullNonce({ + nonce: startNonce, + entityId: expectedEntityId, + isDeferredAction: true, + }), + ])) + ); + } + } + + // deploy the account and install at entity id 1 with global validation + const uo1 = await newClient.installValidation({ + validationConfig: { + moduleAddress: getDefaultSingleSignerValidationModuleAddress( + newClient.chain + ), + entityId: 1, + isGlobal: true, + isSignatureValidation: false, + isUserOpValidation: false, + }, + selectors: [], + installData: SingleSignerValidationModule.encodeOnInstallData({ + entityId: 1, + signer: await sessionKey.getAddress(), + }), + hooks: [], + }); + await newClient.waitForUserOperationTransaction(uo1); + + const selectors = ["execute", "executeBatch"].map( + (e) => + prepareEncodeFunctionData({ + abi: semiModularAccountBytecodeAbi, + functionName: e as ContractFunctionName< + typeof semiModularAccountBytecodeAbi + >, + }).functionName + ); + + // deploy the account and install some entity ids with selector validation + const uo2 = await newClient.installValidation({ + validationConfig: { + moduleAddress: getDefaultSingleSignerValidationModuleAddress( + newClient.chain + ), + entityId: 2, + isGlobal: false, + isSignatureValidation: false, + isUserOpValidation: false, + }, + selectors, + installData: SingleSignerValidationModule.encodeOnInstallData({ + entityId: 2, + signer: await sessionKey.getAddress(), + }), + hooks: [], + }); + await newClient.waitForUserOperationTransaction(uo2); + + // entity id and nonce selection for undeployed account + for (let startEntityId = 1; startEntityId < 5; startEntityId++) { + for (let startNonce = 0n; startNonce < 5n; startNonce++) { + const { entityId, nonce } = await newClient.getEntityIdAndNonce({ + entityId: startEntityId, + nonce: startNonce, + isGlobalValidation: true, + }); + + const expectedEntityId: number = Math.max(startEntityId, 3); + + // expect to get max(3, startEntityId) + assert(entityId === expectedEntityId); + assert( + nonce === + (await entryPointContract.read.getNonce([ + newClient.account.address, + buildFullNonce({ + nonce: startNonce, + entityId: expectedEntityId, + isDeferredAction: true, + }), + ])) + ); + } + } + }); + it("upgrade from a lightaccount", async () => { const lightAccountClient = await createLightAccountClient({ chain: instance.chain, @@ -1398,11 +1523,13 @@ describe("MA v2 Tests", async () => { signerEntity, accountAddress, paymasterMiddleware, + salt = 0n, }: { signer: SmartAccountSigner; signerEntity?: SignerEntity; accountAddress?: `0x${string}`; paymasterMiddleware?: "alchemyGasAndPaymasterAndData" | "erc7677"; + salt?: bigint; }) => createModularAccountV2Client({ chain: instance.chain, @@ -1419,6 +1546,7 @@ describe("MA v2 Tests", async () => { : paymasterMiddleware === "erc7677" ? erc7677Middleware() : {}), + salt, }); it("alchemy client calls the createAlchemySmartAccountClient", async () => { diff --git a/account-kit/smart-contracts/src/ma-v2/index.ts b/account-kit/smart-contracts/src/ma-v2/index.ts index f911b6b525..b0f610c258 100644 --- a/account-kit/smart-contracts/src/ma-v2/index.ts +++ b/account-kit/smart-contracts/src/ma-v2/index.ts @@ -29,6 +29,7 @@ export { getDefaultTimeRangeModuleAddress, getDefaultWebauthnValidationModuleAddress, } from "./modules/utils.js"; +export { buildFullNonce } from "./utils.js"; export { allowlistModuleAbi } from "./modules/allowlist-module/abis/allowlistModuleAbi.js"; export { AllowlistModule } from "./modules/allowlist-module/module.js"; export { nativeTokenLimitModuleAbi } from "./modules/native-token-limit-module/abis/nativeTokenLimitModuleAbi.js"; diff --git a/account-kit/smart-contracts/src/ma-v2/utils.ts b/account-kit/smart-contracts/src/ma-v2/utils.ts index 2d6cca4289..46a8336c53 100644 --- a/account-kit/smart-contracts/src/ma-v2/utils.ts +++ b/account-kit/smart-contracts/src/ma-v2/utils.ts @@ -3,6 +3,7 @@ import { toHex, custom, encodeFunctionData, + maxUint32, type Hex, type Chain, type Address, @@ -228,3 +229,28 @@ export async function getMAV2UpgradeToData< }), }; } + +export const entityIdAndNonceReaderBytecode = + "0x608060405234801561001057600080fd5b506040516104f13803806104f183398101604081905261002f916101e5565b60006008826001600160c01b0316901c90506000808263ffffffff1611610057576001610059565b815b90506001600160a01b0385163b15610133575b60006001600160a01b03861663d31b575b6bffffffff0000000000000000604085901b166040516001600160e01b031960e084901b1681526001600160401b03199091166004820152602401600060405180830381865afa1580156100d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526100fd91908101906103c6565b805190915060ff161580156101155750606081015151155b156101205750610133565b8161012a816104a4565b9250505061006c565b604051631aab3f0d60e11b81526001600160a01b03868116600483015264ffffffff01600160c01b038516600884901b64ffffffff0016176024830152600091908616906335567e1a90604401602060405180830381865afa15801561019d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c191906104d7565b90508060005260206000f35b6001600160a01b03811681146101e257600080fd5b50565b6000806000606084860312156101fa57600080fd5b8351610205816101cd565b6020850151909350610216816101cd565b60408501519092506001600160c01b038116811461023357600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156102765761027661023e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156102a4576102a461023e565b604052919050565b60006001600160401b038211156102c5576102c561023e565b5060051b60200190565b600082601f8301126102e057600080fd5b81516102f36102ee826102ac565b61027c565b8082825260208201915060208360051b86010192508583111561031557600080fd5b602085015b8381101561034857805166ffffffffffffff198116811461033a57600080fd5b83526020928301920161031a565b5095945050505050565b600082601f83011261036357600080fd5b81516103716102ee826102ac565b8082825260208201915060208360051b86010192508583111561039357600080fd5b602085015b838110156103485780516001600160e01b0319811681146103b857600080fd5b835260209283019201610398565b6000602082840312156103d857600080fd5b81516001600160401b038111156103ee57600080fd5b82016080818503121561040057600080fd5b610408610254565b815160ff8116811461041957600080fd5b815260208201516001600160401b0381111561043457600080fd5b610440868285016102cf565b60208301525060408201516001600160401b0381111561045f57600080fd5b61046b868285016102cf565b60408301525060608201516001600160401b0381111561048a57600080fd5b61049686828501610352565b606083015250949350505050565b600063ffffffff821663ffffffff81036104ce57634e487b7160e01b600052601160045260246000fd5b60010192915050565b6000602082840312156104e957600080fd5b505191905056fe"; + +export type BuildNonceParams = { + nonce?: bigint; + entityId?: number; + isGlobalValidation?: boolean; + isDeferredAction?: boolean; + isDirectCallValidation?: boolean; +}; + +export const buildFullNonce = ({ + nonce = 0n, + entityId = 0, + isGlobalValidation = true, + isDeferredAction = false, +}: BuildNonceParams): bigint => { + return ( + (nonce << 40n) + + BigInt(entityId << 8) + + (isDeferredAction ? 2n : 0n) + + (isGlobalValidation ? 1n : 0n) + ); +}; From 277165e0fb47dc67d0ac16facdd7336bf3399a94 Mon Sep 17 00:00:00 2001 From: howydev <132113803+howydev@users.noreply.github.com> Date: Thu, 27 Mar 2025 13:44:25 -0400 Subject: [PATCH 2/6] chore: remove unused var --- .../src/ma-v2/actions/{DeferralActions.ts => deferralActions.ts} | 0 account-kit/smart-contracts/src/ma-v2/utils.ts | 1 - 2 files changed, 1 deletion(-) rename account-kit/smart-contracts/src/ma-v2/actions/{DeferralActions.ts => deferralActions.ts} (100%) diff --git a/account-kit/smart-contracts/src/ma-v2/actions/DeferralActions.ts b/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts similarity index 100% rename from account-kit/smart-contracts/src/ma-v2/actions/DeferralActions.ts rename to account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts diff --git a/account-kit/smart-contracts/src/ma-v2/utils.ts b/account-kit/smart-contracts/src/ma-v2/utils.ts index 46a8336c53..3636028153 100644 --- a/account-kit/smart-contracts/src/ma-v2/utils.ts +++ b/account-kit/smart-contracts/src/ma-v2/utils.ts @@ -3,7 +3,6 @@ import { toHex, custom, encodeFunctionData, - maxUint32, type Hex, type Chain, type Address, From fb37e096ab37399a3081227ff1a5daf6ae72c480 Mon Sep 17 00:00:00 2001 From: Zer0dot Date: Tue, 1 Apr 2025 17:09:15 -0400 Subject: [PATCH 3/6] Update account-kit/smart-contracts/src/ma-v2/client/client.test.ts --- account-kit/smart-contracts/src/ma-v2/client/client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts index fbee114805..6071b9e097 100644 --- a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts +++ b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts @@ -1413,7 +1413,7 @@ describe("MA v2 Tests", async () => { await newClient.waitForUserOperationTransaction(uo1); const selectors = ["execute", "executeBatch"].map( - (e) => + (s) => prepareEncodeFunctionData({ abi: semiModularAccountBytecodeAbi, functionName: e as ContractFunctionName< From 3e6bd9dcf1d4a1d4d45c660efae7d856cacfe0d7 Mon Sep 17 00:00:00 2001 From: Zer0dot Date: Tue, 1 Apr 2025 17:09:50 -0400 Subject: [PATCH 4/6] Update account-kit/smart-contracts/src/ma-v2/client/client.test.ts --- account-kit/smart-contracts/src/ma-v2/client/client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts index 6071b9e097..66bfb685b2 100644 --- a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts +++ b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts @@ -1416,7 +1416,7 @@ describe("MA v2 Tests", async () => { (s) => prepareEncodeFunctionData({ abi: semiModularAccountBytecodeAbi, - functionName: e as ContractFunctionName< + functionName: s as ContractFunctionName< typeof semiModularAccountBytecodeAbi >, }).functionName From c2978e514c08fdb57f604775a9b2714580e7bf8b Mon Sep 17 00:00:00 2001 From: howydev <132113803+howydev@users.noreply.github.com> Date: Wed, 2 Apr 2025 12:16:11 -0400 Subject: [PATCH 5/6] fix: reviews --- .../src/ma-v2/actions/deferralActions.ts | 14 +++-- .../src/ma-v2/client/client.test.ts | 61 ++++++++++--------- .../smart-contracts/src/ma-v2/utils.ts | 6 +- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts b/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts index 8c15277d4a..37f56b07ff 100644 --- a/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts +++ b/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts @@ -68,7 +68,7 @@ export type BuildUserOperationWithDeferredActionParams = { export type EntityIdAndNonceParams = { entityId: number; - nonce: bigint; + nonceKey: bigint; isGlobalValidation: boolean; }; @@ -120,8 +120,10 @@ export const deferralActions: ( client: client, }); + // 2 = deferred action flags 0b10 + // 1 = isGlobal validation flag 0b01 const fullNonceKey: bigint = buildFullNonce({ - nonce: nonceKeyOverride, + nonceKey: nonceKeyOverride, entityId, isGlobalValidation, isDeferredAction: true, @@ -238,15 +240,15 @@ export const deferralActions: ( const getEntityIdAndNonce = async ({ entityId, - nonce, + nonceKey, isGlobalValidation, }: EntityIdAndNonceParams) => { if (!client.account) { throw new AccountNotFoundError(); } - if (nonce > maxUint152) { - throw new InvalidNonceKeyError(nonce); + if (nonceKey > maxUint152) { + throw new InvalidNonceKeyError(nonceKey); } const entryPoint = client.account.getEntryPoint(); @@ -261,7 +263,7 @@ export const deferralActions: ( client.account.address, entryPoint.address, buildFullNonce({ - nonce, + nonceKey, entityId, isGlobalValidation, isDeferredAction: true, diff --git a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts index 66bfb685b2..4ef558a99c 100644 --- a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts +++ b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts @@ -1370,25 +1370,24 @@ describe("MA v2 Tests", async () => { for (let startNonce = 0n; startNonce < 5n; startNonce++) { const { entityId, nonce } = await newClient.getEntityIdAndNonce({ entityId: startEntityId, - nonce: startNonce, + nonceKey: startNonce, isGlobalValidation: true, }); const expectedEntityId: number = Math.max(1, startEntityId); // account not deployed, expect to get 1 when we pass in 0 - assert(entityId === expectedEntityId); - assert( - nonce === - (await entryPointContract.read.getNonce([ - newClient.account.address, - buildFullNonce({ - nonce: startNonce, - entityId: expectedEntityId, - isDeferredAction: true, - }), - ])) - ); + expect(entityId).toEqual(expectedEntityId); + await expect( + entryPointContract.read.getNonce([ + newClient.account.address, + buildFullNonce({ + nonceKey: startNonce, + entityId: expectedEntityId, + isDeferredAction: true, + }), + ]) + ).resolves.toEqual(nonce); } } @@ -1412,13 +1411,16 @@ describe("MA v2 Tests", async () => { }); await newClient.waitForUserOperationTransaction(uo1); - const selectors = ["execute", "executeBatch"].map( + const fns: ContractFunctionName[] = [ + "execute", + "executeBatch", + ]; + + const selectors = fns.map( (s) => prepareEncodeFunctionData({ abi: semiModularAccountBytecodeAbi, - functionName: s as ContractFunctionName< - typeof semiModularAccountBytecodeAbi - >, + functionName: s, }).functionName ); @@ -1447,25 +1449,24 @@ describe("MA v2 Tests", async () => { for (let startNonce = 0n; startNonce < 5n; startNonce++) { const { entityId, nonce } = await newClient.getEntityIdAndNonce({ entityId: startEntityId, - nonce: startNonce, + nonceKey: startNonce, isGlobalValidation: true, }); const expectedEntityId: number = Math.max(startEntityId, 3); // expect to get max(3, startEntityId) - assert(entityId === expectedEntityId); - assert( - nonce === - (await entryPointContract.read.getNonce([ - newClient.account.address, - buildFullNonce({ - nonce: startNonce, - entityId: expectedEntityId, - isDeferredAction: true, - }), - ])) - ); + expect(entityId).toEqual(expectedEntityId); + await expect( + entryPointContract.read.getNonce([ + newClient.account.address, + buildFullNonce({ + nonceKey: startNonce, + entityId: expectedEntityId, + isDeferredAction: true, + }), + ]) + ).resolves.toEqual(nonce); } } }); diff --git a/account-kit/smart-contracts/src/ma-v2/utils.ts b/account-kit/smart-contracts/src/ma-v2/utils.ts index 3636028153..ec9ae4791c 100644 --- a/account-kit/smart-contracts/src/ma-v2/utils.ts +++ b/account-kit/smart-contracts/src/ma-v2/utils.ts @@ -233,7 +233,7 @@ export const entityIdAndNonceReaderBytecode = "0x608060405234801561001057600080fd5b506040516104f13803806104f183398101604081905261002f916101e5565b60006008826001600160c01b0316901c90506000808263ffffffff1611610057576001610059565b815b90506001600160a01b0385163b15610133575b60006001600160a01b03861663d31b575b6bffffffff0000000000000000604085901b166040516001600160e01b031960e084901b1681526001600160401b03199091166004820152602401600060405180830381865afa1580156100d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526100fd91908101906103c6565b805190915060ff161580156101155750606081015151155b156101205750610133565b8161012a816104a4565b9250505061006c565b604051631aab3f0d60e11b81526001600160a01b03868116600483015264ffffffff01600160c01b038516600884901b64ffffffff0016176024830152600091908616906335567e1a90604401602060405180830381865afa15801561019d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c191906104d7565b90508060005260206000f35b6001600160a01b03811681146101e257600080fd5b50565b6000806000606084860312156101fa57600080fd5b8351610205816101cd565b6020850151909350610216816101cd565b60408501519092506001600160c01b038116811461023357600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156102765761027661023e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156102a4576102a461023e565b604052919050565b60006001600160401b038211156102c5576102c561023e565b5060051b60200190565b600082601f8301126102e057600080fd5b81516102f36102ee826102ac565b61027c565b8082825260208201915060208360051b86010192508583111561031557600080fd5b602085015b8381101561034857805166ffffffffffffff198116811461033a57600080fd5b83526020928301920161031a565b5095945050505050565b600082601f83011261036357600080fd5b81516103716102ee826102ac565b8082825260208201915060208360051b86010192508583111561039357600080fd5b602085015b838110156103485780516001600160e01b0319811681146103b857600080fd5b835260209283019201610398565b6000602082840312156103d857600080fd5b81516001600160401b038111156103ee57600080fd5b82016080818503121561040057600080fd5b610408610254565b815160ff8116811461041957600080fd5b815260208201516001600160401b0381111561043457600080fd5b610440868285016102cf565b60208301525060408201516001600160401b0381111561045f57600080fd5b61046b868285016102cf565b60408301525060608201516001600160401b0381111561048a57600080fd5b61049686828501610352565b606083015250949350505050565b600063ffffffff821663ffffffff81036104ce57634e487b7160e01b600052601160045260246000fd5b60010192915050565b6000602082840312156104e957600080fd5b505191905056fe"; export type BuildNonceParams = { - nonce?: bigint; + nonceKey?: bigint; entityId?: number; isGlobalValidation?: boolean; isDeferredAction?: boolean; @@ -241,13 +241,13 @@ export type BuildNonceParams = { }; export const buildFullNonce = ({ - nonce = 0n, + nonceKey = 0n, entityId = 0, isGlobalValidation = true, isDeferredAction = false, }: BuildNonceParams): bigint => { return ( - (nonce << 40n) + + (nonceKey << 40n) + BigInt(entityId << 8) + (isDeferredAction ? 2n : 0n) + (isGlobalValidation ? 1n : 0n) From d7f99b89754b3d7d41c65d99dc344aa48ab20c38 Mon Sep 17 00:00:00 2001 From: howydev <132113803+howydev@users.noreply.github.com> Date: Wed, 2 Apr 2025 12:22:39 -0400 Subject: [PATCH 6/6] fix: review2 --- .../smart-contracts/src/ma-v2/actions/deferralActions.ts | 6 +++--- account-kit/smart-contracts/src/ma-v2/client/client.test.ts | 6 +++--- account-kit/smart-contracts/src/ma-v2/index.ts | 2 +- account-kit/smart-contracts/src/ma-v2/utils.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts b/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts index 37f56b07ff..8c0048e7b5 100644 --- a/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts +++ b/account-kit/smart-contracts/src/ma-v2/actions/deferralActions.ts @@ -18,7 +18,7 @@ import { encodeDeployData, hexToNumber, } from "viem"; -import { entityIdAndNonceReaderBytecode, buildFullNonce } from "../utils.js"; +import { entityIdAndNonceReaderBytecode, buildFullNonceKey } from "../utils.js"; import { entityIdAndNonceReaderAbi } from "../abis/entityIdAndNonceReader.js"; import type { ModularAccountV2Client } from "../client/client.js"; @@ -122,7 +122,7 @@ export const deferralActions: ( // 2 = deferred action flags 0b10 // 1 = isGlobal validation flag 0b01 - const fullNonceKey: bigint = buildFullNonce({ + const fullNonceKey: bigint = buildFullNonceKey({ nonceKey: nonceKeyOverride, entityId, isGlobalValidation, @@ -262,7 +262,7 @@ export const deferralActions: ( args: [ client.account.address, entryPoint.address, - buildFullNonce({ + buildFullNonceKey({ nonceKey, entityId, isGlobalValidation, diff --git a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts index 4ef558a99c..da163ee264 100644 --- a/account-kit/smart-contracts/src/ma-v2/client/client.test.ts +++ b/account-kit/smart-contracts/src/ma-v2/client/client.test.ts @@ -39,7 +39,7 @@ import { AllowlistModule, NativeTokenLimitModule, semiModularAccountBytecodeAbi, - buildFullNonce, + buildFullNonceKey, } from "@account-kit/smart-contracts/experimental"; import { createLightAccountClient, @@ -1381,7 +1381,7 @@ describe("MA v2 Tests", async () => { await expect( entryPointContract.read.getNonce([ newClient.account.address, - buildFullNonce({ + buildFullNonceKey({ nonceKey: startNonce, entityId: expectedEntityId, isDeferredAction: true, @@ -1460,7 +1460,7 @@ describe("MA v2 Tests", async () => { await expect( entryPointContract.read.getNonce([ newClient.account.address, - buildFullNonce({ + buildFullNonceKey({ nonceKey: startNonce, entityId: expectedEntityId, isDeferredAction: true, diff --git a/account-kit/smart-contracts/src/ma-v2/index.ts b/account-kit/smart-contracts/src/ma-v2/index.ts index b0f610c258..e70d15268a 100644 --- a/account-kit/smart-contracts/src/ma-v2/index.ts +++ b/account-kit/smart-contracts/src/ma-v2/index.ts @@ -29,7 +29,7 @@ export { getDefaultTimeRangeModuleAddress, getDefaultWebauthnValidationModuleAddress, } from "./modules/utils.js"; -export { buildFullNonce } from "./utils.js"; +export { buildFullNonceKey } from "./utils.js"; export { allowlistModuleAbi } from "./modules/allowlist-module/abis/allowlistModuleAbi.js"; export { AllowlistModule } from "./modules/allowlist-module/module.js"; export { nativeTokenLimitModuleAbi } from "./modules/native-token-limit-module/abis/nativeTokenLimitModuleAbi.js"; diff --git a/account-kit/smart-contracts/src/ma-v2/utils.ts b/account-kit/smart-contracts/src/ma-v2/utils.ts index ec9ae4791c..5486d7f6b0 100644 --- a/account-kit/smart-contracts/src/ma-v2/utils.ts +++ b/account-kit/smart-contracts/src/ma-v2/utils.ts @@ -240,7 +240,7 @@ export type BuildNonceParams = { isDirectCallValidation?: boolean; }; -export const buildFullNonce = ({ +export const buildFullNonceKey = ({ nonceKey = 0n, entityId = 0, isGlobalValidation = true,