
EIP-7702 is an Ethereum upgrade that allows EOAs to temporarily act as smart accounts. This guide provides a roadmap for app developers to leverage these new capabilities, focusing on detection, batching, and permissions.
What is EIP-7702 for Developers?
For developers, EIP-7702 is a "superpower" for standard wallets. It allows a dApp to request that a user’s EOA temporarily delegate its authority to a smart contract to execute advanced operations. This unlocks "native" support for features that previously required a dedicated smart account, such as batching multiple calls in a single transaction (EIP-7821), managing granular permission trees (EIP-7715), and requesting gas sponsorship via EIP-5792.
This guide provides a concise, actionable roadmap for integrating EIP-7702 enabled wallets into your decentralized application (dApp), focusing on detecting support, wallet interactions, transaction batching (with EIP-7821), permissions (with EIP-7715), and transaction history.
Table of Contents
- Detecting EIP-7702 Support
- Integrating with EIP-5792 for Wallet Interactions
- Implementing Transaction Batching with EIP-7821
- Managing Permissions with EIP-7715
- Enhancing Transaction History
Detecting EIP-7702 Support
Before enabling EIP-7702 features, your dApp must confirm that the connected wallet supports this proposal to ensure compatibility and a seamless user experience.
Methods to Detect Support
-
Wallet Capabilities Check (Recommended): Use the
wallet_getCapabilitiesmethod from EIP-5792 to query wallet features securely._10async function check7702Support(provider) {_10try {_10const capabilities = await provider.request({ method: 'wallet_getCapabilities' });_10return capabilities.includes('eip7702');_10} catch (error) {_10console.error('Error checking EIP-7702 support:', error);_10return false;_10}_10} -
On-Chain Verification (Alternative): Check for temporary smart contract code, though less reliable due to delegation’s transient nature.
_10function is7702Enabled(address eoa) public view returns (bool) {_10return eoa.code.length > 0 && eoa.code[0] == 0xEF; // EIP-7702 marker_10}
Implementation Tip
Use the capabilities check to dynamically enable EIP-7702 features in your frontend, falling back to standard flows for unsupported wallets.
Integrating with EIP-5792 for Wallet Interactions
EIP-5792 provides JSON-RPC methods for dApps to interact with wallets, serving as the primary interface for accessing EIP-7702 features like batching and gas sponsorship.
Key Methods
wallet_sendCalls: Sends batched transactions.wallet_getCapabilities: Queries supported features.wallet_sponsorTransaction: Requests gas sponsorship.
Steps to Integrate
- Study the EIP-5792 specification for method details.
- Update wallet connection logic (e.g., ethers.js, Web3.js) to support these methods.
- Handle responses and errors gracefully.
Example: Sending a Batch
_13async function sendBatchedTransactions(provider, transactions) {_13 try {_13 const result = await provider.request({_13 method: 'wallet_sendCalls',_13 params: [{ calls: transactions }]_13 });_13 console.log('Batch sent:', result);_13 return result;_13 } catch (error) {_13 console.error('Error sending batch:', error);_13 throw error;_13 }_13}
Next Steps
Check wallet provider documentation (e.g., Openfort) for EIP-5792 implementation specifics.
Implementing Transaction Batching with EIP-7821
Transaction batching, enabled by EIP-7702, allows multiple actions (e.g., token approval and swap) to be executed in a single transaction, reducing user signatures and improving UX. EIP-7821 complements this by introducing a standard for Call Operation Events, enabling wallets to emit structured events for batched calls, which simplifies tracking and verification.
How It Works
- EIP-7702: The wallet delegates execution to a smart contract, which processes multiple calls in one transaction.
- EIP-7821: Defines a
CallOperationevent emitted for each call in a batch, allowing dApps to parse and display individual operations (e.g., on block explorers or transaction histories).
EIP-7821 Event
_10event CallOperation(_10 address indexed caller,_10 address indexed target,_10 bytes4 selector,_10 uint256 value,_10 bytes data,_10 bool success,_10 bytes returnData_10);
Steps to Implement
- Prepare Transactions:
Create an array of transaction objects with
to(target address) anddata(encoded function call). - Send the Batch:
Use EIP-5792’s
wallet_sendCallsto execute the batch. - Parse CallOperation Events:
Monitor transaction logs for
CallOperationevents to verify each call’s outcome and update your UI.
Example Code
_22const transactions = [_22 { to: tokenAddress, data: approveData }, // Approve token_22 { to: swapAddress, data: swapData } // Perform swap_22];_22_22async function sendAndTrackBatch(provider, transactions) {_22 const tx = await sendBatchedTransactions(provider, transactions);_22 const receipt = await provider.getTransactionReceipt(tx.transactionHash);_22_22 // Parse CallOperation events_22 const callEventABI = [_22 "event CallOperation(address indexed caller, address indexed target, bytes4 selector, uint256 value, bytes data, bool success, bytes returnData)"_22 ];_22 const iface = new ethers.utils.Interface(callEventABI);_22 receipt juice.forEach(log => {_22 try {_22 const event = iface.parseLog(log);_22 console.log(`Call to ${event.args.target} ${event.args.success ? 'succeeded' : 'failed'}`);_22 } catch (e) {}_22 });_22 return receipt;_22}
Benefits
- EIP-7702: Fewer signatures, streamlined UX.
- EIP-7821: Transparent tracking of batched calls, improving auditability and user trust.
UI Tip
Display batched transactions as a single action (e.g., “Approve + Swap”) with expandable details derived from CallOperation events.
Managing Permissions with EIP-7715
EIP-7702 enables temporary delegations, such as session keys, for restricted actions. EIP-7715 (Permission Tree) complements this by providing a standard for wallets to manage and expose granular permissions, allowing dApps to request specific capabilities (e.g., limited token transfers) without full account control.
Understanding EIP-7715
- Defines a Permission Tree, a structured format for wallets to represent permissions (e.g., allowed functions, contracts, or time limits).
- Enables dApps to query permissions via a
getPermissionsmethod, ensuring compatibility with wallet-managed restrictions.
Key Interface (EIP-7715)
_11interface IPermissionTree {_11 function getPermissions(address account) external view returns (Permission[] memory);_11_11 struct Permission {_11 address target; // Contract address_11 bytes4 selector; // Function selector_11 uint256 valueLimit; // Max ETH value_11 uint256 expiration; // Permission expiry_11 bytes extraData; // Additional constraints_11 }_11}
Requesting Permissions
Use EIP-5792 or wallet-specific methods to request permissions, then query the wallet’s Permission Tree to verify granted capabilities.
Example Code
_25async function requestAndVerifyPermissions(provider, requestedPermissions) {_25 try {_25 // Request permissions (wallet-specific or future EIP-5792 extension)_25 await provider.request({_25 method: 'wallet_requestPermissions',_25 params: [{_25 target: tokenAddress,_25 selector: '0xa9059cbb', // transfer(address,uint256)_25 valueLimit: 0,_25 expiration: Math.floor(Date.now() / 1000) + 3600_25 }]_25 });_25_25 // Query Permission Tree_25 const permissionTreeContract = new ethers.Contract(permissionTreeAddress, [_25 'function getPermissions(address account) view returns (tuple(address target, bytes4 selector, uint256 valueLimit, uint256 expiration, bytes extraData)[])'_25 ], provider);_25 const permissions = await permissionTreeContract.getPermissions(await provider.getSigner().getAddress());_25 console.log('Granted permissions:', permissions);_25 return permissions;_25 } catch (error) {_25 console.error('Error managing permissions:', error);_25 throw error;_25 }_25}
Note
EIP-7715 adoption may vary; ensure fallback logic for wallets without Permission Tree support.
Enhancing Transaction History
EIP-7702’s batched transactions require tailored handling to display meaningful history, especially with EIP-7821’s event logs.
Fetching On-Chain Data
Fetch ETH transfers directly to avoid third-party APIs:
_10struct Transfer {_10 address from;_10 address to;_10 uint256 value;_10}_10_10function getEthTransfers(address account) public view returns (Transfer[] memory) {_10 // Parse logs or traces (implementation-specific)_10}
Handling Batched Transactions
- Use EIP-7821’s
CallOperationevents to extract individual actions from a batch. - Display batches as a single entry with expandable details.
Example Code
_21async function displayTransactionHistory(provider, txHash) {_21 const receipt = await provider.getTransactionReceipt(txHash);_21 const callEventABI = [_21 "event CallOperation(address indexed caller, address indexed target, bytes4 selector, uint256 value, bytes data, bool success, bytes returnData)"_21 ];_21 const iface = new ethers.utils.Interface(callEventABI);_21 const actions = receipt.logs.map(log => {_21 try {_21 const event = iface.parseLog(log);_21 return {_21 target: event.args.target,_21 success: event.args.success,_21 action: event.args.selector_21 };_21 } catch (e) {_21 return null;_21 }_21 }).filter(action => action);_21 console.log('Batch actions:', actions);_21 // Update UI with actions_21}
Conclusion
This guide equips you to integrate EIP-7702 enabled wallets by:
- Detecting support to ensure compatibility.
- Using EIP-5792 for seamless wallet interactions.
- Implementing transaction batching with EIP-7821 for auditable, streamlined UX.
- Managing permissions with EIP-7715 for secure, granular control.
- Enhancing transaction history with on-chain data and event parsing.
Related reading: