Batch Transactions
One of the most powerful features of ERC-4337 Smart Accounts is the ability to batch multiple transactions together into a single UserOperation.
Why batch?
Section titled “Why batch?”In traditional Web3 applications, standard EOAs force users into frustrating UX patterns:
- “Approve this token” $\rightarrow$ Wait for block $\rightarrow$ Sign $\rightarrow$ Pay Gas
- “Now execute the swap” $\rightarrow$ Wait for block $\rightarrow$ Sign $\rightarrow$ Pay Gas
With Smart Accounts, you can group both the Approve and the Swap actions into a single array. The user signs once, pays gas once (or the Paymaster covers it entirely), and the entire batch executes atomically. If one call in the batch reverts, the entire batch reverts.
sendBatchTransactions
Section titled “sendBatchTransactions”To send a batch, pass an array of transaction objects to smartAccount.sendTransaction or client.sendBatchTransactions (if using 0xgas-auth).
import { encodeFunctionData, parseAbi } from "viem";
const usdcContract = "0x...";const swapRouter = "0x...";
// 1. Prepare Approve callconst approveData = encodeFunctionData({ abi: parseAbi(["function approve(address spender, uint256 amount)"]), functionName: "approve", args: [swapRouter, 1000000n], // Approve $1.00 USDC});
// 2. Prepare Swap callconst swapData = encodeFunctionData({ abi: parseAbi(["function exactInputSingle(tuple params)"]), functionName: "exactInputSingle", args: [{ /* swap params */ }],});
// 3. Send the batchconst userOpResponse = await smartAccount.sendTransaction([ { to: usdcContract, value: 0n, data: approveData, }, { to: swapRouter, value: 0n, data: swapData, }]);
// 4. Wait for confirmationconst receipt = await userOpResponse.wait();console.log("Batch executed atomically in tx:", receipt.receipt.transactionHash);Atomicity and Execution Order
Section titled “Atomicity and Execution Order”Batched transactions execute exactly in the order they appear in the array.
- Call 1: Sent to
usdcContract(Approve) - Call 2: Sent to
swapRouter(Swap)
Because they are executed within the same Ethereum transaction (wrapped by the Bundler), they are atomic. The approval guarantees the router has allowance immediately in the next EVM execution step. You never have to wait for separate blocks.