[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-eip-7702-in-practice-building-smart-account-flows-after-pectra":3},{"article":4,"author":55},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":34,"related_articles":35},"dd000000-0000-0000-0000-000000000003","a0000000-0000-0000-0000-000000000002","EIP-7702 in Practice: Building Smart Account Flows After Pectra","eip-7702-in-practice-building-smart-account-flows-after-pectra","EIP-7702 lets any Ethereum EOA temporarily act as a smart contract within a single transaction. Here is how to implement batch transactions, gas sponsorship, and social recovery using the new account abstraction primitive.","## What EIP-7702 Enables\n\nEIP-7702, activated with Ethereum's Pectra upgrade in March 2025, introduces a new transaction type that allows any Externally Owned Account (EOA) to set a **delegation designator** — a pointer to a smart contract whose code the EOA temporarily adopts for the duration of a transaction. This means your existing MetaMask wallet address can execute arbitrary smart contract logic (batch calls, custom validation, gas sponsorship) without deploying a new contract wallet or changing your address.\n\nThis is the most significant UX improvement in Ethereum's history. Users no longer need to choose between the simplicity of an EOA and the power of a smart account.\n\n## EIP-7702 vs ERC-4337: When to Use Which\n\nBoth EIP-7702 and ERC-4337 enable account abstraction, but they operate at different levels and suit different use cases:\n\n| Feature | EIP-7702 | ERC-4337 |\n|---------|----------|----------|\n| Level | Protocol (new tx type) | Application (smart contract) |\n| Account type | Upgrades existing EOAs | Requires new smart contract wallet |\n| Address | Keeps existing EOA address | New address (counterfactual) |\n| Persistence | Per-transaction delegation | Permanent smart contract |\n| Bundler required | No (standard tx flow) | Yes (separate mempool) |\n| Gas overhead | ~20,000 gas for delegation | ~42,000 gas for UserOp validation |\n| Supported wallets | MetaMask, Coinbase Wallet, Rainbow | Specialized (Safe, ZeroDev, Biconomy) |\n| Best for | Upgrading existing users | New users, complex account logic |\n\n### Decision Framework\n\n**Use EIP-7702 when:**\n- Your users already have EOA wallets (MetaMask, Coinbase Wallet)\n- You need batch transactions or gas sponsorship\n- You want minimal integration complexity\n- The smart account logic is per-transaction (not permanent)\n\n**Use ERC-4337 when:**\n- You are building a new wallet or onboarding new users\n- You need persistent account logic (permanent multisig, complex recovery)\n- You want the account to be a smart contract by default\n- You need advanced features like account modules, plugins, or guardians\n\n**Use both together when:**\n- You want ERC-4337 smart accounts that can also process EIP-7702 delegations from EOAs (for backward compatibility)\n\n## Code Examples\n\n### Batch Transactions\n\nThe most common EIP-7702 use case: execute multiple operations in a single transaction. No more \"approve then swap\" two-step flows.\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\n\u002F\u002F\u002F @title BatchExecutor — EIP-7702 delegation target for batch calls\n\u002F\u002F\u002F @notice EOAs delegate to this contract to execute multiple calls atomically\ncontract BatchExecutor {\n    struct Call {\n        address target;\n        uint256 value;\n        bytes data;\n    }\n    \n    \u002F\u002F\u002F @notice Execute a batch of calls from the delegating EOA\n    \u002F\u002F\u002F @dev When called via EIP-7702, msg.sender is the EOA itself\n    \u002F\u002F\u002F @param calls Array of calls to execute\n    function executeBatch(Call[] calldata calls) external payable {\n        for (uint256 i = 0; i \u003C calls.length; i++) {\n            (bool success, bytes memory result) = calls[i].target.call{\n                value: calls[i].value\n            }(calls[i].data);\n            \n            if (!success) {\n                \u002F\u002F Bubble up the revert reason\n                assembly {\n                    revert(add(result, 32), mload(result))\n                }\n            }\n        }\n    }\n}\n```\n\nClient-side usage with ethers.js v6:\n\n```typescript\nimport { ethers } from \"ethers\";\n\n\u002F\u002F EIP-7702 transaction type (type: 4)\nconst batchTx = {\n    type: 4,\n    to: userAddress, \u002F\u002F EOA delegates to itself\n    authorizationList: [{\n        chainId: 1,\n        address: BATCH_EXECUTOR_ADDRESS, \u002F\u002F delegation target\n        nonce: await provider.getTransactionCount(userAddress),\n        \u002F\u002F Signed by the EOA owner:\n        yParity: 0, r: \"0x...\", s: \"0x...\"\n    }],\n    data: batchExecutorInterface.encodeFunctionData(\"executeBatch\", [[\n        {\n            target: USDC_ADDRESS,\n            value: 0,\n            data: usdcInterface.encodeFunctionData(\"approve\", [\n                UNISWAP_ROUTER, ethers.parseUnits(\"1000\", 6)\n            ])\n        },\n        {\n            target: UNISWAP_ROUTER,\n            value: 0,\n            data: routerInterface.encodeFunctionData(\"exactInputSingle\", [{\n                tokenIn: USDC_ADDRESS,\n                tokenOut: WETH_ADDRESS,\n                fee: 3000,\n                recipient: userAddress,\n                amountIn: ethers.parseUnits(\"1000\", 6),\n                amountOutMinimum: 0,\n                sqrtPriceLimitX96: 0\n            }])\n        }\n    ]])\n};\n\nconst tx = await signer.sendTransaction(batchTx);\n```\n\n### Gas Sponsorship\n\nWith EIP-7702, a paymaster can sponsor gas for any EOA transaction by submitting the transaction on the user's behalf while the user's authorization list delegates execution:\n\n```solidity\n\u002F\u002F\u002F @title SponsoredExecutor — gas sponsorship via EIP-7702\ncontract SponsoredExecutor {\n    mapping(address => uint256) public nonces;\n    \n    \u002F\u002F\u002F @notice Execute a call on behalf of a user, gas paid by msg.sender\n    \u002F\u002F\u002F @param user The EOA that signed the authorization\n    \u002F\u002F\u002F @param target The contract to call\n    \u002F\u002F\u002F @param data The calldata\n    \u002F\u002F\u002F @param userNonce Replay protection nonce\n    \u002F\u002F\u002F @param deadline Expiration timestamp\n    \u002F\u002F\u002F @param signature User's EIP-712 signature over the above params\n    function sponsoredExecute(\n        address user,\n        address target,\n        bytes calldata data,\n        uint256 userNonce,\n        uint256 deadline,\n        bytes calldata signature\n    ) external {\n        require(block.timestamp \u003C= deadline, \"Expired\");\n        require(nonces[user] == userNonce, \"Invalid nonce\");\n        nonces[user]++;\n        \n        \u002F\u002F Verify user's signature (EIP-712)\n        bytes32 digest = _hashTypedData(user, target, data, userNonce, deadline);\n        address signer = ECDSA.recover(digest, signature);\n        require(signer == user, \"Invalid signature\");\n        \n        \u002F\u002F Execute the call as the user (via delegatecall in EIP-7702 context)\n        (bool success, bytes memory result) = target.call(data);\n        require(success, \"Call failed\");\n    }\n}\n```\n\nThe paymaster submits the type-4 transaction, paying gas. The user signs only an EIP-712 message approving the specific action — no ETH needed in their wallet.\n\n### Social Recovery\n\nEIP-7702 enables social recovery patterns without requiring a permanent smart contract wallet:\n\n```solidity\n\u002F\u002F\u002F @title RecoveryModule — social recovery via EIP-7702\ncontract RecoveryModule {\n    struct RecoveryConfig {\n        address[] guardians;\n        uint256 threshold;\n        uint256 delay;\n    }\n    \n    mapping(address => RecoveryConfig) public configs;\n    mapping(bytes32 => uint256) public recoveryTimestamps;\n    mapping(bytes32 => uint256) public approvalCounts;\n    mapping(bytes32 => mapping(address => bool)) public hasApproved;\n    \n    \u002F\u002F\u002F @notice Register recovery guardians (called by the EOA via EIP-7702)\n    function setupRecovery(\n        address[] calldata guardians,\n        uint256 threshold,\n        uint256 delay\n    ) external {\n        require(guardians.length >= threshold, \"Invalid threshold\");\n        require(threshold >= 2, \"Min 2 guardians\");\n        configs[msg.sender] = RecoveryConfig(guardians, threshold, delay);\n    }\n    \n    \u002F\u002F\u002F @notice Guardian approves a recovery request\n    function approveRecovery(\n        address account,\n        address newOwner\n    ) external {\n        RecoveryConfig memory config = configs[account];\n        require(_isGuardian(config, msg.sender), \"Not a guardian\");\n        \n        bytes32 recoveryId = keccak256(abi.encode(account, newOwner));\n        require(!hasApproved[recoveryId][msg.sender], \"Already approved\");\n        \n        hasApproved[recoveryId][msg.sender] = true;\n        approvalCounts[recoveryId]++;\n        \n        if (approvalCounts[recoveryId] >= config.threshold) {\n            recoveryTimestamps[recoveryId] = block.timestamp + config.delay;\n        }\n    }\n    \n    \u002F\u002F\u002F @notice Execute recovery after delay period\n    function executeRecovery(\n        address account,\n        address newOwner\n    ) external {\n        bytes32 recoveryId = keccak256(abi.encode(account, newOwner));\n        uint256 timestamp = recoveryTimestamps[recoveryId];\n        require(timestamp > 0 && block.timestamp >= timestamp, \"Not ready\");\n        \n        \u002F\u002F Transfer control by updating the account's delegation target\n        \u002F\u002F to a contract controlled by newOwner\n        \u002F\u002F Implementation depends on the specific wallet architecture\n    }\n}\n```\n\n## Wallet Integration Status\n\nAs of March 2026, EIP-7702 support has rolled out across major wallets:\n\n### MetaMask\n\nMetaMask added EIP-7702 support in version 12.4 (September 2025). Users see a \"Smart Transaction\" badge when a dApp requests a type-4 transaction. The wallet shows:\n- The delegation target contract (with verified source on Etherscan)\n- Each call in the batch with decoded parameters\n- Estimated gas savings vs separate transactions\n- A warning if the delegation target is unverified\n\n### Coinbase Wallet\n\nCoinbase Wallet has been the most aggressive adopter, integrating EIP-7702 into its \"Smart Wallet\" feature (launched November 2025). Key features:\n- **Auto-batching** — the wallet automatically batches approve+swap sequences\n- **Gas sponsorship** — Coinbase sponsors gas for transactions under $1 in fee\n- **One-click DeFi** — pre-built delegation targets for common DeFi operations\n\n### Rainbow, Rabby, and Others\n\nRainbow added support in January 2026. Rabby supports type-4 transactions but lacks the batch visualization UI. Frame (the desktop wallet) was among the first to support EIP-7702, shipping support in April 2025.\n\n## Migration Guide: From EOA to Smart Accounts\n\nFor dApp developers, here is the recommended migration path to support EIP-7702:\n\n### Step 1: Deploy Delegation Targets\n\nCreate and audit the smart contracts your users will delegate to. Common patterns:\n\n```\nBatchExecutor       — multi-call batching\nSessionKeyManager   — time-limited permissions\nSpendingLimiter     — daily\u002Fweekly spending caps\nRecoveryModule      — social recovery setup\n```\n\n### Step 2: Update Your Frontend\n\nDetect whether the connected wallet supports EIP-7702:\n\n```typescript\nasync function supportsEIP7702(provider: ethers.Provider): Promise\u003Cboolean> {\n    try {\n        \u002F\u002F Check if the node supports type-4 transactions\n        const capabilities = await provider.send(\n            \"wallet_getCapabilities\", []\n        );\n        return capabilities?.atomicBatch?.supported === true;\n    } catch {\n        return false;\n    }\n}\n```\n\n### Step 3: Implement Graceful Degradation\n\nNot all users will have EIP-7702-capable wallets. Your dApp should detect capabilities and fall back:\n\n```typescript\nasync function executeSwap(tokenIn, tokenOut, amount) {\n    if (await supportsEIP7702(provider)) {\n        \u002F\u002F Single transaction: approve + swap\n        return executeBatchSwap(tokenIn, tokenOut, amount);\n    } else {\n        \u002F\u002F Legacy: two separate transactions\n        await approve(tokenIn, ROUTER, amount);\n        return swap(tokenIn, tokenOut, amount);\n    }\n}\n```\n\n### Step 4: Update Transaction Tracking\n\nBatch transactions contain multiple operations in a single tx hash. Update your transaction history UI to parse and display each sub-operation:\n\n```typescript\ninterface BatchOperation {\n    target: string;\n    method: string;\n    params: Record\u003Cstring, unknown>;\n    status: \"success\" | \"reverted\";\n}\n\n\u002F\u002F Parse batch operations from transaction receipt\nfunction parseBatchOps(receipt: TransactionReceipt): BatchOperation[] {\n    \u002F\u002F Decode logs and internal calls from the receipt\n    \u002F\u002F ...\n}\n```\n\n## Security Considerations\n\nEIP-7702 introduces new attack surfaces that developers must understand:\n\n### Delegation Target Verification\n\nThe delegation target contract has **full control** over the EOA's assets during the transaction. A malicious delegation target can:\n- Transfer all ETH and tokens from the EOA\n- Approve unlimited token allowances to attacker addresses\n- Interact with DeFi protocols to drain positions\n\n**Mitigation:** Only delegate to audited, verified contracts. Wallets should maintain an allowlist of trusted delegation targets.\n\n### Replay Protection\n\nEIP-7702 authorization lists include a nonce to prevent replay attacks. However, developers must ensure:\n- The authorization nonce matches the EOA's current nonce\n- Each authorization is used exactly once\n- Cross-chain replay is prevented by including the chain ID\n\n### Phishing via Delegation\n\nAttackers may trick users into signing authorization lists that delegate to malicious contracts. This is similar to the existing \"approve\" phishing problem but potentially more dangerous because delegation grants broader access.\n\n**Mitigation:** Wallets must clearly display what code the EOA is delegating to, with source verification and risk scoring.\n\n### Reentrancy in Batch Execution\n\nBatch executors that use `call` in a loop are vulnerable to reentrancy if one of the batch targets calls back into the executor. Use reentrancy guards or the checks-effects-interactions pattern:\n\n```solidity\n\u002F\u002F Use a reentrancy guard on the batch executor\nbool private locked;\n\nmodifier noReentrant() {\n    require(!locked, \"Reentrant\");\n    locked = true;\n    _;\n    locked = false;\n}\n\nfunction executeBatch(Call[] calldata calls) external payable noReentrant {\n    \u002F\u002F ...\n}\n```\n\n### Storage Collisions\n\nWhen an EOA delegates to a contract, the contract's code executes in the context of the EOA's storage. If two different delegation targets use the same storage slots for different purposes, data corruption can occur.\n\n**Mitigation:** Use EIP-7201 (namespaced storage) in all delegation targets:\n\n```solidity\n\u002F\u002F EIP-7201 namespaced storage\nbytes32 constant STORAGE_SLOT = keccak256(\n    abi.encode(uint256(keccak256(\"batch.executor.storage\")) - 1)\n) & ~bytes32(uint256(0xff));\n```\n\n## Frequently Asked Questions\n\n### Does EIP-7702 change my wallet address?\n\nNo. Your EOA address stays the same. EIP-7702 temporarily gives your address smart contract capabilities for the duration of a single transaction. After the transaction completes, your address returns to being a standard EOA.\n\n### Can I use EIP-7702 on L2s?\n\nYes. All major L2s (Arbitrum, Base, Optimism, zkSync) have adopted EIP-7702 as part of their Pectra-equivalent upgrades. The transaction format and delegation mechanics are identical.\n\n### What happens if the delegation target has a bug?\n\nThe damage is limited to the single transaction. Unlike a permanent smart contract wallet, EIP-7702 delegation expires after the transaction completes. However, within that transaction, the delegation target has full access to the EOA's assets — a bug could drain the account.\n\n### Is EIP-7702 compatible with hardware wallets?\n\nYes. Hardware wallets (Ledger, Trezor) can sign type-4 transactions, including the authorization list. Ledger added support in firmware version 2.3.0 (December 2025). The user confirms the delegation target on the hardware device screen.\n\n### How much gas does EIP-7702 save?\n\nFor a typical approve+swap flow, EIP-7702 saves approximately **40-50%** on gas by eliminating the second transaction overhead (21,000 base gas) and enabling more efficient calldata encoding. For complex multi-step DeFi operations (e.g., zap into a vault), savings can reach 60-70%.","\u003Ch2 id=\"what-eip-7702-enables\">What EIP-7702 Enables\u003C\u002Fh2>\n\u003Cp>EIP-7702, activated with Ethereum’s Pectra upgrade in March 2025, introduces a new transaction type that allows any Externally Owned Account (EOA) to set a \u003Cstrong>delegation designator\u003C\u002Fstrong> — a pointer to a smart contract whose code the EOA temporarily adopts for the duration of a transaction. This means your existing MetaMask wallet address can execute arbitrary smart contract logic (batch calls, custom validation, gas sponsorship) without deploying a new contract wallet or changing your address.\u003C\u002Fp>\n\u003Cp>This is the most significant UX improvement in Ethereum’s history. Users no longer need to choose between the simplicity of an EOA and the power of a smart account.\u003C\u002Fp>\n\u003Ch2 id=\"eip-7702-vs-erc-4337-when-to-use-which\">EIP-7702 vs ERC-4337: When to Use Which\u003C\u002Fh2>\n\u003Cp>Both EIP-7702 and ERC-4337 enable account abstraction, but they operate at different levels and suit different use cases:\u003C\u002Fp>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C\u002Fth>\u003Cth>EIP-7702\u003C\u002Fth>\u003Cth>ERC-4337\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Level\u003C\u002Ftd>\u003Ctd>Protocol (new tx type)\u003C\u002Ftd>\u003Ctd>Application (smart contract)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Account type\u003C\u002Ftd>\u003Ctd>Upgrades existing EOAs\u003C\u002Ftd>\u003Ctd>Requires new smart contract wallet\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Address\u003C\u002Ftd>\u003Ctd>Keeps existing EOA address\u003C\u002Ftd>\u003Ctd>New address (counterfactual)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Persistence\u003C\u002Ftd>\u003Ctd>Per-transaction delegation\u003C\u002Ftd>\u003Ctd>Permanent smart contract\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Bundler required\u003C\u002Ftd>\u003Ctd>No (standard tx flow)\u003C\u002Ftd>\u003Ctd>Yes (separate mempool)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Gas overhead\u003C\u002Ftd>\u003Ctd>~20,000 gas for delegation\u003C\u002Ftd>\u003Ctd>~42,000 gas for UserOp validation\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Supported wallets\u003C\u002Ftd>\u003Ctd>MetaMask, Coinbase Wallet, Rainbow\u003C\u002Ftd>\u003Ctd>Specialized (Safe, ZeroDev, Biconomy)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Best for\u003C\u002Ftd>\u003Ctd>Upgrading existing users\u003C\u002Ftd>\u003Ctd>New users, complex account logic\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch3>Decision Framework\u003C\u002Fh3>\n\u003Cp>\u003Cstrong>Use EIP-7702 when:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Your users already have EOA wallets (MetaMask, Coinbase Wallet)\u003C\u002Fli>\n\u003Cli>You need batch transactions or gas sponsorship\u003C\u002Fli>\n\u003Cli>You want minimal integration complexity\u003C\u002Fli>\n\u003Cli>The smart account logic is per-transaction (not permanent)\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Use ERC-4337 when:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>You are building a new wallet or onboarding new users\u003C\u002Fli>\n\u003Cli>You need persistent account logic (permanent multisig, complex recovery)\u003C\u002Fli>\n\u003Cli>You want the account to be a smart contract by default\u003C\u002Fli>\n\u003Cli>You need advanced features like account modules, plugins, or guardians\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Use both together when:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>You want ERC-4337 smart accounts that can also process EIP-7702 delegations from EOAs (for backward compatibility)\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"code-examples\">Code Examples\u003C\u002Fh2>\n\u003Ch3>Batch Transactions\u003C\u002Fh3>\n\u003Cp>The most common EIP-7702 use case: execute multiple operations in a single transaction. No more “approve then swap” two-step flows.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\n\u002F\u002F\u002F @title BatchExecutor — EIP-7702 delegation target for batch calls\n\u002F\u002F\u002F @notice EOAs delegate to this contract to execute multiple calls atomically\ncontract BatchExecutor {\n    struct Call {\n        address target;\n        uint256 value;\n        bytes data;\n    }\n    \n    \u002F\u002F\u002F @notice Execute a batch of calls from the delegating EOA\n    \u002F\u002F\u002F @dev When called via EIP-7702, msg.sender is the EOA itself\n    \u002F\u002F\u002F @param calls Array of calls to execute\n    function executeBatch(Call[] calldata calls) external payable {\n        for (uint256 i = 0; i &lt; calls.length; i++) {\n            (bool success, bytes memory result) = calls[i].target.call{\n                value: calls[i].value\n            }(calls[i].data);\n            \n            if (!success) {\n                \u002F\u002F Bubble up the revert reason\n                assembly {\n                    revert(add(result, 32), mload(result))\n                }\n            }\n        }\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Client-side usage with ethers.js v6:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">import { ethers } from \"ethers\";\n\n\u002F\u002F EIP-7702 transaction type (type: 4)\nconst batchTx = {\n    type: 4,\n    to: userAddress, \u002F\u002F EOA delegates to itself\n    authorizationList: [{\n        chainId: 1,\n        address: BATCH_EXECUTOR_ADDRESS, \u002F\u002F delegation target\n        nonce: await provider.getTransactionCount(userAddress),\n        \u002F\u002F Signed by the EOA owner:\n        yParity: 0, r: \"0x...\", s: \"0x...\"\n    }],\n    data: batchExecutorInterface.encodeFunctionData(\"executeBatch\", [[\n        {\n            target: USDC_ADDRESS,\n            value: 0,\n            data: usdcInterface.encodeFunctionData(\"approve\", [\n                UNISWAP_ROUTER, ethers.parseUnits(\"1000\", 6)\n            ])\n        },\n        {\n            target: UNISWAP_ROUTER,\n            value: 0,\n            data: routerInterface.encodeFunctionData(\"exactInputSingle\", [{\n                tokenIn: USDC_ADDRESS,\n                tokenOut: WETH_ADDRESS,\n                fee: 3000,\n                recipient: userAddress,\n                amountIn: ethers.parseUnits(\"1000\", 6),\n                amountOutMinimum: 0,\n                sqrtPriceLimitX96: 0\n            }])\n        }\n    ]])\n};\n\nconst tx = await signer.sendTransaction(batchTx);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Gas Sponsorship\u003C\u002Fh3>\n\u003Cp>With EIP-7702, a paymaster can sponsor gas for any EOA transaction by submitting the transaction on the user’s behalf while the user’s authorization list delegates execution:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F\u002F @title SponsoredExecutor — gas sponsorship via EIP-7702\ncontract SponsoredExecutor {\n    mapping(address =&gt; uint256) public nonces;\n    \n    \u002F\u002F\u002F @notice Execute a call on behalf of a user, gas paid by msg.sender\n    \u002F\u002F\u002F @param user The EOA that signed the authorization\n    \u002F\u002F\u002F @param target The contract to call\n    \u002F\u002F\u002F @param data The calldata\n    \u002F\u002F\u002F @param userNonce Replay protection nonce\n    \u002F\u002F\u002F @param deadline Expiration timestamp\n    \u002F\u002F\u002F @param signature User's EIP-712 signature over the above params\n    function sponsoredExecute(\n        address user,\n        address target,\n        bytes calldata data,\n        uint256 userNonce,\n        uint256 deadline,\n        bytes calldata signature\n    ) external {\n        require(block.timestamp &lt;= deadline, \"Expired\");\n        require(nonces[user] == userNonce, \"Invalid nonce\");\n        nonces[user]++;\n        \n        \u002F\u002F Verify user's signature (EIP-712)\n        bytes32 digest = _hashTypedData(user, target, data, userNonce, deadline);\n        address signer = ECDSA.recover(digest, signature);\n        require(signer == user, \"Invalid signature\");\n        \n        \u002F\u002F Execute the call as the user (via delegatecall in EIP-7702 context)\n        (bool success, bytes memory result) = target.call(data);\n        require(success, \"Call failed\");\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The paymaster submits the type-4 transaction, paying gas. The user signs only an EIP-712 message approving the specific action — no ETH needed in their wallet.\u003C\u002Fp>\n\u003Ch3>Social Recovery\u003C\u002Fh3>\n\u003Cp>EIP-7702 enables social recovery patterns without requiring a permanent smart contract wallet:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F\u002F @title RecoveryModule — social recovery via EIP-7702\ncontract RecoveryModule {\n    struct RecoveryConfig {\n        address[] guardians;\n        uint256 threshold;\n        uint256 delay;\n    }\n    \n    mapping(address =&gt; RecoveryConfig) public configs;\n    mapping(bytes32 =&gt; uint256) public recoveryTimestamps;\n    mapping(bytes32 =&gt; uint256) public approvalCounts;\n    mapping(bytes32 =&gt; mapping(address =&gt; bool)) public hasApproved;\n    \n    \u002F\u002F\u002F @notice Register recovery guardians (called by the EOA via EIP-7702)\n    function setupRecovery(\n        address[] calldata guardians,\n        uint256 threshold,\n        uint256 delay\n    ) external {\n        require(guardians.length &gt;= threshold, \"Invalid threshold\");\n        require(threshold &gt;= 2, \"Min 2 guardians\");\n        configs[msg.sender] = RecoveryConfig(guardians, threshold, delay);\n    }\n    \n    \u002F\u002F\u002F @notice Guardian approves a recovery request\n    function approveRecovery(\n        address account,\n        address newOwner\n    ) external {\n        RecoveryConfig memory config = configs[account];\n        require(_isGuardian(config, msg.sender), \"Not a guardian\");\n        \n        bytes32 recoveryId = keccak256(abi.encode(account, newOwner));\n        require(!hasApproved[recoveryId][msg.sender], \"Already approved\");\n        \n        hasApproved[recoveryId][msg.sender] = true;\n        approvalCounts[recoveryId]++;\n        \n        if (approvalCounts[recoveryId] &gt;= config.threshold) {\n            recoveryTimestamps[recoveryId] = block.timestamp + config.delay;\n        }\n    }\n    \n    \u002F\u002F\u002F @notice Execute recovery after delay period\n    function executeRecovery(\n        address account,\n        address newOwner\n    ) external {\n        bytes32 recoveryId = keccak256(abi.encode(account, newOwner));\n        uint256 timestamp = recoveryTimestamps[recoveryId];\n        require(timestamp &gt; 0 &amp;&amp; block.timestamp &gt;= timestamp, \"Not ready\");\n        \n        \u002F\u002F Transfer control by updating the account's delegation target\n        \u002F\u002F to a contract controlled by newOwner\n        \u002F\u002F Implementation depends on the specific wallet architecture\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"wallet-integration-status\">Wallet Integration Status\u003C\u002Fh2>\n\u003Cp>As of March 2026, EIP-7702 support has rolled out across major wallets:\u003C\u002Fp>\n\u003Ch3>MetaMask\u003C\u002Fh3>\n\u003Cp>MetaMask added EIP-7702 support in version 12.4 (September 2025). Users see a “Smart Transaction” badge when a dApp requests a type-4 transaction. The wallet shows:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>The delegation target contract (with verified source on Etherscan)\u003C\u002Fli>\n\u003Cli>Each call in the batch with decoded parameters\u003C\u002Fli>\n\u003Cli>Estimated gas savings vs separate transactions\u003C\u002Fli>\n\u003Cli>A warning if the delegation target is unverified\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Coinbase Wallet\u003C\u002Fh3>\n\u003Cp>Coinbase Wallet has been the most aggressive adopter, integrating EIP-7702 into its “Smart Wallet” feature (launched November 2025). Key features:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Auto-batching\u003C\u002Fstrong> — the wallet automatically batches approve+swap sequences\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Gas sponsorship\u003C\u002Fstrong> — Coinbase sponsors gas for transactions under $1 in fee\u003C\u002Fli>\n\u003Cli>\u003Cstrong>One-click DeFi\u003C\u002Fstrong> — pre-built delegation targets for common DeFi operations\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Rainbow, Rabby, and Others\u003C\u002Fh3>\n\u003Cp>Rainbow added support in January 2026. Rabby supports type-4 transactions but lacks the batch visualization UI. Frame (the desktop wallet) was among the first to support EIP-7702, shipping support in April 2025.\u003C\u002Fp>\n\u003Ch2 id=\"migration-guide-from-eoa-to-smart-accounts\">Migration Guide: From EOA to Smart Accounts\u003C\u002Fh2>\n\u003Cp>For dApp developers, here is the recommended migration path to support EIP-7702:\u003C\u002Fp>\n\u003Ch3>Step 1: Deploy Delegation Targets\u003C\u002Fh3>\n\u003Cp>Create and audit the smart contracts your users will delegate to. Common patterns:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>BatchExecutor       — multi-call batching\nSessionKeyManager   — time-limited permissions\nSpendingLimiter     — daily\u002Fweekly spending caps\nRecoveryModule      — social recovery setup\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Step 2: Update Your Frontend\u003C\u002Fh3>\n\u003Cp>Detect whether the connected wallet supports EIP-7702:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">async function supportsEIP7702(provider: ethers.Provider): Promise&lt;boolean&gt; {\n    try {\n        \u002F\u002F Check if the node supports type-4 transactions\n        const capabilities = await provider.send(\n            \"wallet_getCapabilities\", []\n        );\n        return capabilities?.atomicBatch?.supported === true;\n    } catch {\n        return false;\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Step 3: Implement Graceful Degradation\u003C\u002Fh3>\n\u003Cp>Not all users will have EIP-7702-capable wallets. Your dApp should detect capabilities and fall back:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">async function executeSwap(tokenIn, tokenOut, amount) {\n    if (await supportsEIP7702(provider)) {\n        \u002F\u002F Single transaction: approve + swap\n        return executeBatchSwap(tokenIn, tokenOut, amount);\n    } else {\n        \u002F\u002F Legacy: two separate transactions\n        await approve(tokenIn, ROUTER, amount);\n        return swap(tokenIn, tokenOut, amount);\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Step 4: Update Transaction Tracking\u003C\u002Fh3>\n\u003Cp>Batch transactions contain multiple operations in a single tx hash. Update your transaction history UI to parse and display each sub-operation:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">interface BatchOperation {\n    target: string;\n    method: string;\n    params: Record&lt;string, unknown&gt;;\n    status: \"success\" | \"reverted\";\n}\n\n\u002F\u002F Parse batch operations from transaction receipt\nfunction parseBatchOps(receipt: TransactionReceipt): BatchOperation[] {\n    \u002F\u002F Decode logs and internal calls from the receipt\n    \u002F\u002F ...\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"security-considerations\">Security Considerations\u003C\u002Fh2>\n\u003Cp>EIP-7702 introduces new attack surfaces that developers must understand:\u003C\u002Fp>\n\u003Ch3>Delegation Target Verification\u003C\u002Fh3>\n\u003Cp>The delegation target contract has \u003Cstrong>full control\u003C\u002Fstrong> over the EOA’s assets during the transaction. A malicious delegation target can:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Transfer all ETH and tokens from the EOA\u003C\u002Fli>\n\u003Cli>Approve unlimited token allowances to attacker addresses\u003C\u002Fli>\n\u003Cli>Interact with DeFi protocols to drain positions\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Mitigation:\u003C\u002Fstrong> Only delegate to audited, verified contracts. Wallets should maintain an allowlist of trusted delegation targets.\u003C\u002Fp>\n\u003Ch3>Replay Protection\u003C\u002Fh3>\n\u003Cp>EIP-7702 authorization lists include a nonce to prevent replay attacks. However, developers must ensure:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>The authorization nonce matches the EOA’s current nonce\u003C\u002Fli>\n\u003Cli>Each authorization is used exactly once\u003C\u002Fli>\n\u003Cli>Cross-chain replay is prevented by including the chain ID\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Phishing via Delegation\u003C\u002Fh3>\n\u003Cp>Attackers may trick users into signing authorization lists that delegate to malicious contracts. This is similar to the existing “approve” phishing problem but potentially more dangerous because delegation grants broader access.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Mitigation:\u003C\u002Fstrong> Wallets must clearly display what code the EOA is delegating to, with source verification and risk scoring.\u003C\u002Fp>\n\u003Ch3>Reentrancy in Batch Execution\u003C\u002Fh3>\n\u003Cp>Batch executors that use \u003Ccode>call\u003C\u002Fcode> in a loop are vulnerable to reentrancy if one of the batch targets calls back into the executor. Use reentrancy guards or the checks-effects-interactions pattern:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F Use a reentrancy guard on the batch executor\nbool private locked;\n\nmodifier noReentrant() {\n    require(!locked, \"Reentrant\");\n    locked = true;\n    _;\n    locked = false;\n}\n\nfunction executeBatch(Call[] calldata calls) external payable noReentrant {\n    \u002F\u002F ...\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Storage Collisions\u003C\u002Fh3>\n\u003Cp>When an EOA delegates to a contract, the contract’s code executes in the context of the EOA’s storage. If two different delegation targets use the same storage slots for different purposes, data corruption can occur.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Mitigation:\u003C\u002Fstrong> Use EIP-7201 (namespaced storage) in all delegation targets:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F EIP-7201 namespaced storage\nbytes32 constant STORAGE_SLOT = keccak256(\n    abi.encode(uint256(keccak256(\"batch.executor.storage\")) - 1)\n) &amp; ~bytes32(uint256(0xff));\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"frequently-asked-questions\">Frequently Asked Questions\u003C\u002Fh2>\n\u003Ch3 id=\"does-eip-7702-change-my-wallet-address\">Does EIP-7702 change my wallet address?\u003C\u002Fh3>\n\u003Cp>No. Your EOA address stays the same. EIP-7702 temporarily gives your address smart contract capabilities for the duration of a single transaction. After the transaction completes, your address returns to being a standard EOA.\u003C\u002Fp>\n\u003Ch3 id=\"can-i-use-eip-7702-on-l2s\">Can I use EIP-7702 on L2s?\u003C\u002Fh3>\n\u003Cp>Yes. All major L2s (Arbitrum, Base, Optimism, zkSync) have adopted EIP-7702 as part of their Pectra-equivalent upgrades. The transaction format and delegation mechanics are identical.\u003C\u002Fp>\n\u003Ch3 id=\"what-happens-if-the-delegation-target-has-a-bug\">What happens if the delegation target has a bug?\u003C\u002Fh3>\n\u003Cp>The damage is limited to the single transaction. Unlike a permanent smart contract wallet, EIP-7702 delegation expires after the transaction completes. However, within that transaction, the delegation target has full access to the EOA’s assets — a bug could drain the account.\u003C\u002Fp>\n\u003Ch3 id=\"is-eip-7702-compatible-with-hardware-wallets\">Is EIP-7702 compatible with hardware wallets?\u003C\u002Fh3>\n\u003Cp>Yes. Hardware wallets (Ledger, Trezor) can sign type-4 transactions, including the authorization list. Ledger added support in firmware version 2.3.0 (December 2025). The user confirms the delegation target on the hardware device screen.\u003C\u002Fp>\n\u003Ch3 id=\"how-much-gas-does-eip-7702-save\">How much gas does EIP-7702 save?\u003C\u002Fh3>\n\u003Cp>For a typical approve+swap flow, EIP-7702 saves approximately \u003Cstrong>40-50%\u003C\u002Fstrong> on gas by eliminating the second transaction overhead (21,000 base gas) and enabling more efficient calldata encoding. For complex multi-step DeFi operations (e.g., zap into a vault), savings can reach 60-70%.\u003C\u002Fp>\n","en","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:35.031290Z","Learn how to implement EIP-7702 batch transactions, gas sponsorship, and social recovery. Code examples, wallet support, and security guide.","EIP-7702",null,"index, follow",[21,26,30],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000013","Security","security","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000014","Solidity","solidity",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000009","Web3","web3","Blockchain",[36,43,49],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":41,"published_at":42},"d0200000-0000-0000-0000-000000000003","Why Bali Is Becoming Southeast Asia's Impact-Tech Hub in 2026","why-bali-becoming-southeast-asia-impact-tech-hub-2026","Bali ranks #16 among Southeast Asian startup ecosystems. With a growing concentration of Web3 builders, AI sustainability startups, and eco-travel tech companies, the island is carving a niche as the region's impact-tech capital.","Engineering","2026-03-28T10:44:37.748283Z",{"id":44,"title":45,"slug":46,"excerpt":47,"locale":12,"category_name":41,"published_at":48},"d0200000-0000-0000-0000-000000000002","ASEAN Data Protection Patchwork: A Developer's Compliance Checklist","asean-data-protection-patchwork-developer-compliance-checklist","Seven ASEAN countries now have comprehensive data protection laws, each with different consent models, localization requirements, and penalty structures. Here is a practical compliance checklist for developers building multi-country applications.","2026-03-28T10:44:37.374741Z",{"id":50,"title":51,"slug":52,"excerpt":53,"locale":12,"category_name":41,"published_at":54},"d0200000-0000-0000-0000-000000000001","Indonesia's $29 Billion Digital Transformation: Opportunities for Software Companies","indonesia-29-billion-digital-transformation-opportunities-software-companies","Indonesia's IT services market is projected to reach $29.03 billion in 2026, up from $24.37 billion in 2025. Cloud infrastructure, AI, e-commerce, and data centers are driving the fastest growth in Southeast Asia.","2026-03-28T10:44:37.349311Z",{"id":13,"name":56,"slug":57,"bio":58,"photo_url":18,"linkedin":18,"role":59,"created_at":60,"updated_at":60},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]