Guide for App Developers: Leveraging EIP-7702 Enabled Wallets in Your dApp

Joan Alavedra7 min read
Guide for App Developers: Leveraging EIP-7702 Enabled Wallets in Your dApp

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

  1. Detecting EIP-7702 Support
  2. Integrating with EIP-5792 for Wallet Interactions
  3. Implementing Transaction Batching with EIP-7821
  4. Managing Permissions with EIP-7715
  5. 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.


    _10
    async function check7702Support(provider) {
    _10
    try {
    _10
    const capabilities = await provider.request({ method: 'wallet_getCapabilities' });
    _10
    return capabilities.includes('eip7702');
    _10
    } catch (error) {
    _10
    console.error('Error checking EIP-7702 support:', error);
    _10
    return false;
    _10
    }
    _10
    }

  • On-Chain Verification (Alternative): Check for temporary smart contract code, though less reliable due to delegation’s transient nature.


    _10
    function is7702Enabled(address eoa) public view returns (bool) {
    _10
    return 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

  1. Study the EIP-5792 specification for method details.
  2. Update wallet connection logic (e.g., ethers.js, Web3.js) to support these methods.
  3. Handle responses and errors gracefully.

Example: Sending a Batch


_13
async 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


_10
event 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

  1. Prepare Transactions: Create an array of transaction objects with to (target address) and data (encoded function call).
  2. Send the Batch: Use EIP-5792’s wallet_sendCalls to execute the batch.
  3. Parse CallOperation Events: Monitor transaction logs for CallOperation events to verify each call’s outcome and update your UI.

Example Code


_22
const transactions = [
_22
{ to: tokenAddress, data: approveData }, // Approve token
_22
{ to: swapAddress, data: swapData } // Perform swap
_22
];
_22
_22
async 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)


_11
interface 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


_25
async 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:


_10
struct Transfer {
_10
address from;
_10
address to;
_10
uint256 value;
_10
}
_10
_10
function 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


_21
async 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:

Share this article

Keep Reading