ERC-4337 Account Abstraction Integration

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 1 servicesAll 1306 services
ERC-4337 Account Abstraction Integration
Complex
~1-2 weeks
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

ERC-4337 Integration (Account Abstraction)

ERC-4337 is a standard that appeared on Ethereum mainnet in March 2023 and fundamentally changes how wallets work. Before it, every account in the network is either an EOA (externally owned account), controlled by a private key, or a smart contract. EOA is simple, but rigidly limited: one signature, one key, lose it — lose everything. ERC-4337 allows every user to have a smart contract wallet with arbitrary authorization logic — without changing Ethereum consensus.

The essence of the architectural trick: instead of regular transactions, users create UserOperation objects, which are aggregated in a separate mempool. Specialized nodes called bundlers collect UserOps and send them through the EntryPoint contract — a singleton deployed at a single address across all EVM-compatible networks. All validation and execution logic lives inside the user's Account contract.

How UserOperation is Structured

UserOperation is not a transaction in the classical sense. It's a data structure that the user signs and sends to the alt mempool:

struct UserOperation {
    address sender;           // address of the smart contract wallet
    uint256 nonce;
    bytes initCode;           // if the wallet hasn't been deployed yet
    bytes callData;           // what to execute
    uint256 callGasLimit;
    uint256 verificationGasLimit;
    uint256 preVerificationGas;
    uint256 maxFeePerGas;
    uint256 maxPriorityFeePerGas;
    bytes paymasterAndData;   // who pays for gas (optional)
    bytes signature;
}

initCode is a key moment for UX. A user can get a wallet address (via CREATE2) before its deployment and use that address to receive assets. The wallet deploys automatically on the first UserOperation — the user doesn't see a separate step to "create wallet".

The Bundler calls EntryPoint.handleOps(), passing a batch of UserOps. The EntryPoint makes two passes: validation loop (checks signatures and balances) and execution loop (executes callData). The separation is critical — validation is isolated so the bundler can check profitability without side effects.

Smart Contract Account: What to Implement

A minimal Account contract must implement the IAccount interface with one method:

function validateUserOp(
    UserOperation calldata userOp,
    bytes32 userOpHash,
    uint256 missingAccountFunds
) external returns (uint256 validationData);

validationData is a packed uint256 containing: validation result (0 = success, 1 = failure), validAfter and validUntil time restrictions. This enables time-limited session keys directly in validation logic.

A real Account implementation we work with usually inherits from BaseAccount (from eth-infinitism/account-abstraction repo) and adds custom logic:

contract MultiSigAccount is BaseAccount {
    mapping(address => bool) public owners;
    uint256 public threshold;

    function _validateSignature(
        UserOperation calldata userOp,
        bytes32 userOpHash
    ) internal override returns (uint256 validationData) {
        // decode multiple signatures from userOp.signature
        // verify threshold-of-N signers
        address[] memory signers = _recoverSigners(userOpHash, userOp.signature);
        uint256 validCount = 0;
        for (uint i = 0; i < signers.length; i++) {
            if (owners[signers[i]]) validCount++;
        }
        return validCount >= threshold ? 0 : SIG_VALIDATION_FAILED;
    }
}

Paymaster: Gas Without ETH

Paymaster is a smart contract that sponsors gas for the user. Two main patterns:

Verifying Paymaster — accepts an off-chain signature from the backend and verifies it on-chain. Used for freemium models: dApp pays gas for users. The backend signs permission, the wallet includes it in paymasterAndData.

ERC-20 Paymaster — the user pays gas in ERC-20 token (e.g., USDC). The Paymaster converts the rate through a Chainlink oracle, takes slightly more ERC-20 from the user, and pays ETH gas itself. The user doesn't need ETH at all.

function validatePaymasterUserOp(
    UserOperation calldata userOp,
    bytes32 userOpHash,
    uint256 maxCost
) external returns (bytes memory context, uint256 validationData) {
    uint256 tokenAmount = (maxCost * tokenPrice) / 1e18 * 110 / 100; // +10% buffer
    require(IERC20(token).allowance(userOp.sender, address(this)) >= tokenAmount);
    return (abi.encode(userOp.sender, tokenAmount), 0);
}

Social Recovery

One of the main features of Account Abstraction is social recovery. The user appoints guardians (trusted addresses or address hashes) who can change owner through a timelock:

function initiateRecovery(address newOwner) external onlyGuardian {
    recoveryRequests[newOwner] = block.timestamp + RECOVERY_DELAY;
}

function finalizeRecovery(address newOwner) external {
    require(block.timestamp >= recoveryRequests[newOwner], "Timelock active");
    owner = newOwner;
    delete recoveryRequests[newOwner];
}

RECOVERY_DELAY (usually 48-72 hours) gives the user time to cancel recovery if a guardian is compromised.

Session Keys

Session keys are temporary keys with limited permissions. A dApp asks to sign a policy: "this key can spend up to 10 USDC per day only in contract 0x...". The user signs once, then the dApp signs UserOps with the session key — no popup each time. Implemented via SessionKeyValidator module or custom logic in validateUserOp.

Kernel from ZeroDev and Safe{Wallet} implement this through a modular architecture: Account is the execution layer, and validators/executors are pluggable modules. The choice of base SDK depends on requirements: Kernel — maximum flexibility, Biconomy SDK — ready bundler+paymaster infrastructure.

Stack and Infrastructure

Smart contracts: Solidity 0.8.x, eth-infinitism/account-abstraction v0.6 or v0.7, Foundry for tests. Critical to test via simulateValidation — EntryPoint has storage access rules for the validation phase, violations of which bundlers will reject UserOps.

Bundler: Stackup, Alchemy, Pimlico — managed bundlers for production. For your own — eth-infinitism/bundler (TypeScript) or Silius (Rust). Bundler must conform to ERC-4337 mempool specification.

Frontend SDK: permissionless.js (viem-based), Biconomy SDK, ZeroDev SDK. permissionless.js is the most low-level, full control over UserOperation construction.

Component Technology Note
Account contract Solidity + eth-infinitism Audit required
Paymaster Solidity + Chainlink For ERC-20 gas
Bundler Stackup/Pimlico API Managed for start
Frontend SDK permissionless.js + viem Viem-based, actively developed
Session keys ZeroDev Kernel / Biconomy Ready implementations

Gas Overhead and L2

On Ethereum mainnet, each UserOperation costs more than a regular EOA transaction by ~42,000 gas (EntryPoint overhead). On L2 this is almost unnoticeable: on Arbitrum/Optimism gas is orders of magnitude cheaper, and Account Abstraction becomes practical for mass adoption.

For Polygon, Base, Optimism, Arbitrum — EntryPoint is already deployed at the standard address 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 (v0.6). One implementation works across all networks.

Timeline and Scope

Basic integration (Account + Paymaster + bundler connection, without custom logic): 3-4 weeks. Includes: Account smart contract with ECDSA or WebAuthn validation, Verifying Paymaster, integration with managed bundler, frontend SDK.

Full implementation with social recovery, session keys, ERC-20 paymaster, custom modules, audit: 8-12 weeks.

Audit of Account and Paymaster contracts is a separate mandatory step before production deployment. Errors in validateUserOp can allow wallet draining.