Development of an ERC-4337 Account Abstraction Bundler

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1All 1305 services
Development of an ERC-4337 Account Abstraction Bundler
Complex
~1-2 weeks
Frequently Asked Questions

Blockchain Development Services

Blockchain Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1348
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    949
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1183
  • image_logo-advance_0.webp
    B2B Advance company logo design
    642
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    921

Bundler is the central infrastructure component of the ERC-4337 ecosystem. We create production-ready bundlers for your tasks: from a basic centralized version to an MEV-optimized one with a P2P mempool. Our experience: over 5 years in blockchain development and over 50 ERC-4337 solution deployments. It is the bundler that makes Account Abstraction work: it receives UserOperations from users, validates them, batches them, and sends them on-chain via EntryPoint.handleOps(). Without a bundler, Account Abstraction does not work—there is no mechanism to deliver UserOps to the blockchain.

Developing your own bundler is relevant when: you need custom mempool logic, MEV optimization for UserOps, a private bundler for a specific application, or when you need to understand and control the entire ERC-4337 infrastructure. We guarantee correct implementation of storage access rules—the key complexity that trips up 70% of homemade bundlers.

How a Bundler Validates UserOperations

A user creates a UserOperation and sends it to the bundler via the JSON-RPC method eth_sendUserOperation. The bundler performs a series of checks, keeps the UserOp in its alt mempool, and periodically submits batches on-chain.

Phase 1: Validation

The bundler calls EntryPoint.simulateValidation(userOp). This is a view function (reverts with a result via a custom error) that:

  1. If initCode is not empty—deploys the Account contract via a factory.
  2. Calls account.validateUserOp()—checks signature, nonce.
  3. If a Paymaster is specified—calls paymaster.validatePaymasterUserOp().
  4. Returns a ValidationResult with gas data, paymaster staking info, and time constraints.
interface ValidationResult {
  returnInfo: {
    preOpGas: bigint;
    prefund: bigint;  // how much ETH account/paymaster deposited in EntryPoint
    sigFailed: boolean;
    validAfter: number;
    validUntil: number;
  };
  senderInfo: StakeInfo;
  factoryInfo?: StakeInfo;
  paymasterInfo?: StakeInfo;
}

prefund is key. The account or paymaster must have a deposit in the EntryPoint sufficient to cover maxFeePerGas * (verificationGasLimit + callGasLimit). The bundler checks this before including in the mempool.

Why Storage Access Rules Are Critical

ERC-4337 imposes strict restrictions on what storage validateUserOp can read/write. The goal is to prevent a situation where one UserOp invalidates others (griefing attack).

Prohibited during validation:

  • Read storage of other contracts except the account itself and related entities.
  • Call block.timestamp, block.number (except limited use via validAfter/validUntil).
  • Access storage that might be changed by another UserOp in the same batch.

This requirement is described in the ERC-4337 specification. The bundler tracks the storage slots accessed during validation using debug_traceCall with an EVM tracer. This is a costly operation—one of the main performance bottlenecks of a bundler.

// Simplified tracer for tracking storage access
async function traceValidation(userOp: UserOperation): Promise<StorageMap> {
  const trace = await provider.send('debug_traceCall', [{
    to: ENTRY_POINT_ADDRESS,
    data: entryPoint.interface.encodeFunctionData('simulateValidation', [userOp])
  }, 'latest', {
    tracer: bundlerCollectorTracer, // custom JS tracer
    tracerConfig: { /* ... */ }
  }])
  
  return parseStorageAccess(trace)
}

bundlerCollectorTracer is a JavaScript tracer for go-ethereum's debug_traceCall. It tracks every SLOAD/SSTORE opcode and associates them with the calling contract. This is the most technically challenging part of a bundler.

Managing the Alternative Mempool

A UserOp accepted into the mempool must remain valid. The bundler monitors:

  • Nonce invalidation. If the on-chain nonce of an account changes (another UserOp went through), the pending UserOp with the old nonce is removed.
  • Deposit insufficiency. If the deposit balance in the EntryPoint decreases (another UserOp sponsored by the same Paymaster went through), the bundler must recalculate whether it covers all pending UserOps of that Paymaster.
  • Gas price changes. A UserOp with maxFeePerGas below the current base fee will not pass; the bundler may temporarily defer or drop it.
class UserOpMempool {
  private pool: Map<string, MempoolEntry> = new Map()
  
  async add(userOp: UserOperation): Promise<string> {
    const hash = getUserOpHash(userOp)
    
    // Reputation system: limit by sender/paymaster/factory
    this.reputationManager.checkReputation(userOp)
    
    this.pool.set(hash, {
      userOp,
      prefund: await this.calculatePrefund(userOp),
      addedAt: Date.now()
    })
    
    return hash
  }
  
  getBundle(maxGas: bigint): UserOperation[] {
    // Greedy algorithm: select UserOps with highest priority fee
    // taking into account gas limit and storage conflicts
    return this.selectNonConflicting(
      [...this.pool.values()]
        .sort((a, b) => Number(b.userOp.maxPriorityFeePerGas - a.userOp.maxPriorityFeePerGas)),
      maxGas
    )
  }
}

Submitting a Bundle On-chain

The bundler forms a batch of valid UserOps and sends EntryPoint.handleOps(ops, beneficiary). beneficiary is the address where the EntryPoint will send the collected gas (priority fee of the bundler).

Critical point: the bundler sends a regular EOA transaction. It pays gas upfront; the EntryPoint reimburses from the deposits of accounts/paymasters. If handleOps reverts, the bundler loses gas. Therefore, simulation before submission is mandatory.

Protection against reverting bundles: In handleOps, the EntryPoint skips UserOps that revert during the execution phase (not validation). For the validation phase—if it reverts, the entire handleOps fails. The bundler must ensure validation is guaranteed to pass.

Decentralization and Protection: Reputation and P2P

To prevent spam and DoS attacks, ERC-4337 introduces a reputation system for unbanned entities (Paymaster, Factory, Aggregator). The logic:

class ReputationManager {
  // For each entity track: ops included vs ops unsuccessful
  
  updateIncluded(entity: string): void {
    this.entries[entity].opsSeen++
    this.entries[entity].opsIncluded++
  }
  
  updateFailed(entity: string): void {
    this.entries[entity].opsIncluded-- // if bundle was reverted
  }
  
  getStatus(entity: string): 'ok' | 'throttled' | 'banned' {
    const entry = this.entries[entity]
    if (!entry) return 'ok'
    
    const ratio = entry.opsIncluded / Math.max(1, entry.opsSeen)
    if (ratio < MIN_INCLUSION_RATE_DENOMINATOR) return 'banned'
    if (entry.opsSeen > THROTTLE_THRESHOLD) return 'throttled'
    return 'ok'
  }
}

Staking in the EntryPoint increases limits: an entity with stake can have more UserOps in the mempool. This is an anti-spam mechanism: you cannot freely spam the mempool.

For a decentralized bundler, a P2P alt mempool is needed—a network for exchanging UserOps between bundler nodes. ERC-4337 specifies a protocol based on libp2p with gossipsub:

  • Topic: user_ops/{chainId}/{entryPointAddress}
  • Message: RLP-encoded UserOperation
  • Validation: each node independently validates before relay
import { createLibp2p } from 'libp2p'
import { gossipsub } from '@chainsafe/libp2p-gossipsub'

const libp2p = await createLibp2p({
  /* ... transport, identify, etc */
  services: {
    pubsub: gossipsub({
      allowPublishToZeroPeers: true,
      msgIdFn: (msg) => computeUserOpHash(msg.data)
    })
  }
})

libp2p.services.pubsub.subscribe(userOpsTopic)
libp2p.services.pubsub.addEventListener('message', async (event) => {
  const userOp = decodeUserOp(event.detail.data)
  await mempool.add(userOp) // with all checks
})

MEV and Bundle Construction

A bundler has a unique position: it selects the order of UserOps in a bundle, which opens up MEV opportunities. Two strategies:

Fair FIFO bundler—includes UserOps in the order received, maximizes priority fee. Simple implementation, good for a permissioned bundler for a specific application.

MEV-aware bundler—analyzes the callData of UserOps, finds arbitrage opportunities, and builds the bundle optimally. Integration with Flashbots MEV-boost to submit bundles via a private mempool. Saves 15-25% on gas costs with MEV optimization.

Strategy Advantages Disadvantages
FIFO Simplicity, predictability Misses MEV
MEV-aware Additional revenue More complex, requires callData analysis

What's Included in the Work

  1. Documentation—architecture description, storage access rules, interaction scheme.
  2. Access—to the repository, GitHub Actions, monitoring.
  3. Training—workshop on operation and configuration of the bundler.
  4. Support—2 months after launch, including critical bug fixes.
  5. Source code—under a license, with deployment instructions.

Ready-made Implementations for Forking

  • Infinitism/bundler (TypeScript)—reference implementation from the creators of ERC-4337
  • Stackup bundler (Go)—production bundler from Stackup
  • Silius (Rust)—high-performance bundler
  • Rundler (Rust)—bundler from Alchemy

For custom development: TypeScript reference is easier to understand; Rust/Go are better for production throughput.

Technology Stack and Timelines

Component Technology
RPC server Node.js / Go / Rust
EVM tracing debug_traceCall + custom JS tracer
Mempool storage Redis / in-memory + persistence
P2P (optional) libp2p + gossipsub
Monitoring Prometheus + Grafana
Testing Foundry + Hardhat (local EntryPoint)

Basic centralized bundler with RPC, validation, mempool, and bundle submission: 6-8 weeks. The main difficulty is a correct EVM tracer for storage access rules.

Production bundler with reputation system, P2P mempool, MEV optimization, monitoring: 3-4 months.

Key warning: incorrect implementation of storage access rules leads either to accepting dangerous UserOps (DoS risk) or rejecting valid ones (poor UX). Thorough testing on all edge cases is mandatory.

Order a custom bundler development—we will implement it for your infrastructure. Contact us for a consultation: we will help choose a strategy and calculate the cost for your task.

We develop crypto wallets turnkey — from custodial solutions for fintech to smart contract accounts on EIP-4337. 5+ years in blockchain development, 40+ projects implemented. Let's examine which architecture to choose for your task and why MPC or Account Abstraction solve the private key problem that MetaMask and classic HD wallets could not close.

Why are classic wallets dangerous for business?

A seed phrase in a browser extension is the only way to restore access. For retail users, this is a barrier to entry (lost phrase = lost money). For corporate treasuries, it is incompatible with compliance (KYC/AML, role model, multisignature). Any single key leak compromises all funds. These risks are built into the architecture, not poor UX.

We eliminate them at the protocol level: MPC wallets (key never fully assembled), smart contract wallets (authorization logic in code), hardware HSM for institutional storage. Details below.

What is the real difference between custodial and non-custodial?

Custodial — the provider stores the private key. User authenticates via email/password/OAuth. Recovery is trivial, KYC/AML built-in. For centralized financial applications, often the only regulatory acceptable option. Risk: single point of failure (e.g., Bitfinex hack — $72M, FTX — $600M+ client funds).

Non-custodial — keys are with the user. Provider has no access to funds. Storage responsibility falls on the user. For 99% of people, this model is unworkable without additional protection — hence MPC.

MPC wallets: the key that doesn't exist

Multi-Party Computation (MPC) is a cryptographic protocol that allows multiple parties to jointly sign a transaction without revealing their partial secrets. The private key never exists in its assembled form.

Standard scheme: 2-of-3 MPC between user (share on device), provider server, and backup cloud storage. Transaction is signed by any two of three parties. Lost phone — recovery via server + cloud. Server compromised — attacker holds only one share, signing impossible.

TSS (Threshold Signature Scheme) is a concrete implementation of MPC for ECDSA/EdDSA. Algorithms: GG18, GG20, CGGMP21 (the latter is faster and has better security proofs). Libraries: tss-lib (Go, from Binance), multi-party-sig (Go, from Coinbase), ZenGo-X/multi-party-ecdsa (Rust).

MPC requires no on-chain changes — to the blockchain, the signature looks like a normal single-key signature. This saves gas and keeps the key management scheme confidential (not published in chain) — unlike multisig.

Account Abstraction (EIP-4337): smart contract as wallet

EIP-4337 completely changes the model: instead of EOA (Externally Owned Account), a smart contract Account is used. Authorization logic is in contract code, not in protocol cryptography. This opens up arbitrary signing logic, social recovery, session keys, sponsored transactions, and batch operations.

How the EIP-4337 stack works:

User → UserOperation → Bundler → EntryPoint contract → Account contract
                                          ↑
                                    Paymaster (optional, pays gas)

UserOperation — a new type of object (not an L1 transaction). Bundler collects UserOps from an alternative mempool, packs them into one transaction, and sends to EntryPoint. EntryPoint calls validateUserOp on the Account contract — Account decides if the signature is valid.

Practical capabilities:

Social recovery. The contract stores a list of guardians (other addresses or a service). Lost key — guardians vote for replacement. Argent has used this scheme since 2020.

Session keys. A temporary key with limited rights: interaction only with a specific contract, until a certain date, up to a certain amount. For GameFi and dApps — user does not sign every micro-transaction.

Paymaster. A third-party contract pays gas for the user. Onboarding pattern: user does not hold ETH, gas is sponsored by dApp or taken from ERC-20 tokens.

Implementations: Safe{Core} Protocol, Biconomy SDK (Stackup), ZeroDev (Kernel), Alchemy (Rundler bundler). EntryPoint v0.6/v0.7 is deployed and active on Ethereum mainnet, Polygon, Arbitrum, Optimism. We guarantee compatibility with the latest contract versions.

What is a Hardware Security Module for corporate wallets?

For treasuries and institutional storage: HSM (Hardware Security Module). The key is generated and never leaves the secure chip. Signing happens inside the HSM. Hardware attestation is supported. Solutions used: AWS CloudHSM, Azure Dedicated HSM, Thales Luna, YubiHSM 2 (for small volumes). Integration via PKCS#11 or cloud-specific API.

A combination of HSM + MPC is optimal for institutional use: key shares are stored in HSMs on different servers/jurisdictions, signing via TSS. This ensures compliance with regulatory requirements (e.g., for crypto custodians).

Integration with dApps: WalletConnect and standards

Any wallet must be able to interact with dApps. Standard: WalletConnect v2 (Sign API): QR code or deep link, peer-to-peer encrypted channel via relay server. For browser extensions: EIP-1193 (Ethereum Provider API).

On the frontend, we use wagmi + viem — one interface for MetaMask, WalletConnect, Coinbase Wallet, injected providers. For Account Abstraction: EIP-5792 (wallet capabilities) and EIP-7677 (paymaster service).

Development process

  1. Threat model — who is the user (B2C, B2B, institutional), what operations, what is the acceptable risk model. Architecture depends on this.
  2. Selection and design of key storage scheme — MPC, HSM, multisig, or a combination.
  3. Development of Account contract (if EIP-4337) or integration of MPC library.
  4. Backend — MPC coordination, session management, paymaster service (if needed).
  5. Mobile/browser application — UI with WalletConnect integration, biometrics, QR.
  6. Integration with dApps — EIP-1193, WalletConnect v2.
  7. Audit of contracts and cryptographic implementations — mandatory step. MPC libraries have known vulnerabilities (GG18 susceptible to attack with malicious participant without abort protocol). We use libraries with up-to-date security reviews (CGGMP21). Experience passing audits with Certik, Hacken, Trail of Bits — we have certificates.

What is included in the work (deliverables)

  • Source code of smart contracts (Solidity/Rust) with documentation
  • Backend MPC coordination service (Go or Rust) with API
  • Mobile application (iOS/Android) or browser extension
  • Integration with WalletConnect, Ledger/Trezor (if required)
  • Preparation for security audit (vulnerability report)
  • Administrator and user documentation
  • Access to repository, CI/CD, monitoring (Tenderly, Etherscan API)
  • Training of your team (2-3 sessions)
  • Post-launch support — 1 month

Timeline and cost

Solution type Timeline (working weeks)
Custodial with basic UI 4–8
Non-custodial with MPC integration 8–16
EIP-4337 Account with paymaster 6–12
Institutional (HSM + MPC + compliance) from 16

Cost is calculated individually for your project. We will estimate within one day — contact us by email or Telegram. We provide a guarantee on code and timeline.

Typical mistakes in crypto wallet development (and how to avoid them)

  • Using outdated MPC libraries — GG18 without abort protocol. Choose CGGMP21 or tss-lib with up-to-date audit reports.
  • Tight coupling to a single blockchain — not abstracting for L2/sidechains. Use viem/wagmi for cross-chain.
  • Ignoring MEV attacks — when using multisig without timelocks. Add tx simulation (Tenderly) and sandwiching protection.
  • Lack of fallback recovery mechanism — for Account Abstraction, not setting up social recovery. Include from the first release.

We eliminate these pitfalls at the design stage — for each project, we create a threat model and security checklist.

Need a reliable wallet with no compromises? Get a consultation from our architect — we will analyze your task and propose an architecture with a precise estimate. Leave a request — we will respond within a day.