diff --git a/examples/CREATE_AND_USE_A_BATCH_SESSION.md b/examples/CREATE_AND_USE_A_BATCH_SESSION.md index abd31b4cd..aa195d642 100644 --- a/examples/CREATE_AND_USE_A_BATCH_SESSION.md +++ b/examples/CREATE_AND_USE_A_BATCH_SESSION.md @@ -116,11 +116,12 @@ const nftMintTx: Transaction = { }), }; -const txs = [transferTx, nftMintTx]; +const txs = [nftMintTx, transferTx]; +const correspondingIndexes = [1, 0]; // The order of the txs from the sessionBatch const batchSessionParams = await getBatchSessionTxParams( - ["ERC20", "ABI"], txs, + correspondingIndexes, session, chain ); diff --git a/src/account/utils/Constants.ts b/src/account/utils/Constants.ts index 9280ba735..50ddb5826 100644 --- a/src/account/utils/Constants.ts +++ b/src/account/utils/Constants.ts @@ -83,8 +83,8 @@ export const ERROR_MESSAGES = { "'Amount' is required for withdrawal of native token without using a paymaster", MISSING_RPC_URL: "rpcUrl is required for PrivateKeyAccount signer type, please provide it in the config", - INVALID_SESSION_TYPES: - "Session types and transactions must be of the same length", + INVALID_SESSION_INDEXES: + "Session indexes and transactions must be of the same length and correspond to each other", SIGNER_REQUIRED: "Signer is required for creating a smart account" } diff --git a/src/modules/BatchedSessionRouterModule.ts b/src/modules/BatchedSessionRouterModule.ts index d13016ccc..53181c728 100644 --- a/src/modules/BatchedSessionRouterModule.ts +++ b/src/modules/BatchedSessionRouterModule.ts @@ -301,8 +301,6 @@ export class BatchedSessionRouterModule extends BaseValidationModule { keccak256(leafDataHex) ) - console.log({ proof }) - const sessionDataTuple: SessionDataTuple = [ BigInt(sessionSignerData.validUntil), BigInt(sessionSignerData.validAfter), diff --git a/src/modules/sessions/batch.ts b/src/modules/sessions/batch.ts index c013e4556..d46592162 100644 --- a/src/modules/sessions/batch.ts +++ b/src/modules/sessions/batch.ts @@ -183,31 +183,29 @@ export const createBatchSession = async ( } } -const types = ["ERC20", "ABI"] as const export type BatchSessionParamsPayload = { params: { batchSessionParams: SessionParams[] } } -export type SessionValidationType = (typeof types)[number] /** * getBatchSessionTxParams * * Retrieves the transaction parameters for a batched session. * - * @param sessionTypes - An array of session types. * @param transactions - An array of {@link Transaction}s. + * @param correspondingIndexes - An array of indexes for the transactions corresponding to the relevant session * @param session - {@link Session}. * @param chain - The chain. * @returns Promise<{@link BatchSessionParamsPayload}> - session parameters. * */ export const getBatchSessionTxParams = async ( - sessionValidationTypes: SessionValidationType[], transactions: Transaction[], + correspondingIndexes: number[], { sessionIDInfo, sessionStorageClient }: Session, chain: Chain ): Promise => { - if (sessionValidationTypes.length !== transactions.length) { - throw new Error(ERROR_MESSAGES.INVALID_SESSION_TYPES) + if (correspondingIndexes.length !== transactions.length) { + throw new Error(ERROR_MESSAGES.INVALID_SESSION_INDEXES) } const sessionSigner = await sessionStorageClient.getSignerBySession( @@ -217,17 +215,14 @@ export const getBatchSessionTxParams = async ( chain ) - const batchSessionParams: SessionParams[] = sessionValidationTypes.map( - (sessionType, i): SessionParams => ({ - sessionSigner, - sessionValidationModule: MODULE_ADDRESSES[sessionType], - sessionID: sessionIDInfo[i] - }) - ) - return { params: { - batchSessionParams + batchSessionParams: correspondingIndexes.map( + (i): SessionParams => ({ + sessionSigner, + sessionID: sessionIDInfo[i] + }) + ) } } } diff --git a/tests/modules/read.test.ts b/tests/modules/read.test.ts index e54381ce8..19307f3cc 100644 --- a/tests/modules/read.test.ts +++ b/tests/modules/read.test.ts @@ -72,7 +72,7 @@ describe("Modules:Read", () => { const EXPECTED_SESSION_KEY_DATA = "0x000000000000000000000000fa66e705cf2582cf56528386bb9dfca119767262000000000000000000000000747a4168db14f57871fa8cda8b5455d8c2a8e90a0000000000000000000000003079b249dfde4692d7844aa261f8cf7d927a0da50000000000000000000000000000000000000000000000000000000000989680" const EXPECTED_ABI_SESSION_DATA = - "0xFA66E705cf2582cF56528386Bb9dFCA119767262747A4168DB14F57871fa8cda8B5455D8C2a8e90aa9059cbb0000000000000000000000000098968000020000000000000000000000000000003079B249DFDE4692D7844aA261f8cf7D927A0DA5000101989680" + "0xFA66E705cf2582cF56528386Bb9dFCA119767262747A4168DB14F57871fa8cda8B5455D8C2a8e90aa9059cbb0000000000000000000000000098968000020000000000000000000000000000003079B249DFDE4692D7844aA261f8cf7D927A0DA50001010000000000000000000000000000000000000000000000000000000000989680" const sessionKeyEOA = "0xFA66E705cf2582cF56528386Bb9dFCA119767262" const token = "0x747A4168DB14F57871fa8cda8B5455D8C2a8e90a" const recipient = "0x3079B249DFDE4692D7844aA261f8cf7D927A0DA5" diff --git a/tests/modules/write.test.ts b/tests/modules/write.test.ts index 9c7be562f..934caac17 100644 --- a/tests/modules/write.test.ts +++ b/tests/modules/write.test.ts @@ -174,7 +174,7 @@ describe("Modules:Write", () => { }) // User must be connected with a wallet to grant permissions - test.skip("should create a single session on behalf of a user", async () => { + test("should create a single session on behalf of a user", async () => { const { sessionKeyAddress, sessionStorageClient } = await createSessionKeyEOA( smartAccountThree, @@ -213,7 +213,7 @@ describe("Modules:Write", () => { } = await wait() // Save the sessionID for the next test - stores.single.sessionIDInfo = session.sessionIDInfo + stores.single = session expect(success).toBe("true") Logger.log("Tx Hash: ", transactionHash) @@ -221,10 +221,10 @@ describe("Modules:Write", () => { // User no longer has to be connected, // Only the reference to the relevant sessionID and the store from the previous step is needed to execute txs on the user's behalf - test.skip("should use the session to mint an NFT for the user", async () => { + test("should use the session to mint an NFT for the user", async () => { // Setup const session = stores.single - expect(stores.single.sessionIDInfo).toHaveLength(2) // Should have been set in the previous test + expect(stores.single.sessionIDInfo).toHaveLength(1) // Should have been set in the previous test // Assume the real signer for userSmartAccountThree is no longer available (ie. user has logged out) const smartAccountThreeWithSession = await createSessionSmartAccountClient( @@ -274,7 +274,7 @@ describe("Modules:Write", () => { }) // User must be connected with a wallet to grant permissions - test.skip("should create a batch session on behalf of a user", async () => { + test("should create a batch session on behalf of a user", async () => { const { sessionKeyAddress, sessionStorageClient } = await createSessionKeyEOA( smartAccountFour, @@ -333,8 +333,7 @@ describe("Modules:Write", () => { expect(success).toBe("true") stores.batch = session // Save the sessionID for the next test - expect(session.sessionIDInfo).toHaveLength(2) - // Save the sessionID for the next test + expect(session.sessionIDInfo).toHaveLength(2) // Save the sessionID for the next test Logger.log("Tx Hash: ", transactionHash) Logger.log("session: ", { session }) @@ -342,12 +341,9 @@ describe("Modules:Write", () => { // User no longer has to be connected, // Only the reference to the relevant sessionID and the store from the previous step is needed to execute txs on the user's behalf - test.skip("should use the batch session to mint an NFT, and pay some token for the user", async () => { - // Setup + test("should use the batch session to mint an NFT, and pay some token for the user", async () => { // Setup const session = stores.batch - expect(session.sessionIDInfo).toHaveLength(2) - // Should have been set in the previous test // Assume the real signer for userSmartAccountFour is no longer available (ie. user has logged out); const smartAccountFourWithSession = await createSessionSmartAccountClient( @@ -392,8 +388,8 @@ describe("Modules:Write", () => { const txs = [transferTx, nftMintTx] const batchSessionParams = await getBatchSessionTxParams( - ["ERC20", "ABI"], txs, + [0, 1], session, chain ) @@ -414,7 +410,7 @@ describe("Modules:Write", () => { expect(nftBalanceAfter - nftBalanceBefore).toBe(1n) }, 50000) - test.skip("should use MultichainValidationModule to mint an NFT on two chains with sponsorship", async () => { + test("should use MultichainValidationModule to mint an NFT on two chains with sponsorship", async () => { const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" const chainIdBase = 84532 @@ -532,7 +528,7 @@ describe("Modules:Write", () => { expect(success2).toBe("true") }, 50000) - test.skip("should use SessionValidationModule to send a user op", async () => { + test("should use SessionValidationModule to send a user op", async () => { let sessionSigner: WalletClientSigner const sessionKeyEOA = walletClient.account.address const recipient = walletClientTwo.account.address @@ -667,7 +663,7 @@ describe("Modules:Write", () => { expect(maticBalanceAfter).toEqual(maticBalanceBefore) }, 60000) - test.skip("should enable batched module", async () => { + test("should enable batched module", async () => { const smartAccount = await createSmartAccountClient({ signer: walletClient, bundlerUrl, @@ -690,7 +686,7 @@ describe("Modules:Write", () => { } }, 50000) - test.skip("should use ABI SVM to allow transfer ownership of smart account", async () => { + test("should use ABI SVM to allow transfer ownership of smart account", async () => { const smartAccount = await createSmartAccountClient({ chainId, signer: walletClient, @@ -860,23 +856,10 @@ describe("Modules:Write", () => { new SessionMemoryStorage(smartAccountAddress) ) - const submitOrderAbi = parseAbi(["function submitOrder(uint256 _orderNum)"]) - - const submitCancelAbi = parseAbi([ - "function submitCancel(uint256 _orderNum)" - ]) - - const paddedOne = pad("0x1", { size: 32 }) + const order = parseAbi(["function submitOrder(uint256 _orderNum)"]) + const cancel = parseAbi(["function submitCancel(uint256 _orderNum)"]) - // const testContract = getContract({ - // address: DUMMY_CONTRACT_ADDRESS, - // abi: submitCancelAbi, - // client: { public: publicClient, wallet: walletClient } - // }) - - // const thash = await testContract.write.submitCancel([1n]) - - const allowedFunctionCalls: CreateSessionDataParams[] = [ + const sessionBatch: CreateSessionDataParams[] = [ createABISessionDatum({ interval: { validUntil: 0, @@ -884,12 +867,12 @@ describe("Modules:Write", () => { }, sessionKeyAddress, contractAddress: DUMMY_CONTRACT_ADDRESS, - functionSelector: submitCancelAbi[0], + functionSelector: cancel[0], rules: [ { offset: 0, condition: 0, - referenceValue: { raw: paddedOne } + referenceValue: BigInt(1) } ], valueLimit: 0n @@ -901,12 +884,12 @@ describe("Modules:Write", () => { }, sessionKeyAddress, contractAddress: DUMMY_CONTRACT_ADDRESS, - functionSelector: submitOrderAbi[0], + functionSelector: order[0], rules: [ { offset: 0, condition: 0, - referenceValue: { raw: paddedOne } + referenceValue: BigInt(1) } ], valueLimit: 0n @@ -916,7 +899,7 @@ describe("Modules:Write", () => { const { wait, session } = await createBatchSession( smartAccount, sessionStorageClient, - allowedFunctionCalls, + sessionBatch, withSponsorship ) @@ -925,6 +908,9 @@ describe("Modules:Write", () => { success } = await wait() + expect(success).toBe("true") + expect(transactionHash).toBeTruthy() + const smartAccountWithSession = await createSessionSmartAccountClient( { accountAddress: await smartAccount.getAccountAddress(), // Set the account address on behalf of the user @@ -936,29 +922,30 @@ describe("Modules:Write", () => { true ) - const submitOrderTx: Transaction = { + const submitCancelTx: Transaction = { to: DUMMY_CONTRACT_ADDRESS, data: encodeFunctionData({ - abi: submitOrderAbi, - functionName: "submitOrder", + abi: cancel, + functionName: "submitCancel", args: [BigInt(1)] }) } - const submitCancelTx: Transaction = { + + const submitOrderTx: Transaction = { to: DUMMY_CONTRACT_ADDRESS, data: encodeFunctionData({ - abi: submitCancelAbi, - functionName: "submitCancel", + abi: order, + functionName: "submitOrder", args: [BigInt(1)] }) } - // const txs = [submitOrderTx, submitCancelTx] const txs = [submitOrderTx, submitCancelTx] + const correspondingIndexes = [1, 0] // The order of the txs from the sessionBatch const batchSessionParams = await getBatchSessionTxParams( - ["ABI", "ABI"], txs, + correspondingIndexes, session, chain ) @@ -966,10 +953,12 @@ describe("Modules:Write", () => { const { wait: waitForTx } = await smartAccountWithSession.sendTransaction( txs, { - ...batchSessionParams + ...batchSessionParams, + ...withSponsorship } ) - const receipt = await waitForTx() + const { success: txSuccess } = await waitForTx() + expect(txSuccess).toBe("true") }, 60000) })