> For the complete documentation index, see [llms.txt](https://www.anandisheladiya.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.anandisheladiya.com/protocols/ercs-and-eips/erc-4337.md).

# ERC 4337

### What is ERC-4337?

ERC-4337 is an Ethereum standard that implements **account abstraction** without requiring changes to the core Ethereum protocol. Instead of relying on traditional **Externally Owned Accounts (EOAs)** controlled by private keys, users can operate through **smart contract wallets** with enhanced flexibility, security, and usability.

### **Why is ERC-4337 Important?**

Traditionally, Ethereum has two types of accounts:

1. **Externally Owned Accounts (EOAs):**
   * Controlled by private keys (e.g., MetaMask, Ledger).
   * Only EOAs can sign transactions.
   * If the private key is lost, funds are permanently inaccessible.
2. **Smart Contract Accounts:**
   * Can include **custom logic** (multi-signature, social recovery, spending limits).
   * Require an EOA to initiate transactions, limiting usability.

**ERC-4337 removes the dependency on EOAs, allowing transactions to be validated directly by smart contracts, enabling features like:**\
\- Multi-Factor Authentication\
\- Gas fee payment in **any** ERC-20 token\
\- Social recovery and key rotation\
\- Transaction batching

### **ERC-4337 Architecture Overview**

#### ***Key Components of ERC-4337***

ERC-4337 introduces a **new mempool** and several key actors:

1. **User Operation (`UserOp`)** – A new transaction format sent to the network.
2. **Smart Contract Wallet** – A contract that verifies and executes transactions instead of a private key signing it.
3. **Bundler** – A specialized node that collects multiple UserOps and submits them as a single Ethereum transaction.
4. **EntryPoint Contract** – A singleton contract that ensures security and execution of transactions.
5. **Paymaster** – Allows gas fee abstraction (users can pay gas in stablecoins or get sponsorships).

### ERC-4337 Architecture Diagram

```
+-------------------------------------------------------+
|                   Ethereum Network                   |
|                  (Settlement Layer)                  |
+-------------------------------------------------------+
             |                           |
             |                           |
      +------------+                +----------------+
      |   EntryPoint  |<---[Executes]--|  Bundler     |
      | (Singleton SC)|                | (Relayer)   |
      +------------+                +----------------+
             ^                           |
             |  [Validation & Execution] |
+----------------+       +-----------------+
| Smart Contract |       |    Paymaster    |
|     Wallet     |       | (Optional Gas   |
| (User Account) |       |  Sponsor)       |
+----------------+       +-----------------+
             ^
             |
     +---------------+
     |  UserOp      |  <---- Transaction sent by User
     +---------------+

```

### ERC-4337 Code Structure

#### **1. Smart Contract Wallet (Minimal Implementation)**

The smart contract wallet must be able to validate transactions **without relying on EOAs**. Below is a basic implementation of an **ERC-4337-compatible wallet**:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

interface IEntryPoint {
    function handleOps(address user, bytes calldata txData) external;
}

contract ERC4337Wallet is Ownable {
    using ECDSA for bytes32;

    address public entryPoint;
    
    constructor(address _entryPoint) {
        entryPoint = _entryPoint;
    }

    function validateUserOp(
        bytes32 hash,
        bytes memory signature
    ) external view returns (bool) {
        address signer = hash.toEthSignedMessageHash().recover(signature);
        return signer == owner();
    }

    function executeTransaction(
        address to,
        uint256 value,
        bytes calldata data
    ) external onlyOwner {
        (bool success, ) = to.call{value: value}(data);
        require(success, "Tx failed");
    }
}

```

**Key Features:**\
\- The wallet can validate **User Operations (UserOps)** via `validateUserOp()`.\
\- Allows execution of transactions without an EOA using `executeTransaction()`.\
\- Owner-based control using OpenZeppelin’s `Ownable`.

2. #### **EntryPoint Contract (Simplified Implementation)**

   The **EntryPoint** contract acts as a **security layer** that verifies UserOps before they are executed by the smart contract wallet.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract EntryPoint {
    mapping(address => bool) public authorizedWallets;

    function handleOps(
        address user,
        bytes calldata txData
    ) external {
        require(authorizedWallets[user], "Unauthorized wallet");
        (bool success, ) = user.call(txData);
        require(success, "Tx failed");
    }

    function registerWallet(address wallet) external {
        authorizedWallets[wallet] = true;
    }
}

```

**Key Features:**\
\- Ensures only authorized wallets can send UserOps.\
\- Acts as a **universal validation layer**.\
\- Bundlers interact with this contract to process transactions.

3. #### **Bundler (Node that Collects Transactions)**

   Bundlers act like miners but **batch multiple UserOps into a single Ethereum transaction**.

```typescript
import { ethers } from "ethers";

async function bundleTransactions(userOps) {
    const provider = new ethers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_API_KEY");
    const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider);
    
    const entryPoint = new ethers.Contract(
        "ENTRYPOINT_CONTRACT_ADDRESS",
        ["function handleOps(address user, bytes txData)"],
        signer
    );

    for (let op of userOps) {
        await entryPoint.handleOps(op.user, op.txData);
    }
}

bundleTransactions(userOps);

```

**Key Features:**\
\- Aggregates multiple UserOps into one transaction to **reduce fees**.\
\- Sends transactions via the `EntryPoint` contract.

4. #### **Paymaster (Gas Abstraction via ERC-20 Tokens)**

   Users can pay gas fees in **any ERC-20 token** via a **Paymaster contract**.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IERC20 {
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

contract Paymaster {
    address public token;
    address public relayer;

    constructor(address _token, address _relayer) {
        token = _token;
        relayer = _relayer;
    }

    function payForUserOp(address user, uint256 amount) external {
        IERC20(token).transferFrom(user, relayer, amount);
    }
}

```

**Key Features:**\
\- Allows **gas sponsorship** (dApps can cover user gas fees).\
\- Users can pay fees in **USDT, DAI, or any ERC-20 token**.

### &#x20;**Advantages**

* **Improved UX:** No need to manage private keys directly.
* &#x20;**Gas Fee Flexibility:** Pay gas in any ERC-20 token.
* **Multi-Factor Authentication (MFA):** Enhanced security.
* **Social Recovery:** No risk of losing funds due to lost private keys.
* **Transaction Batching:** Execute multiple transactions at once.

### **Disadvantages**

* &#x20;**Higher Gas Costs:** Smart contract wallets consume more gas than EOAs.
* **Increased Complexity:** Requires new infrastructure (bundlers, paymasters).
* &#x20;**Adoption Hurdles:** dApps and wallets must integrate ERC-4337 support.
