# Contract Addresses Source: https://docs.fibrous.finance/api-reference/chains-tokens-contracts/contract-addresses Fibrous router contract addresses across all supported chains # Contract Addresses Fibrous router contract addresses can be found below for each supported blockchain network. Please note that router contracts have different addresses on each chain. Always verify you are using the correct contract address for the chain you are working with. ## Starknet | Contract | Mainnet Address | Testnet Address | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **RouterV2** | `0x00f6f4CF62E3C010E0aC2451cC7807b5eEc19a40b0FaaCd00CCA3914280FDf5a` [Voyager](https://voyager.online/contract/0x00f6f4cf62e3c010e0ac2451cc7807b5eec19a40b0faacd00cca3914280fdf5a) [Starkscan](https://starkscan.co/contract/0x00f6f4cf62e3c010e0ac2451cc7807b5eec19a40b0faacd00cca3914280fdf5a) | `0x0144701728b210ccb78b3b50f963e5bc6c22159d90161d821344bcab22fadd2d` [Voyager](https://voyager.online/contract/0x0144701728b210ccb78b3b50f963e5bc6c22159d90161d821344bcab22fadd2d) [Starkscan](https://starkscan.co/contract/0x0144701728b210ccb78b3b50f963e5bc6c22159d90161d821344bcab22fadd2d) | | **RouterV1** | `0x01b23ed400b210766111ba5b1e63e33922c6ba0c45e6ad56ce112e5f4c578e62` [Voyager](https://voyager.online/contract/0x01b23ed400b210766111ba5b1e63e33922c6ba0c45e6ad56ce112e5f4c578e62) [Starkscan](https://starkscan.co/contract/0x01b23ed400b210766111ba5b1e63e33922c6ba0c45e6ad56ce112e5f4c578e62) | - | | **Limit Order Chef** | `0x6895ac06993e5eb4531600e959622d74017e8259310ef98d8c471557815890b` [Voyager](https://voyager.online/contract/0x6895ac06993e5eb4531600e959622d74017e8259310ef98d8c471557815890b) [Starkscan](https://starkscan.co/contract/0x6895ac06993e5eb4531600e959622d74017e8259310ef98d8c471557815890b) | `0x026627b1fb3cb387a0f1b26aebb57033e487e51a5aab1d065bea8f3806396734` [Voyager](https://goerli.voyager.online/contract/0x026627b1fb3cb387a0f1b26aebb57033e487e51a5aab1d065bea8f3806396734) [Starkscan](https://testnet.starkscan.co/contract/0x026627b1fb3cb387a0f1b26aebb57033e487e51a5aab1d065bea8f3806396734) | Starknet uses Cairo contract format. Addresses are in felt252 format. ## Base | Contract | Mainnet Address | | ---------- | -------------------------------------------------------------------------------------------------------------------------------- | | **Router** | `0x274602a953847d807231d2370072f5f4e4594b44` [BaseScan](https://basescan.org/address/0x274602a953847d807231d2370072f5f4e4594b44) | ## Citrea | Contract | Mainnet Address | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Router** | `0x274602a953847d807231d2370072F5f4E4594B44` [Citrea Explorer](https://explorer.mainnet.citrea.xyz/address/0x274602a953847d807231d2370072F5f4E4594B44) | ## HyperEVM | Contract | Mainnet Address | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **Router** | `0x274602a953847d807231d2370072f5f4e4594b44` [HyperEVMScan](https://hyperevmscan.io/address/0x274602a953847d807231d2370072f5f4e4594b44) | ## Monad | Contract | Mainnet Address | | ---------- | -------------------------------------------------------------------------------------------------------------------------------------- | | **Router** | `0x274602a953847d807231d2370072f5f4e4594b44` [MonadVision](https://monadvision.com/address/0x274602a953847d807231d2370072F5f4E4594B44) | Router addresses are automatically included in API responses. You don't need to hardcode them in your application. ## Getting Router Address Programmatically ### Using the API The router address is always included in API responses: ```bash theme={null} curl -X POST "https://api.fibrous.finance/base/execute" \ -H "Content-Type: application/json" \ -d '{...}' ``` Response includes: ```json theme={null} { "to": "0x274602a953847d807231d2370072f5f4e4594b44", // Router address "calldata": "0x...", "value": "0" } ``` ### Using the SDK ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; const fibrous = new FibrousRouter(); const chains = fibrous.supportedChains; // Get router address for a specific chain const baseChain = chains.find(c => c.chain_id === 8453); console.log("Base Router:", baseChain?.router_address); ``` ## Related Resources * [Supported Chains](/api-reference/chains-tokens-contracts/supported-chains) - Network details * [Supported Tokens](/api-reference/chains-tokens-contracts/supported-tokens) - Token addresses * [API Reference](/api-reference/introduction) - API documentation * [SDK Reference](/integrate-best-trading/fibrous-sdk/index) - SDK integration # Supported Chains Source: https://docs.fibrous.finance/api-reference/chains-tokens-contracts/supported-chains Fibrous is currently supported on the following blockchain networks # Supported Chains Fibrous Finance provides optimal token swap routing across multiple blockchain networks. Each network is fully integrated with our routing algorithm to ensure the best possible trading experience. ## Mainnets | Chain Name | Chain ID | Chain Tag | | ------------ | -------- | ---------- | | **Starknet** | SN\_MAIN | `starknet` | | **Base** | 8453 | `base` | | **Citrea** | 4114 | `citrea` | | **HyperEVM** | 998 | `hyperevm` | | **Monad** | 143 | `monad` | ## Chain Details ### Overview Starknet is a permissionless Layer 2 network that uses Cairo VM and STARK proofs for scalability. ### Key Features * **VM Type**: Cairo VM * **Native Token**: ETH * **Block Time**: \~10 seconds * **Unique Features**: Batch swaps, Cairo-specific transaction format ### Network Information * **RPC Endpoint**: `https://starknet-mainnet.public.blastapi.io` * **Explorer**: [Starkscan](https://starkscan.co) * **API Base URL**: `https://api.fibrous.finance/starknet` * **Latest API Version**: `v1` ### Common Tokens | Token | Address | Decimals | | ----- | -------------------------------------------------------------------- | -------- | | ETH | `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` | 18 | | USDC | `0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8` | 6 | | STRK | `0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d` | 18 | Starknet uses a different address format and transaction structure compared to EVM chains. ### Overview Base is an Ethereum Layer 2 optimistic rollup developed by Coinbase, offering low fees and fast transactions. ### Key Features * **VM Type**: EVM Compatible * **Native Token**: ETH * **Block Time**: \~2 seconds * **Unique Features**: Low fees, Coinbase ecosystem integration ### Network Information * **Chain ID**: 8453 * **RPC Endpoint**: `https://mainnet.base.org` * **Explorer**: [Basescan](https://basescan.org) * **API Base URL**: `https://api.fibrous.finance/base/{version}` * **Latest API Version**: `v2` ### Common Tokens | Token | Address | Decimals | | ----- | -------------------------------------------- | -------- | | ETH | `0x0000000000000000000000000000000000000000` | 18 | | USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | 6 | | USDbC | `0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA` | 6 | | WETH | `0x4200000000000000000000000000000000000006` | 18 | | DAI | `0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb` | 18 | Base accepts both `0x0000000000000000000000000000000000000000` and `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native ETH. ### Overview Citrea is Bitcoin's first ZK rollup that enhances Bitcoin blockspace with zero-knowledge technology. It uses Bitcoin as a settlement layer via its BitVM-based trust-minimized two-way bridge, Clementine, while maintaining full EVM compatibility. ### Key Features * **VM Type**: Type 2 zkEVM (EVM Equivalent) * **Native Token**: cBTC * **Block Time**: TBD * **Unique Features**: Bitcoin settlement layer, zero-knowledge proofs, full EVM compatibility, BitVM-based bridge ### Network Information * **Chain ID**: 4114 * **RPC Endpoint**: TBD * **Explorer**: [Citrea Explorer](https://explorer.mainnet.citrea.xyz) * **API Base URL**: `https://api.fibrous.finance/citrea/{version}` * **Latest API Version**: `v2` * **Website**: [Citrea](https://citrea.xyz) * **Router Address**: `0x274602a953847d807231d2370072F5f4E4594B44` [View on Explorer](https://explorer.mainnet.citrea.xyz/address/0x274602a953847d807231d2370072F5f4E4594B44) ### Common Tokens | Token | Address | Decimals | | ------ | -------------------------------------------- | -------- | | cBTC | `0x0000000000000000000000000000000000000000` | 18 | | wcBTC | `0x3100000000000000000000000000000000000006` | 18 | | USDC.e | `0xE045e6c36cF77FAA2CfB54466D71A3aEF7bbE839` | 6 | Citrea is fully EVM compatible (Type 2 zkEVM), enabling all EVM developers to easily build on Bitcoin. The rollup keeps settlement and data availability on-chain, on Bitcoin, while providing a modular execution layer. ### Overview HyperEVM is a high-performance EVM-compatible blockchain optimized for speed and efficiency. ### Key Features * **VM Type**: EVM Compatible * **Native Token**: HYPE * **Block Time**: \~2 seconds * **Unique Features**: Ultra-fast execution, native HYPE token ### Network Information * **Chain ID**: 998 * **RPC Endpoint**: Contact HyperEVM for details * **API Base URL**: `https://api.fibrous.finance/hyperevm/{version}` * **Latest API Version**: `v2` ### Common Tokens | Token | Address | Decimals | | ----- | -------------------------------------------- | -------- | | HYPE | `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` | 18 | | USDC | `0xb88339cb7199b77e23db6e890353e22632ba630f` | 6 | | WHYPE | `0x5555555555555555555555555555555555555555` | 18 | HyperEVM accepts both `0x0000000000000000000000000000000000000000` and `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native HYPE. ### Overview Monad is a high-performance EVM-compatible Layer 1 blockchain designed for parallel execution and optimized throughput. ### Key Features * **VM Type**: EVM Compatible * **Native Token**: MON * **Block Time**: \~1 second * **Unique Features**: Parallel execution, high throughput, EVM compatibility ### Network Information * **Chain ID**: 143 * **RPC Endpoint**: `https://rpc.monad.xyz` * **Explorer**: [MonadVision](https://monadvision.com/address/0x274602a953847d807231d2370072F5f4E4594B44) * **API Base URL**: `https://api.fibrous.finance/monad/{version}` * **Latest API Version**: `v2` ### Common Tokens | Token | Address | Decimals | | ----- | -------------------------------------------- | -------- | | MON | `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` | 18 | | USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | 6 | | WMON | `0x4200000000000000000000000000000000000006` | 18 | Monad accepts both `0x0000000000000000000000000000000000000000` and `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native MON. ## Integration Support ### API Support All chains are fully supported through our unified API: * ✅ Route optimization * ✅ Swap execution * ✅ Calldata generation * ✅ Health monitoring ### SDK Support Our TypeScript SDK supports all chains: ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; const fibrous = new FibrousRouter(); const chains = fibrous.supportedChains; // Supported chains: // - starknet (SN_MAIN) // - base (8453) // - citrea (4114) // - hyperevm (998) // - monad (41454) ``` ### Smart Contract Support Router contracts are deployed on all supported chains. See [Contract Addresses](/api-reference/chains-tokens-contracts/contract-addresses) for details. ## Adding New Chains Interested in adding Fibrous to your chain? We're always looking to expand to new networks. Reach out to learn more about adding Fibrous to your chain ## Network Status Check the real-time status of all supported networks: View live network status and uptime ## Related Resources * [Contract Addresses](/api-reference/chains-tokens-contracts/contract-addresses) - Router and token addresses * [Supported Tokens](/api-reference/chains-tokens-contracts/supported-tokens) - Available tokens per chain * [API Reference](/api-reference/introduction) - API documentation * [SDK Reference](/integrate-best-trading/fibrous-sdk/index) - SDK integration guide # Supported Tokens & Routes Source: https://docs.fibrous.finance/api-reference/chains-tokens-contracts/supported-tokens Fibrous supports token swaps across multiple chains with comprehensive token coverage # Supported Tokens & Routes Fibrous aggregates liquidity from multiple DEX protocols on each supported chain, enabling optimal token swaps with the best possible rates. ## Token Support Overview | Chain | Native Token | | ------------ | ------------ | | **Starknet** | ETH | | **Base** | ETH | | **Citrea** | cBTC | | **HyperEVM** | HYPE | | **Monad** | MON | ## Common Tokens by Chain ### Starknet | Token | Symbol | Address | Decimals | | -------------- | ------ | -------------------------------------------------------------------- | -------- | | Ether | ETH | `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` | 18 | | USD Coin | USDC | `0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8` | 6 | | Starknet Token | STRK | `0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d` | 18 | | Dai Stablecoin | DAI | `0x00da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3` | 18 | | Tether USD | USDT | `0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8` | 6 | ### Base | Token | Symbol | Address | Decimals | | -------------- | ------ | -------------------------------------------- | -------- | | Ether | ETH | `0x0000000000000000000000000000000000000000` | 18 | | USD Coin | USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | 6 | | USD Base Coin | USDbC | `0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA` | 6 | | Wrapped Ether | WETH | `0x4200000000000000000000000000000000000006` | 18 | | Dai Stablecoin | DAI | `0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb` | 18 | | Tether USD | USDT | `0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2` | 6 | Base accepts both `0x0000000000000000000000000000000000000000` and `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native ETH. ### Citrea | Token | Symbol | Address | Decimals | | ---------------------- | ------ | -------------------------------------------- | -------- | | Citrea Bitcoin | cBTC | `0x0000000000000000000000000000000000000000` | 18 | | Wrapped Citrea Bitcoin | wcBTC | `0x3100000000000000000000000000000000000006` | 18 | | Bridged USD Coin | USDC.e | `0xE045e6c36cF77FAA2CfB54466D71A3aEF7bbE839` | 6 | Citrea accepts `0x0000000000000000000000000000000000000000` for native cBTC. wcBTC is the wrapped version of cBTC. ### HyperEVM | Token | Symbol | Address | Decimals | | ------------ | ------ | -------------------------------------------- | -------- | | Hype | HYPE | `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` | 18 | | USD Coin | USDC | `0xb88339cb7199b77e23db6e890353e22632ba630f` | 6 | | Wrapped Hype | WHYPE | `0x5555555555555555555555555555555555555555` | 18 | HyperEVM accepts both `0x0000000000000000000000000000000000000000` and `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native HYPE. ### Monad | Token | Symbol | Address | Decimals | | ------------- | ------ | -------------------------------------------- | -------- | | Monad | MON | `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` | 18 | | USD Coin | USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | 6 | | Wrapped Monad | WMON | `0x4200000000000000000000000000000000000006` | 18 | Monad accepts both `0x0000000000000000000000000000000000000000` and `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native MON. ## Getting Token Information ### Using the API You can query supported tokens through our API: ```bash theme={null} # Get all supported tokens for a chain curl "https://api.fibrous.finance/base/tokens" ``` ### Using the SDK ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; const fibrous = new FibrousRouter(); const chainId = 8453; // Base // Get all supported tokens const tokens = await fibrous.supportedTokens(chainId); // Access specific token const usdc = tokens.get("usdc"); console.log(usdc); // { // address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // decimals: 6, // symbol: "USDC", // name: "USD Coin" // } // Get token by address (for unverified tokens) const customToken = await fibrous.getToken( "0x...", chainId ); ``` ## Supported Liquidity Sources Fibrous aggregates liquidity from multiple DEX protocols on each chain. You can query available protocols through our API: ```bash theme={null} curl https://graph.fibrous.finance/base/protocols ``` **Example Response:** ```json theme={null} [ { "amm_name": "aerodromeV2Stable", "protocol": 1, "type": "Stable", "display_name": "Aerodrome Stable", "image_url": "" }, { "amm_name": "uniswapV3", "protocol": 5, "type": "V3", "display_name": "Uniswap V3", "image_url": "" } // ... more protocols ] ``` **Available Sources:** Aerodrome (Stable, Volatile, Slipstream), Uniswap V2/V3/V4, SushiSwap V2/V3, AlienBase V2/V3, PancakeSwap V2/V3, BaseSwap V2/V3, RocketSwap V2, SmarDex V2, IzumiSwap V3, Baso Finance (V2, Stable), BMX, BVM (V2, Stable), DackieSwap V2/V3, SoSwap V2, Infusion (Stable, Classic), Solidly V3, Curve (Stable NG, Stable Meta, TriCrypto, TwoCrypto), Balancer (V2/V3 Stable, Composable, Weighted, Gyro ECLP), Dodo (CP, DPP, DSP, DVM), Equalizer (V2/V3, Stable), Spark PSM, Fluid Dex, Hydrex and more. ```bash theme={null} curl https://graph.fibrous.finance/hyperevm/protocols ``` **Example Response:** ```json theme={null} [ { "protocol": 1, "amm_name": "hyperSwapV2", "display_name": "HyperSwap V2", "image_url": null, "type": "v2" }, { "protocol": 3, "amm_name": "hyperSwapV3", "display_name": "HyperSwap V3", "image_url": null, "type": "v3" } // ... more protocols ] ``` **Available Sources:** HyperSwap (V2, V2 Stable, V3), KittenSwap (V2, V2 Stable, V3, Algebra V4), Laminar (V2, V3), Ramses (CL, V3), Project X, Hybra Finance (V2, V2 Stable, V3, V4), Hyper Cat V3, GLiquid V3, Curve (TwoCrypto, Stable, TriCrypto), Balancer (Gyro ECLP, ReCCLAMM, Stable, Stable Surge, Weighted, LB Pool), HyperBrick LB, Valantis, BrownFi V2, Upheaval V3, UltraSolid (V2, V3), RingSwap, Funnel (V1, V2), SpinUp (V2, Stable) ```bash theme={null} curl https://graph.fibrous.finance/citrea/protocols ``` **Example Response:** ```json theme={null} [ { "amm_name": "protocolName", "protocol": 1, "type": "V3", "display_name": "Protocol Name", "image_url": "https://raw.githubusercontent.com/..." } // ... more protocols (will be available at launch) ] ``` **Available Sources:** Protocol information will be available once Citrea mainnet launches. ```bash theme={null} curl https://graph.fibrous.finance/monad/protocols ``` **Example Response:** ```json theme={null} [ { "protocol": 1, "amm_name": "AethonswapV3", "display_name": "Aethonswap V3", "image_url": null, "type": "v3" }, { "protocol": 12, "amm_name": "UniswapV3", "display_name": "Uniswap V3", "image_url": null, "type": "v3" } // ... more protocols ] ``` **Available Sources:** Aethonswap V3, Octoswap (V2, V3), PancakeSwap (V2, V3), PinotFinance (V2, V3), Purpswap V2, Swyrl (V2, V3), Uniswap (V2, V3, V4), Capricorn CL, Atlantis Algebra, Lfj V1, Dyor Swap ```bash theme={null} curl https://graph.fibrous.finance/starknet/protocols ``` **Example Response:** ```json theme={null} [ { "protocol_id": "jediswap", "name": "JediSwap", "type": "AMM" }, { "protocol_id": "ekubo", "name": "Ekubo", "type": "Concentrated Liquidity" } // ... more protocols ] ``` **Available Sources:** JediSwap, mySwap, 10KSwap, SithSwap, Ekubo, Haiko, StarkDeFi ### Response Structure Each protocol response includes: * **amm\_name** / **protocol\_id**: Unique identifier for the protocol * **protocol**: Protocol number used in routing * **type**: Protocol type (V2, V3, Stable, etc.) * **display\_name** / **name**: Human-readable protocol name * **image\_url**: Logo URL (when available) ## Route Support ### Single-Hop Routes Direct swaps between two tokens through a single liquidity pool: ``` ETH → USDC (via Uniswap V3 ETH/USDC pool) ``` ### Multi-Hop Routes Swaps that route through multiple tokens to find the best price: ``` TokenA → WETH → USDC → TokenB ``` ### Split Routes Large swaps split across multiple protocols to minimize price impact: ``` 1000 ETH → USDC: - 600 ETH via Uniswap V3 - 300 ETH via Aerodrome - 100 ETH via SushiSwap ``` ## Related Resources * [Supported Chains](/api-reference/chains-tokens-contracts/supported-chains) - Network details * [Contract Addresses](/api-reference/chains-tokens-contracts/contract-addresses) - Router addresses * [API Reference](/api-reference/introduction) - API documentation * [SDK Reference](/integrate-best-trading/fibrous-sdk/index) - SDK integration # Get Calldata Source: https://docs.fibrous.finance/api-reference/endpoints/calldata POST /{network}/calldata Get route and transaction calldata in a single request ## Overview **V2 Available**: This endpoint maps to `/{network}/v2/routeAndCallData` in V2, with integrator support and metadata. See [Route and Calldata V2](/api-reference/endpoints/routeAndCallData-v2) and the [V2 Migration Guide](/api-reference/v2-migration). The Calldata endpoint combines the functionality of both `/route` and `/execute` endpoints, providing an optimized way to get transaction calldata in a single API call. This is ideal for applications that want to minimize API calls and latency. ## Supported Networks ```bash theme={null} https://api.fibrous.finance/{network}/calldata ``` ```bash theme={null} https://api.fibrous.finance/hyperevm/calldata ``` ```bash theme={null} https://api.fibrous.finance/citrea/calldata ``` ```bash theme={null} https://api.fibrous.finance/monad/calldata ``` ```bash theme={null} https://api.fibrous.finance/starknet/calldata ``` ## Request Body Parameters The amount of input tokens in wei format. Example: `"1000000000000000000"` for 1 token with 18 decimals The contract address of the input token. The contract address of the output token. Maximum acceptable slippage in percentage (0.1 to 100). The destination address to receive the output tokens. Array of protocol IDs to exclude from routing. If true, only direct swaps will be considered. ## Response This endpoint combines the route and execute responses: Indicates if the route was successfully found Complete route information (same as /route endpoint) Input token details (name, address, decimals, price) Output token details (name, address, decimals, price) Input amount in wei Expected output amount in wei Route calculation time in seconds Array of route segments with swap details Swap parameters for execution Input token address Output token address Exchange rate Protocol identifier Pool address The encoded transaction calldata ready for execution Fibrous Router contract address The amount of native token to send with the transaction ```bash cURL theme={null} curl -X POST "https://api.fibrous.finance/{network}/calldata" \ -H "Content-Type: application/json" \ -d '{ "amount": "1000000000000000000", "tokenInAddress": "0x0000000000000000000000000000000000000000", "tokenOutAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "slippage": 0.5, "destination": "0x1234567890123456789012345678901234567890" }' ``` ```javascript JavaScript theme={null} const response = await fetch('https://api.fibrous.finance/{network}/calldata', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: '1000000000000000000', tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', slippage: 0.5, destination: '0x1234567890123456789012345678901234567890' }) }); const data = await response.json(); // Execute the transaction const tx = await wallet.sendTransaction({ to: data.to, data: data.calldata, value: data.value }); ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/{network}/calldata" payload = { "amount": "1000000000000000000", "tokenInAddress": "0x0000000000000000000000000000000000000000", "tokenOutAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "slippage": 0.5, "destination": "0x1234567890123456789012345678901234567890" } response = requests.post(url, json=payload) data = response.json() # Use the calldata to execute transaction print(f"Send transaction to: {data['to']}") print(f"Calldata: {data['calldata']}") print(f"Value: {data['value']}") ``` ```java Java theme={null} import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; public class FibrousCalldata { public static void main(String[] args) throws Exception { String url = "https://api.fibrous.finance/{network}/calldata"; Map payload = new HashMap<>(); payload.put("amount", "1000000000000000000"); payload.put("tokenInAddress", "0x0000000000000000000000000000000000000000"); payload.put("tokenOutAddress", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"); payload.put("slippage", 0.5); payload.put("destination", "0x1234567890123456789012345678901234567890"); ObjectMapper mapper = new ObjectMapper(); String jsonBody = mapper.writeValueAsString(payload); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(jsonBody)) .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } ``` ```go Go theme={null} package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" ) type Payload struct { Amount string `json:"amount"` TokenInAddress string `json:"tokenInAddress"` TokenOutAddress string `json:"tokenOutAddress"` Slippage float64 `json:"slippage"` Destination string `json:"destination"` } func main() { url := "https://api.fibrous.finance/{network}/calldata" payload := Payload{ Amount: "1000000000000000000", TokenInAddress: "0x0000000000000000000000000000000000000000", TokenOutAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", Slippage: 0.5, Destination: "0x1234567890123456789012345678901234567890", } jsonData, err := json.Marshal(payload) if err != nil { panic(err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println("Response:", string(body)) } ``` ```json theme={null} { "success": true, "route": { "inputToken": { "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 3171.37 }, "outputToken": { "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.99971 }, "inputAmount": "1000000000000000000", "outputAmount": "3165007379", "time": 0.495, "route": [ { "percent": "51%", "swaps": [[...]] } ] }, "swap_parameters": [ { "token_in": "0x4200000000000000000000000000000000000006", "token_out": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "rate": "3165007379", "protocol_id": "9", "pool_address": "0x72ab388e2e2f6facef59e3c3fa2c4e29011c2d38" } ], "calldata": "0x...", "to": "0x274602a953847d807231d2370072f5f4e4594b44", "value": "1000000000000000000" } ``` ## When to Use This Endpoint * Single-step swap execution * Minimizing API calls * Reducing latency * Simple integrations * Need to display route preview * User confirmation required * Complex routing logic * Custom route manipulation ## Best Practices 1. **Token Approvals** * Check token allowance before calling * Approve Fibrous Router to spend tokens * Not needed for native token swaps 2. **Transaction Execution** * Use the exact `to`, `calldata`, and `value` from response * Set appropriate gas limit (use `estimatedGas` + buffer) * Monitor transaction status after submission 3. **Error Handling** * Implement retry logic for failed requests * Handle insufficient liquidity gracefully * Validate addresses before calling ## Complete Integration Example ```javascript theme={null} import { ethers } from 'ethers'; async function executeSwap(provider, signer) { // 1. Get calldata const response = await fetch('https://api.fibrous.finance/{network}/calldata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: '1000000000000000000', tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', slippage: 0.5, destination: await signer.getAddress() }) }); const data = await response.json(); // 2. Execute transaction const tx = await signer.sendTransaction({ to: data.to, data: data.calldata, value: data.value, gasLimit: Math.floor(Number(data.estimatedGas) * 1.2) // 20% buffer }); // 3. Wait for confirmation const receipt = await tx.wait(); console.log('Swap completed:', receipt.transactionHash); return receipt; } ``` ## Network-Specific Router Addresses ``` Router: 0x... (included in response) ``` ``` Router: 0x... (included in response) ``` ``` Router: 0x... (included in response) ``` ``` Router: 0x... (Cairo format, included in response) ``` Router addresses are always included in the API response. No need to hardcode them in your application. ## Related Endpoints * [Get Route](/api-reference/endpoints/route) - Get route without execution data * [Execute Swap](/api-reference/endpoints/execute) - Execute with existing route * [Health Check](/api-reference/endpoints/health-check) - Check API status * [Route and Calldata V2](/api-reference/endpoints/routeAndCallData-v2) - V2 equivalent of this endpoint * [V2 Migration Guide](/api-reference/v2-migration) - Migrate to V2 API # Calldata (V2) Source: https://docs.fibrous.finance/api-reference/endpoints/calldata-v2 POST /{network}/v2/calldata Generate calldata for executing a swap using a pre-calculated route ## Overview The Calldata V2 endpoint generates transaction calldata for executing a swap using a pre-calculated route. This endpoint is useful when you already have a route from the `/v2/route` endpoint and want to generate the execution calldata with specific slippage and destination parameters. Currently available on EVM networks. V2 API is currently available on EVM networks. V1 endpoints remain available for backward compatibility. ## Endpoint ```bash theme={null} https://api.fibrous.finance/{network}/v2/calldata ``` Generate transaction calldata for executing a swap using a pre-calculated route. This endpoint is useful when you already have a route and want to generate calldata with different slippage or destination parameters. ## Request Body Parameters The complete route response object from the `/v2/route` endpoint. This contains all the necessary information about the optimal route. Maximum acceptable slippage percentage (0-49, e.g., 0.5 for 0.5%). Recipient address for the output tokens. **API Key Required**: Integrator features (integratorAddress, integratorFeePercentageBps or integratorSurplusPercentageBps) require an API key. Partners must obtain an API key from Fibrous to use these monetization features. Include the API key in the request headers as `X-API-Key`. ## Response Route information for the calldata. Input token address Output token address Input amount in wei Output amount in wei Minimum amount to receive (considering slippage) Recipient address Type of swap Array of swap parameters for each hop in the route. Input token address for this swap Output token address for this swap Rate of the swap Protocol identifier Pool address for this swap Type of swap Protocol-specific extra data (hex encoded) Router contract address for executing the swap. API metadata including version and timestamp. API version (e.g., "2.0") Response timestamp in ISO 8601 format ```bash cURL theme={null} curl -X POST "https://api.fibrous.finance/{network}/v2/calldata" \ -H "Content-Type: application/json" \ -d '{ "route": { "success": true, "routeSwapType": 0, "inputToken": { "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 2949.717076112869 }, "inputAmount": "1000000000000000000", "outputToken": { "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.999597487941284 }, "outputAmount": "2951108576", "route": [] }, "slippage": 0.5, "destination": "0x1234567890123456789012345678901234567890" }' ``` ```javascript JavaScript theme={null} const axios = require('axios'); const route = { success: true, routeSwapType: 0, inputToken: { name: "Wrapped Ether", address: "0x4200000000000000000000000000000000000006", decimals: 18, price: 2949.717076112869 }, inputAmount: "1000000000000000000", outputToken: { name: "USD Coin", address: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", decimals: 6, price: 0.999597487941284 }, outputAmount: "2951108576", route: [] }; const data = { route, slippage: 0.5, destination: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }; axios.post('https://api.fibrous.finance/{network}/v2/calldata', data, { headers: { 'Content-Type': 'application/json' } }) .then(response => { console.log(`API Version: ${response.data.meta.apiVersion}`); console.log(`Router: ${response.data.router_address}`); // Use response.data for transaction execution }) .catch(error => console.error(error)); ``` ```python Python theme={null} import requests import json url = "https://api.fibrous.finance/{network}/v2/calldata" route = { "success": True, "routeSwapType": 0, "inputToken": { "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 2949.717076112869 }, "inputAmount": "1000000000000000000", "outputToken": { "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.999597487941284 }, "outputAmount": "2951108576", "route": [] } payload = { "route": route, "slippage": 0.5, "destination": "0x1234567890123456789012345678901234567890" } response = requests.post(url, json=payload) data = response.json() print(f"API Version: {data['meta']['apiVersion']}") print(f"Router Address: {data['router_address']}") ``` ```java Java theme={null} import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; public class FibrousCalldata { public static void main(String[] args) throws Exception { String url = "https://api.fibrous.finance/{network}/v2/calldata"; Map route = new HashMap<>(); route.put("success", true); route.put("routeSwapType", 0); Map inputToken = new HashMap<>(); inputToken.put("name", "Wrapped Ether"); inputToken.put("address", "0x4200000000000000000000000000000000000006"); inputToken.put("decimals", 18); inputToken.put("price", 2949.717076112869); route.put("inputToken", inputToken); route.put("inputAmount", "1000000000000000000"); Map outputToken = new HashMap<>(); outputToken.put("name", "USD Coin"); outputToken.put("address", "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"); outputToken.put("decimals", 6); outputToken.put("price", 0.999597487941284); route.put("outputToken", outputToken); route.put("outputAmount", "2951108576"); route.put("route", new Object[0]); Map payload = new HashMap<>(); payload.put("route", route); payload.put("slippage", 0.5); payload.put("destination", "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"); ObjectMapper mapper = new ObjectMapper(); String jsonBody = mapper.writeValueAsString(payload); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(jsonBody)) .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } ``` ```go Go theme={null} package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" ) type Route struct { Success bool `json:"success"` RouteSwapType int `json:"routeSwapType"` InputToken map[string]interface{} `json:"inputToken"` InputAmount string `json:"inputAmount"` OutputToken map[string]interface{} `json:"outputToken"` OutputAmount string `json:"outputAmount"` Route []interface{} `json:"route"` } type Payload struct { Route Route `json:"route"` Slippage float64 `json:"slippage"` Destination string `json:"destination"` } func main() { url := "https://api.fibrous.finance/{network}/v2/calldata" route := Route{ Success: true, RouteSwapType: 0, InputToken: map[string]interface{}{ "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 2949.717076112869, }, InputAmount: "1000000000000000000", OutputToken: map[string]interface{}{ "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.999597487941284, }, OutputAmount: "2951108576", Route: []interface{}{}, } payload := Payload{ Route: route, Slippage: 0.5, Destination: "0x1234567890123456789012345678901234567890", } jsonData, err := json.Marshal(payload) if err != nil { panic(err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println("Response:", string(body)) } ``` ```json theme={null} { "route": { "token_in": "0x4200000000000000000000000000000000000006", "token_out": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "amount_in": "1000000000000000000", "amount_out": "2951108576", "min_received": "2936407033", "destination": "0x1234567890123456789012345678901234567890", "swap_type": 0 }, "swap_parameters": [ { "token_in": "0x4200000000000000000000000000000000000006", "token_out": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "rate": "2951108576", "protocol_id": "3", "pool_address": "0xb2cc224c1c9fee385f8ad6a55b4d94e92359dc59", "swap_type": 0, "extra_data": "0x0064" } ], "router_address": "0x274602a953847d807231d2370072f5f4e4594b44", "meta": { "apiVersion": "2.0", "timestamp": "2026-01-24T21:46:40.000Z" } } ``` ## Differences from V1 | Feature | V1 | V2 | | ------------------ | ------------ | ---------------- | | HTTP Method | GET | POST | | Meta field | ❌ | ✅ Always present | | Integrator support | ❌ | ✅ With API key | | Request format | Query params | Request body | ## Best Practices 1. **Use fresh routes** - Routes can become stale within 30-60 seconds 2. **Verify min\_received** - Always check that the minimum received amount matches your expectations 3. **Check destination** - Ensure the destination address is correct 4. **Monitor meta.timestamp** - Track when the calldata was generated ## Error Responses ### Invalid Route ```json theme={null} { "success": false, "error": "Invalid route", "details": "The provided route is invalid or expired" } ``` ### Invalid Slippage ```json theme={null} { "success": false, "error": "Invalid slippage", "details": "Slippage must be between 0 and 49" } ``` ## Related Endpoints * [Route V2](/api-reference/endpoints/route-v2) - Get optimal swap routes * [Route and Calldata V2](/api-reference/endpoints/routeAndCallData-v2) - Get route and calldata in one call * [V2 Migration Guide](/api-reference/v2-migration) - Complete migration guide # Execute Swap Source: https://docs.fibrous.finance/api-reference/endpoints/execute POST /{network}/execute Execute a token swap using the optimal route ## Overview **V2 Available**: This endpoint maps to `/{network}/v2/calldata` in V2, with integrator support and metadata. See [Calldata V2](/api-reference/endpoints/calldata-v2) and the [V2 Migration Guide](/api-reference/v2-migration). The Execute endpoint generates the necessary transaction data to execute a token swap using a previously obtained route. This endpoint is available across all supported networks. ## Supported Networks ```bash theme={null} https://api.fibrous.finance/base/execute ``` ```bash theme={null} https://api.fibrous.finance/hyperevm/execute ``` ```bash theme={null} https://api.fibrous.finance/citrea/execute ``` ```bash theme={null} https://api.fibrous.finance/monad/execute ``` ```bash theme={null} https://api.fibrous.finance/starknet/execute ``` Starknet execution uses Cairo-specific transaction format. See [Starknet API](/api-reference/starknet/endpoint/execute) for details. ## Request Body Parameters The route object returned from the `/route` endpoint. This contains all necessary information about the swap path and expected outcomes. Maximum acceptable slippage in percentage (0.1 to 100). Example: `0.5` for 0.5% slippage tolerance The destination address to receive the output tokens. Unix timestamp (in seconds) after which the transaction will revert. Defaults to 20 minutes from the current time if not specified. ## Response The executed route details The amount of input tokens in wei format The amount of output tokens in wei format The minimum amount of output tokens accounting for slippage The destination address for the swap The type of swap operation Swap parameters for every hop in the route The input token address for this hop The output token address for this hop The exchange rate for this swap The protocol identifier The pool address for this swap The type of swap for this hop Additional protocol-specific data The encoded transaction calldata ready for execution Fibrous Router contract address to send the transaction to The amount of native token to send with the transaction (for native token swaps) ## Example Request ```bash cURL theme={null} curl -X POST "https://api.fibrous.finance/{network}/execute" \ -H "Content-Type: application/json" \ -d '{ "route": { "success": true, "inputToken": { "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 3171.37 }, "outputToken": { "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.99971 }, "inputAmount": "1000000000000000000", "outputAmount": "3165007379", "route": [...] }, "slippage": 0.5, "destination": "0x1234567890123456789012345678901234567890" }' ``` ```javascript JavaScript theme={null} const axios = require('axios'); const executeSwap = async () => { const response = await axios.post( 'https://api.fibrous.finance/{network}/execute', { route: { inputToken: { address: '0x0000000000000000000000000000000000000000', decimals: 18, symbol: 'ETH' }, outputToken: { address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', decimals: 6, symbol: 'USDC' }, inputAmount: '1000000000000000000', outputAmount: '2500000000' }, slippage: 0.5, destination: '0x1234567890123456789012345678901234567890' }, { headers: { 'Content-Type': 'application/json' } } ); return response.data; }; ``` ```python Python theme={null} import requests import json url = "https://api.fibrous.finance/{network}/execute" payload = { "route": { "inputToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": 18, "symbol": "ETH" }, "outputToken": { "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "decimals": 6, "symbol": "USDC" }, "inputAmount": "1000000000000000000", "outputAmount": "2500000000" }, "slippage": 0.5, "destination": "0x1234567890123456789012345678901234567890" } headers = { 'Content-Type': 'application/json' } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```java Java theme={null} import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; public class FibrousExecute { public static void main(String[] args) throws Exception { String url = "https://api.fibrous.finance/{network}/execute"; Map route = new HashMap<>(); Map inputToken = new HashMap<>(); inputToken.put("address", "0x0000000000000000000000000000000000000000"); inputToken.put("decimals", 18); inputToken.put("symbol", "ETH"); route.put("inputToken", inputToken); Map outputToken = new HashMap<>(); outputToken.put("address", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"); outputToken.put("decimals", 6); outputToken.put("symbol", "USDC"); route.put("outputToken", outputToken); route.put("inputAmount", "1000000000000000000"); route.put("outputAmount", "2500000000"); Map payload = new HashMap<>(); payload.put("route", route); payload.put("slippage", 0.5); payload.put("destination", "0x1234567890123456789012345678901234567890"); ObjectMapper mapper = new ObjectMapper(); String jsonBody = mapper.writeValueAsString(payload); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(jsonBody)) .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } ``` ```go Go theme={null} package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" ) type Route struct { InputToken map[string]interface{} `json:"inputToken"` OutputToken map[string]interface{} `json:"outputToken"` InputAmount string `json:"inputAmount"` OutputAmount string `json:"outputAmount"` } type Payload struct { Route Route `json:"route"` Slippage float64 `json:"slippage"` Destination string `json:"destination"` } func main() { url := "https://api.fibrous.finance/{network}/execute" route := Route{ InputToken: map[string]interface{}{ "address": "0x0000000000000000000000000000000000000000", "decimals": 18, "symbol": "ETH", }, OutputToken: map[string]interface{}{ "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "decimals": 6, "symbol": "USDC", }, InputAmount: "1000000000000000000", OutputAmount: "2500000000", } payload := Payload{ Route: route, Slippage: 0.5, Destination: "0x1234567890123456789012345678901234567890", } jsonData, err := json.Marshal(payload) if err != nil { panic(err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println("Response:", string(body)) } ``` ```json theme={null} { "route": { "amount_in": "1000000000000000000", "amount_out": "3165007379", "min_received": "3149182360", "destination": "0x1234567890123456789012345678901234567890", "swap_type": 0 }, "swap_parameters": [ { "token_in": "0x4200000000000000000000000000000000000006", "token_out": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "rate": "3165007379", "protocol_id": "9", "pool_address": "0x72ab388e2e2f6facef59e3c3fa2c4e29011c2d38", "swap_type": 0, "extra_data": "0x0064" } ], "calldata": "0x...", "to": "0x274602a953847d807231d2370072f5f4e4594b44", "value": "1000000000000000000" } ``` ## Best Practices 1. **Route Freshness** * Always use a fresh route from the `/route` endpoint * Routes can become stale due to market movements * Implement retry logic with fresh routes if execution fails 2. **Slippage Management** * Set appropriate slippage tolerance based on: * Token pair volatility * Available liquidity * Market conditions * Higher values increase success rate but may result in worse prices * Lower values ensure better prices but may cause more failed transactions 3. **Deadline Setting** * Set reasonable deadlines to prevent stale transactions * Consider network congestion when setting deadlines * Default of 20 minutes is suitable for most cases 4. **Gas Optimization** * Monitor gas costs in responses to optimize future transactions * Consider using direct routes for major pairs * Batch multiple swaps when possible ## Error Responses **Status Code:** 400 ```json theme={null} { "error": "Route expired", "message": "The provided route is no longer valid. Please fetch a new route." } ``` **Solution:** Fetch a new route and retry the execution. **Status Code:** 400 ```json theme={null} { "error": "Insufficient liquidity", "message": "Not enough liquidity available for this swap amount." } ``` **Solution:** Reduce the swap amount or try again later. **Status Code:** 400 ```json theme={null} { "error": "Invalid slippage", "message": "Slippage must be between 0.1 and 100" } ``` **Solution:** Adjust slippage to be within the valid range. ## Network-Specific Notes * Use standard EVM transaction format * Native token swaps require sending value with transaction * Approve token spending before swap if not native token * Gas estimation included in response * Uses Cairo-specific transaction format * Different approval mechanism * See [Starknet Execute](/api-reference/starknet/endpoint/execute) for details ## Complete Swap Flow ```mermaid theme={null} sequenceDiagram participant User participant API participant Router participant DEX User->>API: GET /route API-->>User: Route response User->>API: POST /execute API-->>User: Transaction data User->>Router: Send transaction Router->>DEX: Execute swaps DEX-->>Router: Tokens Router-->>User: Output tokens ``` ## Related Endpoints * [Get Route](/api-reference/endpoints/route) - Find optimal route before execution * [Get Calldata](/api-reference/endpoints/calldata) - Alternative endpoint combining route and execute * [Health Check](/api-reference/endpoints/health-check) - Check API status * [Calldata V2](/api-reference/endpoints/calldata-v2) - V2 equivalent of this endpoint * [V2 Migration Guide](/api-reference/v2-migration) - Migrate to V2 API # Health Check Source: https://docs.fibrous.finance/api-reference/endpoints/health-check GET /{network}/healthcheck Check the API status and network availability ## Overview **V2 Available**: An enhanced version is available at `/{network}/v2/healthcheck` with metadata and API version tracking. See [Health Check V2](/api-reference/endpoints/health-check-v2) and the [V2 Migration Guide](/api-reference/v2-migration). The Health Check endpoint allows you to verify the API status and check if a specific network is operational. This is useful for monitoring, debugging, and implementing fallback logic in your application. ## Supported Networks ```bash theme={null} https://api.fibrous.finance/base/healthcheck ``` ```bash theme={null} https://api.fibrous.finance/hyperevm/healthcheck ``` ```bash theme={null} https://api.fibrous.finance/citrea/healthcheck ``` ```bash theme={null} https://api.fibrous.finance/monad/healthcheck ``` ```bash theme={null} https://api.fibrous.finance/starknet/healthcheck ``` ## Response HTTP status code (200 = healthy) Health status message indicating the API is operational ## Example Request ```bash cURL theme={null} curl "https://api.fibrous.finance/base/healthcheck" ``` ```javascript JavaScript theme={null} const checkHealth = async (network = 'base') => { const response = await fetch( `https://api.fibrous.finance/${network}/healthcheck` ); const data = await response.json(); if (data.staus === 200) { console.log(`${network} API is healthy`); console.log(data.message); } return data; }; // Check health await checkHealth('base'); ``` ```python Python theme={null} import requests def check_health(network='base'): url = f"https://api.fibrous.finance/{network}/healthcheck" response = requests.get(url) data = response.json() if data['staus'] == 200: print(f"{network} API is healthy") print(data['message']) return data # Check health check_health('base') ``` ## Example Response ```json theme={null} { "staus": 200, "message": "{Base} Fibrous Finance Router is alive and well - routing your tokens faster than you can say \"impermanent loss\"" } ``` ## Use Cases Monitor API availability in your application dashboard Implement fallback to alternative networks if one is down Route traffic based on network latency Verify API connectivity when troubleshooting ## Implementation Example ```javascript theme={null} class FibrousClient { constructor() { this.networks = ['base', 'hyperevm', 'citrea', 'starknet']; } async getHealthyNetwork() { const healthChecks = await Promise.all( this.networks.map(async (network) => { try { const response = await fetch( `https://api.fibrous.finance/${network}/health` ); const data = await response.json(); return { network, status: data.status, latency: data.latency?.rpc || Infinity }; } catch (error) { return { network, status: 'unhealthy', latency: Infinity }; } }) ); // Find the healthiest network with lowest latency const healthy = healthChecks .filter(check => check.status === 'healthy') .sort((a, b) => a.latency - b.latency); return healthy[0]?.network || null; } async executeSwapWithFallback(swapParams) { const network = await this.getHealthyNetwork(); if (!network) { throw new Error('No healthy networks available'); } console.log(`Using ${network} network`); // Execute swap on the selected network return this.executeSwap(network, swapParams); } } ``` ## Status Page For real-time status updates and historical uptime data, visit our status page: [https://status.fibrous.finance](https://status.fibrous.finance) ## Best Practices 1. **Periodic Checks** * Check health before critical operations * Implement periodic health checks (every 30-60 seconds) * Cache health status with appropriate TTL 2. **Timeout Handling** * Set reasonable timeout for health checks (2-5 seconds) * Treat timeouts as unhealthy status * Implement exponential backoff for retries 3. **Graceful Degradation** * Have fallback networks configured * Show user-friendly messages during downtime * Queue operations when possible 4. **Monitoring Integration** ```javascript theme={null} // Example: Datadog monitoring async function monitorHealth() { const health = await checkHealth('base'); statsd.gauge('fibrous.api.latency.rpc', health.latency.rpc); statsd.gauge('fibrous.api.latency.database', health.latency.database); if (health.status !== 'healthy') { statsd.increment('fibrous.api.unhealthy'); // Alert your team } } ``` ## Related Resources * [API Status Page](https://status.fibrous.finance) * [Rate Limits](/api-reference/rate-limit) * [Support](/external-links/discord) * [Health Check V2](/api-reference/endpoints/health-check-v2) - Enhanced health check with metadata * [V2 Migration Guide](/api-reference/v2-migration) - Migrate to V2 API # Health Check (V2) Source: https://docs.fibrous.finance/api-reference/endpoints/health-check-v2 GET /{network}/v2/healthcheck Check the health status of the V2 API ## Overview The Health Check V2 endpoint verifies if the API is up and running. This endpoint can be used for monitoring and ensuring the API service is healthy. Currently available on EVM networks. V2 API is currently available on EVM networks. V1 endpoints remain available for backward compatibility. ## Endpoint ```bash theme={null} https://api.fibrous.finance/{network}/v2/healthcheck ``` Verify if the Fibrous V2 API is up and running. This endpoint can be used for monitoring and ensuring the API service is healthy. ## Response The HTTP status code. Will be 200 if the service is healthy. A descriptive message about the API status. API metadata including version and timestamp. API version (e.g., "2.0") Response timestamp in ISO 8601 format ```bash cURL theme={null} curl -X GET "https://api.fibrous.finance/{network}/v2/healthcheck" ``` ```javascript JavaScript theme={null} const axios = require('axios'); axios.get('https://api.fibrous.finance/{network}/v2/healthcheck') .then(response => { console.log(`API Version: ${response.data.meta.apiVersion}`); console.log(response.data); }) .catch(error => console.error(error)); ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/{network}/v2/healthcheck" response = requests.get(url) data = response.json() print(f"API Version: {data['meta']['apiVersion']}") print(data) ``` ```java Java theme={null} import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class FibrousHealthCheck { public static void main(String[] args) throws Exception { String url = "https://api.fibrous.finance/{network}/v2/healthcheck"; HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .GET() .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { url := "https://api.fibrous.finance/{network}/v2/healthcheck" resp, err := http.Get(url) if err != nil { panic(err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println("Response:", string(body)) } ``` ```json theme={null} { "status": 200, "message": "{Monad} Fibrous Finance Router is alive and well - routing your tokens faster than you can say \"impermanent loss\"", "meta": { "apiVersion": "2.0", "timestamp": "2026-01-24T21:46:35.496Z" } } ``` ## Usage Use this endpoint to: 1. Monitor API availability 2. Check API version 3. Implement health checks in your application 4. Verify connectivity before making other API calls 5. Track API response times via `meta.timestamp` ## Differences from V1 | Feature | V1 | V2 | | -------------------- | -- | ---------------- | | Meta field | ❌ | ✅ Always present | | API version tracking | ❌ | ✅ In meta field | | Timestamp | ❌ | ✅ In meta field | ## Rate Limits The health check endpoint has a higher rate limit than other endpoints. Please refer to our rate limiting documentation for specific details. ## Related Endpoints * [Route V2](/api-reference/endpoints/route-v2) - Find optimal swap routes * [Route and Calldata V2](/api-reference/endpoints/routeAndCallData-v2) - Get route and calldata in one call * [Calldata V2](/api-reference/endpoints/calldata-v2) - Generate transaction data * [V2 Migration Guide](/api-reference/v2-migration) - Complete migration guide # Get Route Source: https://docs.fibrous.finance/api-reference/endpoints/route GET /{network}/route Find the optimal trading route across supported networks ## Overview **V2 Available**: An enhanced version of this endpoint is available at `/{network}/v2/route` with integrator support, metadata, and API key features. See [Get Route V2](/api-reference/endpoints/route-v2) and the [V2 Migration Guide](/api-reference/v2-migration). Route endpoint finds the optimal trading path through Fibrous' integrated liquidity sources to maximize output and minimize slippage. This endpoint is available across all supported networks. ## Supported Networks ```bash theme={null} https://api.fibrous.finance/base/route ``` ```bash theme={null} https://api.fibrous.finance/hyperevm/route ``` ```bash theme={null} https://api.fibrous.finance/citrea/route ``` ```bash theme={null} https://api.fibrous.finance/monad/route ``` ```bash theme={null} https://api.fibrous.finance/starknet/route ``` Starknet has additional batch routing capabilities. See [Starknet API](/api-reference/starknet/endpoint/overview) for details. ## Request Parameters The amount of input tokens in wei format (for EVM chains) or the smallest unit for the token. Example: `"1000000000000000000"` for 1 token with 18 decimals The contract address of the input token. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` or `0x0000000000000000000000000000000000000000` for native tokens Use the Cairo contract address format The contract address of the output token. Maximum acceptable slippage in percentage (0.1 to 100). Example: `0.5` for 0.5% slippage tolerance The destination address to receive the output tokens. If not provided, defaults to the sender address. Array of protocol IDs to exclude from routing. If true, only direct swaps will be considered (no multi-hop routes). ## Response Indicates if the route was successfully found Type of swap route (0 = standard) Information about the input token Token name Token contract address Token decimals Current token price in USD Information about the output token (same structure as inputToken) The amount of input tokens in wei format The expected amount of output tokens in wei format Time taken to calculate the route (in seconds) Estimated gas units for the transaction Estimated gas cost in USD Array of route segments showing how the swap is split Percentage of input amount routed through this segment Array of swap hops for this route segment Protocol ID DEX protocol name Liquidity pool address Input token address for this hop Output token address for this hop Percentage split for this specific swap Protocol-specific data (e.g., fee tier, tick spacing) Indicates if this is an initial route calculation ## Example Request ```bash cURL theme={null} curl "https://api.fibrous.finance/{network}/route?amount=1000000000000000000&tokenInAddress=0x0000000000000000000000000000000000000000&tokenOutAddress=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&slippage=0.5" ``` ```javascript JavaScript theme={null} const params = new URLSearchParams({ amount: '1000000000000000000', tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', slippage: '0.5' }); const response = await fetch(`https://api.fibrous.finance/base/route?${params}`); const data = await response.json(); console.log(data); ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/{network}/route" params = { "amount": "1000000000000000000", "tokenInAddress": "0x0000000000000000000000000000000000000000", "tokenOutAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "slippage": 0.5 } response = requests.get(url, params=params) print(response.json()) ``` ```java Java theme={null} import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; public class FibrousRoute { public static void main(String[] args) throws Exception { String baseUrl = "https://api.fibrous.finance/{network}/route"; String params = "amount=1000000000000000000" + "&tokenInAddress=0x0000000000000000000000000000000000000000" + "&tokenOutAddress=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" + "&slippage=0.5"; HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "?" + params)) .header("Accept", "*/*") .GET() .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { baseURL := "https://api.fibrous.finance/{network}/route" params := url.Values{} params.Add("amount", "1000000000000000000") params.Add("tokenInAddress", "0x0000000000000000000000000000000000000000") params.Add("tokenOutAddress", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913") params.Add("slippage", "0.5") req, err := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil) if err != nil { panic(err) } req.Header.Set("Accept", "*/*") client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println("Response:", string(body)) } ``` ```json theme={null} { "success": true, "routeSwapType": 0, "inputToken": { "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 3171.37 }, "inputAmount": "1000000000000000000", "outputToken": { "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.99971 }, "outputAmount": "3165007379", "time": 0.495, "estimatedGasUsed": "0", "estimatedGasUsedInUsd": 0, "route": [ { "percent": "51%", "swaps": [ [ { "protocol": 9, "poolName": "PancakeSwap V3", "poolAddress": "0x72ab388e2e2f6facef59e3c3fa2c4e29011c2d38", "fromTokenAddress": "0x4200000000000000000000000000000000000006", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "100.00%", "extraData": { "fee": 100 } } ] ] }, { "percent": "49%", "swaps": [ [ { "protocol": 9, "poolName": "PancakeSwap V3", "poolAddress": "0xc211e1f853a898bd1302385ccde55f33a8c4b3f3", "fromTokenAddress": "0x4200000000000000000000000000000000000006", "toTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "percent": "100.00%", "extraData": { "fee": 100 } } ], [ { "protocol": 3, "poolName": "Aerodrome Slipstream", "poolAddress": "0x4e962bb3889bf030368f56810a9c96b83cb3e778", "fromTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "61.00%", "extraData": { "tickSpacing": 100 } }, { "protocol": 3, "poolName": "Aerodrome Slipstream", "poolAddress": "0x3e66e55e97ce60096f74b7c475e8249f2d31a9fb", "fromTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "39.00%", "extraData": { "tickSpacing": 2000 } } ] ] } ], "initial": false } ``` ## Best Practices 1. **Fresh Routes** * Always fetch a new route before executing a swap * Routes can become stale due to market movements * Typical validity: 30-60 seconds depending on market volatility 2. **Slippage Settings** * Stable pairs: 0.1% - 0.5% * Volatile pairs: 1% - 3% * Low liquidity tokens: 3% - 5% 3. **Gas Optimization** * Use `direct: true` for major token pairs * Consider gas costs vs. price improvement for small amounts * Exclude high-gas protocols when optimizing for speed 4. **Error Handling** * Implement retry logic with exponential backoff * Check for insufficient liquidity errors * Validate token addresses before calling ## Network-Specific Notes * Native token: ETH * Common tokens: USDC, USDbC, WETH, DAI * Average block time: \~2 seconds * Native token: HYPE * Common tokens: USDC, WHYPE * Average block time: \~2 seconds * Native token: cBTC * Common tokens: wcBTC, USDC.e * Average block time: TBD * Bitcoin's first ZK rollup with EVM compatibility * Native token: ETH * Common tokens: USDC, STRK * Uses Cairo VM (different address format) * See [Starknet-specific documentation](/api-reference/starknet/endpoint/route) ## Related Endpoints * [Execute](/api-reference/endpoints/execute) - Execute the swap using the route * [Calldata](/api-reference/endpoints/calldata) - Get transaction calldata * [Health Check](/api-reference/endpoints/health-check) - Check API status * [Get Route V2](/api-reference/endpoints/route-v2) - Enhanced route endpoint with integrator support * [V2 Migration Guide](/api-reference/v2-migration) - Migrate to V2 API # Get Route (V2) Source: https://docs.fibrous.finance/api-reference/endpoints/route-v2 GET /{network}/v2/route Find the optimal trading route with V2 API features ## Overview Route V2 endpoint provides the same routing functionality as V1, with additional features including integrator support, enhanced metadata, and improved response structure. Currently available on EVM networks. V2 API is currently available on Evm networks. V1 endpoints remain available for backward compatibility. ## Endpoint ```bash theme={null} https://api.fibrous.finance/{network}/v2/route ``` Find the optimal trading route through Fibrous' integrated liquidity sources to maximize output and minimize slippage. This endpoint analyzes multiple protocols, pool depths, and potential paths to deliver the most efficient swap execution for your tokens. ## What's New in V2 Monetize your integration with fees or surplus sharing All responses include API version and timestamp Track output amounts before and after fees Use API keys for higher rate limits and integrator features ## Query Parameters The amount of input tokens in wei format. For tokens with 18 decimals, multiply the amount by 10^18. Example: `"1000000000000000000"` for 1 token The address of the input token. Example: `"0x0000000000000000000000000000000000000000"` for native token The address of the output token. Example: `"0x3bd359c1119da7da1d913d1c4d2b7c461115433a"` for wrapped token Not supported yet - reserved for future use. Default: `false` If true, only direct swaps between the input and output tokens will be considered. Default: `false` Comma-separated list of protocol IDs to exclude from routing (e.g., "1,2,3"). Default: `""` Integrator wallet address to receive fees or surplus. Requires API key authentication. Integrator fee percentage in basis points (0-500, maximum 5%). Cannot be used together with integratorSurplusPercentageBps. Integrator surplus percentage in basis points (0-5000, maximum 50%). Cannot be used together with integratorFeePercentageBps. **API Key Required**: Integrator features (integratorAddress, integratorFeePercentageBps, integratorSurplusPercentageBps) require an API key. Partners must obtain an API key from Fibrous to use these monetization features. Include the API key in the request headers as `X-API-Key`. ## Response Indicates if the request was successful. Type of swap route (0: ETH to Token, 1: Token to ETH, 2: Token to Token). Details about the input token. The token's name The token's contract address Number of decimals the token uses Current price of the token in USD The input amount in wei format. Details about the output token (same structure as inputToken). The estimated amount of output tokens in wei format. The output amount after integrator fee deduction (if integrator fee is used). Estimated gas cost for the swap in wei. Estimated gas cost in USD. Array of route segments with detailed swap information. Percentage of input amount going through this route Array of swap steps in this route segment Protocol identifier Name of the liquidity pool Address of the liquidity pool Percentage of the segment amount through this pool Protocol-specific parameters Integrator address (if provided). Integrator fee percentage in basis points (if applicable). Integrator surplus percentage in basis points (if applicable). Integrator name from API key (if applicable). API metadata including version and timestamp. API version (e.g., "2.0") Response timestamp in ISO 8601 format ```bash cURL theme={null} curl -L \ "https://api.fibrous.finance/{network}/v2/route?amount=1000000000000000000&tokenInAddress=0x0000000000000000000000000000000000000000&tokenOutAddress=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" \ --header "Accept: */*" ``` ```javascript JavaScript theme={null} const axios = require('axios'); const params = { amount: '1000000000000000000', tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' }; // Optional: Add API key for integrator features const headers = { 'X-API-Key': 'your-api-key-here' }; axios.get('https://api.fibrous.finance/{network}/v2/route', { params, headers }) .then(response => { console.log(`API Version: ${response.data.meta.apiVersion}`); console.log(response.data); }) .catch(error => console.error(error)); ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/{network}/v2/route" params = { "amount": "1000000000000000000", "tokenInAddress": "0x0000000000000000000000000000000000000000", "tokenOutAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" } # Optional: Add API key for integrator features headers = { "X-API-Key": "your-api-key-here" # optional } response = requests.get(url, params=params, headers=headers) data = response.json() print(f"API Version: {data['meta']['apiVersion']}") print(data) ``` ```java Java theme={null} import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; public class FibrousRoute { public static void main(String[] args) throws Exception { String baseUrl = "https://api.fibrous.finance/{network}/v2/route"; String params = "amount=1000000000000000000" + "&tokenInAddress=0x0000000000000000000000000000000000000000" + "&tokenOutAddress=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "?" + params)) .header("Accept", "*/*") // Optional: Add API key for integrator features .header("X-API-Key", "your-api-key-here") .GET() .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { baseURL := "https://api.fibrous.finance/{network}/v2/route" params := url.Values{} params.Add("amount", "1000000000000000000") params.Add("tokenInAddress", "0x0000000000000000000000000000000000000000") params.Add("tokenOutAddress", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913") req, err := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil) if err != nil { panic(err) } req.Header.Set("Accept", "*/*") // Optional: Add API key for integrator features req.Header.Set("X-API-Key", "your-api-key-here") client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println("Response:", string(body)) } ``` ```json theme={null} { "success": true, "routeSwapType": 0, "inputToken": { "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 2949.717076112869 }, "inputAmount": "1000000000000000000", "outputToken": { "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.999597487941284 }, "outputAmount": "2951108576", "time": 3.285, "estimatedGasUsed": "0", "estimatedGasUsedInUsd": 0, "route": [ { "percent": "35%", "swaps": [ [ { "protocol": 3, "poolName": "Aerodrome Slipstream", "poolAddress": "0xb2cc224c1c9fee385f8ad6a55b4d94e92359dc59", "fromTokenAddress": "0x4200000000000000000000000000000000000006", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "48.57%", "extraData": { "tickSpacing": 100 } }, { "protocol": 9, "poolName": "PancakeSwap V3", "poolAddress": "0x72ab388e2e2f6facef59e3c3fa2c4e29011c2d38", "fromTokenAddress": "0x4200000000000000000000000000000000000006", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "51.43%", "extraData": { "fee": 100 } } ] ] }, { "percent": "65%", "swaps": [ [ { "protocol": 3, "poolName": "Aerodrome Slipstream", "poolAddress": "0x70acdf2ad0bf2402c957154f944c19ef4e1cbae1", "fromTokenAddress": "0x4200000000000000000000000000000000000006", "toTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "percent": "53.00%", "extraData": { "tickSpacing": 100 } }, { "protocol": 9, "poolName": "PancakeSwap V3", "poolAddress": "0xc211e1f853a898bd1302385ccde55f33a8c4b3f3", "fromTokenAddress": "0x4200000000000000000000000000000000000006", "toTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "percent": "47.00%", "extraData": { "fee": 100 } } ], [ { "protocol": 9, "poolName": "PancakeSwap V3", "poolAddress": "0xb94b22332abf5f89877a14cc88f2abc48c34b3df", "fromTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "75.00%", "extraData": { "fee": 100 } }, { "protocol": 52, "poolName": "Hydrex", "poolAddress": "0x0ba69825c4c033e72309f6ac0bde0023b15cc97c", "fromTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "6.00%", "extraData": null }, { "protocol": 57, "poolName": "Quickswap Algebra", "poolAddress": "0xacc2874ed22e811afdc47979c7b7985cced53b29", "fromTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "18.00%", "extraData": null }, { "protocol": 55, "poolName": "PancakeSwap Infinity", "poolAddress": "0xa0FfB9c1CE1Fe56963B0321B32E7A0302114058b", "fromTokenAddress": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "1.00%", "extraData": { "poolId": "0x2a597b8f49af109cebd39704508265dc0083b4bf95ff4b184fb082ae7d71192e", "token0": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "token1": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf", "fee": 61, "tickSpacing": 1, "hooks": "0x0000000000000000000000000000000000000000" } } ] ] } ], "bestQuotesByProtocols": [], "initial": false, "meta": { "apiVersion": "2.0", "timestamp": "2026-01-24T21:46:39.518Z" } } ``` ## Integrator Features **API Key Required**: To use integrator features, partners must obtain an API key from Fibrous. Contact us at [contact@fibrous.finance](mailto:contact@fibrous.finance) or join our [Discord](https://discord.gg/fibrous) to request an API key. To use integrator features, include your API key in the request headers: ```javascript theme={null} const headers = { 'X-API-Key': 'your-api-key-here' }; const params = { amount: '1000000000000000000', tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x3bd359c1119da7da1d913d1c4d2b7c461115433a', integratorAddress: '0xYourWalletAddress', integratorFeePercentageBps: 100 // 1% fee }; const response = await fetch('https://api.fibrous.finance/{network}/v2/route?' + new URLSearchParams(params), { headers }); ``` You cannot use both `integratorFeePercentageBps` and `integratorSurplusPercentageBps` in the same request. Choose one monetization method. ## Differences from V1 | Feature | V1 | V2 | | -------------------- | -- | ------------------ | | Meta field | ❌ | ✅ Always present | | Integrator support | ❌ | ✅ With API key | | outputAmountAfterFee | ❌ | ✅ When fee is used | | API version tracking | ❌ | ✅ In meta field | ## Best Practices 1. **Always check meta.apiVersion** to ensure you're using the expected API version 2. **Use API keys** for production integrations to access integrator features 3. **Monitor meta.timestamp** for debugging and tracking response times 4. **Handle outputAmountAfterFee** when using integrator fees to show accurate amounts to users ## Related Endpoints * [Route V1](/api-reference/endpoints/route) - Original route endpoint * [Route and Calldata V2](/api-reference/endpoints/routeAndCallData-v2) - Get route and calldata in one call * [Calldata V2](/api-reference/endpoints/calldata-v2) - Generate calldata from route * [V2 Migration Guide](/api-reference/v2-migration) - Complete migration guide # Route and Calldata (V2) Source: https://docs.fibrous.finance/api-reference/endpoints/routeAndCallData-v2 GET /{network}/v2/routeAndCallData Get route and calldata in a single V2 API request **Important**: If integrator fees are used (integratorFeePercentageBps > 0), the `min_received` value in the calldata response will be the amount after fees have been deducted and slippage has been applied. This ensures the minimum received amount accounts for the integrator fee that will be taken from the output. ## Overview The Route and Calldata V2 endpoint combines route finding and calldata generation in a single request, reducing API calls and latency. This is a V2-only endpoint that provides enhanced features including integrator support and metadata. Currently available on EVM networks. This endpoint is V2-only and currently available on EVM networks. For V1, use separate `/route` and `/calldata` endpoints. ## Endpoint ```bash theme={null} https://api.fibrous.finance/{network}/v2/routeAndCallData ``` Find the optimal trading route through Fibrous' integrated liquidity sources and generate the transaction calldata for executing the swap. This endpoint combines route finding with calldata generation, making it ideal for direct integration with smart contracts. ## Query Parameters The amount of input tokens in wei format. For tokens with 18 decimals, multiply the amount by 10^18. Example: `"1000000000000000000"` for 1 token The address of the input token. Example: `"0x0000000000000000000000000000000000000000"` for native token The address of the output token. Example: `"0x3bd359c1119da7da1d913d1c4d2b7c461115433a"` for wrapped token Not supported yet - reserved for future use. Default: `false` If true, only direct swaps between the input and output tokens will be considered. Default: `false` Comma-separated list of protocol IDs to exclude from routing (e.g., "1,2,3"). Default: `""` Maximum acceptable slippage percentage (0-49, e.g., 0.5 for 0.5%). Recipient address for the output tokens. Integrator wallet address to receive fees or surplus. Requires API key authentication. Integrator fee percentage in basis points (0-500, maximum 5%). Cannot be used together with integratorSurplusPercentageBps. Integrator surplus percentage in basis points (0-5000, maximum 50%). Cannot be used together with integratorFeePercentageBps. **API Key Required**: Integrator features (integratorAddress, integratorFeePercentageBps or integratorSurplusPercentageBps) require an API key. Partners must obtain an API key from Fibrous to use these monetization features. Include the API key in the request headers as `X-API-Key`. ## Response The complete route response object (same structure as `/v2/route` endpoint). Indicates if the route calculation was successful. Details about the input token. Details about the output token. The estimated amount of output tokens in wei format. Array of route segments with detailed swap information. API metadata including version and timestamp. Transaction calldata for executing the swap. Route information for the calldata. Input token address Output token address Input amount in wei Output amount in wei Minimum amount to receive (considering slippage). If integrator fees are used, this value already accounts for the fee deduction. Recipient address Type of swap Array of swap parameters for each hop in the route. Input token address for this swap Output token address for this swap Rate of the swap Protocol identifier Pool address for this swap Type of swap Protocol-specific extra data (hex encoded) Router contract address for executing the swap. API metadata including version and timestamp. API version (e.g., "2.0") Response timestamp in ISO 8601 format ```bash cURL theme={null} curl -L \ "https://api.fibrous.finance/{network}/v2/routeAndCallData?amount=1000000000000000000&tokenInAddress=0x0000000000000000000000000000000000000000&tokenOutAddress=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&slippage=0.5&destination=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" \ --header "Accept: */*" ``` ```javascript JavaScript theme={null} const axios = require('axios'); const params = { amount: '1000000000000000000', tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', slippage: 0.5, destination: '0x1234567890123456789012345678901234567890' }; axios.get('https://api.fibrous.finance/{network}/v2/routeAndCallData', { params }) .then(response => { const { route, calldata, router_address, meta } = response.data; console.log(`API Version: ${meta.apiVersion}`); // Use calldata to execute transaction console.log(`Router: ${router_address}`); }) .catch(error => console.error(error)); ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/{network}/v2/routeAndCallData" params = { "amount": "1000000000000000000", "tokenInAddress": "0x0000000000000000000000000000000000000000", "tokenOutAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "slippage": 0.5, "destination": "0x1234567890123456789012345678901234567890" } response = requests.get(url, params=params) data = response.json() print(f"API Version: {data['meta']['apiVersion']}") print(f"Router Address: {data['router_address']}") # Use data['calldata'] to execute transaction ``` ```java Java theme={null} import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; public class FibrousRouteAndCallData { public static void main(String[] args) throws Exception { String baseUrl = "https://api.fibrous.finance/{network}/v2/routeAndCallData"; String params = "amount=1000000000000000000" + "&tokenInAddress=0x0000000000000000000000000000000000000000" + "&tokenOutAddress=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" + "&slippage=0.5" + "&destination=0x1234567890123456789012345678901234567890"; HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "?" + params)) .header("Accept", "*/*") .GET() .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Response: " + response.body()); } } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { baseURL := "https://api.fibrous.finance/{network}/v2/routeAndCallData" params := url.Values{} params.Add("amount", "1000000000000000000") params.Add("tokenInAddress", "0x0000000000000000000000000000000000000000") params.Add("tokenOutAddress", "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913") params.Add("slippage", "0.5") params.Add("destination", "0x1234567890123456789012345678901234567890") req, err := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil) if err != nil { panic(err) } req.Header.Set("Accept", "*/*") client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println("Response:", string(body)) } ``` ```json theme={null} { "route": { "success": true, "routeSwapType": 0, "inputToken": { "name": "Wrapped Ether", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "price": 2949.717076112869 }, "inputAmount": "1000000000000000000", "outputToken": { "name": "USD Coin", "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "decimals": 6, "price": 0.999597487941284 }, "outputAmount": "2951108576", "time": 3.285, "estimatedGasUsed": "0", "estimatedGasUsedInUsd": 0, "route": [ { "percent": "35%", "swaps": [ [ { "protocol": 3, "poolName": "Aerodrome Slipstream", "poolAddress": "0xb2cc224c1c9fee385f8ad6a55b4d94e92359dc59", "fromTokenAddress": "0x4200000000000000000000000000000000000006", "toTokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "percent": "48.57%", "extraData": { "tickSpacing": 100 } } ] ] } ], "bestQuotesByProtocols": [], "initial": false, "meta": { "apiVersion": "2.0", "timestamp": "2026-01-24T21:46:39.518Z" } }, "calldata": { "route": { "token_in": "0x4200000000000000000000000000000000000006", "token_out": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "amount_in": "1000000000000000000", "amount_out": "2951108576", "min_received": "2936407033", "destination": "0x1234567890123456789012345678901234567890", "swap_type": 0 }, "swap_parameters": [ { "token_in": "0x4200000000000000000000000000000000000006", "token_out": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "rate": "2951108576", "protocol_id": "3", "pool_address": "0xb2cc224c1c9fee385f8ad6a55b4d94e92359dc59", "swap_type": 0, "extra_data": "0x0064" } ] }, "router_address": "0x274602a953847d807231d2370072f5f4e4594b44", "meta": { "apiVersion": "2.0", "timestamp": "2026-01-24T21:46:40.000Z" } } ``` ## When to Use This Endpoint * Single-step swap execution * Minimizing API calls * Reducing latency * Simple integrations * Immediate execution needed * Need to display route preview * User confirmation required * Complex routing logic * Custom route manipulation * Two-step flow preferred ## Benefits Over V1 Approach **V1 (2 API calls):** 1. GET `/route` - Get optimal route 2. GET `/calldata` - Generate calldata from route **V2 (1 API call):** 1. GET `/v2/routeAndCallData` - Get route and calldata together This reduces: * API latency (one round trip instead of two) * API call count (50% reduction) * Code complexity (single request handling) ## Best Practices 1. **Verify min\_received** - Always check that the minimum received amount matches your expectations. Note that if integrator fees are used, `min_received` already accounts for the fee deduction. 2. **Check destination** - Ensure the destination address is correct before executing 3. **Use fresh data** - This endpoint provides fresh route and calldata, ideal for immediate execution 4. **Monitor meta.timestamp** - Track when the response was generated for debugging ## Related Endpoints * [Route V2](/api-reference/endpoints/route-v2) - Get route only * [Calldata V2](/api-reference/endpoints/calldata-v2) - Generate calldata from existing route * [V2 Migration Guide](/api-reference/v2-migration) - Complete migration guide # API Errors Source: https://docs.fibrous.finance/api-reference/errors Complete reference for API error codes and error handling ## Overview Fibrous Router API uses standard HTTP status codes and provides detailed error messages to help you understand and resolve issues. All error responses follow a consistent format. ## Error Response Format All error responses follow this structure: ```json theme={null} { "statusCode": 400, "message": "Error message describing what went wrong", "error": "Bad Request" } ``` ## HTTP Status Codes The API uses standard HTTP status codes to indicate the type of error: | Status Code | Name | Description | | ----------- | --------------------- | ----------------------------------------------- | | 200 | OK | Request succeeded | | 400 | Bad Request | Invalid request parameters or validation failed | | 429 | Too Many Requests | Rate limit exceeded | | 500 | Internal Server Error | Server-side error occurred | ## Error Codes ### 400 Bad Request Bad Request errors occur when the request parameters are invalid or validation fails. #### Token Same Error **Error Code:** `400`\ **Message:** `Token in and token out cannot be the same` **Description:** The input token and output token addresses are identical. **Example:** ```json theme={null} { "statusCode": 400, "message": "Token in and token out cannot be the same", "error": "Bad Request" } ``` **Solution:** Ensure `tokenInAddress` and `tokenOutAddress` are different addresses. *** #### Integrator Fee and Surplus Percentage Conflict **Error Code:** `400`\ **Message:** `Integrator fee and integrator surplus percentage cannot be provided together` **Description:** You cannot specify both `integratorFeePercentageBps` and `integratorSurplusPercentageBps` in the same request. **Example:** ```json theme={null} { "statusCode": 400, "message": "Integrator fee and integrator surplus percentage cannot be provided together", "error": "Bad Request" } ``` **Solution:** Use either `integratorFeePercentageBps` OR `integratorSurplusPercentageBps`, but not both. *** #### Validation Errors Validation errors occur when request parameters don't meet the required format or constraints: **Common Validation Errors:** | Field | Validation Rule | Error Message | | -------------------------------- | -------------------------------- | ------------------------------------------------------------------- | | `amount` | Required | `amount should not be null or undefined` | | `tokenInAddress` | Required, Valid Ethereum Address | `tokenInAddress must be an Ethereum address` | | `tokenOutAddress` | Required, Valid Ethereum Address | `tokenOutAddress must be an Ethereum address` | | `slippage` | Required, 0-49 | `slippage must be a number conforming to the specified constraints` | | `destination` | Required, Valid Ethereum Address | `destination must be an Ethereum address` | | `integratorFeePercentageBps` | 0-500 | `integratorFeePercentageBps must not be greater than 500` | | `integratorSurplusPercentageBps` | 0-5000 | `integratorSurplusPercentageBps must not be greater than 5000` | **Example Validation Error:** ```json theme={null} { "statusCode": 400, "message": [ "tokenInAddress must be an Ethereum address", "slippage must be a number conforming to the specified constraints" ], "error": "Bad Request" } ``` **Solution:** Review the validation rules for each parameter and ensure your request meets all requirements. *** #### Invalid Route **Error Code:** `400`\ **Message:** `Invalid route` or custom error message **Description:** The provided route is invalid, expired, or cannot be processed. **Example:** ```json theme={null} { "statusCode": 400, "message": "Invalid route", "error": "Bad Request" } ``` **Solution:** Fetch a fresh route from the `/route` endpoint before generating calldata. *** ### 429 Too Many Requests **Error Code:** `429`\ **Message:** `ThrottlerException: Too Many Requests` **Description:** You have exceeded the rate limit for API requests. The default rate limit is 200 requests per minute. **Example:** ```json theme={null} { "statusCode": 429, "message": "ThrottlerException: Too Many Requests", "error": "Too Many Requests" } ``` **Response Headers:** * `X-RateLimit-Limit`: Maximum number of requests allowed * `X-RateLimit-Remaining`: Number of requests remaining in the current window * `X-RateLimit-Reset`: Time when the rate limit resets (Unix timestamp) * `Retry-After`: Seconds to wait before retrying **Solution:** * Wait for the rate limit to reset (check `Retry-After` header) * Implement exponential backoff in your retry logic * Consider requesting an API key for higher rate limits * Contact [contact@fibrous.finance](mailto:contact@fibrous.finance) for enterprise rate limits API keys provide higher rate limits. Contact us to obtain an API key for your integration. *** ### 500 Internal Server Error **Error Code:** `500`\ **Message:** `Internal server error` **Description:** An unexpected error occurred on the server side. This could be due to: * Temporary service unavailability * Database connectivity issues * Internal processing errors **Example:** ```json theme={null} { "statusCode": 500, "message": "Internal server error", "error": "Internal Server Error" } ``` **Solution:** * Retry the request after a short delay * Check our [Status Page](https://status.fibrous.finance) for service status * If the issue persists, contact support at [contact@fibrous.finance](mailto:contact@fibrous.finance) *** ## Error Handling Best Practices ### 1. Check Status Codes Always check the HTTP status code before processing the response: ```javascript theme={null} const response = await fetch('https://api.fibrous.finance/monad/v2/route?...'); if (!response.ok) { const error = await response.json(); switch (response.status) { case 400: console.error('Bad Request:', error.message); // Handle validation or parameter errors break; case 429: console.error('Rate Limited:', error.message); // Implement retry logic with backoff break; case 500: console.error('Server Error:', error.message); // Retry after delay break; } } ``` ### 2. Handle Rate Limiting Implement exponential backoff for rate limit errors: ```javascript theme={null} async function fetchWithRetry(url, options, retries = 3) { for (let i = 0; i < retries; i++) { const response = await fetch(url, options); if (response.status === 429) { const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); continue; } return response; } throw new Error('Max retries exceeded'); } ``` ### 3. Validate Input Before Request Validate parameters before making API calls to avoid unnecessary requests: ```javascript theme={null} function validateRouteParams(params) { const errors = []; if (!params.amount || params.amount === '0') { errors.push('amount is required and must be greater than 0'); } if (!params.tokenInAddress || !isValidAddress(params.tokenInAddress)) { errors.push('tokenInAddress must be a valid Ethereum address'); } if (!params.tokenOutAddress || !isValidAddress(params.tokenOutAddress)) { errors.push('tokenOutAddress must be a valid Ethereum address'); } if (params.tokenInAddress === params.tokenOutAddress) { errors.push('tokenInAddress and tokenOutAddress cannot be the same'); } if (params.integratorFeePercentageBps && params.integratorSurplusPercentageBps) { errors.push('Cannot use both integratorFeePercentageBps and integratorSurplusPercentageBps'); } return errors; } ``` ### 4. Handle Validation Errors Validation errors may return an array of error messages: ```javascript theme={null} const response = await fetch('https://api.fibrous.finance/monad/v2/route?...'); const data = await response.json(); if (response.status === 400) { if (Array.isArray(data.message)) { // Multiple validation errors data.message.forEach(error => console.error(error)); } else { // Single error message console.error(data.message); } } ``` ### 5. Log Errors for Debugging Log error details for debugging while being careful not to expose sensitive information: ```javascript theme={null} function handleError(error, context) { console.error('API Error:', { status: error.statusCode, message: error.message, context: context, timestamp: new Date().toISOString() }); // Send to error tracking service (e.g., Sentry) // trackError(error, context); } ``` ## Common Error Scenarios ### Scenario 1: Invalid Token Address **Request:** ```bash theme={null} GET /monad/v2/route?amount=1000&tokenInAddress=invalid&tokenOutAddress=0x... ``` **Response:** ```json theme={null} { "statusCode": 400, "message": ["tokenInAddress must be an Ethereum address"], "error": "Bad Request" } ``` **Fix:** Use a valid Ethereum address format (0x followed by 40 hex characters). *** ### Scenario 2: Same Token Addresses **Request:** ```bash theme={null} GET /monad/v2/route?amount=1000&tokenInAddress=0x...&tokenOutAddress=0x... ``` **Response:** ```json theme={null} { "statusCode": 400, "message": "Token in and token out cannot be the same", "error": "Bad Request" } ``` **Fix:** Use different addresses for input and output tokens. *** ### Scenario 3: Rate Limit Exceeded **Request:** Multiple rapid requests **Response:** ```json theme={null} { "statusCode": 429, "message": "ThrottlerException: Too Many Requests", "error": "Too Many Requests" } ``` **Fix:** Implement rate limiting in your application or request an API key for higher limits. *** ### Scenario 4: Missing Required Parameters **Request:** ```bash theme={null} GET /monad/v2/route?amount=1000 ``` **Response:** ```json theme={null} { "statusCode": 400, "message": [ "tokenInAddress should not be empty", "tokenOutAddress should not be empty" ], "error": "Bad Request" } ``` **Fix:** Include all required parameters in your request. *** ## Error Codes Summary * Token addresses are the same * Invalid Ethereum address format * Missing required parameters * Invalid parameter values (out of range, wrong type) * Integrator parameter conflicts * Route amount exceeds maximum * Invalid route provided * Rate limit exceeded * Too many requests in a short time period * Server-side processing error * Temporary service unavailability * Database connectivity issues ## Getting Help If you encounter errors that aren't covered in this documentation: 1. **Check the Error Message**: The error message usually provides specific information about what went wrong 2. **Review Request Parameters**: Ensure all parameters meet the validation requirements 3. **Check Service Status**: Visit our [Status Page](https://status.fibrous.finance) 4. **Contact Support**: * Email: [contact@fibrous.finance](mailto:contact@fibrous.finance) * Discord: [Join our Discord](https://discord.gg/fibrous) ## Related Documentation * [Rate Limits](/api-reference/rate-limit) - Learn about rate limiting * [V2 Migration Guide](/api-reference/v2-migration) - Common issues during migration * [Route V2](/api-reference/endpoints/route-v2) - Route endpoint documentation * [Calldata V2](/api-reference/endpoints/calldata-v2) - Calldata endpoint documentation # Integration Guide Source: https://docs.fibrous.finance/api-reference/integration-guide Essential considerations and best practices for integrating the Fibrous Router API ## Overview This guide covers critical considerations and best practices for integrating the Fibrous Router API into your application. Following these guidelines will ensure a robust, secure, and user-friendly integration. ## Critical Considerations ### 0. Integrator Features - API Key Requirement ⚠️ **API Key Required for Integrator Features**: To use integrator features (fee or surplus sharing), you MUST obtain an API key from Fibrous. Without an API key, integrator parameters will be ignored and normal swap functionality will be used. **Contract Function Selection**: * **Normal Swap** (no API key) → Use `swap()` function * **Integrator Swap** (with API key) → Use `swapIntegrator()` function See [Integrator Features](#8-integrator-features-and-api-key-requirements) section for detailed implementation. *** ### 1. Understanding min\_received Calculation ⚠️🔴 **Critical**: Understanding `min_received` calculation is essential for proper slippage protection, especially when using integrator features. This is one of the most important concepts to understand before integrating. **What is min\_received?** `min_received` is the minimum amount of output tokens the user will receive after accounting for: 1. Integrator fees (if applicable) 2. Slippage tolerance **Calculation Formula:** #### Without Integrator Fee (Normal Swap) ``` min_received = amount_out - slippage_amount ``` Where: * `amount_out` = Expected output amount from route * `slippage_amount` = `amount_out × (slippage / 100)` **Example:** ```javascript theme={null} const amountOut = BigInt('1000000000000000000'); // 1 token const slippage = 0.5; // 0.5% const slippageAmount = (amountOut * BigInt(slippage * 1000)) / BigInt(100000); // slippageAmount = 1000000000000000000 * 500 / 100000 = 5000000000000000 const minReceived = amountOut - slippageAmount; // minReceived = 1000000000000000000 - 5000000000000000 = 995000000000000000 ``` #### With Integrator Fee **Important**: When integrator fee is applied, `min_received` is calculated AFTER deducting the fee. ``` Step 1: Calculate amount after fee amount_out_after_fee = amount_out - fee_amount Step 2: Calculate min_received from amount_after_fee min_received = amount_out_after_fee - slippage_amount ``` **Complete Formula:** ``` min_received = amount_out - fee_amount - slippage_amount ``` Where: * `amount_out` = Expected output amount from route * `fee_amount` = `amount_out × (integratorFeePercentageBps / 10000)` * `slippage_amount` = `amount_out_after_fee × (slippage / 100)` **Detailed Example:** ```javascript theme={null} // Input values const amountOut = BigInt('1000000000000000000'); // 1 token (18 decimals) const integratorFeePercentageBps = 100; // 1% fee (100 basis points) const slippage = 0.5; // 0.5% // Step 1: Calculate fee amount const feeAmount = (amountOut * BigInt(integratorFeePercentageBps)) / BigInt(10000); // feeAmount = 1000000000000000000 * 100 / 10000 = 10000000000000000 (0.01 token) // Step 2: Calculate amount after fee const amountOutAfterFee = amountOut - feeAmount; // amountOutAfterFee = 1000000000000000000 - 10000000000000000 = 990000000000000000 // Step 3: Calculate slippage amount (from amount_after_fee) const slippageAmount = (amountOutAfterFee * BigInt(slippage * 1000)) / BigInt(100000); // slippageAmount = 990000000000000000 * 500 / 100000 = 4950000000000000 // Step 4: Calculate min_received const minReceived = amountOutAfterFee - slippageAmount; // minReceived = 990000000000000000 - 4950000000000000 = 985050000000000000 // Verification: min_received = amount_out - fee_amount - slippage_amount // minReceived = 1000000000000000000 - 10000000000000000 - 4950000000000000 // = 985050000000000000 ✅ ``` **Visual Example:** ``` ┌─────────────────────────────────────────────────────────┐ │ Route Calculation Result │ ├─────────────────────────────────────────────────────────┤ │ amount_out = 1,000,000,000,000,000,000 (1.0 token) │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Step 1: Apply Integrator Fee (1% = 100 bps) │ ├─────────────────────────────────────────────────────────┤ │ fee_amount = 1,000,000,000,000,000,000 × 100 / 10000 │ │ fee_amount = 10,000,000,000,000,000 (0.01 token) │ │ │ │ amount_out_after_fee = 1,000,000,000,000,000,000 │ │ - 10,000,000,000,000,000 │ │ = 990,000,000,000,000,000 │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Step 2: Apply Slippage (0.5%) │ ├─────────────────────────────────────────────────────────┤ │ slippage_amount = 990,000,000,000,000,000 × 500 / 100000│ │ slippage_amount = 4,950,000,000,000,000 (0.00495 token)│ │ │ │ min_received = 990,000,000,000,000,000 │ │ - 4,950,000,000,000,000 │ │ = 985,050,000,000,000,000 │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Final Result │ ├─────────────────────────────────────────────────────────┤ │ Expected Output: 1.0 token │ │ Integrator Fee: -0.01 token (1%) │ │ After Fee: 0.99 token │ │ Slippage Buffer: -0.00495 token (0.5%) │ │ ───────────────────────────────────── │ │ MIN RECEIVED: 0.98505 token │ └─────────────────────────────────────────────────────────┘ ``` **Why This Matters:** 1. **User Protection**: `min_received` ensures users get at least this amount, protecting against: * Price movements (slippage) * Integrator fees * Both combined 2. **Transaction Reversion**: If the actual output is less than `min_received`, the transaction will revert, protecting the user. 3. **Display to Users**: Always show users the `min_received` amount so they know the minimum they'll receive. 4. **Fee Transparency**: Users should see: * Expected output amount * Fee amount (if applicable) * Amount after fee * Minimum received (with slippage) **Implementation:** ```javascript theme={null} function calculateMinReceived(routeResponse, slippage) { let amountOutBase = BigInt(routeResponse.outputAmount); // Deduct integrator fee if applicable if (routeResponse.integratorFeePercentageBps && routeResponse.integratorFeePercentageBps > 0) { const feeAmount = (amountOutBase * BigInt(routeResponse.integratorFeePercentageBps)) / BigInt(10000); amountOutBase = amountOutBase - feeAmount; } // Apply slippage to amount_after_fee const slippageAmount = (amountOutBase * BigInt(slippage * 1000)) / BigInt(100000); const minReceived = amountOutBase - slippageAmount; return { amountOut: routeResponse.outputAmount, amountOutAfterFee: amountOutBase.toString(), feeAmount: routeResponse.integratorFeePercentageBps ? ((BigInt(routeResponse.outputAmount) * BigInt(routeResponse.integratorFeePercentageBps)) / BigInt(10000)).toString() : '0', slippageAmount: slippageAmount.toString(), minReceived: minReceived.toString() }; } ``` *** ### 2. Slippage Management **Setting Appropriate Slippage:** | Token Pair Type | Recommended Slippage | Notes | | ------------------------ | -------------------- | ------------------------------ | | Stable pairs (USDC/USDT) | 0.1% - 0.5% | Low volatility, high liquidity | | Major pairs (ETH/USDC) | 0.5% - 1% | Moderate volatility | | Volatile pairs | 1% - 3% | Higher price movement risk | | Low liquidity tokens | 3% - 5% | May need higher slippage | **Best Practice:** ```javascript theme={null} function getSlippageTolerance(tokenIn, tokenOut) { // Stable pairs if (isStablePair(tokenIn, tokenOut)) { return 0.1; // 0.1% } // Major pairs if (isMajorPair(tokenIn, tokenOut)) { return 0.5; // 0.5% } // Default for volatile pairs return 1.0; // 1% } // Always validate slippage function validateSlippage(slippage) { if (slippage < 0 || slippage > 49) { throw new Error('Slippage must be between 0 and 49'); } return slippage; } ``` **Important:** * Never set slippage to 0% - transactions will likely fail * Higher slippage increases success rate but may result in worse prices * Monitor price impact in route responses * Consider showing slippage warning to users for values > 1% *** ### 3. Error Handling **Always implement comprehensive error handling:** ```javascript theme={null} async function handleApiRequest(url, options) { try { const response = await fetch(url, options); if (!response.ok) { const error = await response.json(); switch (response.status) { case 400: // Bad request - validation error if (error.message.includes('Token in and token out cannot be the same')) { throw new Error('Cannot swap token to itself'); } throw new Error(`Invalid request: ${error.message}`); case 429: // Rate limited const retryAfter = response.headers.get('Retry-After') || 60; throw new RateLimitError(`Rate limit exceeded. Retry after ${retryAfter} seconds`, retryAfter); case 500: // Server error - retry throw new ServerError('Server error. Please try again.'); default: throw new Error(`API error: ${error.message}`); } } return await response.json(); } catch (error) { // Log error for debugging console.error('API Request failed:', error); // Handle network errors if (error instanceof TypeError) { throw new Error('Network error. Please check your connection.'); } throw error; } } ``` **Key Error Scenarios:** 1. **Token Same Error**: User selected same token for input and output 2. **Rate Limit**: Too many requests - implement exponential backoff 3. **Invalid Route**: Route expired or invalid - fetch new route 4. **Network Error**: Connection issues - retry with backoff 5. **Validation Error**: Invalid parameters - show user-friendly message *** ### 4. Rate Limiting **Default Limits:** * 200 requests per minute (shared across all endpoints) * Rate limits reset every minute **Best Practices:** ```javascript theme={null} class RateLimiter { constructor() { this.queue = []; this.requestsPerMinute = 200; this.windowStart = Date.now(); this.requestCount = 0; } async throttle() { const now = Date.now(); // Reset window if minute passed if (now - this.windowStart >= 60000) { this.windowStart = now; this.requestCount = 0; } // Wait if limit reached if (this.requestCount >= this.requestsPerMinute) { const waitTime = 60000 - (now - this.windowStart); await new Promise(resolve => setTimeout(resolve, waitTime)); this.windowStart = Date.now(); this.requestCount = 0; } this.requestCount++; } } // Use rate limiter const limiter = new RateLimiter(); async function makeRequest(url) { await limiter.throttle(); return fetch(url); } ``` **For Higher Limits:** * Request an API key for increased rate limits * Contact [contact@fibrous.finance](mailto:contact@fibrous.finance) for enterprise limits *** ### 5. Token Approvals **Token Approvals Required**: For ERC-20 token swaps, users must approve the Fibrous Router contract to spend their tokens before executing swaps. **Approval Flow:** ```javascript theme={null} async function checkAndApproveToken(tokenAddress, amount, userAddress, provider) { const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, provider); const routerAddress = '0x274602a953847d807231d2370072f5f4e4594b44'; // Router address // Check current allowance const currentAllowance = await tokenContract.allowance(userAddress, routerAddress); const requiredAmount = ethers.BigNumber.from(amount); if (currentAllowance.lt(requiredAmount)) { // Request approval const signer = provider.getSigner(); const tokenWithSigner = tokenContract.connect(signer); // Approve max amount for better UX (or approve exact amount) const tx = await tokenWithSigner.approve( routerAddress, ethers.constants.MaxUint256 // or requiredAmount for exact approval ); await tx.wait(); return true; } return false; // Already approved } // Before executing swap async function prepareSwap(tokenInAddress, amount, userAddress) { // Native token (ETH/MON) doesn't need approval if (isNativeToken(tokenInAddress)) { return true; } // Check and request approval for ERC-20 tokens const needsApproval = await checkAndApproveToken( tokenInAddress, amount, userAddress, provider ); if (needsApproval) { // Show approval transaction to user // Wait for confirmation } return true; } ``` **Important Notes:** * Native tokens (ETH, MON) don't require approval * Check allowance before every swap * Consider approving max amount for better UX * Show clear approval UI to users *** ### 6. Gas Estimation **Always add gas buffer:** ```javascript theme={null} async function executeSwap(calldataResponse, signer) { const { router_address, calldata } = calldataResponse; // Get estimated gas const estimatedGas = await signer.estimateGas({ to: router_address, data: calldata, value: calldataResponse.value || 0 }); // Add 20% buffer for safety const gasLimit = estimatedGas.mul(120).div(100); // Execute transaction const tx = await signer.sendTransaction({ to: router_address, data: calldata, value: calldataResponse.value || 0, gasLimit: gasLimit }); return tx; } ``` **Best Practices:** * Use estimated gas from API response as baseline * Add 10-20% buffer for safety * Monitor gas prices and adjust accordingly * Consider using `maxFeePerGas` and `maxPriorityFeePerGas` for EIP-1559 *** ### 7. Network-Specific Considerations **EVM Networks (Base, HyperEVM, Citrea, Monad):** * Use standard EVM transaction format * Native tokens: `0x0000000000000000000000000000000000000000` or `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` * Gas estimation required * Token approvals needed for ERC-20 tokens **Starknet:** * Different address format (Cairo) * Different transaction structure * See [Starknet API documentation](/api-reference/starknet/endpoint/overview) *** ### 9. Integrator Features and API Key Requirements **API Key Required**: Integrator features (fee or surplus sharing) require an API key from Fibrous Finance. If you don't have an API key, use normal swap functionality. **Two Swap Modes:** #### Normal Swap (No API Key) If you don't have an API key or don't want to use integrator features: ```javascript theme={null} // Normal swap - no integrator features const route = await fetch(`https://api.fibrous.finance/{network}/v2/route?...`); const calldata = await generateCalldata(route, slippage, destination); // Use standard swap() function in contract const routerContract = new ethers.Contract(ROUTER_ADDRESS, ROUTER_ABI, signer); const tx = await routerContract.swap( calldata.route, calldata.swap_parameters ); ``` #### Integrator Swap (With API Key) If you have an API key and want to monetize your integration: ```javascript theme={null} // Include API key in headers const headers = { 'X-API-Key': 'your-api-key-here', 'Content-Type': 'application/json' }; // Request route with integrator parameters const route = await fetch(`https://api.fibrous.finance/{network}/v2/route?` + new URLSearchParams({ amount, tokenInAddress, tokenOutAddress, integratorAddress: '0xYourWalletAddress', integratorFeePercentageBps: '100' // 1% fee }), { headers } ); const routeData = await route.json(); // Generate calldata - will include integrator_data const calldata = await generateCalldata(routeData, slippage, destination); // ✅ IMPORTANT: Use swapIntegrator() function, not swap() const routerContract = new ethers.Contract(ROUTER_ADDRESS, ROUTER_ABI, signer); const tx = await routerContract.swapIntegrator( calldata.route, calldata.swap_parameters, calldata.integrator_data // Required for integrator swaps ); ``` **Critical Points:** 1. **API Key Required**: Integrator features only work with a valid API key 2. **Function Selection**: * Normal swap → Use `swap()` function * Integrator swap → Use `swapIntegrator()` function 3. **Integrator Data**: When using integrator features, the calldata includes `integrator_data` which must be passed to `swapIntegrator()` **Contract Functions:** ```solidity theme={null} // Standard swap function (no integrator) function swap( RouteParam calldata route, SwapParams[] calldata swap_parameters ) external payable returns (uint256); // Integrator swap function (with fee/surplus) function swapIntegrator( RouteParam calldata route, SwapParams[] calldata swap_parameters, bytes calldata integrator_data ) external payable returns (uint256); ``` *** ### 10. V1 vs V2 API **When to use V1:** * Existing integrations that work well * Simple use cases without integrator features * When you need backward compatibility **When to use V2:** * New integrations * Need integrator features (fee/surplus) * Want enhanced metadata tracking * Prefer clearer endpoint names See [V2 Migration Guide](/api-reference/v2-migration) for detailed comparison and migration steps. **Endpoint Mapping:** * V1 `/calldata` → V2 `/routeAndCallData` (GET) * V1 `/execute` → V2 `/calldata` (POST) *** ### 11. Security Best Practices **Input Validation:** ```javascript theme={null} function validateSwapParams(params) { const errors = []; // Validate amount if (!params.amount || params.amount === '0') { errors.push('Amount must be greater than 0'); } // Validate addresses if (!ethers.utils.isAddress(params.tokenInAddress)) { errors.push('Invalid tokenInAddress'); } if (!ethers.utils.isAddress(params.tokenOutAddress)) { errors.push('Invalid tokenOutAddress'); } // Check same token if (params.tokenInAddress.toLowerCase() === params.tokenOutAddress.toLowerCase()) { errors.push('Cannot swap token to itself'); } // Validate slippage if (params.slippage < 0 || params.slippage > 49) { errors.push('Slippage must be between 0 and 49'); } return errors; } ``` **Security Checklist:** * ✅ Always validate user inputs * ✅ Sanitize addresses (lowercase, checksum) * ✅ Verify route freshness * ✅ Check minimum received amounts * ✅ Never trust client-side calculations * ✅ Use HTTPS only * ✅ Implement request signing for sensitive operations * ✅ Rate limit user requests on your side *** ### 12. User Experience Considerations **Loading States:** ```javascript theme={null} async function swapWithLoadingStates(params) { try { // Show loading: "Finding best route..." setLoadingState('finding-route'); const route = await fetchRoute(params); // Show loading: "Preparing transaction..." setLoadingState('preparing-tx'); const calldata = await generateCalldata(route, params); // Show loading: "Waiting for approval..." if (needsApproval) { setLoadingState('approving'); await approveToken(params.tokenInAddress); } // Show loading: "Confirm transaction..." setLoadingState('confirming'); const tx = await sendTransaction(calldata); // Show loading: "Transaction pending..." setLoadingState('pending'); await tx.wait(); // Success! setLoadingState('success'); } catch (error) { setLoadingState('error'); showError(error.message); } } ``` **User Feedback:** * Show clear loading states * Display route information (output amount, price impact) * Warn about high slippage * Show transaction status * Provide clear error messages * Estimate gas costs *** ### 13. Testing Recommendations **Test Scenarios:** 1. **Happy Path:** * Successful swap with fresh route * Token approval flow * Transaction confirmation 2. **Error Cases:** * Same token addresses * Invalid addresses * Insufficient balance * Rate limiting * Network errors 3. **Edge Cases:** * Very small amounts * Very large amounts * Low liquidity pairs * High volatility tokens 4. **Integration Tests:** * Test on testnets first * Test with small amounts on mainnet * Monitor transaction success rate * Test error recovery **Example Test:** ```javascript theme={null} describe('Swap Integration', () => { it('should execute swap successfully', async () => { // 1. Fetch fresh route const route = await fetchRoute({ amount: '1000000000000000000', tokenInAddress: NATIVE_TOKEN, tokenOutAddress: USDC_ADDRESS }); expect(route.success).toBe(true); expect(route.outputAmount).toBeDefined(); // 2. Generate calldata const calldata = await generateCalldata(route, { slippage: 0.5, destination: USER_ADDRESS }); expect(calldata.calldata).toBeDefined(); expect(calldata.router_address).toBeDefined(); // 3. Execute (on testnet) const tx = await sendTransaction(calldata); expect(tx.hash).toBeDefined(); // 4. Wait for confirmation const receipt = await tx.wait(); expect(receipt.status).toBe(1); }); }); ``` *** ### 14. Monitoring and Analytics **Key Metrics to Track:** * Route fetch success rate * Transaction success rate * Average route calculation time * Average transaction gas cost * Error rates by type * User slippage preferences * Most popular token pairs **Implementation:** ```javascript theme={null} class Analytics { trackRouteFetch(duration, success) { // Track route fetch performance analytics.track('route_fetch', { duration, success, timestamp: Date.now() }); } trackSwapExecution(txHash, success, gasUsed) { // Track swap execution analytics.track('swap_execution', { txHash, success, gasUsed, timestamp: Date.now() }); } trackError(errorType, errorMessage) { // Track errors analytics.track('api_error', { type: errorType, message: errorMessage, timestamp: Date.now() }); } } ``` *** ## Complete Integration Example Here's a complete, production-ready integration example: ```javascript theme={null} class FibrousRouterIntegration { constructor(network, apiKey = null) { this.baseUrl = `https://api.fibrous.finance/${network}/v2`; this.headers = { 'Content-Type': 'application/json', ...(apiKey && { 'X-API-Key': apiKey }) }; } async getRoute(amount, tokenIn, tokenOut, options = {}) { const params = new URLSearchParams({ amount, tokenInAddress: tokenIn, tokenOutAddress: tokenOut, ...(options.direct && { direct: 'true' }), ...(options.excludeProtocols && { excludeProtocols: options.excludeProtocols.join(',') }) }); const response = await fetch(`${this.baseUrl}/route?${params}`, { headers: this.headers }); if (!response.ok) { throw await this.handleError(response); } return await response.json(); } async getRouteAndCalldata(amount, tokenIn, tokenOut, slippage, destination, options = {}) { const params = new URLSearchParams({ amount, tokenInAddress: tokenIn, tokenOutAddress: tokenOut, slippage: slippage.toString(), destination }); const response = await fetch(`${this.baseUrl}/routeAndCallData?${params}`, { headers: this.headers }); if (!response.ok) { throw await this.handleError(response); } return await response.json(); } async generateCalldata(route, slippage, destination) { const response = await fetch(`${this.baseUrl}/calldata`, { method: 'POST', headers: this.headers, body: JSON.stringify({ route, slippage, destination }) }); if (!response.ok) { throw await this.handleError(response); } return await response.json(); } async handleError(response) { const error = await response.json(); switch (response.status) { case 400: return new Error(error.message || 'Invalid request'); case 429: return new Error('Rate limit exceeded. Please try again later.'); case 500: return new Error('Server error. Please try again.'); default: return new Error(error.message || 'Unknown error'); } } async executeSwap(amount, tokenIn, tokenOut, slippage, destination, signer) { try { // 1. Validate inputs this.validateInputs(amount, tokenIn, tokenOut, slippage, destination); // 2. Check token approval (if needed) if (!this.isNativeToken(tokenIn)) { await this.ensureApproval(tokenIn, amount, signer); } // 3. Get fresh route and calldata const { route, calldata, router_address, meta } = await this.getRouteAndCalldata(amount, tokenIn, tokenOut, slippage, destination); // 4. Verify route freshness const routeAge = Date.now() - new Date(meta.timestamp).getTime(); if (routeAge > 60000) { throw new Error('Route expired. Please try again.'); } // 5. Calculate and verify min_received const minReceivedInfo = this.calculateMinReceived(route, slippage); console.log('Swap Details:', { expectedOutput: minReceivedInfo.amountOut, afterFee: minReceivedInfo.amountOutAfterFee, feeAmount: minReceivedInfo.feeAmount, minReceived: minReceivedInfo.minReceived }); // Verify min_received matches calldata if (calldata.route.min_received !== minReceivedInfo.minReceived) { console.warn('min_received mismatch - recalculating calldata'); // Regenerate calldata if mismatch const freshCalldata = await this.generateCalldata(route, slippage, destination); calldata = freshCalldata; } // 6. Estimate gas const estimatedGas = await signer.estimateGas({ to: router_address, data: calldata.calldata, value: this.isNativeToken(tokenIn) ? amount : 0 }); // 7. Determine which contract function to use const routerContract = new ethers.Contract(router_address, ROUTER_ABI, signer); let tx; if (calldata.integrator_data) { // ✅ Use swapIntegrator() when integrator features are enabled tx = await routerContract.swapIntegrator( calldata.route, calldata.swap_parameters, calldata.integrator_data, { value: this.isNativeToken(tokenIn) ? amount : 0, gasLimit: estimatedGas.mul(120).div(100) // 20% buffer } ); } else { // Use standard swap() for normal swaps tx = await routerContract.swap( calldata.route, calldata.swap_parameters, { value: this.isNativeToken(tokenIn) ? amount : 0, gasLimit: estimatedGas.mul(120).div(100) // 20% buffer } ); } return tx; } catch (error) { console.error('Swap execution failed:', error); throw error; } } validateInputs(amount, tokenIn, tokenOut, slippage, destination) { if (!amount || amount === '0') { throw new Error('Amount must be greater than 0'); } if (tokenIn.toLowerCase() === tokenOut.toLowerCase()) { throw new Error('Cannot swap token to itself'); } if (slippage < 0 || slippage > 49) { throw new Error('Slippage must be between 0 and 49'); } if (!ethers.utils.isAddress(destination)) { throw new Error('Invalid destination address'); } } isNativeToken(address) { const nativeAddresses = [ '0x0000000000000000000000000000000000000000', '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' ]; return nativeAddresses.includes(address.toLowerCase()); } async ensureApproval(tokenAddress, amount, signer) { const routerAddress = '0x274602a953847d807231d2370072f5f4e4594b44'; const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, signer); const allowance = await tokenContract.allowance(await signer.getAddress(), routerAddress); if (allowance.lt(amount)) { const tx = await tokenContract.approve(routerAddress, ethers.constants.MaxUint256); await tx.wait(); } } calculateMinReceived(routeResponse, slippage) { let amountOutBase = BigInt(routeResponse.outputAmount); let feeAmount = BigInt(0); // Deduct integrator fee if applicable if (routeResponse.integratorFeePercentageBps && routeResponse.integratorFeePercentageBps > 0) { feeAmount = (amountOutBase * BigInt(routeResponse.integratorFeePercentageBps)) / BigInt(10000); amountOutBase = amountOutBase - feeAmount; } // Apply slippage to amount_after_fee const slippageAmount = (amountOutBase * BigInt(slippage * 1000)) / BigInt(100000); const minReceived = amountOutBase - slippageAmount; return { amountOut: routeResponse.outputAmount, amountOutAfterFee: amountOutBase.toString(), feeAmount: feeAmount.toString(), slippageAmount: slippageAmount.toString(), minReceived: minReceived.toString() }; } } // Usage const router = new FibrousRouterIntegration('monad', 'your-api-key'); const tx = await router.executeSwap( '1000000000000000000', '0x0000000000000000000000000000000000000000', '0x3bd359c1119da7da1d913d1c4d2b7c461115433a', 0.5, userAddress, signer ); ``` *** ## Checklist Before going to production, ensure you've covered: * Route freshness validation * Appropriate slippage settings * Comprehensive error handling * Rate limiting implementation * Token approval flow * Gas estimation with buffer * Input validation * Network-specific handling * User feedback and loading states * Testing on testnets * Error monitoring * Analytics tracking * **Integrator Features (if using)**: * API key obtained from Fibrous * `swapIntegrator()` function used instead of `swap()` * `integrator_data` passed to contract function * `min_received` calculation verified (amount\_out - fee - slippage) * Fee amounts displayed correctly to users *** ## Additional Resources * [API Reference](/api-reference/introduction) - Complete API documentation * [Error Codes](/api-reference/errors) - Error handling reference * [Rate Limits](/api-reference/rate-limit) - Rate limiting details * [V2 Migration Guide](/api-reference/v2-migration) - Migrating to V2 API * [SDK Documentation](/integrate-best-trading/fibrous-sdk/index) - Use our SDK for easier integration *** ## Support Need help with integration? * **Discord**: [Join our Discord](https://discord.gg/fibrous) for community support * **Email**: [contact@fibrous.finance](mailto:contact@fibrous.finance) for direct support * **Documentation**: Check our [FAQ](/essentials/faq) for common questions # API Overview Source: https://docs.fibrous.finance/api-reference/introduction Fibrous Router API provides optimal token swap routing across multiple blockchain networks with the best rates on the market. ## Introduction Fibrous Router API is a cutting-edge discovery and routing algorithm that offers asset exchanges at the best rates on the market. Our API finds the most efficient paths for token swaps, capable of splitting between different protocols and even different market depths within one protocol in the shortest possible time. **Contract ABI**: The router contract ABI is available in our [GitHub repository](https://github.com/Fibrous-Finance/router-contract-abi). ## Supported Networks Fibrous API is available on multiple blockchain networks: * **Starknet** - Cairo-based Layer 2 with batch operations support * **Base** - Optimistic rollup on Ethereum with low fees * **HyperEVM** - High-performance EVM chain with ultra-fast execution * **Citrea** - Bitcoin's first ZK rollup with EVM compatibility * **Monad** - High-performance Layer 1 with parallel execution For detailed network information, see [Supported Chains](/api-reference/chains-tokens-contracts/supported-chains). ## Core Endpoints All networks (except Starknet) share the same endpoint structure: Find the optimal trading route Execute a token swap Get route and calldata in one call Check API and network status Starknet has a different architecture and additional capabilities. See [Starknet API](/api-reference/starknet/endpoint/overview) for details. V2 API offers enhanced features including integrator fee support, improved response metadata, and new endpoints. Currently available on EVM networks. See [V2 Migration Guide](/api-reference/v2-migration) for details. ## Quick Start Here's a complete example of how to perform a swap: ```bash theme={null} curl -X GET "https://api.fibrous.finance/base/route" \ -H "Content-Type: application/json" \ -d '{ "amount": "1000000000000000000", "tokenInAddress": "0x0000000000000000000000000000000000000000", "tokenOutAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "slippage": 0.5 }' ``` ```bash theme={null} curl -X POST "https://api.fibrous.finance/base/execute" \ -H "Content-Type: application/json" \ -d '{ "route": { ... }, "slippage": 0.5, "destination": "0xYourAddress" }' ``` Use the returned calldata to send a transaction using your preferred Web3 library. ## Base URL ``` https://api.fibrous.finance ``` All endpoints follow the pattern: `/{network}/{endpoint}` **Examples:** * `https://api.fibrous.finance/base/v2/route` * `https://api.fibrous.finance/hyperevm/v2/execute` * `https://api.fibrous.finance/citrea/v2/calldata` * `https://api.fibrous.finance/starknet/route` * `https://api.fibrous.finance/monad/v2/route` ## Authentication No authentication is required to use the Fibrous Router API. However, rate limits apply to ensure fair usage. **API Key Required for Integrator Features**: Partners who want to use integrator features (fee or surplus sharing) on V2 API must obtain an API key from Fibrous. Contact us at [contact@fibrous.finance](mailto:contact@fibrous.finance) or join our [Discord](https://discord.gg/fibrous) to request an API key. API keys also provide higher rate limits. Learn about API rate limits and best practices ## Key Features Fibrous aggregates liquidity from multiple DEX protocols on each network, finding the best possible route for your swap. Large swaps can be split across multiple protocols and pools to minimize price impact and maximize output. Routes are calculated in real-time based on current liquidity and prices across all integrated protocols. Our routing algorithm considers gas costs to ensure the best net outcome for your swap. Set custom slippage tolerance to protect against unfavorable price movements during execution. ## Response Format All API responses follow a consistent JSON format: ```json theme={null} { "success": true, "data": { // Endpoint-specific data }, "timestamp": 1699564800 } ``` Error responses include detailed information: ```json theme={null} { "success": false, "error": { "code": "INSUFFICIENT_LIQUIDITY", "message": "Not enough liquidity available for this swap amount", "details": {} }, "timestamp": 1699564800 } ``` ## Best Practices Always fetch a new route before executing. Routes can become stale within 30-60 seconds. Set slippage based on token volatility and liquidity. Stable pairs: 0.1-0.5%, Volatile: 1-3% Implement proper error handling and retry logic for production applications. Essential considerations and best practices for integrating the API Reference guide for all API error codes and error handling Use the estimated gas from API responses and add a 10-20% buffer for safety. ## Need Help? Join our community Read the FAQ Contact us ## Next Steps Learn about each endpoint in detail Use our SDK for easier integration View deployed contract addresses Check real-time API status # Rate Limit Source: https://docs.fibrous.finance/api-reference/rate-limit Learn about API rate limits and enterprise options # Rate Limit The rate limit varies based on the load of the API, but generally it's 200 request per minute. This is across all public endpoints and not specific to each endpoint. To purchase an enterprise rate limit, please send an email to [contact@fibrous.finance](mailto:contact@fibrous.finance) with as many details as possible about your project name, size, and usage requirements. # Batch Route Params Source: https://docs.fibrous.finance/api-reference/starknet/batch-route-params Batch Route Params Page ## Request Parameters | Parameter name | Type | Description | | -------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | amounts \* | \[string] | amounts of tokens to sell, for 1 ETH and 1 Wtbc set as `[1000000000000000000, 100000000]` | | tokenInAddresses \* | \[string] | contract addresses of tokens to sell e.g.: `[0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7, 0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac]` | | tokenOutAddresses \* | \[string] | contract address of a token to buy e.g.: `[0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5eb06f3ecf368a8]` (just one output token supported for now) | | reverse | boolean | Default `false`. it's not supported yet. | | direct | boolean | Default `false`. If it's true direct route | | excludeProtocols | \[string] | The protocol IDs you want to exclude from liquidity sources. | ## Response Parameters | Parameter name | Type | Description | | -------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- | | success | boolean | Indicates if the request was successful. | | routes | array | Array of route objects containing input token details (name, address, decimals, price), output token details, and route segments. | # Calldata Source: https://docs.fibrous.finance/api-reference/starknet/endpoint/calldata GET /starknet/calldata Get calldata for executing a swap through Fibrous ## Endpoint ```bash theme={null} https://api.fibrous.finance/starknet/calldata ``` Generate the calldata required to execute a swap through the Fibrous' router contract. This endpoint provides the raw transaction data that can be used to execute the swap directly through a Web3 provider. ## Request Body Parameters The complete response object from the `/starknet/route` endpoint. This contains all the necessary information about the optimal route. The address of the input token. Example: `"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"` for ETH The address of the output token. Example: `"0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8"` for USDC If true, the amount parameter represents the desired output amount instead of input amount. Default: `false` If true, only direct swaps between the input and output tokens will be considered. Default: `false` Array of protocol names to exclude from routing. Default: `[]` Maximum acceptable slippage in percentage (0.1 to 49). Example: `0.5` for 0.5% slippage tolerance The receiver address for the output token. ## Response The complete response object from the `/starknet/route` endpoint. This contains all the necessary information about the optimal route. The hex-encoded calldata to execute the swap through the router contract. ## Response Types ```typescript theme={null} export class CalldataResponseDto { route: RouteResponse; calldata: string[]; } export type RouteResponse = | { success: false; errorMessage: string; } | { success: true; inputToken: Token; inputAmount: string; outputToken: Token; outputAmount: string; estimatedGasUsed: string; estimatedGasUsedInUsd: number; route: FormattedRoute[]; time: number; bestQuotesByProtocols: any[]; initial: boolean; routeSwapType: route_swap_type; }; export type FormattedRoute = { percent: Percent; swaps: FormattedSwap[][]; }; export type FormattedSwap = { protocol: Protocol; poolName: string; poolAddress: string; fromTokenAddress: string; toTokenAddress: string; percent: Percent; extraData?: any; }; ``` ## Error Responses ### Invalid Route ```json theme={null} { "success": false, "error": "Invalid route", "details": "The provided route is invalid or expired" } ``` ### Invalid Slippage ```json theme={null} { "success": false, "error": "Invalid slippage", "details": "Slippage must be between 0.1 and 49" } ``` ### Invalid Signer ```json theme={null} { "success": false, "error": "Invalid signer", "details": "The provided signer address is not valid" } ``` ```bash cURL theme={null} curl --location 'http://api.fibrous.finance/starknet/calldata?amount=0x0de0b6b3a7640000&tokenInAddress=0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7&tokenOutAddress=0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8&slippage=0.1&destination=0x01fc039de7d864580b57a575e8e6b7114f4d2a954d7d29f876b2eb3dd09394a0' ``` ```python Python theme={null} import requests url = "http://api.fibrous.finance/starknet/calldata?amount=0x0de0b6b3a7640000&tokenInAddress=0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7&tokenOutAddress=0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8&slippage=0.1&destination=0x01fc039de7d864580b57a575e8e6b7114f4d2a954d7d29f876b2eb3dd09394a0" payload = {} headers = {} response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```javascript JavaScript theme={null} const axios = require('axios'); let config = { method: 'get', maxBodyLength: Infinity, url: 'http://api.fibrous.finance/starknet/calldata?amount=0x0de0b6b3a7640000&tokenInAddress=0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7&tokenOutAddress=0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8&slippage=0.1&destination=0x01fc039de7d864580b57a575e8e6b7114f4d2a954d7d29f876b2eb3dd09394a0', headers: { } }; axios.request(config) .then((response) => { console.log(JSON.stringify(response.data)); }) .catch((error) => { console.log(error); }); ``` ```json Response theme={null} { "route": { "success": true, "routeId": "6be48ec4-fd72-4848-9853-07e1794aba3e", "inputToken": { "address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "name": "Ether", "symbol": "ETH", "decimals": 18, "base": true, "native": true, "price": "4729.21" }, "inputAmount": "1000000000000000000", "outputToken": { "address": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "name": "USD Coin", "symbol": "USDC", "decimals": 6, "base": true, "native": false, "price": "0.99981" }, "outputAmount": "4699463143", "time": 1.503, "estimatedGasUsed": 344695077882010240, "estimatedGasUsedInUsd": 0.04676826976284701, "route": [ { "percent": "89%", "swaps": [ [ { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0xc25669ed8b70551736c7833dc0fde2d93d7829df3c0969aaadc642a36d4c98", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "48.31%", "tick_spacing": 1000, "fee": "0x20c49ba5e353f80000000000000000", "liquidity": "18121861980955516", "sqrt_price": "23356049905020762798410560302878241", "pool_key": "0xc25669ed8b70551736c7833dc0fde2d93d7829df3c0969aaadc642a36d4c98", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0x0305a929dfbafeb094fe63430e7f14f9b43a86b29831e3f21088e345ee145d91", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "4.49%", "tick_spacing": 5982, "fee": "0xc49ba5e353f7d00000000000000000", "liquidity": "1988024409739308", "sqrt_price": "23376081081853142768426795891866425", "pool_key": "0x0305a929dfbafeb094fe63430e7f14f9b43a86b29831e3f21088e345ee145d91", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, { "protocol": 9, "poolId": "9:0x05e03162008d76cf645fe53c6c13a7a5fce745e8991c6ffe94400d60e44c210a:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "poolName": "NostraStable", "poolAddress": "0x05e03162008d76cf645fe53c6c13a7a5fce745e8991c6ffe94400d60e44c210a", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "31.46%", "fee": "5000000000000000", "extraData": { "rate_provider1": "0x05a1b2a3cdd0615a706239804e990af3f07b7fb9ba16cef11fac1552059912b9", "rate_provider2": "0x04d94a9b86d12e61351865c0c1cf7ad8aaa02f45fc6dfddc54869b5de6705e87", "amp_start": 25, "amp_end": 100, "rate1": "4710063265940000000000", "rate2": "1000000000000000000000000000000" } }, { "protocol": 2, "poolId": "2:0x04d0390b777b424e43839cd1e744799f3de6c176c7e32c1812a41dbd9c19db6a:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "poolName": "JediSwap", "poolAddress": "0x04d0390b777b424e43839cd1e744799f3de6c176c7e32c1812a41dbd9c19db6a", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "13.48%", "fee": "0.3", "extraData": {} }, { "protocol": 6, "poolId": "6:0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0x071273c5c5780b4be42d9e6567b1b1a6934f43ab8abaf975c0c3da219fc4d040", "poolName": "MyswapCL", "poolAddress": "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "2.25%", "tick_spacing": 10, "fee": "0x1f4", "liquidity": "680564788479507", "sqrt_price": "5437758166868390671900215", "pool_key": "0x071273c5c5780b4be42d9e6567b1b1a6934f43ab8abaf975c0c3da219fc4d040", "extraData": {} } ] ] }, { "percent": "8%", "swaps": [ [ { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x02d91a3f0b1e68b0d5e6f27fb649dcaef141c4efdedb9305764fe22382fc03f0", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "percent": "34.00%", "tick_spacing": 5982, "fee": "0xc49ba5e353f7d00000000000000000", "liquidity": "14679267871345486921322", "sqrt_price": "1839420092889150566493383193281064031", "pool_key": "0x02d91a3f0b1e68b0d5e6f27fb649dcaef141c4efdedb9305764fe22382fc03f0", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x0316eb42a44a40a7c3573b6320f72e34777e6b13ac9a13d50c5deb8a713c0e1d", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "percent": "31.00%", "tick_spacing": 1000, "fee": "0x20c49ba5e353f80000000000000000", "liquidity": "4854909571773452181057", "sqrt_price": "1840582997292339075913712767131718070", "pool_key": "0x0316eb42a44a40a7c3573b6320f72e34777e6b13ac9a13d50c5deb8a713c0e1d", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x01d23cd1b117c9fd7052b4474e7c461589e39ee6f90acebec705f37eb5252471", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "percent": "2.00%", "tick_spacing": 354892, "fee": "0x20c49ba5e353f80000000000000000", "liquidity": "139802832210576943847", "sqrt_price": "1837986790775248850869931843402206401", "pool_key": "0x01d23cd1b117c9fd7052b4474e7c461589e39ee6f90acebec705f37eb5252471", "extraData": { "extension": "0x043e4f09c32d13d43a880e85f69f7de93ceda62d6cf2581a582c6db635548fdc" } }, { "protocol": 9, "poolId": "9:0x068400056dccee818caa7e8a2c305f9a60d255145bac22d6c5c9bf9e2e046b71:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "poolName": "NostraV2", "poolAddress": "0x068400056dccee818caa7e8a2c305f9a60d255145bac22d6c5c9bf9e2e046b71", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "percent": "16.00%", "fee": "0x5", "extraData": {} }, { "protocol": 2, "poolId": "2:0x02ed66297d146ecd91595c3174da61c1397e8b7fcecf25d423b1ba6717b0ece9:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "poolName": "JediSwap", "poolAddress": "0x02ed66297d146ecd91595c3174da61c1397e8b7fcecf25d423b1ba6717b0ece9", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "percent": "3.00%", "fee": "0.3", "extraData": {} }, { "protocol": 6, "poolId": "6:0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x0503f36ee47238549e73e691a840dca44530ed8a2dc98c9bd5adaaacec759536", "poolName": "MyswapCL", "poolAddress": "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "percent": "10.00%", "tick_spacing": 60, "fee": "0xbb8", "liquidity": "889965366693338926873", "sqrt_price": "427724815475510363218869165", "pool_key": "0x0503f36ee47238549e73e691a840dca44530ed8a2dc98c9bd5adaaacec759536", "extraData": {} }, { "protocol": 8, "poolId": "8:0x02045ee4ff371166e6b2b8bd185fd35880f2bfdc8f30d4463bf4a324a7edfa04:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x02045ee4ff371166e6b2b8bd185fd35880f2bfdc8f30d4463bf4a324a7edfa04", "poolName": "JediSwapCL", "poolAddress": "0x02045ee4ff371166e6b2b8bd185fd35880f2bfdc8f30d4463bf4a324a7edfa04", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "percent": "4.00%", "tick_spacing": 60, "fee": "0xbb8", "liquidity": "106452042755923488126", "sqrt_price": "426228830747216117099936844", "pool_key": "0x02045ee4ff371166e6b2b8bd185fd35880f2bfdc8f30d4463bf4a324a7edfa04", "extraData": {} } ], [ { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0x0698f3fbabfb7ab97d2b560ba63329917c6aff2be72bc467266a2fee34543366", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "100.00%", "tick_spacing": 1000, "fee": "0x20c49ba5e353f80000000000000000", "liquidity": "2983406692358421895", "sqrt_price": "126415433958252670078274618966281", "pool_key": "0x0698f3fbabfb7ab97d2b560ba63329917c6aff2be72bc467266a2fee34543366", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } } ] ] }, { "percent": "3%", "swaps": [ [ { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8:0x07fe6f9d2b9f69632211a116ff0749f1277bc214622fc1e772dd280b24dc8473", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "percent": "3.00%", "tick_spacing": 1000, "fee": "0x20c49ba5e353f80000000000000000", "liquidity": "42207485427115", "sqrt_price": "23348532082295602373284849839889066", "pool_key": "0x07fe6f9d2b9f69632211a116ff0749f1277bc214622fc1e772dd280b24dc8473", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, { "protocol": 2, "poolId": "2:0x045e7131d776dddc137e30bdd490b431c7144677e97bf9369f629ed8d3fb7dd6:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "poolName": "JediSwap", "poolAddress": "0x045e7131d776dddc137e30bdd490b431c7144677e97bf9369f629ed8d3fb7dd6", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "percent": "86.00%", "fee": "0.3", "extraData": {} }, { "protocol": 9, "poolId": "9:0x052b136b37a7e6ea52ce1647fb5edc64efe23d449fc1561d9994a9f8feaa6753:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "poolName": "NostraV2", "poolAddress": "0x052b136b37a7e6ea52ce1647fb5edc64efe23d449fc1561d9994a9f8feaa6753", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "percent": "7.00%", "fee": "0xa", "extraData": {} }, { "protocol": 6, "poolId": "6:0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8:0x030baaaf1b243f6e74c656f98dcb24b98687dcbe783d25f35854148c4c602d41", "poolName": "MyswapCL", "poolAddress": "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "percent": "2.00%", "tick_spacing": 10, "fee": "0x1f4", "liquidity": "31214874519446", "sqrt_price": "5437186117343534920496282", "pool_key": "0x030baaaf1b243f6e74c656f98dcb24b98687dcbe783d25f35854148c4c602d41", "extraData": {} }, { "protocol": 8, "poolId": "8:0x0605b2df3c483412bdb0133fb3b74930a52a532e4ce12b3efaae86be8583390f:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8:0x0605b2df3c483412bdb0133fb3b74930a52a532e4ce12b3efaae86be8583390f", "poolName": "JediSwapCL", "poolAddress": "0x0605b2df3c483412bdb0133fb3b74930a52a532e4ce12b3efaae86be8583390f", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "percent": "1.00%", "tick_spacing": 60, "fee": "0xbb8", "liquidity": "3802480556742", "sqrt_price": "5454343979325731925419524", "pool_key": "0x0605b2df3c483412bdb0133fb3b74930a52a532e4ce12b3efaae86be8583390f", "extraData": {} }, { "protocol": 8, "poolId": "8:0x068034cb25db1a4d60b7341f17f092596d9a44e01a6739f7428475b723994cf6:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8:0x068034cb25db1a4d60b7341f17f092596d9a44e01a6739f7428475b723994cf6", "poolName": "JediSwapCL", "poolAddress": "0x068034cb25db1a4d60b7341f17f092596d9a44e01a6739f7428475b723994cf6", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "percent": "1.00%", "tick_spacing": 10, "fee": "0x1f4", "liquidity": "1946897994285", "sqrt_price": "5461347420023146840723167", "pool_key": "0x068034cb25db1a4d60b7341f17f092596d9a44e01a6739f7428475b723994cf6", "extraData": {} } ], [ { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8:0x02c86b7abe3dc5c832e59131fb422d5c57215c16d3e51f7adc96e21d31262a1d", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "100.00%", "tick_spacing": 20, "fee": "0x14f8b588e368f1000000000000000", "liquidity": "2755114608573298", "sqrt_price": "340185810808831823323710136896819153208", "pool_key": "0x02c86b7abe3dc5c832e59131fb422d5c57215c16d3e51f7adc96e21d31262a1d", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } } ] ] } ], "bestQuotesByProtocols": [ { "name": "", "quote": "", "quoteGasAdjusted": "" }, { "name": "", "quote": "", "quoteGasAdjusted": "" }, { "name": "", "quote": "", "quoteGasAdjusted": "" } ], "initial": false }, "calldata": [ "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "1000000000000000000", "0x00", "4694763680", "0x00", "0x01fc039de7d864580b57a575e8e6b7114f4d2a954d7d29f876b2eb3dd09394a0", 20, "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "429959", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x20c49ba5e353f80000000000000000", "1000", "0x00", "1167802495251038139920528015143912", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "39961", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0xc49ba5e353f7d00000000000000000", "5982", "0x00", "1168804054092657138421339794593321", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "279994", "9", "0x05e03162008d76cf645fe53c6c13a7a5fce745e8991c6ffe94400d60e44c210a", "0x00", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "119972", "2", "0x04d0390b777b424e43839cd1e744799f3de6c176c7e32c1812a41dbd9c19db6a", "0x00", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "20025", "6", "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "5", "0x071273c5c5780b4be42d9e6567b1b1a6934f43ab8abaf975c0c3da219fc4d040", "1", "1", "271887908343419533595010", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "27200", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0xc49ba5e353f7d00000000000000000", "5982", "0x00", "36788401857783011329867663865621280620", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "24800", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x20c49ba5e353f80000000000000000", "1000", "0x00", "36811659945846781518274255342634361400", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "1600", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x20c49ba5e353f80000000000000000", "354892", "0x00", "36759735815504977017398636868044128020", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "12800", "9", "0x068400056dccee818caa7e8a2c305f9a60d255145bac22d6c5c9bf9e2e046b71", "0x00", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "2400", "2", "0x02ed66297d146ecd91595c3174da61c1397e8b7fcecf25d423b1ba6717b0ece9", "0x00", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "8000", "6", "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "5", "0x0503f36ee47238549e73e691a840dca44530ed8a2dc98c9bd5adaaacec759536", "0", "1", "8554496309510207264377383300", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "3200", "8", "0x02045ee4ff371166e6b2b8bd185fd35880f2bfdc8f30d4463bf4a324a7edfa04", "3", "0xbb8", "8524576614944322341998736880", "0", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "1000000", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x20c49ba5e353f80000000000000000", "1000", "0x00", "6320771697912633503913730948314", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "900", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "0x20c49ba5e353f80000000000000000", "1000", "0x00", "1167426604114780118664242491994453", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "25800", "2", "0x045e7131d776dddc137e30bdd490b431c7144677e97bf9369f629ed8d3fb7dd6", "0x00", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "2100", "9", "0x052b136b37a7e6ea52ce1647fb5edc64efe23d449fc1561d9994a9f8feaa6753", "0x00", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "600", "6", "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "5", "0x030baaaf1b243f6e74c656f98dcb24b98687dcbe783d25f35854148c4c602d41", "1", "1", "271859305867176746024814", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "300", "8", "0x0605b2df3c483412bdb0133fb3b74930a52a532e4ce12b3efaae86be8583390f", "3", "0xbb8", "272717198966286596270976", "0", "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "300", "8", "0x068034cb25db1a4d60b7341f17f092596d9a44e01a6739f7428475b723994cf6", "3", "0x1f4", "273067371001157342036158", "0", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "1000000", "5", "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "0x14f8b588e368f1000000000000000", "20", "0x00", "340185810808831823323710136896819153208", "1000000" ] } ``` ## Tips 1. Always verify the `min_received` amount matches your expectations 2. Check that the `destination` address is correct 3. Consider gas costs when splitting across multiple protocols 4. Store the route response before requesting calldata ## Rate Limits Please refer to our rate limiting documentation for details about request limits and quotas. ## Related Endpoints * [Route Endpoint](/api-reference/starknet/endpoint/route) - Get optimal swap routes * [Execute Endpoint](/api-reference/starknet/endpoint/execute) - Execute the swap directly # Execute Source: https://docs.fibrous.finance/api-reference/starknet/endpoint/execute POST /starknet/execute Execute a swap using the optimal route found through Fibrous on Starknet ```bash theme={null} https://api.fibrous.finance/starknet/execute ``` Execute a token swap using the optimal route previously found through the route endpoint. This endpoint handles the actual transaction execution and ensures the swap is performed with the best possible outcome on Starknet. # Health Check Source: https://docs.fibrous.finance/api-reference/starknet/endpoint/healthCheck GET /starknet/healthCheck Check the health status of the Fibrous Starknet API ## Endpoint ```bash theme={null} https://api.fibrous.finance/starknet/healthCheck ``` Verify if the Fibrous Starknet API is up and running. This endpoint can be used for monitoring and ensuring the API service is healthy. ## Response The HTTP status code. Will be 200 if the service is healthy. A descriptive message about the API status. ## Error Responses If the service is unhealthy or experiencing issues, the endpoint will return a non-200 status code. ```bash cURL theme={null} curl -X GET "https://api.fibrous.finance/starknet/healthCheck" ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/starknet/healthCheck" response = requests.get(url) print(response.json()) ``` ```javascript JavaScript theme={null} const axios = require('axios'); axios.get('https://api.fibrous.finance/starknet/healthCheck') .then(response => console.log(response.data)) .catch(error => console.error(error)); ``` ```json Response theme={null} { "staus": 200, "message": "{Starknet} Fibrous Finance Router is alive and well - routing your tokens faster than you can say \"impermanent loss\"" } ``` ## Usage Use this endpoint to: 1. Monitor API availability 2. Check API version 3. Implement health checks in your application 4. Verify connectivity before making other API calls ## Rate Limits The health check endpoint has a higher rate limit than other endpoints. Please refer to our rate limiting documentation for specific details. ## Related Endpoints * [Route](/api-reference/starknet/endpoint/route) - Find optimal swap routes * [Calldata](/api-reference/starknet/endpoint/calldata) - Generate transaction data # Route Source: https://docs.fibrous.finance/api-reference/starknet/endpoint/route GET /starknet/route Find optimal route for a token swap through Fibrous on Starknet ```bash theme={null} https://api.fibrous.finance/starknet/route ``` Find the optimal trading route for a token swap through Fibrous's liquidity pools on Starknet. This endpoint analyzes multiple protocols, pool depths, and potential paths to deliver the most efficient swap execution for your tokens. ## Query Parameters Input token amount in wei format. For tokens with 18 decimals, multiply the amount by 10^18. Example: `"1000000000000000000"` (1 ETH) Input token address. Example: `"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"` (ETH) Output token address. Example: `"0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8"` (USDC) If true, the amount parameter represents the desired output amount instead of input amount. Default: `false` If true, only direct swaps between the input and output tokens will be considered. Default: `false` Array of protocol names to exclude from routing. Example: `["JediSwap", "10kSwap"]` ## Response Indicates if the request was successful. Details about the input token Token name Token contract address Token decimals Current token price in USD Details about the output token Token name Token contract address Token decimals Current token price in USD Array of route segments, each containing: Percentage of total amount routed through this segment Array of swap steps in this segment Protocol identifier Name of the liquidity pool Address of the liquidity pool Percentage of segment amount routed through this pool Additional protocol-specific data Time taken to find the route in seconds Estimated gas that will be used for the swap Estimated gas cost in USD ```bash cURL theme={null} curl -L \ "https://api.fibrous.finance/starknet/route?amount=1000000000000000000&tokenInAddress=0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7&tokenOutAddress=0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8" \ --header "Accept: */*" ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/starknet/route" params = { "amount": "1000000000000000000", # 1 ETH "tokenInAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "tokenOutAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8" } response = requests.get(url, params=params) print(response.json()) ``` ```javascript JavaScript theme={null} const axios = require('axios'); const params = { amount: '1000000000000000000', // 1 ETH tokenInAddress: '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', tokenOutAddress: '0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8' }; axios.get('https://api.fibrous.finance/starknet/route', { params }) .then(response => console.log(response.data)) .catch(error => console.error(error)); ``` ```json Response theme={null} { "success": true, "routeId": "b4a3c7ec-cc7a-4911-8271-3bbc0fd0f74c", "inputToken": { "address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "name": "Ether", "symbol": "ETH", "decimals": 18, "base": true, "native": true, "price": "4334.93" }, "inputAmount": "1000000000000000000", "outputToken": { "address": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "name": "Tether USD", "symbol": "USDT", "decimals": 6, "base": true, "native": false, "price": "1" }, "outputAmount": "4294604326", "time": 2.228, "estimatedGasUsed": "452175251237519300", "estimatedGasUsedInUsd": 0.054666630760995635, "route": [ { "percent": "97%", "swaps": [ [ { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0xc25669ed8b70551736c7833dc0fde2d93d7829df3c0969aaadc642a36d4c98", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "74.00%", "tick_spacing": 1000, "fee": "0x20c49ba5e353f80000000000000000", "liquidity": "18192943774893943", "sqrt_price": "22339850386733508665161426074672526", "pool_key": "0xc25669ed8b70551736c7833dc0fde2d93d7829df3c0969aaadc642a36d4c98", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, { "protocol": 5, "poolId": "5:0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0x0305a929dfbafeb094fe63430e7f14f9b43a86b29831e3f21088e345ee145d91", "poolName": "Ekubo", "poolAddress": "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "5.00%", "tick_spacing": 5982, "fee": "0xc49ba5e353f7d00000000000000000", "liquidity": "2225131020847155", "sqrt_price": "22340544698589647251040986459872528", "pool_key": "0x0305a929dfbafeb094fe63430e7f14f9b43a86b29831e3f21088e345ee145d91", "extraData": { "extension": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, { "protocol": 9, "poolId": "9:0x05e03162008d76cf645fe53c6c13a7a5fce745e8991c6ffe94400d60e44c210a:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "poolName": "NostraStable", "poolAddress": "0x05e03162008d76cf645fe53c6c13a7a5fce745e8991c6ffe94400d60e44c210a", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "3.00%", "fee": "5000000000000000", "extraData": { "rate_provider1": "0x05a1b2a3cdd0615a706239804e990af3f07b7fb9ba16cef11fac1552059912b9", "rate_provider2": "0x04d94a9b86d12e61351865c0c1cf7ad8aaa02f45fc6dfddc54869b5de6705e87", "amp_start": 25, "amp_end": 100, "rate1": "4303769280270000000000", "rate2": "1000000000000000000000000000000" } }, { "protocol": 2, "poolId": "2:0x04d0390b777b424e43839cd1e744799f3de6c176c7e32c1812a41dbd9c19db6a:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "poolName": "JediSwap", "poolAddress": "0x04d0390b777b424e43839cd1e744799f3de6c176c7e32c1812a41dbd9c19db6a", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "10.00%", "fee": "0.3", "extraData": {} }, { "protocol": 9, "poolId": "9:0x05ef8800d242c5d5e218605d6a10e81449529d4144185f95bf4b8fb669424516:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "poolName": "NostraV2", "poolAddress": "0x05ef8800d242c5d5e218605d6a10e81449529d4144185f95bf4b8fb669424516", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "1.00%", "fee": "0xa", "extraData": {} }, { "protocol": 6, "poolId": "6:0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0x071273c5c5780b4be42d9e6567b1b1a6934f43ab8abaf975c0c3da219fc4d040", "poolName": "MyswapCL", "poolAddress": "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "6.00%", "tick_spacing": 10, "fee": "0x1f4", "liquidity": "1836583108654633", "sqrt_price": "5199069779344232716823037", "pool_key": "0x071273c5c5780b4be42d9e6567b1b1a6934f43ab8abaf975c0c3da219fc4d040", "extraData": {} }, { "protocol": 6, "poolId": "6:0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111:0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7:0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8:0x018040da4516869bb63f1578b81bf2a7336977b08fb2941de556ca8726913129", "poolName": "MyswapCL", "poolAddress": "0x01114c7103e12c2b2ecbd3a2472ba9c48ddcbf702b1c242dd570057e26212111", "fromTokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "toTokenAddress": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", "percent": "1.00%", "tick_spacing": 60, "fee": "0xbb8", "liquidity": "179539876650193", "sqrt_price": "5205773804419241142396309", "pool_key": "0x018040da4516869bb63f1578b81bf2a7336977b08fb2941de556ca8726913129", "extraData": {} } ] ] } ], "bestQuotesByProtocols": [ {"name": "", "quote": "", "quoteGasAdjusted": ""}, {"name": "", "quote": "", "quoteGasAdjusted": ""}, {"name": "", "quote": "", "quoteGasAdjusted": ""} ], "initial": false } ``` # Route Batch Source: https://docs.fibrous.finance/api-reference/starknet/endpoint/routeBatch GET /starknet/routeBatch Find optimal routes for multiple token swaps through Fibrous on Starknet [https://api.fibrous.finance/starknet](https://api.fibrous.finance/starknet) Find optimal trading routes for multiple token swaps through Fibrous's liquidity pools on Starknet. This endpoint analyzes multiple protocols, pool depths, and potential paths to deliver the most efficient swap execution for your tokens. ## Query Parameters Array of input token amounts in wei format. For tokens with 18 decimals, multiply each amount by 10^18. Example: `["1000000000000000000", "2000000000"]` Array of input token addresses. Example: `["0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5eb06f3ecf368a8"]` Array of output token addresses. Example: `["0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8"]` ## Response Indicates if the request was successful. Array of route objects, each containing: Details about the input token Token name Token contract address Token decimals Current token price in USD Details about the output token Token name Token contract address Token decimals Current token price in USD Array of route segments ```bash cURL theme={null} curl -L \ "https://api.fibrous.finance/starknet/routeBatch?amounts=null&tokenInAddresses=null&tokenOutAddresses=null" \ --header "Accept: */*" ``` ```python Python theme={null} import requests url = "https://api.fibrous.finance/starknet/routeBatch" params = { "amounts": ["1000000000000000000", "2000000000"], "tokenInAddresses": [ "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5eb06f3ecf368a8" ], "tokenOutAddresses": [ "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8" ] } response = requests.get(url, params=params) print(response.json()) ``` ```javascript JavaScript theme={null} const axios = require('axios'); const params = { amounts: ['1000000000000000000', '2000000000'], tokenInAddresses: [ '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', '0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5eb06f3ecf368a8' ], tokenOutAddresses: [ '0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8' ] }; axios.get('https://api.fibrous.finance/starknet/routeBatch', { params }) .then(response => console.log(response.data)) .catch(error => console.error(error)); ``` ```json Response theme={null} { "success": true, "routes": [ { "inputToken": { "name": "Ethereum", "address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "decimals": 18, "price": 1590.87 }, "outputToken": { "name": "USD Coin", "address": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8", "decimals": 6, "price": 0.999982 }, "route": [ { "percent": "100%", "swaps": [ { "protocol": 5, "poolName": "JediSwap", "poolAddress": "0x...", "percent": "100%", "extraData": { "fee": 500 } } ] } ] } ], "time": 1.2, "estimatedGasUsed": "350000", "estimatedGasUsedInUsd": 0.002 } ``` # Execute Params Source: https://docs.fibrous.finance/api-reference/starknet/execute-params Execute Params Page ## Request Parameters | Parameter name | Type | Description | | ------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | amount \* | string | amount of a token to sell, for 1 ETH set as `1000000000000000000` | | tokenInAddress \* | string | contract address of a token to sell e.g.: `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` | | tokenOutAddress \* | string | contract address of a token to buy e.g.: `0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5eb06f3ecf368a8` | | slippage \* | integer | slippage=0.5 means 0.5% slippage is acceptable. Low values increase chances that transaction will fail, high values increase chances of front running. | | destination \* | string | The receiver address for the output token | | reverse | boolean | Default `false`. it's not supported yet. | | direct | boolean | Default `false`. If it's true direct route | | excludeProtocols | \[string] | The protocol ID | ### excludeProtocols This is where you list the IDs of the AMMs you don't want to include. For example, if there are certain AMMs you prefer not to use due to high fees or other reasons, you simply put their unique IDs in this list. [supportPairs](/api-reference/starknet/endpoint/supportPairs) : This function returns a list of supported AMMs, along with the AMM IDs. ## Response Returns data with best route to transaction via Fibrous # Route Params Source: https://docs.fibrous.finance/api-reference/starknet/route-params ## Request Parameters | Parameter name | Type | Description | | ------------------ | --------- | -------------------------------------------------------------------------------------------------------------- | | amount \* | string | amount of a token to sell, for 1 ETH set as `1000000000000000000` | | tokenInAddress \* | string | contract address of a token to sell e.g.: `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` | | tokenOutAddress \* | string | contract address of a token to buy e.g.: `0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5eb06f3ecf368a8` | | reverse | boolean | Default `false`. it's not supported yet. | | direct | boolean | Default `false`. If it's true direct route | | excludeProtocols | \[string] | The protocol ID | ### excludeProtocols This is where you list the IDs of the AMMs you don't want to include. For example, if there are certain AMMs you prefer not to use due to high fees or other reasons, you simply put their unique IDs in this list. [supportPairs](/api-reference/starknet/endpoint/supportPairs) : This function returns a list of supported AMMs, along with the AMM IDs. ## Description of response parameters | Parameter name | Type | Description | | --------------------- | --------- | ------------------------------------------------------------------------- | | success | boolean | It is a boolean value that serves as a status indicator for the API call. | | inputToken | Token | details of a token to sell | | inputAmount | string | details of a token to buy | | outputToken | Token | details of a token to buy | | route | \[Route] | the best route for the swap | | time | number | execute time | | bestQuotesByProtocols | \[string] | quotes from supported AMMs | # V2 API Migration Guide Source: https://docs.fibrous.finance/api-reference/v2-migration Guide to migrating from V1 to V2 API endpoints ## Overview Fibrous Router API V2 introduces enhanced features and improved response structure while maintaining backward compatibility with V1 endpoints. This guide will help you migrate your integration to take advantage of V2 features. ## Quick Reference: Endpoint Mapping **Important**: V2 endpoint names have changed to better reflect their functionality. Pay special attention to these mappings: | V1 Endpoint | V2 Endpoint | HTTP Method | What Changed | | ------------------------ | -------------------------------- | ----------- | --------------------------------------------------------------- | | `/{network}/route` | `/{network}/v2/route` | GET | Same functionality, added integrator support | | `/{network}/calldata` | `/{network}/v2/routeAndCallData` | GET | **Renamed** - Same functionality (route + calldata in one call) | | `/{network}/execute` | `/{network}/v2/calldata` | POST | **Renamed** - Same functionality (generate calldata from route) | | `/{network}/healthcheck` | `/{network}/v2/healthcheck` | GET | Same functionality, added meta field | **Key Changes:** * **V1 `/calldata`** → **V2 `/routeAndCallData`**: Endpoint renamed for clarity (still GET, still returns route + calldata) * **V1 `/execute`** → **V2 `/calldata`**: Endpoint renamed for clarity (still POST, still generates calldata from route) ## What's New in V2 Support for integrator fees and surplus sharing to monetize your integration All responses include API version and timestamp for better tracking Endpoints renamed for clarity: `/calldata` → `/routeAndCallData`, `/execute` → `/calldata` Better organized response format with consistent meta fields ## Key Differences ### Response Structure **V1 Response:** ```json theme={null} { "success": true, "inputToken": {...}, "outputToken": {...}, "outputAmount": "1000000000" } ``` **V2 Response:** ```json theme={null} { "success": true, "inputToken": {...}, "outputToken": {...}, "outputAmount": "1000000000", "outputAmountAfterFee": "995000000", "meta": { "apiVersion": "2.0", "timestamp": "2024-01-15T10:30:00.000Z" } } ``` ### Endpoint Mapping V2 API reorganizes endpoint names for better clarity. Here's how V2 endpoints map to V1: | V1 Endpoint | V2 Endpoint | Description | HTTP Method | | ------------------------ | -------------------------------- | ------------------------------------- | ----------- | | `/{network}/route` | `/{network}/v2/route` | Find optimal route | GET | | `/{network}/calldata` | `/{network}/v2/routeAndCallData` | Get route and calldata in one request | GET | | `/{network}/execute` | `/{network}/v2/calldata` | Generate calldata from existing route | POST | | `/{network}/healthcheck` | `/{network}/v2/healthcheck` | Health check | GET | **Important**: The V2 endpoint names better reflect their functionality: * `routeAndCallData` (V2) replaces `calldata` (V1) - combines route finding and calldata generation * `calldata` (V2) replaces `execute` (V1) - generates calldata from a pre-calculated route ### Integrator Features V2 supports monetization through integrator fees or surplus sharing: * **Integrator Fee**: Charge a percentage (0-5%) on swaps routed through your integration * **Integrator Surplus**: Share in surplus value (0-50%) when routing finds better prices * **Note**: You cannot use both fee and surplus in the same request **API Key Required**: Integrator features require an API key from Fibrous. Partners must obtain an API key before using these monetization features. Contact us at [contact@fibrous.finance](mailto:contact@fibrous.finance) or join our [Discord](https://discord.gg/fibrous) to request an API key. ## Migration Steps ### Step 1: Update Base URL Change your base URL from: ```bash theme={null} https://api.fibrous.finance/{network} ``` To: ```bash theme={null} https://api.fibrous.finance/{network}/v2 ``` ### Step 2: Handle Meta Field All V2 responses include a `meta` field. Update your response handling: ```javascript theme={null} // V1 const { success, outputAmount } = response; // V2 const { success, outputAmount, meta } = response; console.log(`API Version: ${meta.apiVersion}`); console.log(`Response Time: ${meta.timestamp}`); ``` ### Step 3: Update Route Endpoint **V1:** ```javascript theme={null} GET /{network}/route?amount=1000&tokenInAddress=0x...&tokenOutAddress=0x... ``` **V2:** ```javascript theme={null} GET /{network}/v2/route?amount=1000&tokenInAddress=0x...&tokenOutAddress=0x... ``` Optional integrator parameters: ```javascript theme={null} GET /{network}/v2/route?amount=1000&tokenInAddress=0x...&tokenOutAddress=0x...&integratorAddress=0x...&integratorFeePercentageBps=100 ``` ### Step 4: Update Calldata Endpoint (V1 → routeAndCallData V2) **Important**: V1's `/calldata` endpoint is now `/routeAndCallData` in V2. **V1 `/calldata` endpoint:** ```javascript theme={null} // V1: GET request with query parameters GET /{network}/calldata?amount=1000&tokenInAddress=0x...&tokenOutAddress=0x...&slippage=0.5&destination=0x... ``` **V2 `/routeAndCallData` endpoint:** ```javascript theme={null} // V2: Same functionality, renamed for clarity GET /{network}/v2/routeAndCallData?amount=1000&tokenInAddress=0x...&tokenOutAddress=0x...&slippage=0.5&destination=0x... // Response includes both route and calldata const { route, calldata, router_address, meta } = await response.json(); ``` **Migration Note**: If you were using V1's `/calldata` endpoint, update your code to use `/v2/routeAndCallData`. The functionality is the same - it gets route and calldata in one request. ### Step 5: Update Execute Endpoint (V1 → calldata V2) **Important**: V1's `/execute` endpoint is now `/calldata` in V2. **V1 `/execute` endpoint:** ```javascript theme={null} // V1: POST request with route object POST /{network}/execute Body: { "route": {...}, "slippage": 0.5, "destination": "0x..." } ``` **V2 `/calldata` endpoint:** ```javascript theme={null} // V2: Same functionality, renamed for clarity POST /{network}/v2/calldata Body: { "route": {...}, "slippage": 0.5, "destination": "0x...", "integratorAddress": "0x...", // optional "integratorFeePercentageBps": 100 // optional } ``` **Migration Note**: If you were using V1's `/execute` endpoint, update your code to use `/v2/calldata`. The functionality is the same - it generates calldata from a pre-calculated route. ### Step 6: Handle Integrator Features (Optional) **API Key Required**: To use integrator features, you must first obtain an API key from Fibrous. Contact us at [contact@fibrous.finance](mailto:contact@fibrous.finance) or join our [Discord](https://discord.gg/fibrous) to request an API key. If you want to monetize your integration: ```javascript theme={null} // Set up API key authentication const headers = { 'X-API-Key': 'your-api-key-here' }; // Use integrator fee const response = await fetch('/{network}/v2/route', { headers, params: { amount: '1000', tokenInAddress: '0x...', tokenOutAddress: '0x...', integratorAddress: '0xYourWallet', integratorFeePercentageBps: 100 // 1% fee } }); // Response includes outputAmountAfterFee const { outputAmount, outputAmountAfterFee, integratorFeePercentageBps } = response; ``` ## Parameter Changes ### New Optional Parameters All V2 endpoints support these optional integrator parameters: | Parameter | Type | Description | | -------------------------------- | ------ | ---------------------------------------------------- | | `integratorAddress` | string | Wallet address to receive fees/surplus | | `integratorFeePercentageBps` | number | Fee percentage in basis points (0-500, max 5%) | | `integratorSurplusPercentageBps` | number | Surplus percentage in basis points (0-5000, max 50%) | **API Key Required**: Integrator parameters require an API key from Fibrous Finance. Partners must obtain an API key before using these features. Contact us at [contact@fibrous.finance](mailto:contact@fibrous.finance) or join our [Discord](https://discord.gg/fibrous) to request an API key. You cannot use both `integratorFeePercentageBps` and `integratorSurplusPercentageBps` in the same request. ### Response Field Changes | Field | V1 | V2 | Notes | | -------------------------------- | -- | -- | ----------------------------------------- | | `meta` | ❌ | ✅ | Always present in V2 | | `outputAmountAfterFee` | ❌ | ✅ | Present when integrator fee is used | | `integratorAddress` | ❌ | ✅ | Present when integrator features are used | | `integratorFeePercentageBps` | ❌ | ✅ | Present when integrator fee is set | | `integratorSurplusPercentageBps` | ❌ | ✅ | Present when integrator surplus is set | | `integratorName` | ❌ | ✅ | Present when API key is used | ## Code Examples ### Complete Migration Example ```javascript theme={null} // V1 Implementation async function swapV1(amount, tokenIn, tokenOut, slippage, destination) { // Step 1: Get route const routeResponse = await fetch( `https://api.fibrous.finance/{network}/route?amount=${amount}&tokenInAddress=${tokenIn}&tokenOutAddress=${tokenOut}` ); const route = await routeResponse.json(); // Step 2: Get calldata (V1 endpoint name) const calldataResponse = await fetch( `https://api.fibrous.finance/{network}/calldata?amount=${amount}&tokenInAddress=${tokenIn}&tokenOutAddress=${tokenOut}&slippage=${slippage}&destination=${destination}` ); const calldata = await calldataResponse.json(); return { route, calldata }; } // V2 Implementation - Option 1: Using routeAndCallData (replaces V1 calldata) async function swapV2_Option1(amount, tokenIn, tokenOut, slippage, destination, apiKey = null) { const headers = apiKey ? { 'X-API-Key': apiKey } : {}; // Single call to get route and calldata (V1's /calldata → V2's /routeAndCallData) const response = await fetch( `https://api.fibrous.finance/{network}/v2/routeAndCallData?amount=${amount}&tokenInAddress=${tokenIn}&tokenOutAddress=${tokenOut}&slippage=${slippage}&destination=${destination}`, { headers } ); const data = await response.json(); // Log API version for debugging console.log(`Using API ${data.meta.apiVersion} at ${data.meta.timestamp}`); return { route: data.route, calldata: data.calldata, routerAddress: data.router_address, meta: data.meta }; } // V2 Implementation - Option 2: Using route + calldata (replaces V1 execute) async function swapV2_Option2(amount, tokenIn, tokenOut, slippage, destination, apiKey = null) { const headers = apiKey ? { 'X-API-Key': apiKey } : {}; // Step 1: Get route const routeResponse = await fetch( `https://api.fibrous.finance/{network}/v2/route?amount=${amount}&tokenInAddress=${tokenIn}&tokenOutAddress=${tokenOut}`, { headers } ); const route = await routeResponse.json(); // Step 2: Generate calldata from route (V1's /execute → V2's /calldata) const calldataResponse = await fetch( `https://api.fibrous.finance/{network}/v2/calldata`, { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ route, slippage, destination }) } ); const calldata = await calldataResponse.json(); return { route, calldata, meta: calldata.meta }; } ``` ### With Integrator Features ```javascript theme={null} async function swapWithIntegratorFee(amount, tokenIn, tokenOut, slippage, destination, apiKey, integratorAddress) { const headers = { 'X-API-Key': apiKey }; const params = new URLSearchParams({ amount, tokenInAddress: tokenIn, tokenOutAddress: tokenOut, slippage, destination, integratorAddress, integratorFeePercentageBps: '100' // 1% fee }); const response = await fetch( `https://api.fibrous.finance/{network}/v2/route?${params}`, { headers } ); const data = await response.json(); // Show user the amount after fee const amountAfterFee = data.outputAmountAfterFee; const feeAmount = BigInt(data.outputAmount) - BigInt(amountAfterFee); console.log(`Output: ${data.outputAmount}`); console.log(`After ${data.integratorFeePercentageBps / 100}% fee: ${amountAfterFee}`); console.log(`Fee earned: ${feeAmount}`); return data; } ``` ## Backward Compatibility V1 endpoints remain available and fully functional. You can migrate at your own pace without breaking existing integrations. * V1 endpoints: `https://api.fibrous.finance/{network}/*` * V2 endpoints: `https://api.fibrous.finance/{network}/v2/*` Both versions will continue to be supported, but we recommend migrating to V2 to take advantage of new features. ## Testing Your Migration 1. **Test with small amounts first** * Verify responses match expected format * Check that meta fields are present * Validate integrator features if used 2. **Monitor API version in responses** * Log `meta.apiVersion` to ensure you're using V2 * Track `meta.timestamp` for debugging 3. **Verify integrator features** * Test with API key authentication * Verify fee calculations * Check outputAmountAfterFee values ## Common Issues ### Issue: Missing Meta Field **Problem:** Response doesn't include `meta` field **Solution:** Ensure you're using `/{network}/v2/*` endpoints, not `/{network}/*` ### Issue: Integrator Features Not Working **Problem:** Integrator parameters are ignored **Solution:** * **Obtain an API key**: Integrator features require an API key from Fibrous. Contact us at [contact@fibrous.finance](mailto:contact@fibrous.finance) or join our [Discord](https://discord.gg/fibrous) to request an API key * Verify API key is included in request headers as `X-API-Key` * Check that integrator address is valid * Ensure only one of fee or surplus is set ### Issue: Route and Calldata Endpoint Returns 404 **Problem:** `/{network}/v2/routeAndCallData` not found **Solution:** This endpoint is V2-only. Use `/{network}/v2/routeAndCallData` (not `/{network}/routeAndCallData`) **Note:** If you were using V1's `/calldata` endpoint, remember it's now `/v2/routeAndCallData` in V2. *** ### Issue: Endpoint Name Confusion **Problem:** Confused about which V2 endpoint to use **Solution:** Use this mapping guide: | What You Need | V1 Endpoint | V2 Endpoint | | ------------------------------------- | --------------------- | -------------------------------- | | Get route only | `/{network}/route` | `/{network}/v2/route` | | Get route + calldata in one call | `/{network}/calldata` | `/{network}/v2/routeAndCallData` | | Generate calldata from existing route | `/{network}/execute` | `/{network}/v2/calldata` | **Key Points:** * V1's `/calldata` → V2's `/routeAndCallData` (GET request, gets route and calldata together) * V1's `/execute` → V2's `/calldata` (POST request, generates calldata from route) ## Next Steps * Review [V2 Route Endpoint](/api-reference/endpoints/route-v2) documentation * Check [V2 Calldata Endpoint](/api-reference/endpoints/calldata-v2) for POST endpoint details * Explore [Integrator Features](/api-reference/v2-migration#integrator-features) for monetization ## Support If you encounter issues during migration: * Check our [FAQ](/essentials/faq) * Join our [Discord](https://discord.gg/fibrous) for community support * Contact us at [contact@fibrous.finance](mailto:contact@fibrous.finance) # Build with AI Source: https://docs.fibrous.finance/essentials/build-with-ai Connect AI tools like Claude, Cursor, and ChatGPT to Fibrous documentation and API for faster integration development Fibrous documentation is AI-agent ready. AI coding assistants can search the docs in real time, understand the API structure, and help you build swap integrations faster. This works through three mechanisms: an **MCP server** for direct doc access, **llms.txt** for structured indexing, and **skill.md** for agent capability discovery. ## What AI Tools Can Do with Fibrous AI tools search Fibrous docs in real time via MCP, getting accurate API specs instead of stale web results. Ask your AI assistant to build a swap integration using the Fibrous V2 API or SDK with correct parameters and types. AI tools can look up error codes, rate limits, slippage guidance, and contract addresses directly from the docs. ## Connect the Fibrous MCP Server Fibrous hosts an MCP server at `https://docs.fibrous.finance/mcp`. When connected, AI tools can search Fibrous documentation directly during conversations instead of relying on web search. You can also connect from any docs page using the contextual menu (top-right). Options include **Copy MCP server URL**, **Connect to Cursor**, and **Connect to VS Code**. Run the following command to add the Fibrous MCP server: ```bash theme={null} claude mcp add --transport http Fibrous https://docs.fibrous.finance/mcp ``` Verify the connection: ```bash theme={null} claude mcp list ``` After adding, Claude Code can search Fibrous docs during any coding session. Try asking: *"Using the Fibrous API, how do I find the best route for swapping ETH to USDC on Base?"* Navigate to the [Connectors](https://claude.ai/settings/connectors) page in the Claude settings. Select **Add custom connector** and enter: * **Name**: `Fibrous` * **URL**: `https://docs.fibrous.finance/mcp` Select **Add**. When using Claude, select the attachments button (the plus icon) and enable the **Fibrous** connector. Claude will search Fibrous docs when relevant to your questions. Open MCP settings with Command + Shift + P and search for "Open MCP settings". Add the following to your `mcp.json`: ```json theme={null} { "mcpServers": { "Fibrous": { "url": "https://docs.fibrous.finance/mcp" } } } ``` Test the connection by asking Cursor: *"What tools do you have available?"* -- it should list the Fibrous MCP server. Create a `.vscode/mcp.json` file in your project and add: ```json theme={null} { "servers": { "Fibrous": { "type": "http", "url": "https://docs.fibrous.finance/mcp" } } } ``` Open the MCP configuration in Windsurf settings and add: ```json theme={null} { "mcpServers": { "Fibrous": { "url": "https://docs.fibrous.finance/mcp" } } } ``` ChatGPT and Perplexity do not support MCP natively. Instead: * Use the **contextual menu** on any Fibrous docs page to open content directly in ChatGPT or Perplexity * Paste `https://docs.fibrous.finance/llms.txt` into a conversation to give the AI an overview of all available documentation pages ## llms.txt Fibrous hosts an AI-friendly documentation index at [`docs.fibrous.finance/llms.txt`](https://docs.fibrous.finance/llms.txt). This file lists every documentation page with descriptions, acting as a sitemap for AI tools. A full-content version is available at [`docs.fibrous.finance/llms-full.txt`](https://docs.fibrous.finance/llms-full.txt), containing the complete text of all pages in a single file. Paste the llms.txt URL into any AI chat to give it an overview of all Fibrous documentation pages. This works with any LLM, no MCP required. ## skill.md Fibrous hosts a capability descriptor at [`docs.fibrous.finance/skill.md`](https://docs.fibrous.finance/skill.md). This file tells AI agents what they can accomplish with Fibrous: find swap routes, generate calldata, check supported tokens and chains, and more. Agents that support skills (like Claude) can use this to understand Fibrous capabilities upfront, enabling them to proactively search the right documentation when helping you build integrations. The skill.md is automatically generated from your documentation and stays up to date on every deploy. ## Example: Build a Swap Integration with AI Here's a practical walkthrough of using an AI assistant with the Fibrous MCP server connected to build a complete swap integration. Ask your AI assistant: > *Using the Fibrous V2 API, write a function that finds the best route to swap 1 ETH for USDC on Base network.* The AI will search Fibrous docs and produce something like: ```javascript theme={null} async function findRoute() { const params = new URLSearchParams({ amount: '1000000000000000000', // 1 ETH in wei tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', }); const response = await fetch( `https://api.fibrous.finance/base/v2/route?${params}` ); return response.json(); } ``` Follow up with: > *Now get the route and calldata in a single call with 0.5% slippage and show me how to execute it with ethers.js.* The AI will use the `routeAndCallData` V2 endpoint: ```javascript theme={null} async function executeSwap(signer) { const params = new URLSearchParams({ amount: '1000000000000000000', tokenInAddress: '0x0000000000000000000000000000000000000000', tokenOutAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', slippage: '0.5', destination: await signer.getAddress(), }); const response = await fetch( `https://api.fibrous.finance/base/v2/routeAndCallData?${params}` ); const data = await response.json(); const tx = await signer.sendTransaction({ to: data.router_address, data: data.calldata, value: data.calldata.route.swap_type === 0 ? data.calldata.route.amount_in : '0', }); return tx.wait(); } ``` Ask: > *Add token approval checking, rate limit handling, and error handling following Fibrous best practices.* With MCP connected, the AI will pull recommendations from the [Integration Guide](/api-reference/integration-guide) -- slippage tables, error codes, rate limit backoff, and token approval patterns. Try: > *Rewrite this using the @fibrous/router SDK instead of raw API calls.* The AI will reference the [SDK documentation](/integrate-best-trading/fibrous-sdk/index) and produce a cleaner integration using the TypeScript SDK. ## Tips for Best Results * **Be specific about the network** -- Always mention the target chain (Base, Monad, Starknet, etc.) since each has different token addresses and contract formats. * **Specify V1 or V2** -- Tell the AI whether to use V2 endpoints (recommended for new integrations) or V1 for backward compatibility. Both are actively supported. * **Use the SDK for Starknet** -- Starknet uses a different transaction model (Cairo). The `@fibrous/router` SDK abstracts this, so direct the AI to use it for Starknet integrations. * **Ask about integrator features** -- If you want to monetize your integration, tell the AI to include `integratorAddress` and `integratorFeePercentageBps` parameters with API key authentication. ## Related Resources Complete integration guide with best practices for slippage, approvals, and error handling. TypeScript SDK documentation for @fibrous/router. Upgrade from V1 to V2 endpoints with integrator support. Networks, token addresses, and contract details. # Frequently Asked Questions Source: https://docs.fibrous.finance/essentials/faq Find answers to common questions about Fibrous ## General Fibrous is an advanced DEX aggregator and liquidity hub for the Starknet, Citrea, Monad, HyperEVM, and Base ecosystems. It operates by scanning all available liquidity sources, intelligently splitting trades across them to find the optimal price and route for any swap. This allows users to access the entire liquidity of these ecosystems through a single, efficient platform, ensuring best-price execution. Currently, Fibrous does not have a native token. The project's primary focus is on delivering the best aggregation service to its users. Any future updates regarding a token will be announced through official Fibrous channels. Fibrous has active communities on [Discord](https://discord.com/invite/fibrous), [X](https://x.com/fibrousfinance), and [Farcaster](https://warpcast.com/fibrousfinance). Users can join to connect with the team, get support from the community, and stay updated on the latest developments. ## Features and Functionality Fibrous functions as a smart router. It scans liquidity and pricing data from all integrated sources across Starknet, Citrea, Monad, Base and HyperEVM. For each trade, the algorithm intelligently splits the order across multiple venues to determine the most optimal route. This process guarantees users get the best possible execution price without needing to manually compare sources. Fibrous is a leading liquidity aggregator with deep integrations into the Starknet, Citrea, Monad, HyperEVM and Base ecosystems. Its key distinction lies in combining comprehensive liquidity access with a suite of powerful, user-centric features. Tools like **Batch Swaps** and **Limit Orders** provide traders with enhanced efficiency and greater control, offering a more advanced trading experience than standard aggregators. * **Integrated TradingView Charts:** For advanced price analysis. * **Transaction History:** To easily track and review past trades. * **Portfolio Tab:** A clear overview of asset balances and positions. * **Advanced Trading Tools:** Features like Batch Swap and Limit Order for sophisticated strategies. * **Slippage Tolerance Control:** Customizable settings for precise trade execution. * **Real-Time Price Updates:** Live data from all integrated liquidity sources. * **Fibrous AI:** A tool that allows users to customize their trading experience using natural language prompts. ## Fees and Costs Fibrous charges a service fee that varies depending on the swap complexity: * Single-route swaps: 0.02% fee * Multi-route swaps: 0.15% fee This fee is automatically deducted from the swap amount. There are no additional fees charged by Fibrous, but standard network transaction fees (gas fees) apply. Yes, standard network transaction fees apply to all transactions. These fees are required to process transactions on the blockchain and are paid directly to the Ethereum validators and Layer-2 Sequencers, not to Fibrous. Owners of StarkRock NFTs enjoy the benefit of zero service and gas fees on Fibrous. StarkRocks holders will not pay any fees when using Fibrous **only on Starknet**. ## Security Fibrous does not store your tokens. As a non-custodial platform, all your assets remain in your wallet until you execute a transaction. Tokens are transferred directly through smart contracts during your trades, ensuring you maintain control over your funds. Slippage is the difference between the expected price of a trade and the final price at which it is executed. It commonly occurs for three reasons: * **Market Volatility:** Rapid price movements between the time a transaction is submitted and confirmed. * **Liquidity Changes:** Large trades that affect the asset balance within a liquidity pool. * **Network Congestion:** Delays in transaction confirmation on the blockchain. You can minimize slippage by: * Setting a slippage tolerance in the Fibrous interface * Executing trades during stable market conditions * Using Limit Orders to specify exact execution prices ## Technical Support Fibrous supports multiple wallets across different networks: **Starknet Network Wallets:** * Ready * Braavos * Keplr * XVerse  * Ready Web Wallet * BitGet Wallet * OKX Wallet * Argent Mobile * Metamask Snap **EVM Networks:** Fibrous provides a compatible interface for nearly 94 wallets, including the widely used MetaMask. Ensure your wallet is connected to Starknet, Citrea, Monad, Base or HyperEVM to interact with Fibrous. You only need a compatible wallet that supports Starknet, Citrea, Monad, HyperEVM or Base. There are no additional software downloads or browser extensions required to use Fibrous. If you encounter any issues: * Check your wallet to ensure it's properly connected and funded * Review transaction details for any errors * You can report an error using the "Bug Report" or "Feature Request" options left in the application interface * Visit our Discord server for support * Provide details of the issue to our support team * Email us at [contact@fibrous.finance](mailto:contact@fibrous.finance) if needed ## Miscellaneous StarkRocks are a collection of 444 unique NFTs that offer exclusive benefits within the Fibrous ecosystem. For trades executed on Starknet, holding a StarkRock NFT waives the Fibrous service fee and covers the associated network gas fees, enabling a zero-fee trading experience on that network. Holders of StarkRock NFTs enjoy several benefits: * **Zero-Fee Trading on Starknet:** Service fees are waived and network gas fees are covered for all trades executed via Fibrous on Starknet. * **Exclusive Access:** Priority or exclusive access to future product features and community events. * **Community Recognition:** Special status and recognition within the Fibrous community. Fibrous values user feedback. There are several ways to share ideas and suggestions: * Use the **‘Request Feature’** section directly within the Fibrous interface. * Join the official **Discord server** to discuss ideas with the community and team. * Send an email directly to [**contact@fibrous.finance**](mailto:contact@fibrous.finance). * Participate in community polls and discussions on social channels. * Follow the official **X account** for announcements and feedback opportunities. ## Tokens and Swapping Fibrous supports all tokens available through its integrated liquidity sources on the Starknet, Citrea, Monad, HyperEVM and Base networks. For user convenience, the interface features a default list of the most popular tokens. However, users can trade any token by simply searching for its name or pasting its contract address into the search bar. Fibrous has integrated multiple liquidity sources, including prominent decentralized exchanges (DEXs), on supported networks. These integrations allow users to access a vast array of trading options directly through Fibrous. **Starknet Network DEXs:** * Ekubo * Haiko * JediSwap / JediSwap CL * MySwap / MySwap CL * 10KDex * Nostra * SithSwap * StarkDeFi **Citrea Network DEXs:** * Satsuma * JuiceSwap * JuiceSwap Vault * JuiceSwap StablecoinBridge **Monad Network DEXs:** * Aethonswap V3 * Octoswap V2 / Octoswap V3 * PancakeSwap V2 / PancakeSwap V3 * PinotFinance V2 / PinotFinance V3 * Purpswap V2 * Swyrl V2 / Swyrl V3 * Uniswap V2 / Uniswap V3 / Uniswap V4 * Capricorn CL * Atlantis Algebra * Lfj V1 * Dyor Swap * Monday V3 * ZKSwap V2 / ZKSwap V3 * Nabla **Base Network DEXs:** * Aerodrome Stable / Aerodrome Volatile / Aerodrome Slipstream * Uniswap V2 / Uniswap V3 / Uniswap V4 / Uniswap V4 Zora / Uniswap V4 Flaunch / Uniswap v4 Clanker * SushiSwap V2 / SushiSwap V3 * AlienBase V2 / AlienBase V3 * PancakeSwap V2 / PancakeSwap V3 / PancakeSwap Infinity * BaseSwap V2 / BaseSwap V3 * RocketSwap V2 * SmarDex V2 * IzumiSwap V3 * Baso Finance V2 / Baso Finance Stable * BMX * BVM V2 / BVM Stable * DackieSwap / Dackie Swap V3 * SoSwap V2 * Infusion Stable / Infusion Classic * Solidly V3 * Curve Stable NG / Curve fi / Curve Stable Meta / Curve TriCrypto NG / CurveFi Two Crypto * Balancer V2 Stable / Balancer V2 Composable / Balancer V2 Weighted * Balancer V3 Stable / Balancer V3 Stable Surge / Balancer V3 Weighted / Balancer V3 Stable Boosted * Balancer Gyro ECLP / Balancer Gyro ECLP V3 * Dodo CP / Dodo DPP / Dodo DSP / Dodo DVM * Equalizer Thick V3 / Equalizer V2 / Equalizer V2 Stable * Spark PSM * Fluid Dex * Hydrex * Quickswap Algebra * Tessera **HyperEVM Network DEXs:** * HyperSwap V2 / HyperSwap V2 Stable / HyperSwap V3 * KittenSwap V2 / KittenSwap V2 Stable / KittenSwap V3 / Kittenswap V4 * Laminar V2 / Laminar V3 * Hybra Finance V2 / Hybra Finance V2 Stable / Hybra Finance V3 / Hybra Finance V4 * Curve Fi Two Crypto / Curve Fi Stable / CurveFi TriCrypto * Balancer Gyro ECLP / Balancer ReCCLAMM / Balancer Stable / Balancer Stable Surge / Balancer Weighted / Balancer LB Pool / Balancer Stable Boosted * Ramses CL / RamsesV3 * Project X * Hyper Cat V3 * GLiquid V3 * hyperbrick-lb * Valantis * BrownFi V2 * Upheaval V3 * UltraSolidV2 / UltraSolid V3 * RingSwap * Funnel V1 / Funnel V2 * SpinUp / SpinUp Stable * Nest Exchange * Nabla * Liquid Core Batch Swap feature allows users to trade multiple different tokens for a single token, all within one transaction. Fibrous optimizes the pricing for each individual swap within the batch, streamlining the trading process and increasing efficiency. It is especially useful for portfolio rebalancing or consolidating multiple assets into one. Fibrous Limit Order feature gives users the ability to set a specific price target for their trades. Buy or sell orders are placed and then executed automatically only when the market reaches the user's specified price. This provides greater control over trading strategy and removes the need for constant market monitoring. Currently, Fibrous does not directly support cross-chain swaps. Fibrous operates as an aggregator within its integrated networks (Starknet, Citrea, Monad, Base, HyperEVM). To trade assets using the Fibrous interface, users must first bridge their tokens onto one of these supported networks. *** This FAQ aims to provide you with all the information you may need about Fibrous. If you have additional questions or need assistance, feel free to reach out to our support team or join our community channels. **Thank you for choosing Fibrous!** # What is Fibrous? Source: https://docs.fibrous.finance/essentials/inspiration-for-aggregator Learn about how Fibrous started and why we need a DEX aggregator ## The Need for a DEX Aggregator Decentralized Finance is a powerful but fragmented landscape where liquidity is scattered across countless exchanges and networks. This often leads to users getting poor prices, high slippage, and inefficient trades. Fibrous solves this. It is an advanced DEX aggregator that acts as a smart trading router. ## Fibrous' Innovative Solution Fibrous automatically scans the entire market, including AMMs, order books, and private liquidity sources, to find the optimal route for every swap. It intelligently splits trades across multiple venues to ensure users receive the best possible price with minimal costs, all executed in a single transaction. ## Advantages for Users Fibrous distinguishes itself in the DeFi space by offering a suite of user advantages: Image Web * **Optimal Price Execution:** The smart routing algorithm automatically finds and secures the most favorable rates. * **Lower Trading Costs:** By minimizing slippage and price impact, Fibrous ensures users get more value from every trade. * **Unified Trading Hub:** Access deep, market-wide liquidity from one simple and powerful interface. * **Powerful Developer Tools:** A scalable API and SDK provide the infrastructure for dApps and trading bots to achieve best-rate execution at scale. * **Advanced User Control:** Go beyond basic swaps with professional-grade tools like Limit Orders and Batch Swaps. In short, Fibrous makes DeFi trading cheaper, simpler, and more powerful # Fibrous App Source: https://docs.fibrous.finance/external-links/app # Blog Source: https://docs.fibrous.finance/external-links/blog # Brand Assets Source: https://docs.fibrous.finance/external-links/brand-assets # Discord Source: https://docs.fibrous.finance/external-links/discord # Farcaster Source: https://docs.fibrous.finance/external-links/farcaster # GitHub Source: https://docs.fibrous.finance/external-links/github # X Source: https://docs.fibrous.finance/external-links/twitter # YouTube Source: https://docs.fibrous.finance/external-links/youtube # Fibrous Interface Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface-intro Simplicity is the ultimate sophistication Fibrous interface features a modular design that simplifies complex DeFi routing into single-click operations and diversifies trading options for users. Core features like **Swap, Batch Swap,** and **Limit Order** are presented as distinct modules, making them easy to explore and utilize. To ensure the optimized trading experience is both comprehensible and gives users full control, the interface is built on a clean, simple, and intuitive design. This user-centric approach guarantees that even when executing sophisticated trading strategies, the process remains straightforward and transparent. ## User Guides Learn how to connect your wallet to Fibrous Guide to performing swaps on Fibrous Learn about price impact, slippage, and fees Customize your block explorer settings Send tokens to alternative addresses Customize your interface experience Add and manage custom tokens ## Advanced Features Learn about Fibrous's batch swapping feature Explore the Fibrous Arena # Fibrous Arena Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/arena Where Legends are Born! Image(9) Pn As Fibrous, we are thrilled to introduce the Fibrous Arena series, an initiative crafted to honor our dedicated users, foster a competitive environment, and integrate our community into Starknet's technology and ecosystem. Fibrous Arena series comprises various stages, each with its unique ranking factors. It's our priority to provide a fair and equitable platform where our users can compete across different domains. We are committed to ensuring that each stage of the Fibrous Arena has distinct criteria. Participants are awarded specially designed NFTs based on their ranking categories after every stage. The special abilities of these NFTs will be disclosed later. For now, we recommend our users to keep them safe! So far, there have been three stages in the Fibrous Arena series until now: * **Volume Vanguard:** This stage was based on the trading volume conducted by our users on Fibrous. The top 100 participants received reward NFTs according to their ranking categories. * **Transaction Titan:** This stage focused on the number of transactions users made on Fibrous, without considering the volume factor. The top 100 participants in this category also received reward NFTs. * **Winter Swappers:** This stage combined the trading volume and transaction count of our users. Rankings were determined using an Elo rating system, which calculated a combination of trading volume and transaction count. **The Elo System:** We developed a scoring system where users earned points based on every \$1 swapped and each transaction made on Fibrous. The scoring formula is as follows: P = (Volume x a) + (TransactionCount x b) * P represents the total points achieved by the user. * Volume is the trading volume of the user (in USD). * Transaction Count is the total number of transactions conducted by the user. * a is the points earned per USD, set at 0.0049. * b is the points earned per transaction, set at 1.5. Stay tuned for future stages of the Fibrous Arena series. Remember, every transaction you make and every ranking you achieve holds great value to us! # Fibrous Batch Swap Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/batch-swap Fibrous's Batch Swap feature allows you to input multiple tokens simultaneously and receive an aggregated output, ensuring you get the best price for more than two assets. Thanks to Starknet's Native Account Abstraction (AA), it is possible to manage multiple assets in a single transaction ## How to Use Fibrous Batch Swap? You can access the Batch Swap via the button top of the swap bar on the middle of the screen. Image(6) Pn Next, desire the amount you want to enter for the selected input assets either from the toolbar below them or directly by entering the amount. Once everything is ready, press the "Swap" button located at the bottom.
Batch Swaps on app.fibrous.finance
Batch Swaps on app.fibrous.finance
In the subsequent tab, you can adjust your slippage settings and see the minimum amount you will receive. By pressing the "Confirm" button and approving the transaction in the popup window of the wallet you have connected, you can provide multiple token inputs and their signatures all at once, executing your best-priced transaction.
Image(8) Pn
# Changing Block Explorer Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/block-explorer This will have a symbolic meaning, so choose wisely :) To examine your transactions via our interface, click the links in the History and Transaction pop-up. ## Supported Block Explorers We offer support for two block explorers on each network: ### Starknet * [Voyager](https://voyager.online) * [StarkScan](https://starkscan.co) ### Scroll * [ScrollScan](https://scrollscan.com) * [L2scan](https://scroll.l2scan.co) ### **Base** * [BaseScan ](https://basescan.org/) * [Base Blockscout](https://base.blockscout.com/) ### HyperEVM * [HyperEVMScan ](https://hyperevmscan.io/) * [**HyperScan**](https://www.hyperscan.com/) ## To select your preferred block explorer 1. Navigate to Swap Settings on top right corner of swap bar Swap Setting button on app.fibrous.finance 1. Choose your desired explorer from the options provided Changing Block Explorer on app.fibrous.finance # Connecting Your Wallet to Fibrous Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/connecting-wallet Learn how to connect your wallet and start using Fibrous ## Compatibility and Requirements At Fibrous, we understand the importance of accessibility. As such, rest assured that there's no need for additional applications or tools when using Fibrous. Owning one of the supported wallets suffices. Fibrous is designed to integrate smoothly with these wallets, ensuring you a hassle-free experience. Fibrous has an interface where you can easily connect both many prominent wallets designed for use on EVM networks and Starknet-native wallets. ## Connecting a Wallet To connect your Web3 wallet, click on the Connect Wallet button at the top right of the page. This will bring up a wallet selection pop-up where various wallet connection options will be displayed. Connect Wallet Button Location To proceed with the connection, make sure you select the Scroll or Base network if you want to use one of your EVM wallets. To continue with one of your Starknet wallets, select the Starknet network in the network tab and proceed by choosing one of the relevant Starknet wallets. Next, select the Web3 wallet that you would like to use to connect to Fibrous and authorize the connection to Fibrous in your chosen Web3 wallet's UI. ## Ready Wallet Example For the example below, we are connecting to Fibrous with **Ready (Formerly Argent X) Wallet**. Image Avi
Choosing Wallet on app.fibrous.finance
Connecting Wallet 1 2(1) Web ## Portfolio Tab After connecting a Web3 wallet, when you click on the tab at the top right of the interface where your address or ENS/StarknetID domain is displayed, you can view an account summary for your connected address. In this tab, you can review the assets available in Fibrous for your address and access historical information about the transactions you have performed on Fibrous. Portfolio Section View # Importing Custom Tokens Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/custom-tokens Empower your trades on every token While Fibrous provides a whitelist of the most commonly transacted tokens on our platform, you also have the flexibility to search for and add custom ERC20 tokens to the Fibrous interface. Here's how you can do it: ### Step 1: Select the Correct Network Before you begin, ensure that your wallet is connected to the intended network. The token search function is network-specific and will only display tokens native to the network you're currently using. ### Step 2: Search for the Token Click on one (or both) of the token selector buttons to open the Token Selection screen. By default, this screen lists all whitelisted tokens. To find a specific non-whitelisted token, use the search bar at the top. You can search for the token by entering its ticker symbol or by pasting its contract address into the search bar. Custom Token Importing on app.fibrous.finance ### Step 3: Import the Token Once you've located the token you wish to add, click the Import button next to it. A confirmation prompt will appear—click I Understand to proceed. The custom token is now imported into Fibrous. It will appear under your Imported Tokens list in the token selector screen, and you can now use it for swapping operations. # Display Settings Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/display-settings Way of standardization... In the Fibrous interface, trading settings have been defined to enhance your experience and allow customization for all types of usage habits. Fibrous Interface Settings ## Rate Comparison Table Rate Comparison Table is an indicator that allows you to compare exchange rates across multiple liquidity sources in real-time. When you initiate a token swap, Fibrous aggregates rates from various decentralized exchanges (DEXs) and displays them in a convenient table format. This enables you to see which platform offers the most favorable rate for your trade, ensuring you get the best value possible. By providing transparent rate comparisons, Fibrous helps you make informed trading decisions quickly and efficiently. ## Trading Chart Trading Chart provides a visual representation of the price movements and trading volumes for selected tokens over different time frames. This interactive chart helps you analyze market trends, historical prices, and volatility, aiding in making informed trading decisions. You can customize the chart by: * Adjusting time intervals * Viewing candlestick patterns * Applying technical indicators The Trading Chart is an essential tool for monitoring the market and planning your trades effectively. ## Show Routing The Show Routing feature allows you to view the exact path your trade will take across various liquidity pools and exchanges. When you execute a swap, Fibrous may route your transaction through multiple tokens or platforms to secure the best rate. By enabling Show Routing, you gain transparency into this process, seeing each step your assets will pass through. This feature helps you understand how your trade is being executed and ensures confidence in the transaction's efficiency and security. ## Input Kit The Input Kit refers to the set of tools and options available for entering and adjusting your trade parameters. This includes fields for selecting tokens, inputting the amount you wish to swap, and setting preferences like slippage tolerance and transaction speed. The Input Kit is designed for ease of use, allowing you to: * **Directly enter amounts**: Type in the exact number of tokens you want to trade. * **Use sliders or percentage buttons**: Quickly select common fractions of your balance (e.g., 25%, 50%, 75%, 100%). * **Adjust advanced settings**: Access additional options to fine-tune your trade according to your needs. ## Language Preference The Language Preference setting allows you to customize the Fibrous interface in your preferred language. By selecting from the available language options, you can navigate the platform more comfortably and understand all features and instructions clearly. This personalization enhances your user experience, making the platform more accessible and user-friendly regardless of your native language. ## Interface Theme The Interface Theme option lets you personalize the visual appearance of the Fibrous platform. You can choose between different themes, such as light mode or dark mode, depending on your preference or ambient lighting conditions. Adjusting the interface theme can improve readability and reduce eye strain, providing a more comfortable environment for managing your trades. ## Decimal Separator Decimal Separator setting allows you to select your preferred numerical formatting for decimal numbers displayed on the platform. Depending on your regional settings or personal preference, you can choose between a period (.) or a comma (,) and space as the decimal separator. This customization ensures that all numerical data, such as token amounts and prices, are presented in a format that is familiar and easily understandable to you, reducing the risk of misinterpretation during transactions. ## Clearing Cookies & Local Storage You can easily clear the Cookies & Local Storage for [app.fibrous.finance](http://app.fibrous.finance) in case of any browser-based technical issue. Remember, if you encounter a technical problem! Otherwise, the cookies in Fibrous are customized for you and exist to enhance your user experience. # Understanding Price Impact, Slippage and Fees Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/price-impact Learn about price impact, slippage, and fees on Fibrous ## Understanding Price Impact ### Definition and Effects Price Impact refers to the influence a specific trade has on the market value of an asset pair, which is closely linked to the liquidity of the source. In scenarios where market or pair liquidity is low, the price impact can be substantial, potentially leading to losses for the trader. Essentially, a large trade in a small market can significantly disturb the market equilibrium. ### Favorable Scenarios However, price impact can sometimes work in favor of the trader. If the pool's liquidity is skewed opposite to your trade direction, you may trade at a more advantageous rate than the pool's average, opening opportunities for arbitrage. ## Distinguishing Between Price Impact and Slippage ### Key Differences * **Price Slippage** refers to the price variation resulting from market movements that are not directly linked to an individual trade. * **Price Impact**, conversely, is the price change directly caused by an individual's trade. Both are influenced by the liquidity in a pool; limited liquidity can lead to significant rate shifts from minor overall market movements. Also, slippage can sometimes be beneficial. If the exchange rate shifts advantageously, you receive extra tokens in a swap. ## Strategies to Reduce Negative Price Impact ### Fibrous' Pathfinder Algorithm Fibrous' algorithm is designed to distribute trading volume across various liquidity sources, minimizing adverse price impact. However, for tokens with a single liquidity source, especially illiquid ones, optimizing price impact is challenging. ### Personal Strategies To reduce swap price impact, consider trading smaller volumes or waiting for increased market liquidity. For certain tokens, especially those from dubious projects, this liquidity boost may never arrive. Ensure the "Minimum received after slippage" reflects accurate token counts based on current market rates. ## Managing Slippage on Fibrous ### Slippage Tolerance Settings Fibrous features a "Slippage Tolerance" option, allowing traders to set a preferred slippage percentage for their trades. The platform typically uses "auto-slippage," adjusting tolerance based on the pair's volatility. This option can be found and adjusted in the general settings, with the ability to pin the slippage tolerance display to the main swap interface for easy access. Swap Setting button on app.fibrous.finance If the final token amount deviates beyond the set slippage tolerance during the trade process, the transaction will be aborted, preventing significant losses despite non-refundable gas costs. ## Implications of Extreme Slippage Tolerance Settings The ideal slippage tolerance varies by token, transaction, and personal preference. ### Very High / High Impact An overly generous slippage tolerance permits the trade to finalize even with substantial price shifts, exposing the user to potential front-running and sandwich attacks. In a sandwich attack, a malicious actor places two larger trades just before and after a target transaction, forcing the target to buy at a higher rate. High Slippage Risk Indicator By the victim having a high slippage tolerance, the attacker gains more. While the likelihood seems minimized on the Starknet, Scroll and Base at the moment, as the Fibrous team, we are developing MEV-resistant transactions and preparing to offer you the best experience. Therefore, it is not recommended to execute a transaction under such conditions. ### Medium Impact / Low Impact A very strict slippage tolerance might cause the transaction to be rejected if price fluctuations surpass the designated percentage. While this might ward off front-runners, it also results in wasted gas fees for the failed transaction. A transaction that gets rejected due to very low slippage tolerance will display "**Fail with error 'Min return not reached**" when inspected on a block explorer. Medium Slippage Risk Indicator In transactions with this level of price impact, the key is to set the correct slippage settings. The transactions are safe to execute; however, the output price may be affected depending on liquidity. It is advisable to monitor the "Minimum received amount." Fortunately, in the transactions you perform on Fibrous, the price impact will be minimized. ### Positive Slippage As we emphasized, these price impacts can also be positive. For such transactions, Fibrous ensures you can obtain a positive return. With Fibrous, you can catch arbitrage opportunities and earn. ## Gas and Transaction Fees Just as with EVM chains, gas fees and mechanisms for Starknet's CairoVM are vital for the network's operation and protocol flow. Therefore, specific gas fees are charged for every transaction executed, and if these fees are met, your transaction is processed. Therefore, to perform transactions, you need to have enough of the required gas tokens on both the Starknet and Scroll networks. However, to minimize these costs, we have developed a **"Flash Accounts"** model that ensures you encounter more favorable gas fees as your routes become more complex. ## Service Fee Fibrous is not just a Decentralized Exchange platform; it also aims to offer users the best DeFi experience by integrating a wide range of DeFi applications and infrastructures. \ \ For all these services, Fibrous charges a fee of * 0.02% for single-route and 0.15% for multi-route swaps on **Starknet.** * Only positive surpluss on **Base** & \*\*HyperEVM. \*\* * And no-fee policy on **Scroll!** # Swapping on Fibrous Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/swapping Elevate Your Trading Experience with Fibrous! ## Optimized Token Swapping with Fibrous Fibrous allows you to swap tokens and offers various settings to provide the best trade options for you. By scanning the prominent liquidity sources on the network you are using, it creates a complex trade pathway for you and delivers favorable rates in the simplest way. ## Benefits of Using Fibrous * **Price Optimization**: Fibrous isn't just an exchange; it's an aggregator. This means it looks across multiple exchanges to get you the best price. * **Gas Fee Savings**: Compared to other platforms, Fibrous often results in lower gas fees. In conclusion, while platforms like Uniswap are direct exchanges, Fibrous ensures that you get the best deal across multiple exchanges, often saving you on fees and getting you a better swap rate. ## Finding the best rates, easily! ### Step 1: Connect Your Wallet Go to Fibrous, and click on the Connect Wallet button in the upper right corner. Connect Wallet Interface ### Step 2: Choose Your Swap Pair Once connected, select the tokens you want to swap. You can do this by typing the token name in the token field or by importing a custom token. Additionally, for a seamless experience, we have pre-listed and categorized the most popular tokens on your current network. Token Selection Interface on app.fibrous.finance ### Step 3: Configure Your Swap Amount Type in the amount in the top field. You will then see a quote of the amount you will receive in the field below. To adjust the amount, you can directly enter the amounts, or you can use sliders or percentage adjustment buttons. Swap Amount Configuration ### Step 4: Approve or Permit Contract to Swap Tokens Approve or permit Fibrous to swap the tokens on your behalf. Proceed to Step 5 if token approval/permit is not required. Thanks to [Starknet's Native Account Abstraction](https://www.starknet.io/blog/account-abstraction/native-account-abstraction/)! You do not need to approve separately for your swaps. If this is your first time swapping token on Scroll network with Fibrous using your wallet, you'll find that the Swap button is grayed out. You'll need to approve the Fibrous smart contract to spend your tokens before you can proceed with the swap. Token Approval Interface To help our users save on gas fees, Fibrous offers a Permit based approval option for tokens that adhere to the ERC-2612 standard. Unlike the basic ERC20 token implementation, ERC-2612 allows for gasless approvals of smart contract allowances through a simple signed message. In other words, approving a token via Approve doesn't require any gas and has the same effect as the ERC20 Approve. To ensure the security of your tokens, you'll be prompted to sign the transaction for the exact amount in your wallet's interface. By signing the approval request, you're ensuring that Fibrous can only swap the exact number of tokens specified from your wallet. If future swaps exceed this amount, you'll need to complete the approval process again. Approval pop-up on app.fibrous.finance Upon signing the approval, you will then be able to proceed with the swap. ### Step 5: Confirm the Swap After everything is set up, you can click on the Swap button. In the tab that appears, you can adjust the slippage settings and see the amount you will receive in the event of negative slippage. Once everything is in order, you can initiate your transaction by clicking the Confirm button. Swap Setting button on app.fibrous.finance Example confirmation tab on Argent Wallet ## Monitoring Transaction Confirmations After confirming the transactions in Fibrous, you can complete the process once you also approve them in your wallet. Later, you can view the details of the transaction in the pop-up that will appear in the bottom right corner of the Fibrous interface. Transaction confirmation notification By clicking on the "transaction id" in the pop-up at the bottom right, you can view and track many technical details of your transaction on the preferred block explorer. Lastly, you can view the aggregated swap you executed in Fibrous under the history tab for your all confirmations. Transaction history view ## Customizing Slippage Tolerance Slippage is the potential price difference from when you initiate a trade to when it's processed on the blockchain. 'Auto' is set at 1.0%, meaning the final price could vary by half a percent from the quoted price. You can adjust this according to your risk tolerance. Apart from the options of 0.1%, 0.5%, and 1%, you can also set a custom slippage. Slippage settings interface ## Find Your Favorite Tokens To make it easy for you to swap any two tokens at the best rates on the Fibrous interface, we have developed token categorization. In this categorization: Slippage settings interface * **All**: Displays all tokens with a specific ticker on the selected network. * **Verified**: This category includes a selection of tokens that are widely used and generally considered reliable for trading. If you want your token to be verified on Fibrous, you can check the repository below. [https://github.com/Fibrous-Finance/Fibrous-tokens](https://github.com/Fibrous-Finance/Fibrous-tokens) * **Stable**: Offers a selection of all available stablecoins. * **Meme**: Showcases meme tokens that are prominent on your network and have surpassed a certain volume threshold. * **Unrugged (for Starknet)**: This selection displays all tokens originating from the [Unruggable.meme](https://unruggable.meme) platform, which allows the deployment of unruggable tokens on Starknet. ## Managing Liquidity Sources Fibrous will automatically select the best sources on the selected network. You can choose the liquidity sources you want to use from this tab according to your preference. By default, all Fibrous supported DEXes on the connected chain will be selected. You can view the list of supported DEXs on each chain by the Swap Settings tab.
If you do not select all liquidity sources, you may not achieve the best price fetching. To maximize your swap outputs and trade with the widest variety of token variations, you should keep all liquidity sources enabled. # Token Security Scoring System Source: https://docs.fibrous.finance/fibrous-solutions/fibrous-interface/token_security Assess token security risks on Fibrous using the GoPlus Token Security API. ## Overview At Fibrous, we prioritize providing users with the best trading execution rates while ensuring robust detection of security risks associated with tokens. To achieve this, we have integrated the [**GoPlus Token Security API**](https://gopluslabs.io/token-security) into our interface. This integration enables us to deliver a transparent and user-friendly security risk assessment for tokens. The dedicated page outlines our token security scoring system, as implemented in [Fibrous](https://app.fibrous.finance/), detailing the risk categories, scoring methodology, and security levels. ## Risk Categories and Scoring ### Critical Risks (100 Points) The following parameters indicate severe security concerns, each contributing **100 points** to the token's risk score, marking them as **CRITICAL** risks. | Parameter | Score | Risk Level | | --------------------------- | ----- | ---------- | | `is_open_source` (value: 0) | +100 | CRITICAL | | `is_honeypot` | +100 | CRITICAL | | `hidden_owner` | +100 | CRITICAL | | `external_call` | +100 | CRITICAL | | `can_take_back_ownership` | +100 | CRITICAL | | `owner_change_balance` | +100 | CRITICAL | | `selfdestruct` | +100 | CRITICAL | | `cannot_buy` | +100 | CRITICAL | | `cannot_sell_all` | +100 | CRITICAL | | `transfer_pausable` | +100 | CRITICAL | | `is_blacklisted` | +100 | CRITICAL | | `gas_abuse` | +100 | CRITICAL | | `is_airdrop_scam` | +100 | CRITICAL | | `fake_token` | +100 | CRITICAL | | `buy_tax` (100%) | +100 | CRITICAL | | `sell_tax` (100%) | +100 | CRITICAL | | `transfer_tax` (100%) | +100 | CRITICAL | ### High, Medium, and Low-Level Risks These parameters contribute to the risk score based on their severity, ranging from **HIGH** to **LOW** risk levels. | Parameter | Score Contribution | Detailed Risk Level | | ------------------------------ | ------------------ | ------------------- | | `honeypot_with_same_creator` | +50 | HIGH | | `buy_tax` (>15%) | +50 | HIGH | | `buy_tax` (>5% and ≤15%) | +30 | MEDIUM | | `buy_tax` (>0% and ≤5%) | +10 | LOW | | `sell_tax` (>15%) | +50 | HIGH | | `sell_tax` (>5% and ≤15%) | +30 | MEDIUM | | `sell_tax` (>0% and ≤5%) | +10 | LOW | | `transfer_tax` (>15%) | +50 | HIGH | | `transfer_tax` (>5% and ≤15%) | +30 | MEDIUM | | `transfer_tax` (>0% and ≤5%) | +10 | LOW | | `slippage_modifiable` | +30 | MEDIUM | | `personal_slippage_modifiable` | +30 | MEDIUM | | `is_whitelisted` | +20 | MEDIUM | | `trading_cooldown` | +15 | MEDIUM | ### Governance Risks and Long-Term Factors These parameters reflect governance-related risks or factors that may impact the token's security over time. | Parameter | Score | Risk Level | | ----------------------- | ----- | ---------- | | `is_mintable` | +20 | MEDIUM | | `anti_whale_modifiable` | +10 | LOW | | `other_potential_risks` | +15 | MEDIUM | ### Risk Mitigating / Trust-Enhancing Factors Certain parameters reduce the risk score, indicating positive attributes that enhance the token's security. | Parameter | Score | Risk Level | | ------------------------------------------------------- | ----- | ---------- | | `is_anti_whale` (non-modifiable) | -10 | POSITIVE | | `contract_renounced` (owner\_address is a burn address) | -50 | POSITIVE | | `trust_list` | -30 | POSITIVE | | `is_in_cex` | -20 | POSITIVE | | `launchpad_token` | -25 | POSITIVE | ## Security Levels and Scoring Based on the total risk score, tokens are classified into one of the following security levels, each accompanied by an icon for user interface representation. | Total Score | Level Code | Icon | Description | | ----------- | ------------------- | --------------------------- | --------------------------------------------------------------------------------------------- | | - | \*\*VERIFIED \*\* | — | Carefully selected by Fibrous, these are widely adopted and established tokens in the market. | | 0–19 | **SAFE\_TO\_TRADE** | Low Risk | Tokens with minimal risk that you can trade with confidence and low concern | | 20–49 | **MEDIUM\_RISK** | Medium Risk | Potentially moderately risky tokens requiring caution. | | 50–99 | **HIGH\_RISK** | High Risk | High-risk tokens with significant security concerns. | | 100+ | **CRITICAL\_RISK** | Critical Risk | The highest risk level, indicating critical security issues. | For more details and explanations, users can refer to the GoPlus Labs documentation at [https://docs.gopluslabs.io/reference/response-details](https://docs.gopluslabs.io/reference/response-details). # Best Route Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/best-route Returns Best Route via Fibrous The `getBestRoute` function finds the optimal trading route for a token swap through Fibrous's liquidity pools. ## Function Signature ```typescript theme={null} /** * Fetches the best route from the API. * @param params Route parameters object. * @returns Route response. * @throws Error if the chain is not supported. */ getBestRoute( params: getBestRouteParams, ): Promise; ``` ### getBestRouteParams Type ```typescript theme={null} type getBestRouteParams = { amount: AmountType; tokenInAddress: string; tokenOutAddress: string; chainId: number; options?: Partial; integrationData?: IntegrationData; }; ``` ### IntegrationData Type ```typescript theme={null} type IntegrationData = { integratorAddress: string; integratorFeePercentageBps?: number; // 0-500, maximum 5% integratorSurplusPercentageBps?: number; // 0-5000, maximum 50% }; ``` ## Parameters | Parameter | Type | Description | | ---------------------- | --------------- | ----------------------------------------------------- | | params.amount | BigNumber | Amount to swap, formatted according to token decimals | | params.tokenInAddress | string | Token address to swap from | | params.tokenOutAddress | string | Token address to swap to | | params.chainId | number | Chain ID where the transaction will take place | | params.options | RouteOverrides | Optional parameters for route customization | | params.integrationData | IntegrationData | Optional integrator fee/surplus configuration | ### RouteOverrides Type ```typescript theme={null} type RouteOverrides = { reverse: boolean; direct: boolean; excludeProtocols: number[]; }; ``` * **excludeProtocols**: This is where you list the IDs of the AMMs you don't want to include. For example, if there are certain AMMs you prefer not to use due to high fees or other reasons, you simply put their unique IDs (numbers) in this list. * Use `supportedProtocols(chainId)` to get a list of supported AMMs and their IDs. ## RouteResponse Type ```typescript theme={null} type RouteResponse = { success: true; inputToken: Token; inputAmount: string; outputToken: Token; outputAmount: string; estimatedGasUsed: string; estimatedGasUsedInUsd?: number; route: FormattedRoute[]; time: number; bestQuotesByProtocols: string[]; initial?: boolean; routeSwapType?: RouteSwapType; integratorAddress?: string; integratorFeePercentage?: number; integratorSurplusPercentage?: number; meta: { apiVersion: string; timestamp: string; }; }; ``` ## Example Usage ```typescript theme={null} import { Router as FibrousRouter, getBestRouteParams } from "fibrous-router-sdk"; import { parseUnits } from "ethers"; // Create a new router instance with v2 API const fibrous = new FibrousRouter({ apiKey: "your-api-key", // optional, required for integrator features apiVersion: "v2", // optional, v2 is the latest version }); // Refresh and get supported chains const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "hyperevm")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } // Build route options const tokens = await fibrous.supportedTokens(chainId); // Get input token from tokens map const inputToken = tokens.get("usdc"); if (!inputToken) { throw new Error("Input token not found"); } // Get output token by address (for unverified tokens) const outputToken = await fibrous.getToken( "0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb", chainId, ); if (!outputToken) { throw new Error("Output token not found"); } const tokenInAddress = inputToken.address; const tokenOutAddress = outputToken.address; const tokenInDecimals = Number(inputToken.decimals); const inputAmount = BigInt(parseUnits("4", tokenInDecimals)); // 4 USDC const getBestRouteParams: getBestRouteParams = { amount: inputAmount, tokenInAddress: tokenInAddress, tokenOutAddress: tokenOutAddress, chainId: chainId, options: { reverse: false, }, }; const route = await fibrous.getBestRoute(getBestRouteParams); // returns route type (src/types/route.ts) ``` # Execute Batch Swap Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/execute-batch-swap Learn how to execute multiple token swaps in a single transaction using Fibrous Router SDK # Execute Batch Swap Slippage is an important concept in trading that can have a significant impact on your trading outcomes. It refers to the difference between the expected price of a trade and the actual price at which the trade is executed. Slippage can occur in various market conditions and for several reasons, and it's crucial for traders to be aware of its potential effects. Fibrous uses slippage settings to prevent you from losing money; there is no need to increase your slippage when you spot an arbitrage opportunity. **Fibrous is still in alpha version. Please make sure you have adjusted your slippage properly.** Generate transaction data for calling the Fibrous Router contract to execute multiple swaps in a single transaction. ## Basic Setup First, let's set up the router and get the token information: ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; import { parseUnits } from "ethers"; const fibrous = new FibrousRouter(); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "starknet")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } // Get the supported tokens for the Starknet chain const tokens = await fibrous.supportedTokens(chainId); const ethToken = tokens.get("eth"); const strkToken = tokens.get("strk"); const usdcToken = tokens.get("usdc"); const usdtToken = tokens.get("usdt"); if (!ethToken || !strkToken || !usdcToken || !usdtToken) { throw new Error("Required tokens not found"); } const tokenInAddress_1 = ethToken.address; const tokenInAddress_2 = strkToken.address; const tokenInAddress_3 = usdcToken.address; const tokenOutAddress = usdtToken.address; const tokenInDecimals_1 = ethToken.decimals; const tokenInDecimals_2 = strkToken.decimals; const tokenInDecimals_3 = usdcToken.decimals; const inputAmounts = [ BigInt(parseUnits("0.001", tokenInDecimals_1)), // 0.001 ETH BigInt(parseUnits("10", tokenInDecimals_2)), // 10 STRK BigInt(parseUnits("5", tokenInDecimals_3)), // 5 USDC ]; ``` ## Usage on Backend For backend implementations on Starknet: ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; import { Call } from "starknet"; import { parseUnits } from "ethers"; import { account } from "./account"; const fibrous = new FibrousRouter(); const chainId = fibrous.supportedChains.find(chain => chain.chain_name == "starknet")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } // Get the supported tokens for the Starknet chain const tokens = await fibrous.supportedTokens(chainId); const ethToken = tokens.get("eth"); const strkToken = tokens.get("strk"); const usdcToken = tokens.get("usdc"); const usdtToken = tokens.get("usdt"); if (!ethToken || !strkToken || !usdcToken || !usdtToken) { throw new Error("Required tokens not found"); } const tokenInAddress_1 = ethToken.address; const tokenInAddress_2 = strkToken.address; const tokenInAddress_3 = usdcToken.address; const tokenOutAddress = usdtToken.address; const tokenInDecimals_1 = ethToken.decimals; const tokenInDecimals_2 = strkToken.decimals; const tokenInDecimals_3 = usdcToken.decimals; const inputAmounts = [ BigInt(parseUnits("0.001", tokenInDecimals_1)), // 0.001 ETH BigInt(parseUnits("10", tokenInDecimals_2)), // 10 STRK BigInt(parseUnits("5", tokenInDecimals_3)), // 5 USDC ]; const public_key = process.env.STARKNET_PUBLIC_KEY; const privateKey = process.env.STARKNET_PRIVATE_KEY; const RPC_URL = process.env.STARKNET_RPC_URL; const destination = process.env.STARKNET_PUBLIC_KEY; // The address to receive the tokens after the swap is completed (required) if (!privateKey || !public_key || !RPC_URL || !destination) { throw new Error("Missing environment variables"); } // Call the buildTransaction method in order to build the transaction // slippage: The maximum acceptable slippage of the buyAmount amount. const slippage = 1; // 1% const tokenInAddresses = [ tokenInAddress_1, tokenInAddress_2, tokenInAddress_3, ]; const tokenOutAddresses = [tokenOutAddress]; const swapCalls = await fibrous.buildBatchTransaction( inputAmounts, tokenInAddresses, tokenOutAddresses, slippage, destination, chainId, {reverse: false, direct: false, excludeProtocols: []}, // excludeProtocols is array of protocol IDs (numbers) ); // https://www.starknetjs.com/docs/guides/connect_account // If this account is based on a Cairo v2 contract (for example OpenZeppelin account 0.7.0 or later), do not forget to add the parameter "1" after the privateKey parameter const account0 = account(privateKey, public_key, "1", RPC_URL); const approveCalls: Call[] = []; for (let i = 0; i < inputAmounts.length; i++) { const approveCall: Call = await fibrous.buildApproveStarknet( inputAmounts[i], tokenInAddresses[i], ); approveCalls.push(approveCall); } // Type guard: Starknet chains return Call[] if ( Array.isArray(swapCalls) && swapCalls.every( (call) => "contractAddress" in call && "entrypoint" in call, ) ) { const resp = await account0.execute([...approveCalls, ...swapCalls]); console.log(`https://voyager.online/tx/${resp.transaction_hash}`); } else { console.error("Invalid swap call data for Starknet batch transaction"); } ``` The swap call returns a transaction object with the following structure: ```typescript theme={null} { contractAddress:ROUTER_ADDRESS, entrypoint: "swap", calldata: calldata, } ``` ## Important Notes 1. All swaps in a batch must succeed for the transaction to be successful 2. Make sure to have sufficient balance for all tokens being swapped 3. Approve all tokens before executing the batch swap 4. Consider gas costs for multiple swaps in a single transaction 5. Monitor the transaction status for all swaps in the batch 6. Handle errors appropriately for each swap in the batch ## Related Topics * [Execute Swap](/integrate-best-trading/fibrous-sdk/execute-swap) * [Best Route](/integrate-best-trading/fibrous-sdk/best-route) * [Supported Tokens](/integrate-best-trading/fibrous-sdk/supported-tokens) # SDK Overview Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/index Integrate Fibrous into your application with our powerful TypeScript SDK ## Introduction Fibrous Router SDK is a TypeScript library that provides a simple and efficient way to integrate optimal token swaps into your decentralized applications. Built on top of the Fibrous Router API, it handles all the complexity of finding the best routes and executing swaps across multiple chains. ## Why Use the SDK? Full TypeScript support with comprehensive type definitions Single interface for Base, HyperEVM, Citrea, Monad, and Starknet Simple API that abstracts away complex routing logic Automatically finds the best swap paths across all DEXs ## Supported Chains The SDK supports the following blockchain networks: | Chain | Chain ID | | ------------ | -------- | | **Starknet** | SN\_MAIN | | **Base** | 8453 | | **Citrea** | 4114 | | **HyperEVM** | 998 | | **Monad** | 143 | ## Quick Start ```bash theme={null} npm install fibrous-router-sdk ``` ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; const fibrous = new FibrousRouter({ apiVersion: "v2", // optional, v2 is the latest version }); ``` ```typescript theme={null} const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "base")?.chain_id; const route = await fibrous.getBestRoute({ amount: inputAmount, tokenInAddress, tokenOutAddress, chainId, }); ``` ```typescript theme={null} const { route, calldata } = await fibrous.buildRouteAndCalldata({ inputAmount, tokenInAddress, tokenOutAddress, slippage: 0.5, // 0.5% slippage destination: userAddress, chainId, }); ``` ## Key Features ### 🔍 Smart Routing The SDK automatically finds the optimal route by: * Aggregating liquidity from multiple DEX protocols * Splitting large trades across multiple paths * Minimizing price impact and slippage * Considering gas costs in route optimization ### Batch Operations Execute multiple swaps in a single transaction (Starknet): ```typescript theme={null} const routes = await fibrous.getBestRouteBatch( amounts, tokenInAddresses, tokenOutAddresses, "starknet" ); ``` ### Token Management Easy access to supported tokens: ```typescript theme={null} const tokens = await fibrous.supportedTokens(chainId); const usdc = tokens.get("usdc"); ``` ### Protocol Flexibility Exclude specific protocols or use only certain ones: ```typescript theme={null} const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "base")?.chain_id; const route = await fibrous.getBestRoute({ amount, tokenInAddress: tokenIn, tokenOutAddress: tokenOut, chainId, options: { excludeProtocols: [1, 2], // Protocol IDs, not names direct: false } }); ``` ## Complete Example Here's a complete example of swapping tokens on Base: ```typescript theme={null} import { Router as FibrousRouter, getBestRouteParams, buildRouteAndCalldataParams } from "fibrous-router-sdk"; import { parseUnits } from "ethers"; async function swapTokens() { // Initialize router with v2 API const fibrous = new FibrousRouter({ apiVersion: "v2", }); // Refresh and get supported chains const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "base")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } // Get supported tokens const tokens = await fibrous.supportedTokens(chainId); const eth = tokens.get("eth"); const usdc = tokens.get("usdc"); if (!eth || !usdc) { throw new Error("Tokens not found"); } // Prepare swap parameters const inputAmount = BigInt(parseUnits("1", Number(eth.decimals))); // 1 ETH const slippage = 0.5; // 0.5% const userAddress = "0xYourAddress"; // Get best route const getBestRouteParams: getBestRouteParams = { amount: inputAmount, tokenInAddress: eth.address, tokenOutAddress: usdc.address, chainId, }; const route = await fibrous.getBestRoute(getBestRouteParams); console.log(`Input: ${route.inputAmount} ${eth.symbol}`); console.log(`Output: ${route.outputAmount} ${usdc.symbol}`); // Build route and calldata const buildRouteAndCalldataParams: buildRouteAndCalldataParams = { inputAmount, tokenInAddress: eth.address, tokenOutAddress: usdc.address, slippage, destination: userAddress, chainId, }; const { route: routeData, calldata } = await fibrous.buildRouteAndCalldata(buildRouteAndCalldataParams); // Execute with your wallet // const receipt = await wallet.sendTransaction(tx); return { route: routeData, calldata }; } ``` ## Chain-Specific Examples ```typescript theme={null} const fibrous = new FibrousRouter({ apiVersion: "v2" }); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "base")?.chain_id; const route = await fibrous.getBestRoute({ amount: BigInt(parseUnits("1", 18)), tokenInAddress: "0x0000000000000000000000000000000000000000", // ETH tokenOutAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC chainId, }); ``` ```typescript theme={null} const fibrous = new FibrousRouter({ apiVersion: "v2" }); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "hyperevm")?.chain_id; const route = await fibrous.getBestRoute({ amount: BigInt(parseUnits("1", 18)), tokenInAddress: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", // HYPE tokenOutAddress: "0xb88339cb7199b77e23db6e890353e22632ba630f", // USDC chainId, }); ``` ```typescript theme={null} const fibrous = new FibrousRouter({ apiVersion: "v2" }); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "citrea")?.chain_id; const route = await fibrous.getBestRoute({ amount: BigInt(parseUnits("1", 18)), tokenInAddress: "0x0000000000000000000000000000000000000000", // cBTC tokenOutAddress: "0xE045e6c36cF77FAA2CfB54466D71A3aEF7bbE839", // USDC.e chainId, }); ``` ```typescript theme={null} const fibrous = new FibrousRouter({ apiVersion: "v2" }); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "starknet")?.chain_id; const route = await fibrous.getBestRoute({ amount: BigInt(parseUnits("1", 18)), tokenInAddress: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", // ETH tokenOutAddress: "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", // USDC chainId, }); ``` ```typescript theme={null} const fibrous = new FibrousRouter({ apiVersion: "v2" }); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "monad")?.chain_id; const route = await fibrous.getBestRoute({ amount: BigInt(parseUnits("1", 18)), tokenInAddress: "0x0000000000000000000000000000000000000000", // ETH tokenOutAddress: "0x754704bc059f8c67012fed69bc8a327a5aafb603", // USDC chainId, }); ``` ## SDK vs API **Use the SDK when:** * Building a TypeScript/JavaScript application * You want type safety and autocomplete * You need simplified integration * Working with multiple chains * You want built-in error handling **Use the API when:** * Building in a different language * You need maximum flexibility * Building a lightweight integration * You have custom routing logic * Working with a single chain ## Requirements * **Node.js**: Version 18.x or higher * **Web3 Provider**: ethers.js v6+ or starknet.js v5+ * **TypeScript**: Version 4.5+ (recommended) ## Installation ```bash npm theme={null} npm install fibrous-router-sdk ``` ```bash yarn theme={null} yarn add fibrous-router-sdk ``` ```bash pnpm theme={null} pnpm add fibrous-router-sdk ``` ## Next Steps Detailed installation and setup instructions Explore all available SDK methods Learn how to find optimal swap routes Build and execute swap transactions ## Resources * [GitHub Repository](https://github.com/Fibrous-Finance/router-sdk) * [NPM Package](https://www.npmjs.com/package/fibrous-router-sdk) * [API Reference](/api-reference/introduction) * [Discord Community](https://discord.gg/fibrous) ## Support Need help? We're here for you: * 💬 [Join our Discord](https://discord.gg/fibrous) * 📧 [Email Support](mailto:contact@fibrous.finance) * 🐛 [Report Issues](https://github.com/Fibrous-Finance/router-sdk/issues) # Installation Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/installation Learn how to install and setup Fibrous Router SDK # Installation You can install Fibrous Router SDK using npm, yarn, or pnpm: Latest stable version: 1.0.1 ```bash npm theme={null} npm install fibrous-router-sdk ``` ```bash yarn theme={null} yarn add fibrous-router-sdk ``` ```bash pnpm theme={null} pnpm add fibrous-router-sdk ``` # Quick Start Check out the detailed example in the [Fibrous SDK Github Repository](https://github.com/Fibrous-Finance/router-sdk) section for a simple example of how to initialize and use the SDK. Here's a simple example of how to initialize and use the SDK: ```typescript theme={null} import { Router as FibrousRouter, getBestRouteParams } from "fibrous-router-sdk"; import { parseUnits } from "ethers"; // Create a new router instance with v2 API const fibrous = new FibrousRouter({ apiVersion: "v2", // optional, v2 is the latest version }); // Refresh and get supported chains const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "hyperevm")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } // Build route options const tokens = await fibrous.supportedTokens(chainId); // Get input token from tokens map const inputToken = tokens.get("usdc"); if (!inputToken) { throw new Error("Input token not found"); } // Get output token by address (for unverified tokens) const outputToken = await fibrous.getToken( "0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb", chainId, ); if (!outputToken) { throw new Error("Output token not found"); } const tokenInAddress = inputToken.address; const tokenOutAddress = outputToken.address; const tokenInDecimals = Number(inputToken.decimals); const inputAmount = BigInt(parseUnits("4", tokenInDecimals)); // 4 USDC const getBestRouteParams: getBestRouteParams = { amount: inputAmount, tokenInAddress: tokenInAddress, tokenOutAddress: tokenOutAddress, chainId: chainId, options: { reverse: false, }, }; const route = await fibrous.getBestRoute(getBestRouteParams); ``` # Requirements * Node.js version 18.x or higher * A Web3 provider (like ethers.js) for transaction signing * Access to supported blockchain networks (Base, Citrea, HyperEVM, Monad, or Starknet) # Next Steps After installation, check out these guides to learn more about specific features: * [Overview](/integrate-best-trading/fibrous-sdk/overview) * [Supported Tokens](/integrate-best-trading/fibrous-sdk/supported-tokens) * [Best Route](/integrate-best-trading/fibrous-sdk/best-route) * [Execute Swap](/integrate-best-trading/fibrous-sdk/execute-swap) # Overview Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/overview Overview of Fibrous Router SDK main functions compatible with all supported chains v2 API ## Supported Chains * Starknet * Base * Citrea * HyperEVM * Monad ```typescript theme={null} /** * List of supported chains and their router addresses. */ supportedChains: CHAIN_MAP[]; ``` ## Supported Tokens Returns the list of Tokens supported by Fibrous ```typescript theme={null} /** * Returns the supported token list for a given chain. * @param chainId Chain ID. * @returns Map of lowercased symbol -> Token. */ supportedTokens(chainId: number): Promise>; ``` ## Supported Protocols Returns the list of Protocols supported by Fibrous ```typescript theme={null} /** * Returns supported protocols. * @param chainId Chain ID. * @returns Mapping of AMM name -> protocol identifier. */ supportedProtocols(chainId: number): Promise>; ``` ## Best Route Returns the best route via Fibrous ```typescript theme={null} /** * Fetches the best route from the API. * @param params Route parameters object. * @returns Route response. * @throws Error if the chain is not supported. */ getBestRoute( params: getBestRouteParams, ): Promise; ``` ### getBestRouteParams Type ```typescript theme={null} type getBestRouteParams = { amount: AmountType; tokenInAddress: string; tokenOutAddress: string; chainId: number; options?: Partial; integrationData?: IntegrationData; }; ``` ### IntegrationData Type ```typescript theme={null} type IntegrationData = { integratorAddress: string; integratorFeePercentageBps?: number; // 0-500, maximum 5% integratorSurplusPercentageBps?: number; // 0-5000, maximum 50% }; ``` ### RouteOverrides Type ```typescript theme={null} type RouteOverrides = { reverse: boolean; direct: boolean; excludeProtocols: number[]; // Array of protocol IDs }; ``` ## Build Transaction Returns calldata with best route to transaction via Fibrous ```typescript theme={null} /** * Legacy method that builds a route and calldata to prepare a transaction. * Note: This will be deprecated; prefer `buildRouteAndCalldata`. * @param params Transaction parameters object. * @returns Starknet `Call` or EVM calldata/transaction structure. */ buildTransaction( params: buildTransactionParams, ): Promise; ``` ### buildTransactionParams Type ```typescript theme={null} type buildTransactionParams = { inputAmount: AmountType; tokenInAddress: string; tokenOutAddress: string; slippage: number; destination: string; chainId: number; options?: Partial; integrationData?: IntegrationData; }; ``` ## Build Route and Calldata ```typescript theme={null} /** * Returns the best route and executable calldata in a single call. * @param params Route and calldata parameters object. * @returns Route and calldata structure (includes Starknet swap call when applicable). */ buildRouteAndCalldata( params: buildRouteAndCalldataParams, ): Promise; ``` ### buildRouteAndCalldataParams Type ```typescript theme={null} type buildRouteAndCalldataParams = { inputAmount: AmountType; tokenInAddress: string; tokenOutAddress: string; slippage: number; destination: string; chainId: number; options?: Partial; integrationData?: IntegrationData; }; ``` ## Build Approve Starknet ```typescript theme={null} /** * Builds Starknet approve call parameters. * @param amount Amount to approve (will be converted to hex). * @param tokenAddress ERC-20 token address. */ buildApproveStarknet(amount: AmountType, tokenAddress: string): Promise; ``` ## Build Approve EVM ```typescript theme={null} /** * Performs EVM approve if needed and returns the result. * @param amount Amount to approve. * @param tokenAddress ERC-20 token address. * @param account Wallet/signer used for the transaction. * @param chainId Chain ID. * @returns `true` if allowance is sufficient or approve succeeded. */ buildApproveEVM( amount: AmountType, tokenAddress: string, account: Wallet, chainId?: number, ): Promise; ``` ## Best Route Batch ```typescript theme={null} /** * Fetches best routes in batch for multiple inputs (Starknet and Base for now). * @param amounts List of input amounts. * @param tokenInAddresses Input token addresses. * @param tokenOutAddresses Output token addresses. * @param chainId Chain ID. * @param options Optional route parameters. * @returns List of route responses. */ getBestRouteBatch( amounts: bigint[] | string[] | number[] | BigNumberish[], tokenInAddresses: string[], tokenOutAddresses: string[], chainId: number, options?: Partial, ): Promise; ``` ## Build Batch Transaction ```typescript theme={null} /** * Builds calldata/call list for batch transactions (Starknet for now). * @param inputAmounts Input amounts. * @param tokenInAddresses Input token addresses. * @param tokenOutAddresses Output token addresses. * @param slippage Slippage percentage. * @param destination Receiver address. * @param chainId Chain ID. * @param options Optional parameters. * @returns Array of Starknet `Call`s or chain-specific payload. */ buildBatchTransaction( inputAmounts: AmountType[], tokenInAddresses: string[], tokenOutAddresses: string[], slippage: number, destination: string, chainId: number, options?: Partial, ): Promise; ``` # Route and Calldata Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/route-and-calldata Learn how to execute token swaps using Fibrous Router SDK # Route and Calldata Slippage is an important concept in trading that can have a significant impact on your trading outcomes. It refers to the difference between the expected price of a trade and the actual price at which the trade is executed. Slippage can occur in various market conditions and for several reasons, and it's crucial for traders to be aware of its potential effects. Fibrous uses slippage settings to prevent you from losing money; there is no need to increase your slippage when you spot an arbitrage opportunity. **Fibrous is still in alpha version. Please make sure you have adjusted your slippage properly.** ## Usage on EVM Networks (Base, Citrea, HyperEVM, Monad) Here's how to execute a swap on EVM-compatible networks like Base, Citrea, HyperEVM and Monad: ```typescript theme={null} import { Router as FibrousRouter, buildRouteAndCalldataParams } from "fibrous-router-sdk"; import { ethers, parseUnits } from "ethers"; import { account } from "./account"; import { humanReadableEvmSwapCallDataLog } from "../utils/humanReadableEvmLog"; import dotenv from "dotenv"; import { monitorTransaction } from "./utils"; dotenv.config(); // RPC URL for the EVM network, you can change this to the RPC URL of your choice const RPC_URL = process.env.RPC_URL; // Destination address for the swap (optional) const destination = process.env.EVM_PUBLIC_KEY; // Private key of the account that will be used to sign the transaction const privateKey = process.env.EVM_PRIVATE_KEY; const fibrous = new FibrousRouter({ apiKey: "your-api-key", // optional, required for integrator features apiVersion: "v2", }); if (!privateKey || !RPC_URL || !destination) { throw new Error("Missing environment variables"); } // Create a new contract instance const account0 = account(privateKey, RPC_URL); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "hyperevm")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } const contractWallet = await fibrous.getContractWAccount(account0 as any, chainId); const provider = new ethers.JsonRpcProvider(RPC_URL); // Build route options const tokens = await fibrous.supportedTokens(chainId); // const inputToken = await fibrous.getToken( // "0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb", // chainId, // ); const inputToken = tokens.get("usdc"); if (!inputToken) { throw new Error("Input token not found"); } const tokenInAddress = inputToken.address; const outputToken = tokens.get("whype"); // if you want to search for a token that is not verified, you can use the getToken method // const outputToken = await fibrous.getToken( // "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC address // "base", // ); if (!outputToken) { throw new Error("Output token not found"); } const tokenOutAddress = outputToken.address; const tokenInDecimals = Number(inputToken.decimals); const inputAmount = BigInt(parseUnits("2", tokenInDecimals)); // 2 USDC const isNativeToken = tokenInAddress == "0x0000000000000000000000000000000000000000"; // Call the buildRouteAndCalldata method in order to build the transaction // slippage: The maximum acceptable slippage of the buyAmount amount. const slippage = 0.5; // 0.5% const { route, calldata } = await fibrous.buildRouteAndCalldata({ inputAmount: inputAmount, tokenInAddress: tokenInAddress, tokenOutAddress: tokenOutAddress, slippage, destination: destination || account0.address, chainId: chainId, }); const approveResponse = await fibrous.buildApproveEVM( inputAmount, tokenInAddress, account0 as any, chainId, ); humanReadableEvmSwapCallDataLog( calldata, inputToken, outputToken, await fibrous.supportedProtocols(chainId), ); if (approveResponse === true) { try { // Type guard: EVM chains return EvmTransactionData if ("route" in calldata && "swap_parameters" in calldata) { const feeData = await provider.getFeeData(); if (!feeData.gasPrice) { console.log("gasPrice not found"); return; } let tx; if (isNativeToken) { tx = await contractWallet.swap( calldata.route, calldata.swap_parameters, { value: inputAmount, gasPrice: feeData.gasPrice * 4n, }, ); } else { tx = await contractWallet.swap( calldata.route, calldata.swap_parameters, { gasPrice: feeData.gasPrice * 2n, }, ); } await monitorTransaction(tx); } else { console.error("Invalid swap call data for EVM transaction"); } } catch (e) { console.error("Error swapping tokens: ", e); } } else { console.error("Error approving tokens"); } ``` ## Usage on Starknet For Starknet, the process is slightly different due to its unique architecture: ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; import { Call } from "starknet"; import { parseUnits } from "ethers"; import "dotenv/config"; import { account } from "./account"; import { humanReadableStarknetSwapCallDataLog } from "../utils/humanReadableStarknetLog"; const PUBLIC_KEY = process.env.STARKNET_PUBLIC_KEY; const PRIVATE_KEY = process.env.STARKNET_PRIVATE_KEY; const RPC_URL = process.env.STARKNET_RPC_URL; const DESTINATION = process.env.STARKNET_PUBLIC_KEY; // The address to receive the tokens after the swap is completed (required) // Create a new router instance const fibrous = new FibrousRouter({ apiKey: "your-api-key", // optional, required for integrator features apiVersion: "v2", }); const chains = await fibrous.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "starknet")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } if (!DESTINATION || !PRIVATE_KEY || !RPC_URL || !PUBLIC_KEY) { throw new Error("Missing environment variables"); } // Get the supported tokens for the Starknet chain const tokens = await fibrous.supportedTokens(chainId); /** * recommended that use the token address directly * because there may be more than one token with the same symbol. */ const inputToken = await fibrous.getToken( "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", // ETH address chainId, ); if (!inputToken) { throw new Error("Input token not found"); } const outputToken = tokens.get("strk"); // this search in only the tokens that are verified // if you want to search for a token that is not verified, you can use the getToken method // const outputToken = await fibrous.getToken( // "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d", // STRK address // "starknet", // ); if (!outputToken) { throw new Error("Output token not found"); } const tokenInAddress = inputToken.address; const tokenOutAddress = outputToken.address; const tokenInDecimals = Number(inputToken?.decimals); if (!tokenInAddress || !tokenOutAddress || !tokenInDecimals) { throw new Error("Token not found"); } const inputAmount = BigInt(parseUnits("0.0001", tokenInDecimals)); // 0.0001 ETH // Call the buildRouteAndCalldata method in order to build the transaction // slippage: The maximum acceptable slippage of the buyAmount amount. const slippage = 1; // 1% const { route, calldata } = await fibrous.buildRouteAndCalldata({ inputAmount: inputAmount, tokenInAddress: tokenInAddress, tokenOutAddress: tokenOutAddress, slippage, destination: DESTINATION, chainId: chainId, options: { reverse: false, direct: false, excludeProtocols: [], // Array of protocol IDs (numbers) }, }); // https://www.starknetjs.com/docs/guides/connect_account // If this account is based on a Cairo v2 contract (for example OpenZeppelin account 0.7.0 or later), do not forget to add the parameter "1" after the privateKey parameter const account0 = account(PRIVATE_KEY, PUBLIC_KEY, "1", RPC_URL); const approveCall: Call = await fibrous.buildApproveStarknet( inputAmount, tokenInAddress, ); humanReadableStarknetSwapCallDataLog( calldata, inputToken, outputToken, await fibrous.supportedProtocols(chainId), ); // Type guard: Starknet chains return Call if ("contractAddress" in calldata && "entrypoint" in calldata) { const resp = await account0.execute([approveCall, calldata]); console.log(`https://voyager.online/tx/${resp.transaction_hash}`); } else { console.error("Invalid swap call data for Starknet transaction"); } ``` ## Important Notes 1. Always handle errors appropriately in production code 2. Set a reasonable slippage value based on your trading strategy 3. Make sure to have sufficient balance and approved tokens before executing swaps 4. Monitor transaction status and implement proper error handling 5. Consider implementing retry mechanisms for failed transactions 6. Keep private keys secure and never expose them in your code ## Related Topics * [Best Route](/integrate-best-trading/fibrous-sdk/best-route) * [Supported Tokens](/integrate-best-trading/fibrous-sdk/supported-tokens) * [Supported Protocols](/integrate-best-trading/fibrous-sdk/supported-protocols) # Supported Protocols Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/supported-protocols Fetch a list of protocols supported by Fibrous api The `supportedProtocols` function returns a list of protocols (AMMs) that are supported by Fibrous on a specific chain. ## Function Signature ```typescript theme={null} /** * Returns supported protocols. * @param chainId Chain ID. * @returns Mapping of AMM name -> protocol identifier. */ supportedProtocols(chainId: number): Promise>; ``` ## Example Usage ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; const router = new FibrousRouter({ apiVersion: "v2", }); const chains = await router.refreshSupportedChains(); const chainId = chains.find(chain => chain.chain_name == "hyperevm")?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } const protocols = await router.supportedProtocols(chainId); ``` ## Parameters | Parameter | Type | Description | | --------- | ------ | ---------------------------------------------------------------------------------- | | chainId | number | The chain ID to get supported protocols for (e.g., 8453 for Base, 4114 for Citrea) | ## Response Returns a Promise that resolves to a Record mapping protocol names to their IDs. The response includes: ```typescript theme={null} type ProtocolId = { id: number; // Protocol unique identifier name: string; // Protocol name logoURI?: string; // Optional protocol logo URL }; ``` ## Example Response ```json theme={null} [ { "protocol": 1, "amm_name": "hyperSwapV2", "display_name": "HyperSwap V2", "image_url": null, "type": "v2" }, { "protocol": 2, "amm_name": "hyperSwapV2Stable", "display_name": "HyperSwap V2 Stable", "image_url": null, "type": "stable" }, { "protocol": 3, "amm_name": "hyperSwapV3", "display_name": "HyperSwap V3", "image_url": null, "type": "v3" }, { "protocol": 4, "amm_name": "kittenSwapV2", "display_name": "KittenSwap V2", "image_url": null, "type": "v2" }, { "protocol": 5, "amm_name": "kittenSwapV2Stable", "display_name": "KittenSwap V2 Stable", "image_url": null, "type": "stable" }, { "protocol": 6, "amm_name": "kittenSwapV3", "display_name": "KittenSwap V3", "image_url": null, "type": "v3" }, { "protocol": 7, "amm_name": "laminarV2", "display_name": "Laminar V2", "image_url": null, "type": "v2" }, { "protocol": 8, "amm_name": "laminarV3", "display_name": "Laminar V3", "image_url": null, "type": "v3" }, { "protocol": 9, "amm_name": "ramsesV3", "display_name": "Ramses V3", "image_url": null, "type": "v3" }, { "protocol": 10, "amm_name": "projectX", "display_name": "Project X", "image_url": null, "type": "v3" } ... ] ``` # Supported Tokens Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-sdk/supported-tokens Fetch a list of tokens supported by Fibrous API The `supportedTokens` function returns a list of tokens supported by Fibrous on a specific chain. ## Function Signature ```typescript theme={null} /** * Returns the supported token list for a given chain. * @param chainId Chain ID. * @returns Map of lowercased symbol -> Token. */ supportedTokens(chainId: number): Promise>; ``` ## Example Usage ```typescript theme={null} import { Router as FibrousRouter } from "fibrous-router-sdk"; const router = new FibrousRouter(); const chains = await router.refreshSupportedChains(); const chainId = chains.find( (chain) => chain.chain_name == "starknet", )?.chain_id; if (!chainId) { throw new Error("Chain not supported"); } const tokens = await router.supportedTokens(chainId); ``` ## Parameters | Parameter | Type | Description | | --------- | ------ | ----------------------------------------------------------- | | chainId | number | The chain id to get supported tokens for (e.g. 8453, 84532) | ## Response Returns a Promise that resolves to a Record mapping token symbols to Token objects. Each Token object contains: ```typescript theme={null} export type Token = { // Address of the token contract address: string; // Name of the token name: string; // Symbol of the token symbol: string; // Decimal points of the token (can be string from API) decimals: string; // Price in USD (can be null or string from API) price: string | null; // Image URL for the token icon image_url?: string; // Base token flag (can be null) base?: boolean | null; // Native token flag (can be null) native?: boolean | null; // Verification status verified?: boolean; // Token category category?: string | null; // Legacy fields for backward compatibility isBase?: boolean; isNative?: boolean; }; ``` ## Example Response ```json theme={null} { "ETH": { "name": "Ethereum", "symbol": "ETH", "address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "decimals": 18, "price": null, "image_url": "https://tokens.1inch.io/0x0000000000000000000000000000000000000000.png" }, "USDC": { "name": "USD Coin", "symbol": "USDC", "address": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5eb06f3ecf368a8", "decimals": 6, "price": null, "image_url": "https://tokens.1inch.io/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.png" } } ``` # EVM Router - Swap Functions Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-smart-contracts/evm-router Comprehensive guide to EVM Router swap functions including swap, swapIntegrator, and swapWithPermit # EVM Router Swap Functions EVM Router is the advanced router contract for executing token swaps across multiple protocols on EVM-compatible chains. It supports native token handling, multi-hop swaps, integrator fee/surplus sharing, and permit-based approvals. ## Overview EVM Router provides three main swap functions: 1. **`swap`** - Standard swap function for normal token exchanges 2. **`swapIntegrator`** - Swap with integrator fee or surplus sharing 3. **`swapWithPermit`** - Swap with ERC-20 permit signature (gasless approval) All swap functions support: * **Multi-hop swaps** across different protocols * **Native token handling** (MONAD ↔ WMONAD conversion) * **Rate-based amount distribution** for splitting input across multiple swaps * **Surplus handling** to cap output at expected amount * **Minimum received protection** to ensure slippage tolerance *** ## Contract ABI **Router Contract ABI**: The complete Application Binary Interface (ABI) for EVM Router is available on GitHub: 🔗 **[View Router ABI on GitHub](https://github.com/Fibrous-Finance/router-contract-abi/blob/main/routerAbi.json)** The ABI includes all function signatures, event definitions, and error types needed for integration. *** ## Function: `swap` Performs a standard token swap using the provided route and swap parameters. ### Signature ```solidity theme={null} function swap( RouteParam calldata route, SwapParams[] calldata swap_parameters ) external payable nonReentrant whenNotPaused returns (uint256) ``` ### Parameters #### `route` (RouteParam) The route parameters defining the overall swap path. ```solidity theme={null} struct RouteParam { address token_in; // Input token address address token_out; // Output token address uint256 amount_in; // Amount of input tokens to swap uint256 amount_out; // Expected output amount (for surplus calculation) uint256 min_received; // Minimum amount user must receive address destination; // Recipient address (address(0) = msg.sender) SwapType swap_type; // Type of swap (ethToToken, tokenToEth, tokenToToken) } ``` | Field | Type | Description | | -------------- | ---------- | -------------------------------------------------------------------------------------------------------- | | `token_in` | `address` | Contract address of the input token to sell | | `token_out` | `address` | Contract address of the output token to buy | | `amount_in` | `uint256` | Amount of input tokens to swap (in token's smallest unit) | | `amount_out` | `uint256` | Expected output amount. Used for surplus calculation - if actual output exceeds this, it's capped | | `min_received` | `uint256` | Minimum amount of output tokens user must receive. Transaction reverts if actual output \< min\_received | | `destination` | `address` | Address to receive output tokens. If `address(0)`, uses `msg.sender` | | `swap_type` | `SwapType` | Enum indicating swap type: `ethToToken` (0), `tokenToEth` (1), `tokenToToken` (2) | #### `swap_parameters` (SwapParams\[]) Array of swap parameters for each hop in the multi-hop swap. ```solidity theme={null} struct SwapParams { address token_in; // Input token for this hop address token_out; // Output token for this hop uint32 rate; // Rate percentage (1-1000000, where 1000000 = 100%) int24 protocol_id; // Protocol identifier (maps to swap handler) address pool_address; // Pool contract address for this swap SwapType swap_type; // Swap type for this hop bytes extra_data; // Protocol-specific extra data } ``` | Field | Type | Description | | -------------- | ---------- | ----------------------------------------------------------------------------------------------- | | `token_in` | `address` | Input token address for this swap hop | | `token_out` | `address` | Output token address for this swap hop | | `rate` | `uint32` | Percentage of input amount to use (1-1000000). `amount_in = (previous_amount * rate) / 1000000` | | `protocol_id` | `int24` | Protocol identifier. Maps to swap handler via `swappers` mapping | | `pool_address` | `address` | Pool contract address where swap will execute | | `swap_type` | `SwapType` | Swap type for this hop | | `extra_data` | `bytes` | Protocol-specific data (e.g., fee tier, tick spacing, hooks config) | ### Returns * `uint256`: Amount of output tokens received by the destination address ### Behavior 1. **Validation**: Checks that `token_in != token_out`, `amount_in > 0`, `min_received > 0`, and `swap_parameters.length > 0` 2. **Token Transfer**: * For `tokenToToken` and `tokenToEth`: Transfers `amount_in` from `msg.sender` to contract * For `ethToToken`: Expects ETH sent with transaction (`msg.value`) 3. **Multi-Hop Execution**: * For first swap: Uses `route.amount_in` multiplied by first swap's `rate` * For subsequent swaps: Uses previous swap's output multiplied by current swap's `rate` * Handles native token conversion (MONAD ↔ WMONAD) if protocol supports it 4. **Surplus Handling**: * If actual output > `route.amount_out`, caps output at `route.amount_out` * User receives capped amount, surplus stays in contract 5. **Slippage Protection**: * Verifies `actual_output >= route.min_received` * Reverts with `MinReceivedAmountNotReached` if check fails 6. **Token Transfer**: Sends output tokens to `destination` (or `msg.sender` if `destination == address(0)`) ### Example ```solidity theme={null} // Swap 1 MONAD for USDC via two hops: MONAD -> WMONAD -> USDC RouteParam memory route = RouteParam({ token_in: address(0x0000000000000000000000000000000000000000), // Native MONAD token_out: USDC_ADDRESS, amount_in: 1e18, // 1 MONAD amount_out: 3000e6, // Expected ~3000 USDC min_received: 2950e6, // Minimum 2950 USDC (1.67% slippage) destination: address(0), // Use msg.sender swap_type: SwapType.ethToToken }); SwapParams[] memory swaps = new SwapParams[](2); // First hop: MONAD -> WMONAD swaps[0] = SwapParams({ token_in: address(0x0000000000000000000000000000000000000000), token_out: WMONAD_ADDRESS, rate: 1000000, // 100% of input protocol_id: UNISWAP_V4_PROTOCOL_ID, pool_address: MONAD_WMONAD_POOL, swap_type: SwapType.ethToToken, extra_data: abi.encode(...) // Pool-specific data }); // Second hop: WMONAD -> USDC swaps[1] = SwapParams({ token_in: WMONAD_ADDRESS, token_out: USDC_ADDRESS, rate: 1000000, // 100% of previous output protocol_id: UNISWAP_V3_PROTOCOL_ID, pool_address: WMONAD_USDC_POOL, swap_type: SwapType.tokenToToken, extra_data: abi.encode(...) }); // Execute swap uint256 amountOut = router.swap{value: 1e18}(route, swaps); ``` See [EVM Router Events](/integrate-best-trading/fibrous-smart-contracts/evm-router-events) for complete event documentation. ### Errors | Error | Condition | | ------------------------------- | ------------------------------------------------- | | `TokenAddressesAreSame()` | `token_in == token_out` | | `NoSwapsProvided()` | `swap_parameters.length == 0` | | `AmountInZero()` | `amount_in == 0` | | `MinReceivedZero()` | `min_received == 0` | | `MinReceivedAmountNotReached()` | Actual output \< `min_received` | | `SwapHandlerNotSet()` | No handler set for `protocol_id` | | `SwapFailed()` | Delegatecall to swap handler failed | | `RateZero()` | `rate == 0` in any swap parameter | | `RateExceedsMaximum()` | `rate > 1000000` in any swap parameter | | `AmountTooSmallForRate()` | `(amount * rate) / 1000000 == 0` but `amount > 0` | *** ## Function: `swapIntegrator` Performs a swap with integrator fee or surplus sharing. Integrators can monetize by taking a percentage fee from output or sharing in surplus profits. ### Signature ```solidity theme={null} function swapIntegrator( RouteParam calldata route, SwapParams[] calldata swap_parameters, bytes memory integrator_data ) external payable nonReentrant whenNotPaused returns (uint256) ``` ### Parameters #### `route` (RouteParam) Same as `swap` function. See [swap route parameters](#route-routeparam). #### `swap_parameters` (SwapParams\[]) Same as `swap` function. See [swap parameters](#swap_parameters-swapparams). #### `integrator_data` (bytes) Encoded `IntegratorParams` struct: ```solidity theme={null} struct IntegratorParams { address integrator_address; // Address to receive integrator fee/surplus uint16 surplus_percentage; // Surplus share in bips (max 5000 = 50%) uint16 fee_percentage; // Fee percentage in bips (max 500 = 5%) } ``` | Field | Type | Description | | -------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------- | | `integrator_address` | `address` | Address to receive integrator fee or surplus share. Must not be `address(0)` | | `surplus_percentage` | `uint16` | Percentage of surplus to share with integrator (in basis points). Max 5000 (50%). Cannot be used with `fee_percentage` | | `fee_percentage` | `uint16` | Percentage of output to take as fee (in basis points). Max 500 (5%). Cannot be used with `surplus_percentage` | **Important**: You cannot use both `fee_percentage` and `surplus_percentage` simultaneously. Choose one monetization model. ### Returns * `uint256`: Amount of output tokens received by the user (after integrator fee/surplus) ### Behavior #### Fee-Based Model (`fee_percentage > 0`) 1. Executes swaps normally 2. Calculates total amount received 3. Calculates integrator fee: `fee_amount = (total_received * fee_percentage) / 10000` 4. User receives: `total_received - fee_amount` 5. Integrator receives: `fee_amount` **Example**: * Total received: 1000 tokens * Fee percentage: 100 bips (1%) * Integrator fee: 10 tokens * User receives: 990 tokens #### Surplus-Based Model (`surplus_percentage > 0`) 1. Executes swaps normally 2. Calculates total amount received 3. Calculates surplus: `surplus = max(0, total_received - route.amount_out)` 4. If surplus > 0: * Integrator share: `(surplus * surplus_percentage) / 10000` * User receives: `route.amount_out` (capped at expected) * Integrator receives: integrator share of surplus 5. If surplus == 0: * User receives: `total_received` * Integrator receives: 0 **Example**: * Expected output: 1000 tokens * Actual received: 1050 tokens * Surplus: 50 tokens * Surplus percentage: 2000 bips (20%) * Integrator share: 10 tokens * User receives: 1000 tokens (capped) * Integrator receives: 10 tokens ### min\_received Calculation **Critical**: When using integrator fees, `min_received` is checked AFTER deducting the fee. This ensures users receive at least `min_received` after all fees. **Formula**: ``` For fee-based: user_amount = total_received - fee_amount Check: user_amount >= min_received For surplus-based: user_amount = min(total_received, route.amount_out) Check: user_amount >= min_received ``` ### Example ```solidity theme={null} // Swap with 1% integrator fee RouteParam memory route = RouteParam({ token_in: TOKEN_A, token_out: TOKEN_B, amount_in: 1000e18, amount_out: 2000e18, min_received: 1980e18, // After 1% fee, user gets at least 1980 destination: msg.sender, swap_type: SwapType.tokenToToken }); SwapParams[] memory swaps = new SwapParams[](1); swaps[0] = SwapParams({ token_in: TOKEN_A, token_out: TOKEN_B, rate: 1000000, protocol_id: PROTOCOL_ID, pool_address: POOL_ADDRESS, swap_type: SwapType.tokenToToken, extra_data: abi.encode(...) }); // Encode integrator parameters IntegratorParams memory integratorParams = IntegratorParams({ integrator_address: INTEGRATOR_ADDRESS, surplus_percentage: 0, // Not using surplus fee_percentage: 100 // 1% fee (100 bips) }); bytes memory integratorData = abi.encode(integratorParams); // Execute swap uint256 userAmount = router.swapIntegrator(route, swaps, integratorData); ``` See [EVM Router Events](/integrate-best-trading/fibrous-smart-contracts/evm-router-events) for complete event documentation, including `IntegratorFeeDistribution` event details. ### Errors All errors from `swap` function, plus: | Error | Condition | | ----------------------------------- | ------------------------------------------------------ | | `InvalidAddress()` | `integrator_address == address(0)` | | `CannotTakeBothFeeAndSurplus()` | Both `fee_percentage > 0` and `surplus_percentage > 0` | | `SurplusPercentageExceedsMaximum()` | `surplus_percentage > 5000` | | `FeePercentageExceedsMaximum()` | `fee_percentage > 500` | *** ## Function: `swapWithPermit` Performs a swap using ERC-20 permit signature for gasless token approval. This allows users to approve tokens without a separate transaction. ### Signature ```solidity theme={null} function swapWithPermit( RouteParam calldata route, SwapParams[] calldata swap_parameters, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external payable nonReentrant whenNotPaused returns (uint256) ``` ### Parameters #### `route` (RouteParam) Same as `swap` function. See [swap route parameters](#route-routeparam). **Note**: `route.token_in` must be an ERC-20 token that supports `permit` (ERC-2612). #### `swap_parameters` (SwapParams\[]) Same as `swap` function. See [swap parameters](#swap_parameters-swapparams). #### `deadline` (uint256) Unix timestamp after which the permit signature expires. Must be `>= block.timestamp`. #### `v`, `r`, `s` (uint8, bytes32, bytes32) ECDSA signature components for the permit. Generated by signing: ```solidity theme={null} keccak256(abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR, keccak256(abi.encode( keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"), owner, spender, // EVM Router contract address value, // route.amount_in nonce, // Current nonce from token contract deadline )) )) ``` ### Returns * `uint256`: Amount of output tokens received by the destination address ### Behavior 1. **Permit Validation**: Checks `deadline >= block.timestamp` 2. **Permit Execution**: Calls `IERC20Permit(route.token_in).permit(...)` with signature 3. **Swap Execution**: Executes swap using same logic as `swap` function ### Example ```javascript theme={null} // Frontend: Generate permit signature const domain = { name: 'Token Name', version: '1', chainId: CHAIN_ID, verifyingContract: TOKEN_ADDRESS }; const types = { Permit: [ { name: 'owner', type: 'address' }, { name: 'spender', type: 'address' }, { name: 'value', type: 'uint256' }, { name: 'nonce', type: 'uint256' }, { name: 'deadline', type: 'uint256' } ] }; const value = { owner: userAddress, spender: EVM_ROUTER_ADDRESS, value: amountIn, nonce: await tokenContract.nonces(userAddress), deadline: Math.floor(Date.now() / 1000) + 3600 // 1 hour }; const signature = await signer._signTypedData(domain, types, value); const { r, s, v } = ethers.utils.splitSignature(signature); // Execute swap with permit const tx = await router.swapWithPermit( route, swapParameters, value.deadline, v, r, s ); ``` ### Errors All errors from `swap` function, plus: | Error | Condition | | ------------------- | ---------------------------- | | `DeadlineExpired()` | `deadline < block.timestamp` | *** ## Advanced Features ### Native Token Support EVM Router supports native token swaps through automatic wrapped token conversion. **How it works**: * Protocols can support native token pairs (e.g., ETH/TOKEN) or wrapped pairs (e.g., WETH/TOKEN) * EVM Router automatically converts native ↔ wrapped tokens when needed * Conversion is controlled by `shouldConvertInput` flag in `extra_data` **Example Scenarios**: 1. **MONAD → USDC** (using WMONAD/USDC pool): * User sends MONAD * Router wraps to WMONAD * Swaps WMONAD → USDC 2. **WMONAD → USDC** (using MONAD/USDC pool): * User sends WMONAD * Router unwraps to MONAD * Swaps MONAD → USDC **extra\_data Format** (for protocols with native support): ```solidity theme={null} (address token0, address token1, uint24 fee, int24 tickSpacing, address hook, bool shouldConvertInput) = abi.decode(extra_data, ...); ``` ### Rate-Based Amount Distribution Each swap in `swap_parameters` has a `rate` field that determines what percentage of input to use. **Rate Calculation**: ```solidity theme={null} amount_in_for_swap = (previous_amount * rate) / 1000000 ``` **Example**: * First swap: `rate = 1000000` (100%) → Uses all input * Second swap: `rate = 500000` (50%) → Uses 50% of first swap's output * Third swap: `rate = 1000000` (100%) → Uses all of second swap's output **Use Cases**: * Splitting input across multiple pools for better execution * Partial swaps with different protocols * Complex routing strategies ### Surplus Handling EVM Router caps output at `route.amount_out` to prevent users from receiving unexpected excess. **Surplus Calculation**: ```solidity theme={null} actual_output = balance_after - balance_before surplus = max(0, actual_output - route.amount_out) user_receives = min(actual_output, route.amount_out) ``` **Why it matters**: * Protects against unexpected price improvements * Ensures predictable output amounts * Enables integrator surplus sharing *** ## Common Patterns ### Simple Token-to-Token Swap ```solidity theme={null} RouteParam memory route = RouteParam({ token_in: TOKEN_A, token_out: TOKEN_B, amount_in: amount, amount_out: expectedOut, min_received: minOut, destination: address(0), swap_type: SwapType.tokenToToken }); SwapParams[] memory swaps = new SwapParams[](1); swaps[0] = SwapParams({ token_in: TOKEN_A, token_out: TOKEN_B, rate: 1000000, protocol_id: PROTOCOL_ID, pool_address: POOL, swap_type: SwapType.tokenToToken, extra_data: abi.encode(...) }); router.swap(route, swaps); ``` ### Multi-Hop Swap ```solidity theme={null} // TOKEN_A -> TOKEN_B -> TOKEN_C SwapParams[] memory swaps = new SwapParams[](2); // First hop: 100% of input swaps[0] = SwapParams({ token_in: TOKEN_A, token_out: TOKEN_B, rate: 1000000, // 100% ... }); // Second hop: 100% of first hop output swaps[1] = SwapParams({ token_in: TOKEN_B, token_out: TOKEN_C, rate: 1000000, // 100% ... }); ``` ### Integrator Fee Swap ```solidity theme={null} IntegratorParams memory params = IntegratorParams({ integrator_address: INTEGRATOR, surplus_percentage: 0, fee_percentage: 100 // 1% }); router.swapIntegrator(route, swaps, abi.encode(params)); ``` *** ## Error Reference | Error | Description | | ----------------------------------- | ------------------------------------------------------ | | `TokenAddressesAreSame()` | Input and output tokens are the same | | `NoSwapsProvided()` | Empty swap parameters array | | `AmountInZero()` | Input amount is zero | | `MinReceivedZero()` | Minimum received is zero | | `MinReceivedAmountNotReached()` | Actual output less than minimum required | | `SwapHandlerNotSet()` | No handler configured for protocol ID | | `SwapFailed()` | Swap execution failed | | `RateZero()` | Rate is zero | | `RateExceedsMaximum()` | Rate exceeds 1000000 (100%) | | `AmountTooSmallForRate()` | Amount too small for rate calculation (precision loss) | | `InvalidAddress()` | Invalid address (zero address) | | `CannotTakeBothFeeAndSurplus()` | Both fee and surplus percentages provided | | `SurplusPercentageExceedsMaximum()` | Surplus percentage > 5000 bips (50%) | | `FeePercentageExceedsMaximum()` | Fee percentage > 500 bips (5%) | | `DeadlineExpired()` | Permit deadline has passed | | `CallFailed()` | External call failed | *** ## Contract Address EVM Router is deployed on multiple EVM-compatible networks. Check [Contract Addresses](/api-reference/chains-tokens-contracts/contract-addresses) for the latest deployment addresses. **Contract ABI**: [View on GitHub](https://github.com/Fibrous-Finance/router-contract-abi/blob/main/routerAbi.json) *** ## Related Documentation * [EVM Router Events](/integrate-best-trading/fibrous-smart-contracts/evm-router-events) - Complete event reference and monitoring guide * [Integration Guide](/api-reference/integration-guide) - Best practices for integrating with Fibrous API * [V2 Migration Guide](/api-reference/v2-migration) - Migrating from V1 to V2 API * [Error Codes](/api-reference/errors) - Complete error reference # EVM Router - Events Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-smart-contracts/evm-router-events Complete reference for all EVM Router contract events # EVM Router Events EVM Router emits events for all important contract operations, including swaps, integrator fee distributions, and handler management. These events are essential for tracking contract activity, monitoring integrations, and building analytics. *** ## Event: `Swap` Emitted whenever a swap is executed successfully, regardless of whether it uses `swap`, `swapIntegrator`, or `swapWithPermit`. ### Signature ```solidity theme={null} event Swap( address sender, uint256 amount_in, uint256 amount_out, address token_in, address token_out, address destination ); ``` ### Parameters | Parameter | Type | Description | | ------------- | --------- | --------------------------------------------------------------------------------------------------- | | `sender` | `address` | Address that executed the swap transaction (`msg.sender`) | | `amount_in` | `uint256` | Amount of input tokens swapped (in token's smallest unit) | | `amount_out` | `uint256` | Amount of output tokens received by the destination (after surplus capping, before integrator fees) | | `token_in` | `address` | Contract address of the input token | | `token_out` | `address` | Contract address of the output token | | `destination` | `address` | Address that received the output tokens (or `msg.sender` if `route.destination == address(0)`) | ### When Emitted * After successful execution of `swap()` * After successful execution of `swapIntegrator()` (amount\_out is user amount after integrator fee) * After successful execution of `swapWithPermit()` ### Usage Example ```javascript theme={null} // Listen for Swap events router.on("Swap", (sender, amountIn, amountOut, tokenIn, tokenOut, destination, event) => { console.log(`Swap executed:`); console.log(` From: ${sender}`); console.log(` Input: ${amountIn} of ${tokenIn}`); console.log(` Output: ${amountOut} of ${tokenOut}`); console.log(` Recipient: ${destination}`); console.log(` Transaction: ${event.transactionHash}`); }); // Query past events const filter = router.filters.Swap(null, null, null, TOKEN_A, TOKEN_B, null); const events = await router.queryFilter(filter, fromBlock, toBlock); ``` ### Important Notes * **Surplus Handling**: `amount_out` reflects the actual amount sent to destination, which may be capped at `route.amount_out` if surplus exists * **Integrator Fees**: When using `swapIntegrator` with fee-based model, `amount_out` is the user amount AFTER integrator fee deduction * **Indexed Fields**: None of the fields are indexed, so filtering requires querying all Swap events and filtering in application code *** ## Event: `IntegratorFeeDistribution` Emitted when integrator fees or surplus are distributed during a `swapIntegrator` call. ### Signature ```solidity theme={null} event IntegratorFeeDistribution( address indexed integrator, uint256 integrator_amount, uint256 user_amount ); ``` ### Parameters | Parameter | Type | Description | | ------------------- | ----------------- | ------------------------------------------------------------------------------------------ | | `integrator` | `address indexed` | Address of the integrator receiving the fee/surplus share | | `integrator_amount` | `uint256` | Amount of tokens sent to the integrator | | `user_amount` | `uint256` | Amount of tokens sent to the user (matches `amount_out` in the corresponding `Swap` event) | ### When Emitted * Only emitted when `swapIntegrator()` is called * Emitted when `integrator_amount > 0` (either fee or surplus share) * Not emitted if integrator parameters are provided but no fee/surplus is distributed ### Usage Example ```javascript theme={null} // Listen for integrator fee distributions router.on("IntegratorFeeDistribution", (integrator, integratorAmount, userAmount, event) => { console.log(`Integrator fee distributed:`); console.log(` Integrator: ${integrator}`); console.log(` Integrator received: ${integratorAmount}`); console.log(` User received: ${userAmount}`); console.log(` Total: ${integratorAmount + userAmount}`); }); // Query events for specific integrator const filter = router.filters.IntegratorFeeDistribution(INTEGRATOR_ADDRESS); const events = await router.queryFilter(filter, fromBlock, toBlock); ``` ### Important Notes * **Indexed Field**: `integrator` is indexed, allowing efficient filtering by integrator address * **Fee vs Surplus**: The event doesn't distinguish between fee-based and surplus-based distributions * **Zero Amounts**: Event is not emitted if `integrator_amount == 0` * **Correlation**: Always check for a corresponding `Swap` event in the same transaction *** ## Event: `AddHandler` Emitted when a new swap handler is set for a protocol ID. ### Signature ```solidity theme={null} event AddHandler(int24 protocol_id, address handler); ``` ### Parameters | Parameter | Type | Description | | ------------- | --------- | ------------------------------------------------ | | `protocol_id` | `int24` | Protocol identifier for which the handler is set | | `handler` | `address` | Address of the swap handler contract | ### When Emitted * When `setSwapHandler()` is called successfully * Only emitted by the contract owner * Emitted once per protocol ID (handler can only be set once) ### Usage Example ```javascript theme={null} // Listen for handler additions router.on("AddHandler", (protocolId, handler, event) => { console.log(`New handler added:`); console.log(` Protocol ID: ${protocolId}`); console.log(` Handler address: ${handler}`); console.log(` Set by: ${event.args[0]}`); }); // Query all handler additions const filter = router.filters.AddHandler(); const events = await router.queryFilter(filter, fromBlock, toBlock); ``` ### Important Notes * **One-Time Event**: Handler can only be set once per protocol ID * **Owner Only**: Only contract owner can trigger this event * **Handler Removal**: Use `SwapHandlerRemoved` event to track handler removals *** ## Event: `SwapHandlerRemoved` Emitted when a swap handler is removed for a protocol ID. ### Signature ```solidity theme={null} event SwapHandlerRemoved(int24 protocol_id); ``` ### Parameters | Parameter | Type | Description | | ------------- | ------- | ----------------------------------------------------- | | `protocol_id` | `int24` | Protocol identifier for which the handler was removed | ### When Emitted * When `removeSwapHandler()` is called successfully * Only emitted by the contract owner * Handler address is set to `address(0)` after removal ### Usage Example ```javascript theme={null} // Listen for handler removals router.on("SwapHandlerRemoved", (protocolId, event) => { console.log(`Handler removed:`); console.log(` Protocol ID: ${protocolId}`); console.log(` Removed by: ${event.args[0]}`); }); // Query handler removals const filter = router.filters.SwapHandlerRemoved(); const events = await router.queryFilter(filter, fromBlock, toBlock); ``` ### Important Notes * **Owner Only**: Only contract owner can trigger this event * **Handler State**: After removal, `getSwapHandler(protocol_id)` returns `address(0)` * **Swap Failures**: Swaps using removed handlers will revert with `SwapHandlerNotSet()` *** ## Event: `SetNativeTokenSupport` Emitted when native token support is enabled or disabled for a protocol. ### Signature ```solidity theme={null} event SetNativeTokenSupport(int24 protocol_id, bool support); ``` ### Parameters | Parameter | Type | Description | | ------------- | ------- | ---------------------------------------------------------------- | | `protocol_id` | `int24` | Protocol identifier for which native token support is configured | | `support` | `bool` | `true` if native token support is enabled, `false` if disabled | ### When Emitted * When `setNativeTokenSupport()` is called successfully * Only emitted by the contract owner * Controls whether the protocol can handle native token swaps (e.g., MONAD ↔ WMONAD conversion) ### Usage Example ```javascript theme={null} // Listen for native token support changes router.on("SetNativeTokenSupport", (protocolId, support, event) => { console.log(`Native token support updated:`); console.log(` Protocol ID: ${protocolId}`); console.log(` Support enabled: ${support}`); }); // Query native token support changes const filter = router.filters.SetNativeTokenSupport(); const events = await router.queryFilter(filter, fromBlock, toBlock); ``` ### Important Notes * **Owner Only**: Only contract owner can trigger this event * **Protocol-Specific**: Each protocol can have independent native token support settings * **Conversion Logic**: When enabled, router automatically converts native ↔ wrapped tokens as needed *** ## Event Monitoring Best Practices ### 1. Indexed Fields Only `IntegratorFeeDistribution.integrator` is indexed. For efficient filtering: ```javascript theme={null} // ✅ Efficient - uses indexed field const filter = router.filters.IntegratorFeeDistribution(INTEGRATOR_ADDRESS); // ❌ Inefficient - requires filtering all events const filter = router.filters.Swap(); const events = await router.queryFilter(filter); const filtered = events.filter(e => e.args.token_in === TOKEN_A); ``` ### 2. Event Correlation Correlate related events in the same transaction: ```javascript theme={null} // Get all events from a transaction const receipt = await provider.getTransactionReceipt(txHash); const swapEvents = receipt.logs.filter(log => { try { return router.interface.parseLog(log).name === 'Swap'; } catch { return false; } }); const integratorEvents = receipt.logs.filter(log => { try { return router.interface.parseLog(log).name === 'IntegratorFeeDistribution'; } catch { return false; } }); ``` ### 3. Error Handling Always handle event parsing errors: ```javascript theme={null} try { const parsed = router.interface.parseLog(log); // Process event } catch (error) { // Not a Router event or invalid log console.error('Failed to parse log:', error); } ``` ### 4. Block Range Queries Use appropriate block ranges for event queries: ```javascript theme={null} // Query recent events (last 1000 blocks) const latestBlock = await provider.getBlockNumber(); const events = await router.queryFilter(filter, latestBlock - 1000, latestBlock); // Query specific time range const fromBlock = await getBlockNumberForTimestamp(startTimestamp); const toBlock = await getBlockNumberForTimestamp(endTimestamp); const events = await router.queryFilter(filter, fromBlock, toBlock); ``` ### 5. Event Storage Store event data efficiently: ```javascript theme={null} // Store minimal event data const swapData = { txHash: event.transactionHash, blockNumber: event.blockNumber, sender: event.args.sender, amountIn: event.args.amount_in.toString(), amountOut: event.args.amount_out.toString(), tokenIn: event.args.token_in, tokenOut: event.args.token_out, timestamp: (await provider.getBlock(event.blockNumber)).timestamp }; ``` *** ## Event Indexing and Filtering ### Efficient Filtering Strategies #### Filter by Token Pair ```javascript theme={null} // Get all swaps for a specific token pair const filter = router.filters.Swap(); const events = await router.queryFilter(filter, fromBlock, toBlock); const tokenPairSwaps = events.filter(event => { const { token_in, token_out } = event.args; return (token_in.toLowerCase() === TOKEN_A.toLowerCase() && token_out.toLowerCase() === TOKEN_B.toLowerCase()) || (token_in.toLowerCase() === TOKEN_B.toLowerCase() && token_out.toLowerCase() === TOKEN_A.toLowerCase()); }); ``` #### Filter by Integrator ```javascript theme={null} // Get all integrator distributions for a specific integrator const filter = router.filters.IntegratorFeeDistribution(INTEGRATOR_ADDRESS); const events = await router.queryFilter(filter, fromBlock, toBlock); ``` #### Filter by Sender ```javascript theme={null} // Get all swaps from a specific address const filter = router.filters.Swap(); const events = await router.queryFilter(filter, fromBlock, toBlock); const userSwaps = events.filter(event => event.args.sender.toLowerCase() === USER_ADDRESS.toLowerCase() ); ``` *** ## Event Analytics Examples ### Calculate Total Volume ```javascript theme={null} async function getTotalVolume(tokenAddress, fromBlock, toBlock) { const filter = router.filters.Swap(); const events = await router.queryFilter(filter, fromBlock, toBlock); let totalVolume = BigInt(0); events.forEach(event => { const { token_in, token_out, amount_in, amount_out } = event.args; if (token_in.toLowerCase() === tokenAddress.toLowerCase()) { totalVolume += BigInt(amount_in); } else if (token_out.toLowerCase() === tokenAddress.toLowerCase()) { totalVolume += BigInt(amount_out); } }); return totalVolume; } ``` ### Track Integrator Earnings ```javascript theme={null} async function getIntegratorEarnings(integratorAddress, fromBlock, toBlock) { const filter = router.filters.IntegratorFeeDistribution(integratorAddress); const events = await router.queryFilter(filter, fromBlock, toBlock); let totalEarnings = BigInt(0); events.forEach(event => { totalEarnings += BigInt(event.args.integrator_amount); }); return totalEarnings; } ``` ### Monitor Handler Changes ```javascript theme={null} async function getHandlerHistory(protocolId, fromBlock, toBlock) { const addFilter = router.filters.AddHandler(protocolId); const removeFilter = router.filters.SwapHandlerRemoved(protocolId); const additions = await router.queryFilter(addFilter, fromBlock, toBlock); const removals = await router.queryFilter(removeFilter, fromBlock, toBlock); return { additions: additions.map(e => ({ handler: e.args.handler, blockNumber: e.blockNumber, txHash: e.transactionHash })), removals: removals.map(e => ({ blockNumber: e.blockNumber, txHash: e.transactionHash })) }; } ``` *** ## Related Documentation * [EVM Router Swap Functions](/integrate-best-trading/fibrous-smart-contracts/evm-router) - Complete guide to swap functions * [Integration Guide](/api-reference/integration-guide) - Best practices for integrating with Fibrous API * [Contract Addresses](/api-reference/chains-tokens-contracts/contract-addresses) - EVM Router deployment addresses # Starknet Source: https://docs.fibrous.finance/integrate-best-trading/fibrous-smart-contracts/starknet Starknet Smart Contracts ### Functions ## constructor ```rust theme={null} #[constructor] fn constructor(ref self: ContractState, _owner: ContractAddress) ``` ## Paramaters | name | type | Description | | ------- | --------------- | -------------------------------- | | \_owner | ContractAddress | The owner of the router contract | ## swap ```typescript theme={null} #[external(v0)] fn swap(ref self: ContractState, route: RouteParam, swap_parameters: Array) ``` ## Paramaters # RouteParam > @notice RouteParam is a struct that contains the parameters needed to execute a swap | name | type | description | | ----------------- | --------------- | ----------------------------------------- | | **token\_in** | ContractAddress | contract address of token to sell | | **token\_out** | ContractAddress | contract address of token to buy | | **amount\_in** | u256 | amount of token to sell | | **min\_received** | u256 | minimum received amount of user get | | **destination** | ContractAddress | The receiver address for the output token | # SwapParams > @notice SwapParams is a struct that contains the parameters needed to execute a swap | name | type | description | | ---------------- | --------------- | ---------------------------------------- | | **token\_in** | ContractAddress | contract address of token to sell | | **token\_out** | ContractAddress | contract address of token to buy | | **rate** | u32 | rate \* 10\*\*4 gives 4 precision points | | **protocol\_id** | u32 | procotol id | | **extra\_data** | Array(felt252) | extra data fro route | ## Events # Swap ```rust theme={null} #[derive(Drop, starknet::Event)] struct Swap { sender: ContractAddress, token_in: ContractAddress, token_out: ContractAddress, amount_in: u256, amount_out: u256, to: ContractAddress } ``` | name | type | description | | --------------- | --------------- | ----------------------------------------- | | **sender** | ContractAddress | address that execute the swap | | **token\_in** | ContractAddress | contract address of token to sold | | **token\_out** | ContractAddress | contract address of token to bought | | **amount\_in** | u256 | amount of token to sold | | **amount\_out** | u256 | amount of token to bought | | **to** | ContractAddress | The receiver address for the output token |