Web3

Account Abstraction ERC-4337: A Complete Implementation Guide

Step-by-step guide to implementing ERC-4337 account abstraction, from UserOperation construction to Paymaster design and bundler integration.

Mudaser Iqbal··14 min read

Why Account Abstraction Matters

Ethereum's original account model has two types: Externally Owned Accounts controlled by private keys, and Contract Accounts with code but no ability to initiate transactions. This separation creates massive UX friction: users must hold ETH for gas, can only do one thing per transaction, and lose everything if they lose their private key.

ERC-4337 Account Abstraction introduces a parallel transaction system that allows smart contract wallets to behave like EOAs — initiating transactions, paying gas via third-party Paymasters, and bundling multiple operations — without requiring a consensus-layer protocol change.

The result: wallets with social recovery, gas sponsorship, session keys, spending limits, multi-sig without multiple signatures, and one-click multi-step DeFi flows. ERC-4337 is already live on mainnet and deployed by Safe, Biconomy, ZeroDev, and Alchemy's embedded wallets.

Core Components: EntryPoint, UserOperation, and Bundler

The ERC-4337 system has four core components:

EntryPoint contract: the singleton on-chain coordinator deployed at a canonical address on every chain. All UserOperations flow through it. It validates, executes, and handles gas accounting. You never need to deploy this — it already exists.

UserOperation: a pseudo-transaction struct submitted by users. It includes sender (smart account address), nonce, initCode (for account creation), callData, gas limits, maxFeePerGas, maxPriorityFeePerGas, paymasterAndData, and signature.

Bundler: an off-chain node that collects UserOperations from an alternative mempool (the UserOperation mempool), simulates them, and batches them into a single handleOps call to the EntryPoint. Bundlers earn the gas fee delta as profit.

Paymaster: an optional contract that sponsors gas for UserOperations. The Paymaster can require ERC-20 payment, a signature from a backend, or an NFT — anything your business logic requires.

Implementing a Smart Account

A minimal ERC-4337 smart account must implement the IAccount interface with a single function: validateUserOp.

The validateUserOp function receives the UserOperation, a userOpHash, and a missingAccountFunds value. It must:
1. Verify the signature against the userOpHash.
2. Pay missingAccountFunds to the EntryPoint if the account has insufficient deposit.
3. Return 0 (SIG_VALIDATION_SUCCESS) or 1 (SIG_VALIDATION_FAILED). It may also return a validUntil and validAfter timestamp packed into a uint256.

The execute function handles the actual call once validation passes. A minimal implementation calls the target address with provided callData and value.

For production accounts, use audited base implementations: Safe's ERC-4337 module, Kernel by ZeroDev, or Biconomy's Nexus account. These handle edge cases around nonce management, upgrade patterns, and multi-owner schemes that a minimal implementation misses.

Building a Paymaster

A Paymaster is a contract that agrees to pay gas on behalf of a UserOperation. The EntryPoint calls validatePaymasterUserOp before execution, and postOp after execution.

Verifying Paymaster pattern (most common):
The Paymaster's backend signs the UserOperation after applying business logic (checking if the user has a subscription, has enough ERC-20 balance, etc.). The on-chain contract verifies that signature. This requires a backend signer but is simple and flexible.

ERC-20 Paymaster pattern:
The Paymaster accepts ERC-20 tokens as payment. It quotes the ETH gas cost in token terms (using a price feed), takes a token transfer in postOp, and pays the ETH gas itself. Users pay in USDC, DAI, or any supported token.

Deposit management: Paymasters must maintain an ETH deposit in the EntryPoint. If the deposit runs out, sponsored transactions will fail. Build monitoring and auto-refill logic into your Paymaster infrastructure.

Testing and Deploying ERC-4337 Accounts

Testing ERC-4337 in Foundry requires simulating the EntryPoint flow. Deploy the canonical EntryPoint contract in your test setup, create your smart account, and call handleOps directly with a crafted UserOperation.

Key test cases:
- Valid signature accepts the UserOperation
- Invalid signature returns SIG_VALIDATION_FAILED without reverting
- Nonce replay is rejected
- Paymaster correctly charges the user
- Account is created via initCode on first operation

Deploying to production:
1. Deploy your account factory (creates accounts at deterministic addresses via CREATE2).
2. Register your Paymaster with the EntryPoint and deposit ETH.
3. Submit UserOperations to a bundler RPC (Pimlico, Alchemy, Stackup all provide endpoints).
4. Monitor the EntryPoint for UserOperationEvent logs to track execution.

Use the permissionless.js or viem account abstraction extensions to handle UserOperation construction, signing, and bundler communication in your frontend.

One Solidity tip + 1 case study per month

Account Abstraction ERC-4337: A Complete Implementation Guide | Crypto Hawking