This example demonstrates how to deposit funds into a DeFi yield strategy using the Deframe API and EIP-7702. Instead of sending each transaction individually, EIP-7702 collapses the entire sequence into a single atomic operation executed directly from your EOA — no smart-contract wallet or contract deployment required.
Overview
This example covers:
- Fetching available strategies
- Getting strategy details
- Generating transaction bytecode
- Batching and executing via EIP-7702
- Verifying the deposit
Prerequisites
- Node.js 18+
- Deframe API key
- Ethereum wallet with USDC balance
- Basic understanding of async/await
Installation
Environment Variables
Create a .env file:
DEFRAME_API_KEY=your-api-key
PRIVATE_KEY=0x...
VITE_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/your-key
Never commit your .env file to version control. Add it to .gitignore.
Step-by-Step Walkthrough
1. Initialize API Client
import axios from 'axios'
const deframe = axios.create({
baseURL: 'https://api.deframe.io',
headers: {
'x-api-key': process.env.DEFRAME_API_KEY,
'Content-Type': 'application/json'
}
})
2. Fetch Available Strategies
const { data: strategies } = await deframe.get('/strategies', {
params: { page: '1', limit: '10' }
})
console.log('Available strategies:')
strategies.data.forEach(strategy => {
console.log(`- ${strategy.id} (${strategy.protocol})`)
console.log(` APY: ${(strategy.apy * 100).toFixed(2)}%`)
})
3. Get Strategy Details
const strategyId = 'aave-usdc-polygon'
const { data: strategy } = await deframe.get(`/strategies/${strategyId}`)
console.log('Strategy:', strategy.id)
console.log('Protocol:', strategy.protocol)
console.log('Network:', strategy.network)
console.log('Asset:', strategy.assetName)
console.log('APY:', (strategy.apy * 100).toFixed(2) + '%')
console.log('Status:', strategy.paused ? 'Paused' : 'Active')
4. Generate Bytecode
The amount parameter is in the token’s base units (e.g. 6 decimals for USDC: 1000000000 = 1000 USDC).
const { data: result } = await deframe.get('/strategies/aave-usdc-polygon/bytecode', {
params: {
action: 'lend',
amount: '1000000000',
wallet: walletAddress
}
})
console.log('Transactions to execute:', result.bytecode.length)
5. Execute Transactions
The standard approach sends each transaction in a loop. With EIP-7702 you encode the entire
result.bytecode array into one executeBatch call and send it as a single type-4 transaction.
All steps succeed or all revert — no partial failures.
import { http, encodeFunctionData, createWalletClient, publicActions } from 'viem'
import { mainnet } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'
const SIMPLE_7702_ACCOUNT_ADDRESS = '0x4Cd241E8d1510e30b2076397afc7508Ae59C66c9'
const EIP7702AccountAbi = [
{ name: 'executeBatch', type: 'function', stateMutability: 'nonpayable',
inputs: [{ name: 'calls', type: 'tuple[]', components: [
{ name: 'target', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'data', type: 'bytes' }
]}], outputs: [] }
]
const account = privateKeyToAccount(process.env.PRIVATE_KEY)
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http(process.env.VITE_RPC_URL)
}).extend(publicActions)
const walletAddress = account.address
// Map Deframe bytecode → executeBatch tuple format: [target, value, data]
const calls = result.bytecode.map(tx => [
tx.to,
BigInt(tx.value ?? '0'),
tx.data
])
// Encode all calls into a single executeBatch calldata
const calldata = encodeFunctionData({
abi: EIP7702AccountAbi,
functionName: 'executeBatch',
args: [calls]
})
// Sign EIP-7702 authorization — temporarily delegates your EOA to Simple7702Account
const authorization = await walletClient.signAuthorization({
contractAddress: SIMPLE_7702_ACCOUNT_ADDRESS,
executor: 'self'
})
// Send one type-4 transaction containing all the calls
const hash = await walletClient.sendTransaction({
to: walletAddress,
data: calldata,
authorizationList: [authorization]
})
console.log('Transaction sent:', hash)
const receipt = await walletClient.waitForTransactionReceipt({ hash })
console.log('Confirmed in block:', receipt.blockNumber)
6. Verify Deposit
// Wait for indexing
await new Promise(resolve => setTimeout(resolve, 5000))
const { data: walletData } = await deframe.get(`/wallets/${walletAddress}`)
console.log('Wallet positions:')
walletData.positions.forEach(position => {
console.log(`${position.strategy.id}:`)
console.log(` Balance: ${position.spotPosition.currentPosition.humanized} ${position.spotPosition.currentPosition.symbol}`)
console.log(` Value: $${position.spotPosition.underlyingBalanceUSD}`)
console.log(` APY: ${(position.spotPosition.apy * 100).toFixed(2)}%`)
})
console.log('Total portfolio value: $' + walletData.summary.totalUnderlyingBalanceUSD)
Error Handling
The example includes comprehensive error handling for both Deframe API errors and EIP-7702 wallet errors:
try {
// Your code here
} catch (error) {
if (error.response?.data?.error) {
const apiError = error.response.data.error
console.error('API Error:', apiError.code)
console.error('Message:', apiError.message)
if (apiError.code === 'STRATEGY_NOT_FOUND') {
console.log('Strategy does not exist or is not available')
} else if (apiError.code === 'INSUFFICIENT_BALANCE') {
console.log('Wallet does not have enough tokens')
}
} else if (error?.code === 4001 || error?.message?.toLowerCase().includes('user rejected')) {
console.error('User rejected the signature or transaction.')
} else if (error?.code === 4200 || error?.message?.toLowerCase().includes('not supported')) {
console.error('Wallet does not support EIP-7702 authorization signing.')
} else {
console.error('Unexpected error:', error.message)
}
}
Running the Example
# Install dependencies
npm install
# Set environment variables
cp .env.example .env
# Edit .env with your values
# Run the example
node strategy-deposit-eip7702.js
Expected Output
1️⃣ Fetching available strategies...
✅ Available strategies:
- aave-usdc-polygon (Aave)
APY: 4.50%
2️⃣ Getting details for aave-usdc-polygon...
✅ Strategy details:
Strategy: aave-usdc-polygon
Protocol: Aave
Network: polygon
Asset: USDC
APY: 4.50%
Status: ✅ Active
3️⃣ Generating deposit bytecode...
✅ Bytecode generated:
Transactions to batch: 2
4️⃣ Signing EIP-7702 authorization...
Encoding executeBatch calldata...
Sending type-4 transaction...
Transaction sent: 0x123...
✅ Transaction confirmed in block 12345678
5️⃣ Verifying deposit...
✅ Wallet positions:
aave-usdc-polygon:
Balance: 1000.00 USDC
Value: $1000.00
APY: 4.17%
Total Portfolio Value: $1000.00
🎉 Strategy deposit completed successfully!
Next Steps
Strategy Withdrawal
Learn how to withdraw from strategies
Cross-Chain Swap
Execute cross-chain token swaps
Check Positions
Track wallet positions
API Reference
View complete API documentation