Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Setting Up a Smart Account Infrastructure for Batch Operations

This guide details the implementation of ERC-4337 smart account wallets to enable native batch transaction capabilities. It covers setting up a bundler, paymaster, and entry point contract, and designing user operations that combine multiple calls. The focus is on moving beyond EOA limitations to enable sponsored transactions, session keys, and atomic multi-action flows.
Chainscore © 2026
introduction
INTRODUCTION

Setting Up a Smart Account Infrastructure for Batch Operations

Smart Accounts enable complex, gas-efficient transaction flows by batching multiple operations into a single on-chain call.

A Smart Account (also known as an Account Abstraction or ERC-4337 account) is a programmable blockchain account. Unlike traditional Externally Owned Accounts (EOAs) controlled by a single private key, Smart Accounts are smart contracts that define their own logic for transaction validation, enabling features like social recovery, sponsored gas, and session keys. The most significant capability for developers is batch operations, which allow multiple discrete actions—such as token swaps, NFT transfers, and contract interactions—to be bundled and executed atomically in a single transaction. This reduces gas costs and improves user experience by minimizing wallet confirmations.

The core infrastructure for batch operations relies on the UserOperation object. Instead of a standard transaction, users submit a UserOperation to a dedicated mempool. This object contains the execution calldata for the Smart Account, along with signatures and gas parameters. A network of Bundlers (specialized nodes) then packages these UserOperations into a single blockchain transaction and submits it through a global EntryPoint contract. The EntryPoint validates and orchestrates the execution, ensuring atomicity: either all operations in the batch succeed, or the entire transaction is reverted, preventing partial state changes.

To implement this, you need three key components: the Smart Account contract itself, a Paymaster for gas abstraction, and a Bundler service. Popular Smart Account implementations include Safe{Wallet} (via its MultiSend library), ZeroDev Kernel, and Biconomy. A Paymaster contract can sponsor transaction fees, allowing users to pay in ERC-20 tokens or enabling dApps to cover gas costs. For development and testing, you can use services like Stackup, Alchemy's Account Kit, or Pimlico, which provide Bundler APIs and Paymaster infrastructure on testnets and mainnets.

Here is a conceptual code snippet showing the structure of a batched UserOperation using the @account-abstraction/sdk:

javascript
const userOp = await smartAccount.buildUserOp([
  {
    to: swapRouterAddress,
    data: swapCalldata,
    value: 0,
  },
  {
    to: nftContractAddress,
    data: transferCalldata,
    value: 0,
  }
]);
const userOpHash = await bundler.sendUserOpToBundler(userOp);

This bundles a token swap and an NFT transfer. The actual execution flow is handled by your Smart Account's executeBatch or execute function.

Setting up this infrastructure shifts complexity off-chain to the bundler and entry point, while keeping security guarantees on-chain. Key considerations include gas estimation for batched calls, ensuring signature scheme compatibility (like EIP-1271), and managing state dependencies between operations in the batch. For production, audit your Smart Account logic and use reputable, decentralized bundler networks to avoid central points of failure. This setup is foundational for building seamless, multi-step DeFi interactions, gaming transactions, and complex onboarding flows.

prerequisites
SETUP GUIDE

Prerequisites

Before implementing batch operations, you need a foundational smart account infrastructure. This guide covers the essential tools and initial configuration.

A smart account (or account abstraction wallet) is required to execute batch transactions. Unlike Externally Owned Accounts (EOAs), smart accounts are programmable contracts that can bundle multiple actions into a single transaction. For this guide, we'll use ERC-4337, the dominant standard for account abstraction, with a focus on the Safe{Core} Account Abstraction SDK and Alchemy's Account Kit. You'll need Node.js (v18+) and a basic understanding of Ethereum development.

First, install the necessary packages. The @safe-global/aa-sdk provides the core client, and viem is used for low-level Ethereum interactions. Run npm install @safe-global/aa-sdk viem in your project. You must also configure a Signer (like a private key) and a Provider (like an RPC endpoint from Alchemy or Infura). The provider connects your app to the blockchain, while the signer authorizes transactions on behalf of the smart account.

Next, initialize the Smart Account Client. This object is your interface for creating and managing the smart account. You'll need your EOA signer, an RPC URL, a Bundler URL (which submits UserOperations to the network), and a Paymaster configuration if you want to sponsor gas fees. For testing, you can use Alchemy's public bundler at https://bundler.etherscan.io and their paymaster. The client will automatically derive your smart account's contract address.

Funding your smart account is critical. The account contract must hold native tokens (like ETH on Sepolia) to pay for its own deployment and transaction gas, unless you're using a full paymaster for gas sponsorship. You can send test ETH from a faucet to the address logged during client initialization. Verify the balance using a block explorer or with const balance = await publicClient.getBalance({ address: smartAccountAddress }).

Finally, understand the core concepts you'll be working with: UserOperations are pseudo-transaction objects that represent user intent, which bundlers package and submit. Paymasters can sponsor transaction fees, enabling gasless UX. EntryPoint is a singleton contract that validates and executes batches of UserOperations. With your environment set up and account funded, you're ready to construct and send your first batch transaction.

key-concepts
SMART ACCOUNT INFRASTRUCTURE

Core ERC-4337 Concepts

Batch operations are a core feature of ERC-4337 smart accounts. This section covers the essential tools and concepts needed to build and manage this infrastructure.

03

Implementing the Smart Account Factory

The Account Factory is a contract that deploys smart account proxies using CREATE2. This enables deterministic addresses and gas-efficient deployment.

  • How it works: Users sign a UserOperation; the factory deploys the account counterfactually (at a pre-computed address) in the same transaction.
  • Standard: The ERC-4337 reference implementation provides a SimpleAccountFactory. Projects like ZeroDev and Safe{Core} have their own optimized factories.
  • Best Practice: Use a singleton factory per account implementation to minimize deployment gas costs for your users.
05

Structuring Batch UserOperations

A single UserOperation can execute multiple calls via the smart account's executeBatch function. This is the key to gas efficiency.

  • Mechanics: The callData in the UserOperation encodes a call to executeBatch(address[] dest, uint256[] value, bytes[] calldata func).
  • Example: Batch a token approval, a swap on Uniswap, and an NFT mint into one transaction with one signature.
  • Gas Savings: Can reduce costs by 30-50% compared to separate EOA transactions by paying overhead (signature check, nonce increment) once.

Your smart account contract must implement this batch execution logic.

architecture-overview
SYSTEM ARCHITECTURE AND FLOW

Setting Up a Smart Account Infrastructure for Batch Operations

This guide explains how to architect a system for executing multiple on-chain actions in a single transaction using smart accounts, covering core components and implementation flow.

Smart accounts, also known as account abstraction wallets, enable complex transaction logic by separating the signer from the account itself. This allows for features like batch operations, where multiple calls to different smart contracts can be bundled and executed atomically in one transaction. The core components of this infrastructure are the smart account contract (e.g., using ERC-4337 standards), a Bundler to relay user operations, and a Paymaster to sponsor gas fees. This architecture shifts transaction execution logic from the Externally Owned Account (EOA) to a programmable contract.

The operational flow begins when a user's dApp frontend constructs a UserOperation object. This object defines the batch of calls, their calldata, and signature. Instead of submitting a standard transaction, the dApp sends this UserOperation to a Bundler node. The Bundler, which can be a dedicated service or a public mempool, is responsible for packaging one or more UserOperations into an actual Ethereum transaction and submitting it to the entry point contract on-chain. This decouples transaction propagation from individual user gas management.

For the batch to execute, the smart account contract must implement a validation and execution function. The validateUserOp function verifies the user's signature and any custom rules (like fee payment). Upon successful validation, the executeBatch function processes the array of target addresses and calldata. A common implementation pattern uses a loop: for (uint i = 0; i < targets.length; i++) { (bool success, ) = targets[i].call{value: values[i]}(calldatas[i]); }. This ensures all calls succeed or the entire batch reverts.

Integrating a Paymaster is crucial for gas sponsorship or paying fees in ERC-20 tokens. The Paymaster contract holds funds and, during the Bundler's simulation, stakes and verifies it will pay for the operation. In the UserOperation, the paymasterAndData field is set, instructing the entry point to delegate gas payment. This allows applications to offer gasless transactions or abstract gas complexity from end-users, significantly improving UX for batch interactions with DeFi protocols or NFT marketplaces.

When implementing, security is paramount. The smart account must include checks for reentrancy within the batch and validate all target addresses. Use established, audited smart account implementations like those from Safe{Wallet}, ZeroDev, or Biconomy rather than writing from scratch. For the Bundler, you can run your own node using the Ethereum Foundation's ERC-4337 Bundler in Golang or use a managed RPC service like Stackup, Alchemy, or Pimlico that offers bundler endpoints and paymaster services.

To test your setup, begin on a testnet like Sepolia or Goerli. Deploy your smart account factory and entry point, then configure your dApp to use a testnet Bundler RPC URL. Tools like UserOp.js or the account-abstraction SDKs from the major providers simplify constructing and sending UserOperations. Monitor transaction success and gas consumption in the block explorer. This infrastructure reduces transaction costs and friction, enabling complex multi-step DeFi strategies, NFT mint-and-list operations, and automated on-chain workflows.

step1-smart-account
INFRASTRUCTURE

Step 1: Deploy a Smart Account Contract

The foundation of any batch operation system is a secure and flexible smart account contract. This step covers deployment using popular frameworks.

A smart account, or smart contract wallet, is an Externally Owned Account (EOA) whose logic and ownership rules are defined by a smart contract. Unlike a standard EOA controlled by a single private key, smart accounts enable features like multi-signature security, social recovery, and, most importantly for our purposes, transaction batching. For developers, this means you can deploy a contract that acts as the central hub for all user operations, allowing multiple actions across different protocols to be bundled into a single transaction.

To deploy, you'll typically use a framework like Safe{Wallet} (formerly Gnosis Safe) or ZeroDev Kernel. These provide audited, battle-tested base contracts. For a custom implementation, you might use ERC-4337 account abstraction standards. The deployment process involves choosing a network (e.g., Ethereum Mainnet, Arbitrum, Polygon), selecting signers (the addresses that can authorize transactions), and defining a threshold (e.g., 2-of-3 multisig). Here's a basic example using the Safe SDK:

javascript
import Safe from '@safe-global/protocol-kit';
const safeSdk = await Safe.create({
  ethAdapter,
  safeAddress: await ethAdapter.getSignerAddress(),
  contractNetworks: CHAIN_CONFIG
});
const safeTransaction = await safeSdk.createTransaction({ transactions: [] });
const txResponse = await safeSdk.executeTransaction(safeTransaction);

After deployment, note your contract address carefully—this is your system's operational address. You'll also need the ABI (Application Binary Interface) to interact with it programmatically. This contract will hold user funds and execute the batched calls you construct in later steps. Ensure you verify the contract on a block explorer like Etherscan to provide transparency and enable easier interaction from other tools. The gas cost for deployment varies by network and contract complexity but is a one-time setup cost for your infrastructure.

step2-bundler-setup
INFRASTRUCTURE

Step 2: Set Up a Bundler Service

A bundler is the core infrastructure component that collects, validates, and submits UserOperations to the blockchain. This step configures a production-ready bundler service.

A bundler is a specialized node that aggregates multiple UserOperation objects from smart accounts into a single transaction. This batch processing is what enables gas sponsorship (paymasters) and efficient fee management. For production use, you need a reliable, high-uptime bundler service. While you can run your own using the Ethereum Foundation's reference bundler, most teams opt for a managed service like Pimlico, Stackup, or Alchemy's Bundler for scalability and maintenance.

To integrate a bundler, you'll need an RPC endpoint and often an API key. The interaction is standardized via the eth_sendUserOperation RPC method. Here's a basic setup using the popular viem and permissionless.js libraries, targeting the Sepolia testnet with Pimlico:

javascript
import { createBundlerClient } from "permissionless";
import { sepolia } from "viem/chains";

const bundlerClient = createBundlerClient({
  chain: sepolia,
  transport: http("https://api.pimlico.io/v1/sepolia/rpc?apikey=YOUR_API_KEY"),
});

This client will be used to submit your batched operations to the network.

Key configuration parameters for your bundler client include the entry point address (e.g., 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 for EntryPoint v0.6) and the chain ID. The bundler handles critical tasks: simulating operations to ensure they will succeed, managing the mempool of pending UserOperations, and ultimately bundling them into a single transaction sent by the bundler's own funded account. You must ensure your chosen bundler supports the specific EntryPoint version your smart accounts use.

For advanced use cases, you may need to configure bundler policies. These are rules that dictate which operations are accepted, such as setting a minimum priority fee, requiring paymaster sponsorship, or whitelisting certain smart account factories. Services like Pimlico allow you to set these via their dashboard. Monitoring is also crucial; track metrics like bundling latency, operation failure rate, and gas costs to optimize performance and user experience.

Finally, always implement robust error handling. A UserOperation can fail during simulation or execution. Your application should listen for the UserOperationRevertReason event from the EntryPoint contract to understand failures. Common reasons include signature verification failure, insufficient funds in the paymaster, or a revert within the smart account's execution logic. Proper logging and user feedback for these scenarios are essential for a production application.

step3-paymaster-integration
SMART ACCOUNT INFRASTRUCTURE

Step 3: Implement a Paymaster for Sponsored Gas

Enable users to transact without holding native tokens by integrating a paymaster to sponsor gas fees for batch operations.

A paymaster is a smart contract that can pay for transaction fees on behalf of a user, a concept central to Account Abstraction (ERC-4337). This allows applications to offer sponsored transactions or gasless experiences, where the end-user does not need to hold the chain's native token (like ETH). For batch operations, this is critical; a user can execute multiple actions in a single transaction without worrying about upfront gas costs. The paymaster contract validates the request and, if the logic passes, uses its own token balance to pay the bundler for including the user's UserOperation.

To implement a paymaster, you typically extend the BasePaymaster contract from the @account-abstraction/contracts library. Your core logic resides in the _validatePaymasterUserOp function. Here, you decide whether to sponsor the operation based on custom rules, such as whitelisted users, specific calldata, or payment in ERC-20 tokens. For a simple sponsorship model, you might just return VALID_PAYMASTER_STAKED after verifying a signature from a trusted server. It's crucial that validation is gas-efficient and secure to prevent exploitation.

After validation, the _postOp hook handles post-transaction logic, like deducting an ERC-20 token balance from the user's smart account. For a batch operation—imagine a user swapping tokens and then depositing liquidity—the paymaster would sponsor the entire bundled action. You must ensure your paymaster contract is staked with the EntryPoint to be considered by bundlers, which involves depositing a security stake to discourage malicious behavior. The official ERC-4337 bundler spec details these requirements.

For development and testing, you can use a verifying paymaster, a common reference implementation. This paymaster relies on an off-chain server to sign UserOperation data, confirming sponsorship. This pattern separates validation logic, keeping the on-chain contract simple. In production, you would replace this with a more robust system, potentially using services like Stackup, Biconomy, or Candide's paymaster infrastructure to manage gas sponsorship and token exchange rates reliably.

Integrating the paymaster into your frontend involves modifying how you construct the UserOperation. When using a library like UserOp.js or Viem, you set the paymasterAndData field with the paymaster's address and any required signature or data from your validation server. This tells the bundler which contract will pay. Always test paymaster flows on a testnet first, monitoring for reverts in validation and ensuring your contract holds sufficient native token balance to cover sponsored gas across multiple batch operations.

step4-craft-userop
TUTORIAL

Step 4: Craft and Send a Batch UserOperation

Learn how to construct and submit a single UserOperation that executes multiple actions, reducing gas costs and improving user experience.

A batch UserOperation allows a smart account to execute multiple, distinct calls within a single transaction. This is a core feature of Account Abstraction (AA) that enables complex interactions—like swapping tokens and then depositing liquidity—without requiring the user to sign and pay for separate transactions. Batching is handled by the account's executeBatch or similar method, which the bundler calls via the callData field. This approach can reduce overall gas costs by up to 30-40% compared to sequential transactions, as you pay the base transaction fee only once.

To craft the batch, you must encode the target contracts, function selectors, and calldata for each desired action. Using viem or ethers.js, you would typically use the encodeFunctionData utility. For example, a batch to approve USDC and then swap on Uniswap V3 would involve two encoded calls. This encoded data becomes the payload for your smart account's execution function. Always verify that your smart account contract (like those from Safe{Core} AA SDK or Biconomy) supports the specific batch interface you are using.

Here is a practical code snippet using viem and the Safe{Core} AA SDK to prepare a batch callData for a simple transfer and an NFT mint:

javascript
import { encodeFunctionData } from 'viem';
import { SafeSmartAccount } from '@safe-global/aa-sdk';

// 1. Encode a native token transfer to address '0x123...'
const transferCallData = encodeFunctionData({
  abi: [{
    inputs: [{ name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }],
    name: 'transfer',
    type: 'function',
    stateMutability: 'payable'
  }],
  functionName: 'transfer',
  args: ['0x123...', parseEther('0.1')]
});

// 2. Encode a mint call to an NFT contract at '0x456...'
const mintCallData = encodeFunctionData({
  abi: [{
    inputs: [],
    name: 'mint',
    type: 'function',
    stateMutability: 'nonpayable'
  }],
  functionName: 'mint',
  args: []
});

// 3. Encode the batch execution for the Smart Account
const batchCallData = encodeFunctionData({
  abi: SafeSmartAccount.abi, // Your account's ABI
  functionName: 'executeBatch',
  args: [
    ['0x123...', '0x456...'], // Array of target addresses
    [0n, 0n], // Array of values (0 ETH for these calls)
    [transferCallData, mintCallData] // Array of calldatas
  ]
});

This batchCallData is then set as the callData in your UserOperation object.

After constructing the callData, you must build the complete UserOperation object. This includes the sender (your smart account address), nonce, initCode (if deploying), callData (your batch), and signature (initially empty). Use your chosen ERC-4337 Bundler client, like those from Stackup, Alchemy, or Biconomy, to estimate the gas (verificationGasLimit, callGasLimit, preVerificationGas) via the eth_estimateUserOperationGas RPC call. Accurate gas estimation is critical; underestimating will cause the operation to revert, while overestimating makes it unnecessarily expensive.

Finally, sign the UserOperation's hash with the smart account's signing key. The signing process depends on your account's implementation but often uses EIP-712 structured data. Submit the signed UserOperation to the bundler via the eth_sendUserOperation RPC method. Monitor its inclusion using the returned userOpHash. Remember, successful execution depends on the Paymaster having sufficient funds if you're using gas sponsorship, and all batched actions must succeed—if one fails, the entire batch will revert, protecting users from partial execution.

PROTOCOL COMPARISON

Smart Account Infrastructure Options

A comparison of leading smart account SDKs and their capabilities for batch operations.

Feature / MetricAccount Abstraction Kit (AA Kit)ZeroDev KernelBiconomy Smart Account

ERC-4337 Bundler Support

Native Batch Transaction Support

Gas Sponsorship (Paymaster) Integration

Multi-chain Deployment (Chains Supported)

15+ EVM chains

10+ EVM chains

20+ EVM chains

Average Gas Overhead for a 3-op Batch

< 10k gas

~15k gas

~12k gas

Session Keys for Recurring Operations

Modular Plugin Architecture

Open Source License

MIT

GPL-3.0

Proprietary with open components

SMART ACCOUNT INFRASTRUCTURE

Common Issues and Troubleshooting

Resolve common challenges when setting up smart accounts for batch operations, including gas management, signature handling, and bundler integration.

This error indicates your smart account's entry point deposit is insufficient to cover the maximum gas cost for the operation. The bundler checks this before submission.

Common causes and fixes:

  • Insufficient deposit: Fund the entry point contract for your account using EntryPoint.depositTo(accountAddress).
  • Incorrect gas estimation: Your verificationGasLimit or callGasLimit is too low. Use a reputable gas estimator like the one in @account-abstraction/sdk.
  • High maxFeePerGas: If gas prices spike, your prefund may not cover the new maximum. Implement a buffer (e.g., 20%) in your estimation.

Check the deposit balance: await entryPoint.getDepositInfo(accountAddress).

conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have successfully configured a smart account infrastructure capable of executing batch operations, a fundamental step towards building efficient and user-centric Web3 applications.

This guide walked through the core components: deploying a smart account factory using ERC-4337 standards, implementing a paymaster for gas sponsorship, and writing a custom handler to validate and execute bundled transactions. The key takeaway is that batching transforms the user experience by reducing transaction friction and gas costs, enabling complex multi-step interactions—like swapping tokens and providing liquidity—to feel like a single action. This is the foundation for applications that can compete with Web2 convenience.

To solidify your understanding, consider these next practical steps. First, audit and test your contracts extensively; use frameworks like Foundry or Hardhat to simulate complex batch scenarios and edge cases. Second, integrate with a bundler service such as Stackup, Alchemy, or Pimlico to submit your UserOperation objects to the network. Finally, explore advanced account features like session keys for temporary permissions, social recovery mechanisms, and integrating with account abstraction SDKs (like ZeroDev or Biconomy) to simplify client-side integration.

The ecosystem is evolving rapidly. Stay updated on ERC-4337 improvements and new Particle Network and Safe{Core} tooling. For production deployment, prioritize security audits and consider using audited smart account implementations like Safe{Wallet} as a base. By mastering batch operations, you are building the infrastructure for the next generation of scalable, user-friendly decentralized applications. Continue experimenting, refer to the official ERC-4337 documentation, and engage with the developer community to push the boundaries of what's possible with smart accounts.

How to Set Up Smart Account Infrastructure for Batch Operations | ChainScore Guides