PRACTICAL EXAMPLES • REAL-WORLD IMPLEMENTATION

X402 API Usage Examples

Practical examples of how to use the Elsa X402 API for real blockchain execution with automatic payment handling.

[EX:01]

Token Swap Execution

SCENARIO

Execute a real token swap on Base network using the Elsa pipeline system with automatic X402 payment handling.

STEP 1: SETUP X402 CLIENT

setup.js
// Setup wallet and X402 v2 payment client
import { wrapAxiosWithPayment, x402Client } from '@x402/axios';
import { ExactEvmScheme } from '@x402/evm/exact/client';
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base } from 'viem/chains';
import axios from 'axios';
const account = privateKeyToAccount('0x...');
// walletClient is used below to sign/send the swap transaction
const walletClient = createWalletClient({ chain: base, transport: http(), account });
const client = wrapAxiosWithPayment(
axios.create({ baseURL: 'https://x402-v2-api.heyelsa.ai' }),
new x402Client().register('eip155:8453', new ExactEvmScheme(account, { rpcUrl: 'https://mainnet.base.org' }))
);
// Note: API calls use /api/ for USDC or /api/elsa/ for ELSA payments

STEP 2: EXECUTE SWAP (DRY RUN)

swap-dryrun.js
// Execute swap USDC to WETH on Base (dry run)
const result = await client.post('/api/execute_swap', {
from_chain: 'base',
from_token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
from_amount: '10',
to_chain: 'base',
to_token: '0x4200000000000000000000000000000000000006', // WETH
wallet_address: walletClient.account.address,
slippage: 2.0,
dry_run: true // Test mode - no real transaction
});
// Response contains pipeline_id for tracking
console.log('Pipeline ID:', result.data.pipeline_id);
console.log('Estimated output:', result.data.tasks[0].estimate.to_amount);

STEP 3: EXECUTE REAL SWAP

swap-real.js
// Execute real swap (actual blockchain transaction)
const realSwap = await client.post('/api/execute_swap', {
from_chain: 'base',
from_token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
from_amount: '10',
to_chain: 'base',
to_token: '0x4200000000000000000000000000000000000006',
wallet_address: walletClient.account.address,
slippage: 2.0,
dry_run: false // Real execution!
});
// Monitor transaction status
const status = await client.post('/api/get_transaction_status', {
pipeline_id: realSwap.data.pipeline_id
});
if (status.data.tasks[0].status === 'sign_pending') {
// Sign and send the transaction
const tx = status.data.tasks[0].tx_data;
const hash = await walletClient.sendTransaction(tx);
console.log('Transaction sent:', hash);
// Submit transaction hash back to pipeline
await client.post('/api/submit_transaction_hash', {
task_id: status.data.tasks[0].task_id,
tx_hash: hash,
status: 'submitted'
});
}

STEP 4 (OPTIONAL): GASLESS SWAP TO ANOTHER RECIPIENT

Three optional routing parameters are accepted by both get_swap_quote and execute_swap. Use them when the sending wallet holds no ETH for gas, or to bridge straight into your Polymarket deposit wallet (the only recipient other than the sender that the backend accepts).

swap-gasless.js
// Bridge Base USDC into pUSD inside your Polymarket deposit wallet on Polygon,
// using only routes that settle by signature (no ETH needed for gas)
const depositWallet = '0x...'; // your Polymarket V2 deposit wallet (see polymarket_user_status)
const bridge = await client.post('/api/execute_swap', {
from_chain: 'base',
from_token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC (Base)
from_amount: '25',
to_chain: 'polygon',
to_token: '0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB', // pUSD (Polygon)
wallet_address: walletClient.account.address,
to_address: depositWallet, // optional — must be wallet_address, or your deposit wallet for pUSD on Polygon
gasless_only: true, // optional — fail instead of falling back to a gas route
slippage: 1.0,
dry_run: false
});
// Same-chain: force CoW Swap explicitly instead of letting the router choose
const cow = await client.post('/api/get_swap_quote', {
from_chain: 'base',
from_token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
from_amount: '10',
to_chain: 'base',
to_token: '0x4200000000000000000000000000000000000006',
wallet_address: walletClient.account.address,
provider: 'cowswap' // optional — backend rejects providers that cannot serve the route
});
// Gasless pipelines return EIP-712 typed data to sign instead of a transaction:
// submit the signature via /api/submit_typed_data_signature — see monitorPipeline() below

COMPLETE IMPLEMENTATION

swap-executor.js
import { wrapAxiosWithPayment, x402Client } from '@x402/axios';
import { ExactEvmScheme } from '@x402/evm/exact/client';
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base } from 'viem/chains';
import axios from 'axios';
class SwapExecutor {
constructor(privateKey) {
const account = privateKeyToAccount(privateKey);
this.walletClient = createWalletClient({ chain: base, transport: http(), account });
this.client = wrapAxiosWithPayment(
axios.create({ baseURL: 'https://x402-v2-api.heyelsa.ai' }),
new x402Client().register('eip155:8453', new ExactEvmScheme(account, { rpcUrl: 'https://mainnet.base.org' }))
);
}
async executeSwap(params) {
// First do dry run to check estimate
const dryRun = await this.client.post('/api/execute_swap', {
...params, dry_run: true
});
console.log('Estimated output:', dryRun.data.tasks[0].estimate);
// Execute real swap
const result = await this.client.post('/api/execute_swap', {
...params, dry_run: false
});
// Monitor and sign transaction
return this.monitorPipeline(result.data.pipeline_id);
}
async monitorPipeline(pipelineId) {
while (true) {
const status = await this.client.post('/api/get_transaction_status', {
pipeline_id: pipelineId
});
const task = status.data.tasks[0];
if (task.status === 'sign_pending' && task.evm_typed_data) {
// Gasless routes (gasless_only / provider: 'cowswap') return EIP-712 typed data
// instead of a transaction — sign it and submit the signature
const signature = await this.walletClient.signTypedData(task.evm_typed_data);
await this.client.post('/api/submit_typed_data_signature', {
task_id: task.task_id,
signature,
status: 'signed'
});
} else if (task.status === 'sign_pending') {
const hash = await this.walletClient.sendTransaction(task.evm_tx_data);
console.log('Transaction sent:', hash);
// Submit transaction hash to pipeline
await this.client.post('/api/submit_transaction_hash', {
task_id: task.task_id,
tx_hash: hash,
status: 'submitted'
});
} else if (task.status === 'success') {
console.log('Swap completed!');
return status.data;
} else if (task.status === 'failed') {
throw new Error('Transaction failed: ' + task.error);
}
await new Promise(r => setTimeout(r, 2000));
}
}
}
// Usage
const executor = new SwapExecutor(process.env.PRIVATE_KEY);
await executor.executeSwap({
from_chain: 'base',
from_token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
from_amount: '10',
to_chain: 'base',
to_token: '0x4200000000000000000000000000000000000006',
wallet_address: executor.walletClient.account.address,
slippage: 2.0
});
[EX:02]

Portfolio Analysis

SCENARIO

Analyze wallet holdings across multiple chains and get comprehensive portfolio data.

GET PORTFOLIO DATA

const portfolio = await client.post('/api/get_portfolio', {
wallet_address: '0x742d35Cc6634C0532925a3b844Bc1e6A8B8C1F3D',
include_spam: false,
include_nfts: true
});
// Response includes token balances, values, and NFTs
console.log('Total value:', portfolio.data.total_value_usd);
console.log('Chains:', portfolio.data.chains);

GET TOKEN PRICES

const price = await client.post('/api/get_token_price', {
chain: 'base',
token_address: '0x4200000000000000000000000000000000000006' // WETH
});
console.log('WETH price:', price.data.price_usd);
[EX:03]

ELSA Airdrop Claim

SCENARIO

Check airdrop eligibility and claim ELSA tokens from a specific tranche using the pipeline system.

CHECK ELIGIBILITY

// Check if wallet is eligible for airdrop tranche 1
const eligibility = await client.post('/api/check_airdrop', {
chain: 'base',
tranche: 1,
eoa_address: walletClient.account.address
});
// Response shows allocation and status
console.log('Eligible amount:', eligibility.data.amount);
console.log('Status:', eligibility.data.status); // "available" or "claimed"

CLAIM AIRDROP

// Claim allocated tokens (creates a pipeline)
const claim = await client.post('/api/claim_airdrop', {
chain: 'base',
tranche: 1,
eoa_address: walletClient.account.address,
dry_run: false
});
// Monitor and sign the claim transaction
const status = await client.post('/api/get_transaction_status', {
pipeline_id: claim.data.pipeline_id
});
if (status.data.tasks[0].status === 'sign_pending') {
const hash = await walletClient.sendTransaction(status.data.tasks[0].tx_data);
// Submit hash to complete claim
await client.post('/api/submit_transaction_hash', {
task_id: status.data.tasks[0].task_id,
tx_hash: hash,
status: 'submitted'
});
}

COMPLETE IMPLEMENTATION

async function claimAirdrop(client, walletClient, tranche) {
// Step 1: Check eligibility
const check = await client.post('/api/check_airdrop', {
chain: 'base',
tranche,
eoa_address: walletClient.account.address
});
if (check.data.status !== 'available') {
console.log('Not eligible or already claimed');
return;
}
console.log(`Eligible for $${check.data.amount} ELSA tokens`);
// Step 2: Create claim pipeline
const claim = await client.post('/api/claim_airdrop', {
chain: 'base',
tranche,
eoa_address: walletClient.account.address,
dry_run: false
});
const pipelineId = claim.data.pipeline_id;
console.log('Pipeline created:', pipelineId);
// Step 3: Monitor and sign
while (true) {
const status = await client.post('/api/get_transaction_status', {
pipeline_id: pipelineId
});
const task = status.data.tasks[0];
if (task.status === 'sign_pending') {
const hash = await walletClient.sendTransaction(task.tx_data);
console.log('Transaction sent:', hash);
await client.post('/api/submit_transaction_hash', {
task_id: task.task_id,
tx_hash: hash,
status: 'submitted'
});
} else if (task.status === 'success') {
console.log('Airdrop claimed successfully!');
return status.data;
} else if (task.status === 'failed') {
throw new Error('Claim failed: ' + task.error);
}
await new Promise(r => setTimeout(r, 2000));
}
}
// Usage
await claimAirdrop(client, walletClient, 1);
[EX:04]

Limit Orders

CREATE LIMIT ORDER

// Create a limit order to sell USDC for WETH at specific price
const order = await client.post('/api/create_limit_order', {
from_chain: 'base',
from_token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
from_amount: '1000',
to_token: '0x4200000000000000000000000000000000000006', // WETH
limit_price: '2500', // Execute when 1 ETH = $2500
wallet_address: walletClient.account.address,
valid_for_hours: 24
});

MONITOR & CANCEL ORDERS

// Get all active limit orders
const orders = await client.post('/api/get_limit_orders', {
wallet_address: walletClient.account.address
});
// Cancel an order
await client.post('/api/cancel_limit_order', {
order_id: orders.data[0].order_id,
wallet_address: walletClient.account.address
});
[EX:05]

Polymarket Market Screener

SCENARIO

Find every market resolving in the next 48 hours where the favorite is priced between roughly 80% and 85%, on either side, with a tight order book — then place a small order on the favorite. Leave search out: a keyword resolves to a single Polymarket tag and would silently shrink the universe to one topic.

SCREEN ALL MARKETS

screener.js
const now = new Date();
const in48h = new Date(now.getTime() + 48 * 60 * 60 * 1000);
// priceCompetitiveness = 1 - |p_yes - p_no|; 0.30–0.40 ≈ favorite at 80–85%
const screen = await client.post('/api/polymarket_advanced_search', {
// no "search" — screen across all markets
end_date_min: now.toISOString(),
end_date_max: in48h.toISOString(),
price_competitiveness_min: 0.30,
price_competitiveness_max: 0.40,
spread_max: 0.005, // tight book: ≤ half a cent per share
sort_by: 'liquidityUsd',
sort_direction: 'DESC',
limit: 20
});
const markets = screen.data.markets ?? [];
console.log(`${markets.length} markets in the 80–85% band closing within 48h`);
if (markets.length === 0) {
throw new Error('No markets matched the screener filters — widen the band or the date window');
}

NARROW TO A TOPIC (OPTIONAL)

// Only add a keyword when you actually want one tag's markets
const finance = await client.post('/api/polymarket_advanced_search', {
search: 'finance',
end_date_min: now.toISOString(),
end_date_max: in48h.toISOString(),
sort_by: 'volumeUsd24h'
});

PLACE AN ORDER ON THE FAVORITE

// No credential setup — pass your EOA; the deposit wallet is derived server-side.
// Fund the deposit wallet with pUSD first (see polymarket_user_status).
const order = await client.post('/api/create_polymarket_v2_order', {
wallet_address: walletClient.account.address,
market_id: markets[0].id,
token_id: markets[0].favoriteTokenId, // the outcome token you want to buy
side: 'buy',
price: 0.83, // USDC per share, 0.0–1.0
size: 5, // USD, minimum 1
dry_run: true // preview first; set false to place the order
});
// Returns a pipeline_id — poll /api/get_transaction_status and submit the
// EIP-712 signature via /api/submit_typed_data_signature
[REF]

Quick API Reference

CORE ENDPOINTS

POST /api/execute_swap
Execute token swap with pipeline system
POST /api/get_transaction_status
Check pipeline status and get tx data for signing
POST /api/submit_transaction_hash
Submit signed transaction hash back to pipeline
POST /api/get_portfolio
Get comprehensive wallet portfolio data
POST /api/get_token_price
Get current token price in USD
POST /api/create_limit_order
Create limit order on CoWSwap
POST /api/check_airdrop
Check airdrop eligibility and allocation
POST /api/claim_airdrop
Claim ELSA airdrop tokens via pipeline
POST /api/open_perp_position
Open perpetual position on Avantis or Hyperliquid
POST /api/close_perp_position
Close perpetual position fully or partially
POST /api/get_perp_positions
Query open perpetual positions
POST /api/polymarket_advanced_search
Screen Polymarket markets by date, probability band and spread (keyword optional)
POST /api/create_polymarket_v2_order
Place a Polymarket order via pipeline — no credential setup
GET /health
Check server health and payment info

REQUIRED PARAMETERS

• wallet_address: Your wallet address (required for all transactions)
• from_chain / to_chain: Chain identifiers ('base', 'ethereum', etc.)
• from_token / to_token: Token contract addresses (not symbols)
• dry_run: true for testing, false for real execution
• slippage: Max slippage tolerance (e.g., 2.0 for 2%)

OPTIONAL SWAP PARAMETERS

• provider: Force a route. One of lifi, bungee, relay, rialto, fynd, superswap, berachain, hyperliquid, hyperliquid-perps, cowswap, agent_token_lp. Backend rejects providers that cannot serve the route
• gasless_only: true to use only signature-settled routes (CoW Swap, Relay permit) — fails rather than falling back to a route that needs ETH for gas
• to_address: Recipient on the destination chain; defaults to wallet_address. Must equal wallet_address except your own Polymarket deposit wallet when bridging to pUSD on Polygon (400 otherwise)

PAYMENT SYSTEM

• All requests require X402 micropayments in USDC or ELSA on Base
• Use wrapAxiosWithPayment from @x402/axios for automatic payments
• Payment recipient: 0x0D224DB2830A32bc75212A0ec6f0008C2B3ae5b5
• Costs range from $0.002 to $0.10 per request
Payment Token Selection:
• USDC: /api/endpoint_name
• ELSA: /api/elsa/endpoint_name
[LIVE]

Built with X402 API

WalletRoast.com

LIVE PROJECT
Visit →

A fun AI-powered app that roasts your crypto wallet. Analyzes your portfolio holdings, transaction history, and DeFi positions using the Elsa X402 API, then generates a humorous roast of your crypto decisions.

Portfolio AnalysisTransaction HistoryX402 PaymentsAI Generated

Ready to Build?

These examples demonstrate real blockchain execution using the Elsa X402 API with automatic USDC or ELSA token micropayments on Base network.