8 supported chains
Every Purple Flea agent wallet supports all 8 chains from a single API key. No separate accounts needed per chain.
Your Purple Flea API key authenticates across all 8 chains. The Wallet API abstracts each chain's native transaction format. You send a unified JSON request and Purple Flea handles signing, broadcasting, and fee management per chain.
Generate your multi-chain wallet
A single API call provisions addresses on all 8 chains, derived from one root key managed by Purple Flea. Your agent gets a stable address per chain immediately.
const WALLET = 'https://purpleflea.com/api/wallet'; const API_KEY = process.env.PF_API_KEY; const headers = { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }; async function generateWallet() { const res = await fetch(`${WALLET}/generate`, { method: 'POST', headers, body: JSON.stringify({ chains: ['ETH', 'SOL', 'BTC', 'XMR', 'TRX', 'MATIC', 'BNB', 'AVAX'], label: 'main-treasury' // optional label }) }); const wallet = await res.json(); // Print addresses for all chains for (const [chain, info] of Object.entries(wallet.addresses)) { console.log(`${chain.padEnd(6)}: ${info.address}`); } console.log(`\nWallet ID: ${wallet.wallet_id}`); // Store wallet_id for subsequent calls return wallet; } generateWallet();
{
"wallet_id": "wlt_Kx9mNpQ3rX7vZ",
"addresses": {
"ETH": { "address": "0x4a2f...c91b", "chain_id": 1 },
"SOL": { "address": "7K8m...Pg2Q", "chain_id": "mainnet-beta" },
"BTC": { "address": "bc1q...x4kz", "format": "bech32" },
"XMR": { "address": "49...long_xmr_addr", "view_key": "..." },
"TRX": { "address": "TKmN...3pRq" },
"MATIC":{ "address": "0x4a2f...c91b", "chain_id": 137 },
"BNB": { "address": "0x4a2f...c91b", "chain_id": 56 },
"AVAX": { "address": "0x4a2f...c91b", "chain_id": 43114 }
}
}ETH, MATIC, BNB, and AVAX share the same EVM address (your
Aggregate balances across all chains
One call returns native balances, USDC balances, and USD-equivalent totals for all 8 chains. Essential for portfolio management and treasury decisions.
async function getPortfolio() { const res = await fetch(`${WALLET}/balances`, { headers }); const portfolio = await res.json(); let totalUSD = 0; console.log('=== Agent Portfolio ==='); console.log('Chain | Native | USDC | USD Value'); console.log('--------|---------------|-----------|----------'); for (const chain of portfolio.chains) { const native = chain.native_balance.toFixed(4).padEnd(13); const usdc = chain.usdc_balance.toFixed(2).padEnd(9); const usd = chain.usd_value.toFixed(2); console.log(`${chain.symbol.padEnd(7)} | ${native} | ${usdc} | $${usd}`); totalUSD += chain.usd_value; } console.log(`\nTotal portfolio value: $${totalUSD.toFixed(2)} USD`); console.log(`Last updated: ${portfolio.updated_at}`); // Price oracle data included console.log(`\nPrices used:`); for (const [sym, price] of Object.entries(portfolio.prices)) { console.log(` ${sym}: $${price}`); } return portfolio; } getPortfolio();
{
"total_usd_value": 487.32,
"chains": [
{ "symbol": "ETH", "native_balance": 0.0821, "usdc_balance": 150.00, "usd_value": 352.18 },
{ "symbol": "SOL", "native_balance": 1.4400, "usdc_balance": 0.00, "usd_value": 204.48 },
{ "symbol": "BTC", "native_balance": 0.0000, "usdc_balance": 0.00, "usd_value": 0.00 },
{ "symbol": "XMR", "native_balance": 0.0000, "usdc_balance": 0.00, "usd_value": 0.00 },
{ "symbol": "MATIC","native_balance": 45.800, "usdc_balance": 50.00, "usd_value": 95.62 }
],
"prices": { "ETH": 2465, "SOL": 142, "MATIC": 0.92, "BNB": 608, "AVAX": 38 },
"updated_at": "2026-03-04T12:00:00Z"
}Transfer funds between addresses
Send native tokens or USDC on any supported chain. Specify the chain, recipient, amount, and asset. Purple Flea handles signing and broadcasting.
async function transferUSDC(chain, toAddress, amount) { // First estimate gas const estimate = await estimateGas(chain, toAddress, amount, 'USDC'); console.log(`Estimated fee: ${estimate.fee_usd} USD on ${chain}`); if (estimate.fee_usd > amount * 0.1) { console.warn('Warning: fee exceeds 10% of transfer amount'); } const res = await fetch(`${WALLET}/transfer`, { method: 'POST', headers, body: JSON.stringify({ chain, // 'ETH' | 'SOL' | 'MATIC' etc. asset: 'USDC', to: toAddress, amount, // in USDC speed: 'standard', // 'slow' | 'standard' | 'fast' memo: 'Payment for services' // optional }) }); const tx = await res.json(); console.log(`TX submitted: ${tx.tx_hash}`); console.log(`Explorer: ${tx.explorer_url}`); return tx; }
async function transferNative(chain, toAddress, amount) { const assetMap = { ETH: 'ETH', SOL: 'SOL', BTC: 'BTC', XMR: 'XMR', TRX: 'TRX', MATIC: 'MATIC', BNB: 'BNB', AVAX: 'AVAX' }; const res = await fetch(`${WALLET}/transfer`, { method: 'POST', headers, body: JSON.stringify({ chain, asset: assetMap[chain], to: toAddress, amount, // in native units (ETH, SOL, BTC, etc.) speed: 'standard' }) }); const tx = await res.json(); if (!res.ok) { throw new Error(`Transfer failed: ${tx.error} (${tx.code})`); } console.log(`${amount} ${chain} sent`); console.log(`Hash: ${tx.tx_hash}`); console.log(`Est. confirmation: ${tx.estimated_confirm_time}`); return tx; } // XMR note: transfers are unlocked after 10 confirmations (~20min) // BTC note: 1 confirmation (~10min) for standard, 6 for high-value
Gas estimation and fee calculation
Always estimate before sending. Gas costs vary wildly between chains and between
async function estimateGas(chain, to, amount, asset) { const res = await fetch(`${WALLET}/estimate`, { method: 'POST', headers, body: JSON.stringify({ chain, to, amount, asset }) }); return await res.json(); } // Fee-aware transfer: pick cheapest chain for USDC transfers async function cheapestUSDCTransfer(to, amount) { const evm_chains = ['ETH', 'MATIC', 'BNB', 'AVAX']; // Estimate fees on all EVM chains in parallel const estimates = await Promise.all( evm_chains.map(async chain => { const est = await estimateGas(chain, to, amount, 'USDC'); return { chain, fee_usd: est.standard.fee_usd, ...est }; }) ); // Sort by fee ascending estimates.sort((a, b) => a.fee_usd - b.fee_usd); console.log('Fee comparison for $100 USDC transfer:'); estimates.forEach(e => { console.log(` ${e.chain.padEnd(6)}: $${e.fee_usd.toFixed(4)} USD`); }); const best = estimates[0]; console.log(`\nCheapest: ${best.chain} at $${best.fee_usd.toFixed(4)} USD`); return best; } // Example output: // Fee comparison for $100 USDC transfer: // MATIC : $0.0012 USD // BNB : $0.0045 USD // AVAX : $0.0110 USD // ETH : $1.4300 USD // Cheapest: MATIC at $0.0012 USD
ETH gas can spike 50-100x during network congestion. For routine USDC transfers between agents, Polygon (MATIC) offers near-zero fees with fast finality. Reserve ETH for operations requiring Ethereum mainnet finality.
{
"chain": "MATIC",
"asset": "USDC",
"amount": 100,
"slow": { "fee_gwei": 30, "fee_usd": 0.0008, "eta_seconds": 120 },
"standard": { "fee_gwei": 50, "fee_usd": 0.0012, "eta_seconds": 15 },
"fast": { "fee_gwei": 100, "fee_usd": 0.0024, "eta_seconds": 5 }
}Monitor transactions
Poll for transaction status or use webhook callbacks. Essential for multi-agent workflows where downstream agents must wait for payment confirmation before starting work.
async function waitForConfirmation(txHash, chain, maxWaitMs = 300000) { const pollIntervals = { ETH: 15000, // 15s SOL: 1000, // 1s (fast finality) BTC: 60000, // 60s XMR: 60000, // 60s TRX: 3000, // 3s MATIC: 5000, // 5s BNB: 5000, // 5s AVAX: 5000 // 5s }; const interval = pollIntervals[chain] || 10000; const deadline = Date.now() + maxWaitMs; while (Date.now() < deadline) { const status = await fetch( `${WALLET}/tx/${chain}/${txHash}`, { headers } ).then(r => r.json()); if (status.confirmed) { console.log(`Confirmed after ${status.confirmations} blocks`); console.log(`Block: ${status.block_number}`); console.log(`Fee paid: ${status.fee_paid} ${chain}`); return status; } if (status.failed) { throw new Error(`TX failed: ${status.failure_reason}`); } console.log(`Pending (${status.confirmations}/${status.required_confirmations})...`); await new Promise(r => setTimeout(r, interval)); } throw new Error(`TX not confirmed within ${maxWaitMs/1000}s`); }
// Register a webhook to receive TX confirmations async function registerWebhook() { const res = await fetch(`${WALLET}/webhooks`, { method: 'POST', headers, body: JSON.stringify({ url: 'https://my-agent.example.com/tx-callback', events: ['tx.confirmed', 'tx.failed', 'deposit.received'], chains: ['ETH', 'MATIC', 'SOL'], secret: process.env.WEBHOOK_SECRET // used to verify signatures }) }); const wh = await res.json(); console.log(`Webhook registered: ${wh.webhook_id}`); return wh; } // Webhook payload received at your callback URL: // { // "event": "tx.confirmed", // "tx_hash": "0xabc...", // "chain": "MATIC", // "amount": 100, // "asset": "USDC", // "to": "0x...", // "block": 52847123, // "signature":"hmac-sha256:..." // }
Cross-chain swap
Swap any supported asset to any other across chains. Purple Flea routes through the best available bridges and DEXes and returns a single signed quote.
async function swapAssets() { // Get a quote first const quote = await fetch(`${WALLET}/swap/quote`, { method: 'POST', headers, body: JSON.stringify({ from_chain: 'ETH', from_asset: 'USDC', from_amount: 500, // 500 USDC on ETH to_chain: 'SOL', to_asset: 'USDC', // receive USDC on Solana slippage_bps: 50 // 0.5% max slippage }) }).then(r => r.json()); console.log(`From: ${quote.from_amount} USDC on ETH`); console.log(`To: ${quote.to_amount} USDC on SOL`); console.log(`Fee: ${quote.total_fee_usd} USD`); console.log(`Route: ${quote.route.join(' → ')}`); console.log(`ETA: ${quote.estimated_time_seconds}s`); // Accept and execute the swap const swap = await fetch(`${WALLET}/swap/execute`, { method: 'POST', headers, body: JSON.stringify({ quote_id: quote.quote_id }) }).then(r => r.json()); console.log(`\nSwap initiated: ${swap.swap_id}`); console.log(`Track at: ${swap.tracker_url}`); return swap; }
Full portfolio manager
A complete agent treasury management script that checks balances, concentrates dust into one chain, and reports P&L.
/** * portfolio-manager.js * Agent treasury manager: aggregate, consolidate dust, report P&L. * Usage: PF_API_KEY=... node portfolio-manager.js */ const WALLET = 'https://purpleflea.com/api/wallet'; const hdr = { 'Authorization': `Bearer ${process.env.PF_API_KEY}`, 'Content-Type': 'application/json' }; const get = url => fetch(url, { headers: hdr }).then(r => r.json()); const post = (url, body) => fetch(url, { method: 'POST', headers: hdr, body: JSON.stringify(body) }).then(r => r.json()); const CONSOLIDATE_TO = 'MATIC'; // cheapest fees for USDC const DUST_THRESHOLD_USD = 1.0; // skip swapping tiny amounts const MIN_NATIVE_RESERVE = 0.001; // keep for future gas async function manageTreasury() { console.log('=== Treasury Management Run ==='); // 1. Get all balances const portfolio = await get(`${WALLET}/balances`); console.log(`Total portfolio: $${portfolio.total_usd_value.toFixed(2)}`); // 2. Find USDC balances above dust threshold on non-consolidation chains const toConsolidate = portfolio.chains.filter(c => c.symbol !== CONSOLIDATE_TO && c.usdc_balance > 0 && c.usdc_balance * portfolio.prices['USDC'] > DUST_THRESHOLD_USD ); // 3. Consolidate to MATIC for cheapest fees for (const chain of toConsolidate) { console.log(`Consolidating ${chain.usdc_balance} USDC from ${chain.symbol}...`); const swap = await post(`${WALLET}/swap/execute`, { from_chain: chain.symbol, from_asset: 'USDC', from_amount: chain.usdc_balance, to_chain: CONSOLIDATE_TO, to_asset: 'USDC', slippage_bps: 50 }); console.log(` Swap ${swap.swap_id} submitted`); } // 4. Generate report const report = await get(`${WALLET}/report?period=7d`); console.log(`\n7-day P&L: $${report.pnl_usd.toFixed(2)}`); console.log(`Total inflows: $${report.inflows_usd.toFixed(2)}`); console.log(`Total outflows: $${report.outflows_usd.toFixed(2)}`); console.log(`Fees paid: $${report.fees_paid_usd.toFixed(2)}`); } manageTreasury().catch(console.error);
Chain reference
| Chain | USDC Support | Avg Confirmation | Avg Fee (USDC transfer) | Notes |
|---|---|---|---|---|
| ETH | Native USDC | ~15s | $0.50–$5.00 | Highest security. Use for large transfers only. |
| SOL | USDC (SPL) | <1s | ~$0.001 | Fastest finality. Great for high-frequency agent payments. |
| BTC | No USDC | ~10min | BTC only | Native BTC only. 6 confirmations for large amounts. |
| XMR | No USDC | ~2min | XMR only | Privacy chain. 10-block unlock (~20min). Needs view key for balance scan. |
| TRX | USDT/USDC | ~3s | ~$0.001 | Very cheap. Large stablecoin ecosystem. TRX bandwidth model. |
| MATIC | Native USDC | ~5s | ~$0.001 | Best for routine agent-to-agent USDC transfers. Recommended default. |
| BNB | USDC (BSC) | ~5s | ~$0.005 | Fast and cheap. Large DeFi ecosystem on BSC. |
| AVAX | Native USDC | ~2s | ~$0.010 | Near-instant finality. Good for time-sensitive agent operations. |