# xPath APIs (/xPath) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. xPath is Rath’s high-performance cross-chain routing engine. *(Coming soon)* xPath APIs compute the fastest and most capital-efficient execution paths across chains, bridges, and execution environments. They abstract fragmented liquidity, variable fees, and latency differences into a single deterministic routing interface. xPath will power instant cross-chain transfers, multi-hop execution, and optimal routing for wallets, solvers, and DeFi applications. # Fspot APIs (/xPath/f-spot) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Flash API Integration Guide [#flash-api-integration-guide] Complete documentation for integrating with the Flash API backend for cross-chain swap applications. Table of Contents [#table-of-contents] * [Overview](#overview) * [Base URL](#base-url) * [Authentication](#authentication) * [Chain Configuration](#chain-configuration) * [API Endpoints](#api-endpoints) * [Supported Chains](#1-supported-chains) * [Authentication](#2-authentication) * [Token List](#3-token-list) * [Quote](#4-quote) * [Gateway Balance](#5-gateway-balance) * [Swap Execution](#6-swap-execution) * [Search Token](#7-search-token) * [Swap History](#8-swap-history) * [Leaderboard](#10-leaderboard) * [User Referrals](#11-user-referrals) * [TypeScript Integration](#typescript-integration) *** Overview [#overview] The Flash API provides a comprehensive backend service for cross-chain USDC swaps using the Gateway protocol. It handles: * Chain configuration management * Token listings and prices * Quote generation for swaps * Swap execution and tracking * User authentication and referrals * Transaction history *** Base URL [#base-url] ``` Production: https://flash.rath.fi ``` *** Authentication [#authentication] Flash API uses wallet signature-based authentication. Flow: [#flow] 1. Request a message to sign 2. Sign the message with user's wallet 3. Verify signature to receive JWT token 4. Include token in subsequent requests Headers: [#headers] ``` Authorization: Bearer Content-Type: application/json ``` *** Chain Configuration [#chain-configuration] Dynamic Chain Support [#dynamic-chain-support] All chain configurations are fetched from the backend, making it easy to add/remove chains without frontend changes. **Key Features:** * Gateway wallet addresses * Gateway minter addresses * USDC contract addresses * Chain metadata (logo, explorer, name) * Domain numbers for Gateway protocol *** API Endpoints [#api-endpoints] 1\. Supported Chains [#1-supported-chains] Get all supported chains with their configuration. **Endpoint:** `GET /supported-chains` **Response:** ```typescript [ { "id": 8453, // Chain ID "name": "Base", // Chain name "displayName": "Base", // Display name "logoUrl": "https://...", // Chain logo URL "explorerUrl": "https://...", // Block explorer URL "domain": 6, // Gateway protocol domain "routerAddress": "0x...", // Swap router address "gatewayWallet": "0x...", // Gateway wallet contract "gatewayMinter": "0x...", // Gateway minter contract "nativeToken": { "address": "0x0000000000000000000000000000000000000000", "name": "Ethereum", "symbol": "ETH", "decimals": 18, "logoUrl": "https://..." }, "usdc": { "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "name": "USD Coin", "symbol": "USDC", "decimals": 6, "logoUrl": "https://..." } } ] ``` **Example:** ```typescript const chains = await fetch('https://flash.rath.fi/supported-chains') .then(res => res.json()); ``` *** 2\. Authentication [#2-authentication] 2.1 Request Sign Message [#21-request-sign-message] **Endpoint:** `POST /auth/message` **Request:** ```typescript { "userAddress": "0x1234567890abcdef1234567890abcdef12345678" } ``` **Response:** ```typescript { "message": "Sign this message to authenticate with Flash Computer...", "expiry": 1705449600, "messageId": "550e8400-e29b-41d4-a716-446655440000" } ``` 2.2 Verify Signature [#22-verify-signature] **Endpoint:** `POST /auth/verify` **Request:** ```typescript { "signature": "0xabcdef...", "messageId": "550e8400-e29b-41d4-a716-446655440000", "referredByCode": "REFERRAL123" // Optional } ``` **Response:** ```typescript { "token": "eyJhbGciOiJIUzI1NiIs...", "user_address": "0x1234567890abcdef1234567890abcdef12345678", "referralCode": "ABC123XYZ", "is_new_user": true } ``` **Complete Flow Example:** ```typescript // 1. Request message const { message, messageId } = await fetch('https://flash.rath.fi/auth/message', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userAddress: address }) }).then(res => res.json()); // 2. Sign message with wallet const signature = await walletClient.signMessage({ message }); // 3. Verify and get token const { token } = await fetch('https://flash.rath.fi/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ signature, messageId }) }).then(res => res.json()); // 4. Use token for authenticated requests const authenticatedHeaders = { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }; ``` *** 3\. Token List [#3-token-list] Get available tokens for swapping. **Endpoint:** `GET /token-list?chain_id={chainId}` **Query Parameters:** * `chain_id` (optional): Filter tokens by chain ID. Omit for all chains. **Response:** ```typescript { "tokens": [ { "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "symbol": "USDC", "decimals": 6, "logo_url": "https://...", "name": "USD Coin", "chain_id": 8453, "in_rath_token_list": true } ] } ``` **Examples:** ```typescript // Get all tokens const { tokens } = await fetch('https://flash.rath.fi/token-list') .then(res => res.json()); // Get tokens for Base (chain ID 8453) const { tokens } = await fetch('https://flash.rath.fi/token-list?chain_id=8453') .then(res => res.json()); ``` *** 4\. Quote [#4-quote] Get a quote for a swap. **Endpoint:** `GET /quote` **Query Parameters:** * `inputAmount`: Amount in USDC smallest units (1 USDC = 1000000) * `outputToken`: Output token address * `chainId`: Destination chain ID * `from`: User wallet address * `slippage`: Slippage tolerance (1.5 = 1.5%) * `recipient`: Recipient address (optional if not passed, defaults to `from`) **Example Request:** ``` GET /quote?inputAmount=1000000&outputToken=0x...&chainId=8453&from=0x...&slippage=1.5&recipient=0x... ``` **Response:** ```typescript { "token_in": { "address": "0x...", "amount": "1000000", "decimals": 6, "logo_url": "https://...", "price_usd": "1.00", "usd_amount": "1.00" }, "token_out": { "address": "0x...", "amount": "998500", "decimals": 6, "logo_url": "https://...", "price_usd": "1.00", "usd_amount": "0.9985" }, "fees": { "total_fee": "1500", "gateway_fee": "1000", "execution_fee": "500" }, "single_swap_router": "0x...", "hook_data": "0x...", "swap_router_address": "0x...", "swap_calldata": "0x...", "expires_at": 1705449600 } ``` **Example:** ```typescript const params = new URLSearchParams({ inputAmount: '1000000', // 1 USDC outputToken: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', chainId: '8453', from: userAddress, slippage: '1.5' }); const quote = await fetch(`https://flash.rath.fi/quote?${params}`) .then(res => res.json()); ``` *** 5\. Gateway Balance [#5-gateway-balance] Get user's balance across all chains in the Gateway protocol. **Endpoint:** `GET /balance/{address}` **Response:** ```typescript { "balances": [ { "domain": 6, "depositor": "0x...", "balance": "5000000", // Balance in USDC smallest units "chainId": 8453, "chainName": "Base" } ], "totalBalance": "5000000" // Total across all chains } ``` **Example:** ```typescript const { balances, totalBalance } = await fetch( `https://flash.rath.fi/balance/${userAddress}` ).then(res => res.json()); ``` *** 6\. Swap Execution [#6-swap-execution] Execute a swap transaction. **Endpoint:** `POST /swap` **Authentication:** Required (Bearer token) **Request:** ```typescript { "signedOrder": [...], // Array of signed burn intents "userAddress": "0x...", "chainId": 8453, "swapRouterAddress": "0x...", "swapCalldata": "0x...", "slippageBps": 150 // 150 basis points = 1.5% } ``` **Response:** ```typescript { "transactionHash": "0xabcdef...", "status": "pending", "message": "Swap initiated successfully" } ``` **Example:** ```typescript // After creating and signing burn intents const result = await fetch('https://flash.rath.fi/swap', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ signedOrder: signedBurnIntents, userAddress: address, chainId: destinationChainId, swapRouterAddress: quote.swap_router_address, swapCalldata: quote.swap_calldata, slippageBps: 150 }) }).then(res => res.json()); ``` *** 7\. Search Token [#7-search-token] Search for a token by address. **Endpoint:** `POST /search-token` **Request:** ```typescript { "chainId": 8453, "address": "0x..." } ``` **Response:** ```typescript { "address": "0x...", "symbol": "UNI", "decimals": 18, "name": "Uniswap", "chainId": 8453, "logoUrl": "https://...", "inRathTokenList": false } ``` **Example:** ```typescript const token = await fetch('https://flash.rath.fi/search-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chainId: 8453, address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984' }) }).then(res => res.json()); ``` *** 8\. Swap History [#8-swap-history] Get user's swap transaction history. **Endpoint:** `GET /history?page={page}&page_size={size}&status={status}` **Authentication:** Required (Bearer token) **Query Parameters:** * `page` (optional): Page number (default: 1) * `page_size` (optional): Items per page (default: 20) * `status` (optional): Filter by status (`pending`, `completed`, `failed`) **Response:** ```typescript { "swaps": [ { "id": "uuid", "sourceDomain": 6, "destinationDomain": 3, "sourceToken": "0x...", "destinationToken": "0x...", "tokenIn": { "address": "0x...", "symbol": "USDC", "decimals": 6, "logo_url": "https://...", "name": "USD Coin", "chain_id": 8453, "in_rath_token_list": true }, "tokenOut": { "address": "0x...", "symbol": "UNI", "decimals": 18, "logo_url": "https://...", "name": "Uniswap", "chain_id": 42161, "in_rath_token_list": true }, "amountUsdc": "1.00", "amountUsdcRaw": "1000000", "chainId": 42161, "minAmountOut": "0.9985", "rathFee": "0.0015", "rathFeeRaw": "1500", "transactionHash": "0x...", "status": "completed", "txId": "gateway-tx-id", "createdAt": "2024-01-17T10:00:00Z", "updatedAt": "2024-01-17T10:05:00Z" } ], "pagination": { "current_page": 1, "page_size": 20, "total_entries": 45, "total_pages": 3, "has_next": true, "has_previous": false }, "summary": { "totalSwaps": 45, "totalVolume": "12500.50", "totalVolumeRaw": "12500500000", "totalFees": "18.75", "totalFeesRaw": "18750000" } } ``` **Example:** ```typescript const history = await fetch( 'https://flash.rath.fi/history?page=1&page_size=20', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } } ).then(res => res.json()); ``` 9\. Leaderboard [#9-leaderboard] Get trading leaderboard rankings. **Endpoint:** `GET /leaderboard?page={page}&page_size={size}&time_range={range}` **Query Parameters:** * `page` (optional): Page number (default: 1) * `page_size` (optional): Items per page (default: 50) * `time_range` (optional): Time filter (`all`, `30d`, `7d`, `24h`) **Response:** ```typescript { "entries": [ { "rank": 1, "walletAddress": "0x...", "totalVolume": "50000.00", "totalVolumeRaw": "50000000000", "swapCount": 150, "referralCount": 25, "referralVolume": "5000.00", "referralVolumeRaw": "5000000000", "combined_volume": "55000.00", "referralCode": "ABC123", "lastSwapAt": "2024-01-17T10:00:00Z" } ], "pagination": { "current_page": 1, "page_size": 50, "total_entries": 250, "total_pages": 5, "has_next": true, "has_previous": false } } ``` **Example:** ```typescript const leaderboard = await fetch( 'https://flash.rath.fi/leaderboard?time_range=7d' ).then(res => res.json()); ``` *** 10\. User Referrals [#10-user-referrals] Get user's referral information. **Endpoint:** `GET /referrals` **Authentication:** Required (Bearer token) **Response:** ```typescript { "referrals": [ { "user_address": "0x...", "total_volume_usdc": 1500.25 } ], "total_referral_volume": 5250.75, "total_referrals_count": 3, "remaining_referral_limit": 7 } ``` **Example:** ```typescript const referrals = await fetch('https://flash.rath.fi/referrals', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }).then(res => res.json()); ``` *** TypeScript Integration [#typescript-integration] Gateway Protocol Integration [#gateway-protocol-integration] Creating Burn Intents (Signed Orders) [#creating-burn-intents-signed-orders] Burn intents are EIP-712 signed messages that authorize cross-chain USDC transfers via the Gateway protocol. Step 1: Define EIP-712 Types [#step-1-define-eip-712-types] ```typescript const EIP712Domain = [ { name: "name", type: "string" }, { name: "version", type: "string" }, ]; const TransferSpec = [ { name: "version", type: "uint32" }, { name: "sourceDomain", type: "uint32" }, { name: "destinationDomain", type: "uint32" }, { name: "sourceContract", type: "bytes32" }, { name: "destinationContract", type: "bytes32" }, { name: "sourceToken", type: "bytes32" }, { name: "destinationToken", type: "bytes32" }, { name: "sourceDepositor", type: "bytes32" }, { name: "destinationRecipient", type: "bytes32" }, { name: "sourceSigner", type: "bytes32" }, { name: "destinationCaller", type: "bytes32" }, { name: "value", type: "uint256" }, { name: "salt", type: "bytes32" }, { name: "hookData", type: "bytes" }, ]; const BurnIntent = [ { name: "maxBlockHeight", type: "uint256" }, { name: "maxFee", type: "uint256" }, { name: "spec", type: "TransferSpec" }, ]; const BurnIntentSet = [ { name: "intents", type: "BurnIntent[]" } ]; const domain = { name: "GatewayWallet", version: "1" }; ``` Step 2: Create Burn Intent [#step-2-create-burn-intent] ```typescript import { pad, maxUint256 } from 'viem'; // Helper to convert address to bytes32 function addressToBytes32(address: string): string { return pad(address.toLowerCase() as `0x${string}`, { size: 32 }); } // Generate random salt function generateRandomSalt(): string { const bytes = new Uint8Array(32); crypto.getRandomValues(bytes); return '0x' + Array.from(bytes) .map(b => b.toString(16).padStart(2, '0')) .join(''); } // Create a burn intent function createBurnIntent({ userAddress, sourceChain, destinationChain, amount, recipient, hookData = '0x', maxFee = '2010000' // Gateway fee in smallest units }: { userAddress: string; sourceChain: ChainConfig; destinationChain: ChainConfig; amount: string; // Amount in smallest units (e.g., 1000000 for 1 USDC) recipient: string; hookData?: string; maxFee?: string; }) { return { maxBlockHeight: maxUint256, // Far future block maxFee: BigInt(maxFee), spec: { version: 1, sourceDomain: sourceChain.domain, destinationDomain: destinationChain.domain, sourceContract: sourceChain.gatewayWallet, destinationContract: destinationChain.gatewayMinter, sourceToken: sourceChain.usdc.address, destinationToken: destinationChain.usdc.address, sourceDepositor: userAddress, destinationRecipient: recipient, sourceSigner: userAddress, destinationCaller: recipient, value: BigInt(amount), salt: generateRandomSalt(), hookData: hookData, }, }; } ``` Step 3: Create Typed Data for Signing [#step-3-create-typed-data-for-signing] ```typescript function createBurnIntentTypedData(burnIntent: any) { return { types: { EIP712Domain, TransferSpec, BurnIntent }, domain, primaryType: "BurnIntent", message: { maxBlockHeight: burnIntent.maxBlockHeight, maxFee: burnIntent.maxFee, spec: { ...burnIntent.spec, sourceContract: addressToBytes32(burnIntent.spec.sourceContract), destinationContract: addressToBytes32(burnIntent.spec.destinationContract), sourceToken: addressToBytes32(burnIntent.spec.sourceToken), destinationToken: addressToBytes32(burnIntent.spec.destinationToken), sourceDepositor: addressToBytes32(burnIntent.spec.sourceDepositor), destinationRecipient: addressToBytes32(burnIntent.spec.destinationRecipient), sourceSigner: addressToBytes32(burnIntent.spec.sourceSigner), destinationCaller: addressToBytes32(burnIntent.spec.destinationCaller), }, }, }; } // For multiple intents (burn intent set) function createBurnIntentSetTypedData(burnIntents: any[]) { return { types: { EIP712Domain, TransferSpec, BurnIntent, BurnIntentSet }, domain, primaryType: "BurnIntentSet", message: { intents: burnIntents.map(intent => createBurnIntentTypedData(intent).message ), }, }; } ``` Step 4: Sign Burn Intent(s) [#step-4-sign-burn-intents] ```typescript // Using ethers.js import { ethers } from 'ethers'; async function signBurnIntent( wallet: ethers.Wallet, burnIntent: any ): Promise { const typedData = createBurnIntentTypedData(burnIntent); const signature = await wallet._signTypedData( typedData.domain, { TransferSpec: typedData.types.TransferSpec, BurnIntent: typedData.types.BurnIntent }, typedData.message ); return signature; } // Using viem import { signTypedData } from 'viem/accounts'; async function signBurnIntentViem( walletClient: any, burnIntent: any ): Promise { const typedData = createBurnIntentTypedData(burnIntent); const signature = await walletClient.signTypedData({ domain: typedData.domain, types: { TransferSpec: typedData.types.TransferSpec, BurnIntent: typedData.types.BurnIntent }, primaryType: 'BurnIntent', message: typedData.message }); return signature; } ``` Complete Example: Creating Signed Order for Swap [#complete-example-creating-signed-order-for-swap] ```typescript async function createSignedSwapOrder({ walletClient, userAddress, sourceChains, // Array of chains to pull USDC from destinationChain, // Chain to swap on allocations, // Amount to pull from each source chain recipient, // Swap router address (from quote) hookData, // Hook data from quote gatewayFee // Gateway fee from quote }: { walletClient: any; userAddress: string; sourceChains: ChainConfig[]; destinationChain: ChainConfig; allocations: { chainId: number; amount: string }[]; recipient: string; hookData: string; gatewayFee: string; }) { // Create burn intents for each source chain const burnIntents = allocations.map((allocation, index) => { const sourceChain = sourceChains[index]; return createBurnIntent({ userAddress, sourceChain, destinationChain, amount: allocation.amount, recipient, hookData, maxFee: gatewayFee }); }); // Create typed data for signing const typedData = createBurnIntentSetTypedData(burnIntents); // Sign the burn intent set const signature = await walletClient.signTypedData({ domain: typedData.domain, types: { TransferSpec: typedData.types.TransferSpec, BurnIntent: typedData.types.BurnIntent, BurnIntentSet: typedData.types.BurnIntentSet }, primaryType: 'BurnIntentSet', message: typedData.message }); // Format for API const signedOrder = burnIntents.map((intent, index) => ({ intent, signature: index === 0 ? signature : undefined // Only first intent needs signature })); return signedOrder; } ``` Depositing USDC to Gateway Wallet [#depositing-usdc-to-gateway-wallet] To deposit USDC into the Gateway wallet, you can use the `depositWithPermit` function which combines USDC approval and deposit in a single transaction using EIP-2612 permits. Gateway Wallet ABI [#gateway-wallet-abi] ```typescript const gatewayWalletAbi = [ { inputs: [ { internalType: "address", name: "token", type: "address" }, { internalType: "address", name: "owner", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "uint8", name: "v", type: "uint8" }, { internalType: "bytes32", name: "r", type: "bytes32" }, { internalType: "bytes32", name: "s", type: "bytes32" } ], name: "depositWithPermit", outputs: [], stateMutability: "nonpayable", type: "function" } ]; ``` Step 1: Generate USDC Permit Signature [#step-1-generate-usdc-permit-signature] ```typescript import { parseUnits } from 'viem'; async function generateUSDCPermit({ walletClient, publicClient, chainId, usdcAddress, usdcName, usdcVersion, ownerAddress, spenderAddress, // Gateway wallet address amount }: { walletClient: any; publicClient: any; chainId: number; usdcAddress: string; usdcName: string; usdcVersion: string; ownerAddress: string; spenderAddress: string; amount: bigint; }) { // Get current nonce const nonce = await publicClient.readContract({ address: usdcAddress, abi: [{ inputs: [{ name: 'owner', type: 'address' }], name: 'nonces', outputs: [{ name: '', type: 'uint256' }], stateMutability: 'view', type: 'function', }], functionName: 'nonces', args: [ownerAddress], }); // Set deadline (e.g., 1 hour from now) const deadline = BigInt(Math.floor(Date.now() / 1000) + 3600); // EIP-2612 Permit types const types = { Permit: [ { name: "owner", type: "address" }, { name: "spender", type: "address" }, { name: "value", type: "uint256" }, { name: "nonce", type: "uint256" }, { name: "deadline", type: "uint256" } ] }; // Domain const domain = { name: usdcName, version: usdcVersion, chainId, verifyingContract: usdcAddress }; // Sign permit const signature = await walletClient.signTypedData({ domain, types, primaryType: 'Permit', message: { owner: ownerAddress, spender: spenderAddress, value: amount, nonce, deadline } }); // Parse signature const { r, s, v } = parseSignature(signature); return { deadline, v, r, s }; } function parseSignature(signature: string) { const r = `0x${signature.slice(2, 66)}`; const s = `0x${signature.slice(66, 130)}`; const v = parseInt(signature.slice(130, 132), 16); return { r, s, v }; } ``` Step 2: Execute depositWithPermit [#step-2-execute-depositwithpermit] ```typescript import { writeContract, waitForTransactionReceipt } from 'viem'; async function depositWithPermit({ walletClient, publicClient, chainConfig, amount, // Amount in USDC (e.g., "1.5" for 1.5 USDC) ownerAddress }: { walletClient: any; publicClient: any; chainConfig: ChainConfig; amount: string; ownerAddress: string; }) { // Convert amount to smallest units (USDC has 6 decimals) const amountInWei = parseUnits(amount, 6); // Generate permit signature const { deadline, v, r, s } = await generateUSDCPermit({ walletClient, publicClient, chainId: chainConfig.id, usdcAddress: chainConfig.usdc.address, usdcName: chainConfig.usdc.name, usdcVersion: chainConfig.usdc.version.toString(), ownerAddress, spenderAddress: chainConfig.gatewayWallet, amount: amountInWei }); // Execute depositWithPermit const hash = await walletClient.writeContract({ address: chainConfig.gatewayWallet, abi: gatewayWalletAbi, functionName: 'depositWithPermit', args: [ chainConfig.usdc.address, ownerAddress, amountInWei, deadline, v, r, s ] }); console.log('Transaction hash:', hash); // Wait for confirmation const receipt = await waitForTransactionReceipt(publicClient, { hash }); console.log('Deposit confirmed:', receipt); return receipt; } ``` Complete Deposit Example [#complete-deposit-example] ```typescript // Example: Deposit 10 USDC on Base chain async function depositExample() { // Get chain config from API const chains = await flashApi.getSupportedChains(); const baseChain = chains.find(c => c.id === 8453); if (!baseChain) { throw new Error('Base chain not found'); } // Deposit 10 USDC const receipt = await depositWithPermit({ walletClient, publicClient, chainConfig: baseChain, amount: '10', ownerAddress: userAddress }); console.log('✅ Deposited 10 USDC to Gateway wallet'); console.log('Transaction:', receipt.transactionHash); // Check new balance const balance = await flashApi.getGatewayBalance(userAddress); console.log('New Gateway balance:', balance.totalBalance); } ```