
EIP-7702 enables Externally Owned Accounts (EOAs) to temporarily delegate authority to smart contracts, unlocking smart account features like transaction batching, gas sponsorship, and session keys without permanent changes to the account.
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_getCapabilities
method 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
CallOperation
event 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_sendCalls
to execute the batch. - Parse CallOperation Events:
Monitor transaction logs for
CallOperation
events 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
getPermissions
method, 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
CallOperation
events 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.