# 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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 * Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/) for higher rate limits * Contact [contact@fibrous.finance](mailto:contact@fibrous.finance) for enterprise rate limits API keys provide higher rate limits. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). *** ### 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 obtain an API key from the [Fibrous Partnership Portal](https://portal.fibrous.finance/) 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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:** * Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/) 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.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 from the [Fibrous Partnership Portal](https://portal.fibrous.finance/) * `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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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. For higher rate limits, generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). ## 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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. Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/). 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**: Generate and manage your API keys at the [Fibrous Partnership Portal](https://portal.fibrous.finance/) * 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. ## 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). # Agent Skills Source: https://docs.fibrous.finance/fibx-agent/agent-skills Pre-built skills that enable AI agents to execute DeFi operations through the fibx CLI using natural language prompts. [fibx-skills](https://github.com/Fibrous-Finance/fibx-skills) is a collection of eleven agent skills that wrap the `fibx` CLI for use by AI agents. Each skill defines a specific capability — authentication, the signing policy, balances, portfolio inspection, transfers, swaps, DeFi management, and transaction verification — with structured rules, allowed tools, and error handling. Skills follow the [Agent Skills](https://agentskills.io) specification and can be imported into any compatible agent framework. ## How Skills Work Each skill is a structured YAML+Markdown file that defines: * **Allowed tools** — The CLI command patterns declared by the installed skill * **Rules** — Constraints and safety checks the agent must follow * **Parameters** — Inputs the agent extracts from the user's natural language prompt * **Error handling** — How the agent should respond to specific failures When a user gives a natural language instruction (e.g., "Swap 0.1 ETH to USDC"), the agent matches it to the appropriate skill, extracts parameters, follows the defined rules, and executes the CLI commands in sequence. ```mermaid theme={null} flowchart LR A[User Prompt] --> B[AI Agent] B --> C[Skill Matching] C --> D[Parameter Extraction] D --> E[Rule Validation] E --> F["fibx CLI Execution"] F --> G[On-Chain Result] ``` ## Getting Started Install the skills directly using the Vercel Skills CLI: ```bash theme={null} npx skills add Fibrous-Finance/fibx-skills ``` Or clone the repository manually and import from the `./skills` directory: ```bash theme={null} git clone https://github.com/Fibrous-Finance/fibx-skills.git ``` No separate installation of `fibx` is needed — all skills use `npx fibx@latest`. Skills require Node.js 18+ and are compatible with fibx CLI v0.10.x. The installed `SKILL.md` files are the source of truth for allowed-tool patterns and rules; the summaries below describe the current published skills and may change independently of this page. *** ## Available Skills **Category:** Read-Only Fetches a swap price without a wallet or a session, so an agent can answer a pricing question for a user who has not logged in — and then offer `authenticate-wallet` if they want to execute. ### Allowed Tools ``` Bash(npx fibx@latest quote *) ``` ### Rules 1. Never require or suggest authentication before quoting — this skill needs none. 2. If the user specifies a chain, include `--chain `; otherwise default to `base` and say so. 3. Default slippage is 0.5%. Include `--slippage` only when the user explicitly requests another value. 4. Direct native/wrapped-native pairs return a 1:1 wrap or unwrap quote. 5. After quoting, offer `trade` as the execution step, noting that it does require a session. ### Trigger Examples | User Prompt | Action | | ------------------------------- | -------------------------------- | | "How much USDC for 0.1 ETH?" | `quote 0.1 ETH USDC` | | "What's the MON price in USDC?" | `quote 1 MON USDC --chain monad` | **Category:** Auth Manages the wallet session. This skill must run before any other wallet operation. Three signing paths are available, and they are peers — `auth setup` presents the choice: * **Your own wallet** (`auth connect`) — pair a wallet you already have over WalletConnect. Every transaction is approved on the phone; nothing is signed on the machine. * **Privy server wallet** (`auth login` + `auth verify`) — a server-managed wallet via email OTP; runs unattended, bounded by Privy's policy and the local one. * **Imported private key** (`auth import`) — encrypted locally; runs unattended, bounded by the local signing policy **alone**. ### Allowed Tools ``` Bash(npx fibx@latest auth setup) Bash(npx fibx@latest auth connect *) Bash(npx fibx@latest auth login *) Bash(npx fibx@latest auth verify *) Bash(npx fibx@latest auth import) Bash(npx fibx@latest auth logout) Bash(npx fibx@latest status) ``` ### Rules 1. If the user has not said how they want to sign, run `auth setup` or ask. Do not default to Privy. 2. Never ask the user for a private key. `auth import` prompts for it in the terminal. 3. Before `auth import`, warn: *"Your private key will be encrypted with AES-256-GCM and stored on this machine. With an imported key, the local signing policy is the only thing bounding what this wallet signs — I can set one with the `policy` skill. Proceed?"* 4. `auth login` must complete before `auth verify` — they are sequential steps. 5. `auth connect` prints a QR and waits; tell the user to scan it with their wallet and approve. Every later `trade` or `send` blocks until they approve it on the phone. 6. After any of these, run `status` to confirm the session. Any of them replaces the active session; say so before switching. 7. Never store or log private keys, OTP codes, pairing URIs, or session data. ### Trigger Examples | User Prompt | Action | | ------------------------------------------------------------ | ------------------------------- | | "Which wallet setup should I use?" | `auth setup` | | "Connect my own wallet" / "Use my MetaMask" | `auth connect` | | "Import my private key" | `auth import` | | "Log me in with [user@example.com](mailto:user@example.com)" | `auth login` then `auth verify` | | "Log me out" | `auth logout` | **Category:** Auth Reads and changes the local signing policy — a file on the user's machine that caps the native value per chain, allowlists chains and destinations, and expires. FibX evaluates it before every signature on all three signing paths. Use it when a transaction is refused with `POLICY_BLOCKED`, or when the user wants to bound what the wallet can sign. No session is needed. ### Allowed Tools ``` Bash(npx fibx@latest policy *) ``` ### Rules 1. Propose a concrete value and explain what it bounds; set it only after the user agrees. 2. `maxValue` bounds native value only — an ERC-20 transfer reaches the policy with `value: 0`. Only `allowedDestinations` bounds where tokens go. Never tell the user the cap limits token amounts. 3. On the imported-key path this file is the only bound. If `policy show` shows nothing on a private-key session, recommend at least a `maxValue` before any `trade` or `send`. 4. A refusal names its rule. Relay the rule and limit and ask; do not retry, and do not loosen the rule unasked. 5. `policy clear` with no rule removes the whole policy and asks for confirmation. Never pass `-y` unless the user explicitly asked to remove everything. ### Trigger Examples | User Prompt | Action | | --------------------------------------------------- | ------------------------------------- | | "Cap what this wallet can sign to 0.05 ETH on Base" | `policy set base.maxValue 0.05` | | "Only let it use Base and Monad" | `policy set allowedChains base,monad` | | "What limits are on my wallet?" | `policy show` | | "Remove the cap" | `policy clear base.maxValue` | **Category:** Wallet Reports which wallet is active — address, wallet ID, session type, and when the session was created. Use it when the user asks for their receiving address or which account they are signed in as. ### Allowed Tools ``` Bash(npx fibx@latest address) Bash(npx fibx@latest address *) Bash(npx fibx@latest wallets) Bash(npx fibx@latest wallets *) ``` **Prerequisite:** An active session is required. If no session is active, run the `authenticate-wallet` skill first. ### Rules 1. Use `address` when only the receiving address is needed; use `wallets` for full session details. 2. Neither command takes `--chain` — the same address is used on every supported chain. 3. Always show the full address. Never truncate an address the user may need to copy. 4. Use `--json` when another skill or automation will consume the output. ### Trigger Examples | User Prompt | Action | | --------------------------- | --------- | | "What's my wallet address?" | `address` | | "Which wallet am I using?" | `wallets` | **Category:** Wallet Fetches native and ERC-20 token balances for the authenticated wallet on any supported chain. ### Allowed Tools ``` Bash(npx fibx@latest balance *) Bash(npx fibx@latest balance) Bash(npx fibx@latest status) ``` ### Rules 1. If the user specifies a chain, include `--chain `. 2. If no chain is specified, default to `base` and state it. 3. Use `--json` when output is consumed by another skill. ### Trigger Examples | User Prompt | Action | | -------------------------- | ---------------------------- | | "Check my balance" | `balance` (defaults to Base) | | "What's my Monad balance?" | `balance --chain monad` | **Category:** Wallet Fetches a consolidated cross-chain portfolio view with USD valuations for all token holdings and DeFi positions across Base, HyperEVM, and Monad. ### Allowed Tools ``` Bash(npx fibx@latest portfolio *) Bash(npx fibx@latest portfolio) Bash(npx fibx@latest status) ``` ### Rules 1. This command fetches all supported chains in parallel, so no `--chain` flag is needed. 2. Use `--json` when the output will be consumed by another skill or automation pipeline. 3. Chains with zero holdings may be hidden in the output. 4. DeFi positions on Aave V3 are included automatically when present. ### Trigger Examples | User Prompt | Action | | ---------------------------- | ------------------ | | "Show me my portfolio" | `portfolio` | | "What's my total net worth?" | `portfolio` | | "Get my portfolio as JSON" | `portfolio --json` | **Category:** Transaction Transfers native tokens or ERC-20 tokens to a destination address. The CLI performs a command-specific preflight and supports `--simulate` for a transfer preview. ### Allowed Tools ``` Bash(npx fibx@latest send *) Bash(npx fibx@latest status) Bash(npx fibx@latest balance *) Bash(npx fibx@latest balance) Bash(npx fibx@latest tx-status *) ``` ### Rules 1. Before any send, verify connectivity (`status`) and funds (`balance`). 2. If the recipient address was not previously mentioned, ask for explicit confirmation. 3. If the user specifies a chain, include `--chain `; otherwise default to `base` and say so. 4. Use the correct native token symbol for each chain — never use `ETH` on non-Base chains. 5. After a successful send, verify the transaction with `tx-status` on the same chain. ### Trigger Examples | User Prompt | Action | | ------------------------------------ | -------------------------------------- | | "Send 10 USDC to 0x123..." | `send 10 0x123... USDC` | | "Send 0.05 MON to 0xdef... on Monad" | `send 0.05 0xdef... MON --chain monad` | **Category:** Transaction Swaps tokens via Fibrous aggregation. Finds a route, handles approvals, estimates the main swap path, and executes. ### Allowed Tools ``` Bash(npx fibx@latest trade *) Bash(npx fibx@latest quote *) Bash(npx fibx@latest status) Bash(npx fibx@latest balance *) Bash(npx fibx@latest balance) Bash(npx fibx@latest tx-status *) ``` ### Rules 1. Before any trade, verify connectivity and source token balance. 2. If the user specifies a chain, include `--chain `; otherwise default to `base` and say so. 3. Default slippage is 0.5%. To change it, ask the user for confirmation. 4. Never use `--approve-max` unless the user explicitly requests it. 5. After a successful trade, verify the transaction with `tx-status` on the same chain. `trade --simulate` does not broadcast an approval or swap. When an ERC-20 approval is required, it returns `requiresApproval: true` without a gas estimate. A live routed ERC-20 trade can leave an approval on-chain if the later swap estimate or submission fails. Treat the approval and swap as separate transactions. ### Trigger Examples | User Prompt | Action | | ------------------------------ | -------------------------------- | | "Swap 0.1 ETH for USDC" | `trade 0.1 ETH USDC` | | "Buy USDC with 1 MON on Monad" | `trade 1 MON USDC --chain monad` | **Category:** DeFi Manages Aave V3 lending positions on **Base only** — status, markets, supply, borrow, repay, withdraw, and health factor monitoring. ETH supply and repay can auto-wrap to WETH, while ETH withdraw can auto-unwrap to ETH. Borrowing the ETH market returns WETH. `aave markets` is a public query. `aave status` and all transactional actions require an active session. An action with `--simulate` returns request metadata without on-chain validation or a gas estimate. ### Allowed Tools ``` Bash(npx fibx@latest aave *) Bash(npx fibx@latest status) Bash(npx fibx@latest balance *) Bash(npx fibx@latest balance) ``` ### Rules 1. This skill only works on Base. Refuse Aave operations on other chains. 2. Before any action, check balance for sufficient ETH for gas. 3. Before borrowing, check `aave status` for the Health Factor: * Health Factor \< 1.5 → Warn the user about liquidation risk * Health Factor \< 1.1 → Do not proceed without explicit double-confirmation 4. `max` is supported only for `repay` and `withdraw`. Use it when fully repaying debt or withdrawing a supplied position to avoid dust residuals. 5. Use `ETH` for ETH-market supply, repay, and withdraw so the CLI can apply the documented wrap/unwrap behavior. Borrowing that market returns WETH. 6. If a `Rate limit / 429` error occurs, use the `config` skill to set a custom RPC. ### ETH ↔ WETH Auto-Wrap Reference | Action | ETH Behavior | | ------------------ | -------------------------------------- | | `supply 1 ETH` | Auto-wraps ETH → WETH before supplying | | `borrow 1 ETH` | Borrows WETH; no automatic unwrap | | `repay max ETH` | Auto-wraps ETH → WETH before repaying | | `withdraw max ETH` | Withdraws WETH and auto-unwraps → ETH | Live wrap, approval, Aave, and unwrap steps are separate transactions, so an earlier step remains on-chain if a later one fails. `aave withdraw max ETH` unwraps the wallet's entire post-withdraw WETH balance, including WETH held before the command. ### Trigger Examples | User Prompt | Action | | --------------------------- | ----------------------- | | "How is my Aave position?" | `aave status` | | "What markets are on Aave?" | `aave markets` | | "Supply 1 ETH to Aave" | `aave supply 1 ETH` | | "Supply 100 USDC to Aave" | `aave supply 100 USDC` | | "Repay my ETH debt" | `aave repay max ETH` | | "Repay all my USDC debt" | `aave repay max USDC` | | "Withdraw all my ETH" | `aave withdraw max ETH` | **Category:** Utility View and modify fibx CLI configuration — primarily used to set custom RPC URLs when hitting rate limits on public endpoints. Configuration is stored locally and persists across sessions. ### Allowed Tools ``` Bash(npx fibx@latest config *) ``` ### Rules 1. If any command fails with a "Rate limit exceeded" or "429" error, use this skill to set a custom RPC for the affected chain. 2. Settings use the OS-specific FibX config directory and persist across sessions (for example, `~/.config/fibx-nodejs/config.json` on Linux and `~/Library/Preferences/fibx-nodejs/config.json` on macOS). 3. The CLI validates URL format but not connectivity — ensure the RPC URL is valid before setting. ### Commands ```bash theme={null} # Set a custom RPC for a chain npx fibx@latest config set-rpc # View the current RPC for a chain npx fibx@latest config get-rpc # Reset one chain or all chains to default npx fibx@latest config reset-rpc npx fibx@latest config reset-rpc # List all custom configurations npx fibx@latest config list ``` ### Trigger Examples | User Prompt | Action | | ---------------------------------- | ---------------------------------------------- | | "I'm getting rate limit errors" | `config set-rpc ` | | "I'm getting rate limited on Base" | `config set-rpc base https://mainnet.base.org` | | "Reset all RPCs to default" | `config reset-rpc` | | "Check my current configuration" | `config list` | **Category:** Utility Checks the on-chain status of a transaction and returns the block explorer link. No authentication is required — this is a public chain query. ### Allowed Tools ``` Bash(npx fibx@latest tx-status *) ``` ### Rules 1. Use the same `--chain` flag that was used for the original transaction. 2. Use this skill after every `send` or `trade` to verify success. ### Trigger Examples | User Prompt | Action | | -------------------------------- | ------------------------------------- | | "Did my transaction go through?" | `tx-status ` | | "Check tx 0xabc...def on Monad" | `tx-status 0xabc...def --chain monad` | *** ## Agent Workflow Example A typical multi-step interaction between a user and an AI agent using fibx-skills: Agent triggers **authenticate-wallet**: ```bash theme={null} npx fibx@latest auth connect npx fibx@latest status ``` The user scans the QR with their wallet app and approves the pairing. Session is now active; every transaction from here is approved on the phone. Agent triggers **balance** then **trade**: ```bash theme={null} npx fibx@latest balance npx fibx@latest trade 0.05 ETH USDC ``` Agent says: *"Approve the swap in your wallet."* The command waits until the user does. Agent triggers **tx-status**: ```bash theme={null} npx fibx@latest tx-status 0x7a3f...c21b ``` Agent responds: *"Swap completed. 0.05 ETH → 47.23 USDC. [View on BaseScan](https://basescan.org/tx/0x7a3f...c21b)"* Agent triggers **authenticate-wallet**: ```bash theme={null} npx fibx@latest auth import npx fibx@latest status ``` The user pastes their private key in the interactive prompt. Session is now active. Agent triggers **policy** after the user agrees: ```bash theme={null} npx fibx@latest policy set base.maxValue 0.05 ``` Agent triggers **balance** then **trade**: ```bash theme={null} npx fibx@latest balance npx fibx@latest trade 0.05 ETH USDC ``` Agent triggers **tx-status**: ```bash theme={null} npx fibx@latest tx-status 0x7a3f...c21b ``` Agent responds: *"Swap completed. 0.05 ETH → 47.23 USDC. [View on BaseScan](https://basescan.org/tx/0x7a3f...c21b)"* Agent triggers **authenticate-wallet**: ```bash theme={null} npx fibx@latest auth login alice@example.com ``` Agent asks: *"Please provide the OTP code sent to your email."* Agent completes authentication: ```bash theme={null} npx fibx@latest auth verify alice@example.com 482910 npx fibx@latest status ``` Agent triggers **balance** then **trade**: ```bash theme={null} npx fibx@latest balance npx fibx@latest trade 0.05 ETH USDC ``` Agent triggers **tx-status**: ```bash theme={null} npx fibx@latest tx-status 0x7a3f...c21b ``` Agent responds: *"Swap completed. 0.05 ETH → 47.23 USDC. [View on BaseScan](https://basescan.org/tx/0x7a3f...c21b)"* # CLI Command Reference Source: https://docs.fibrous.finance/fibx-agent/cli-commands Complete reference for all fibx CLI commands — authentication, signing policy, portfolio, balance, send, trade, Aave V3, configuration, and transaction status. Commands use this general pattern: ```bash theme={null} npx fibx@latest [arguments] [options] ``` Commands that accept `--chain` default to `base` unless documented otherwise. *** ## quote — Price Quotes (No Auth) Get a swap price without a wallet, a session, or any setup. It is the fastest pricing entry point for trying FibX or answering a question before a user has logged in. Other public or local commands, including `status`, `tx-status`, `config`, `policy`, and `aave markets`, also work without an active session. ```bash theme={null} npx fibx@latest quote [--chain ] [--slippage ] [--json] ``` | Parameter | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------------- | | `amount` | number | Yes | Amount of the input token | | `from-token` | string | Yes | Input token symbol or supported contract address | | `to-token` | string | Yes | Output token symbol or supported contract address | | `chain` | string | No | `base`, `hyperevm`, or `monad` | | `slippage` | number | No | Slippage tolerance in percent (default: `0.5`) | ### Examples ```bash theme={null} # Check a price on Base npx fibx@latest quote 0.01 ETH USDC # Compare a pair on Monad npx fibx@latest quote 1 MON USDC --chain monad # Machine-readable output for scripts npx fibx@latest quote 0.1 ETH USDC --json ``` For routed swaps, the output shows the input and output amounts, exchange rate, slippage, router, and chain. A direct native/wrapped-native pair instead reports a 1:1 `wrap` or `unwrap` operation without slippage or router fields. To execute the same trade, use [`trade`](#trade-swap-tokens) with the same arguments once authenticated. *** ## auth — Authentication Manage the wallet session. Authentication is required before commands that inspect or act on a wallet. Three signing paths are available; each of these commands **replaces** the active session. The comparison is on [Signing Paths and the Local Policy](/fibx-agent/signing). ### auth setup Choose how FibX should sign, with the trade-offs explained. Interactive: it asks one question and runs the matching flow below. ```bash theme={null} npx fibx@latest auth setup ``` ### auth connect (Your Own Wallet) Pair a wallet you already have over WalletConnect. The CLI prints a QR code and a `wc:` URI and waits for the wallet app to approve. Every later transaction is approved in that wallet, on your phone; nothing is signed on this machine. ```bash theme={null} npx fibx@latest auth connect # For a host that renders its own QR: prints { "uri": "wc:…" } npx fibx@latest auth connect --json ``` ### auth import (Private Key) Import an existing private key to create a local wallet session that runs unattended. The CLI opens an interactive prompt where you paste the key. ```bash theme={null} npx fibx@latest auth import ``` The key is encrypted at rest with AES-256-GCM and signs locally. No external server holds your private key with this method — and the local signing policy is the only thing bounding it, so set one with [`policy`](#policy-signing-policy). ### auth login / auth verify (Email OTP) Authentication via email OTP. This creates a server-managed wallet through [Privy](https://privy.io) — useful when you do not have an existing private key and want FibX to act without you. ```bash theme={null} # Step 1: Send OTP to email npx fibx@latest auth login # Step 2: Verify with the code received npx fibx@latest auth verify ``` | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------- | | `email` | string | Yes | User's email address | | `code` | string | Yes | OTP code received via email | ### auth logout End the active session. Also ends a WalletConnect pairing. ```bash theme={null} npx fibx@latest auth logout ``` *** ## policy — Signing Policy Read and change the local signing policy: a JSON file the user owns, evaluated before every signature on all three signing paths. No session is needed. ```bash theme={null} npx fibx@latest policy show npx fibx@latest policy set npx fibx@latest policy clear [rule] [-y] ``` | Rule | Meaning | Example | | ----------------------------- | ---------------------------------------------------------- | ---------------------------------------- | | `.maxValue` | Largest native value (ETH / HYPE / MON) in one transaction | `base.maxValue 0.05` | | `allowedChains` | Chains anything may be signed on (comma-separated) | `allowedChains base,monad` | | `.allowedDestinations` | Addresses anything may be sent to on that chain | `base.allowedDestinations 0xAbC…,0xDeF…` | | `expiry` | When the whole policy stops applying (ISO-8601) | `expiry 2026-12-31T00:00:00Z` | `set` replaces the rule's previous value. `clear` with no rule removes the whole policy and asks for confirmation; `-y` skips the question. A transaction outside the policy is refused before any signature is requested, with `POLICY_BLOCKED` and the rule named. `maxValue` bounds the native value only. An ERC-20 transfer reaches the policy with `value: 0`, so the cap never sees the token amount; `allowedDestinations` is what bounds where tokens may go. No file means everything is permitted. A file that exists but cannot be parsed means **everything is refused** until it is fixed or cleared — a corrupt policy does not fail open. ### Examples ```bash theme={null} # Cap one transaction's native value on Base npx fibx@latest policy set base.maxValue 0.05 # Only allow Base and Monad npx fibx@latest policy set allowedChains base,monad # Only allow sends to two addresses on Base npx fibx@latest policy set base.allowedDestinations 0xAbC...,0xDeF... # Remove the cap npx fibx@latest policy clear base.maxValue ``` *** ## status — Session Status Check whether a session is active, which signing path it uses, and the authenticated wallet address. ```bash theme={null} npx fibx@latest status [--chain ] [--json] ``` *** ## address — Wallet Address Print the active wallet address. ```bash theme={null} npx fibx@latest address [--json] ``` *** ## wallets — Wallet Details Show the active wallet details for the current session. ```bash theme={null} npx fibx@latest wallets [--json] ``` *** ## portfolio — Cross-Chain Portfolio View a consolidated portfolio across all supported chains with USD-valued token holdings and DeFi positions. ```bash theme={null} npx fibx@latest portfolio [--json] ``` | Parameter | Type | Required | Description | | --------- | ---- | -------- | ---------------------------- | | `json` | flag | No | Output the portfolio as JSON | ### Examples ```bash theme={null} # Human-readable portfolio summary npx fibx@latest portfolio # Structured JSON for automation npx fibx@latest portfolio --json ``` The portfolio view aggregates holdings across Base, HyperEVM, and Monad. It also includes Aave V3 collateral and debt positions when available. *** ## balance — Check Balances Fetch native and ERC-20 token balances for the authenticated wallet. ```bash theme={null} npx fibx@latest balance [--chain ] [--json] ``` | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------ | | `chain` | string | No | `base`, `hyperevm`, or `monad` | | `json` | flag | No | Output as JSON | ```bash theme={null} npx fibx@latest balance ``` ```bash theme={null} npx fibx@latest balance --chain hyperevm ``` ```bash theme={null} npx fibx@latest balance --chain monad ``` *** ## send — Transfer Tokens Send native tokens or ERC-20 tokens to a recipient address. FibX performs a command-specific preflight before submission. ```bash theme={null} npx fibx@latest send [token] [--chain ] [--simulate] [--json] ``` | Parameter | Type | Required | Description | | ----------- | ------ | -------- | ----------------------------------------------------------------- | | `amount` | number | Yes | Amount to send | | `recipient` | string | Yes | Destination address (`0x...`) | | `token` | string | No | Token symbol or supported contract address; omit for native token | | `chain` | string | No | `base`, `hyperevm`, or `monad` | | `simulate` | flag | No | Preview the transfer without submitting it | | `json` | flag | No | Output as JSON | If `token` is omitted, the chain's native token is used (ETH on Base, HYPE on HyperEVM, MON on Monad). ### Examples ```bash theme={null} # Send native ETH on Base npx fibx@latest send 0.01 0xRecipient # Send ERC-20 on Base npx fibx@latest send 100 0xRecipient USDC # Send native MON on Monad npx fibx@latest send 1 0xRecipient --chain monad # Preview a native transfer npx fibx@latest send 0.1 0xRecipient --simulate ``` *** ## trade: Swap Tokens Exchange one token for another via Fibrous aggregation. The CLI finds a route, handles token approvals, estimates the main swap path, and submits it. ```bash theme={null} npx fibx@latest trade [--chain ] [--slippage ] [--approve-max] [--simulate] [--json] ``` | Parameter | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------------------------------- | | `amount` | number | Yes | Amount of the source token to swap | | `from_token` | string | Yes | Source token symbol or supported contract address | | `to_token` | string | Yes | Target token symbol or supported contract address | | `chain` | string | No | `base`, `hyperevm`, or `monad` | | `slippage` | number | No | Slippage tolerance in percent (default: `0.5`), 0.01–50 | | `approve-max` | flag | No | Use infinite approval instead of exact amount | | `simulate` | flag | No | Return a no-broadcast preview of the main swap | | `json` | flag | No | Output as JSON | The `trade` command automatically detects **Wrap** (Native → Wrapped) and **Unwrap** (Wrapped → Native) operations and executes them directly via contract calls, bypassing the aggregator routing to save gas. If the source is an ERC-20 token with insufficient allowance, `trade --simulate` returns `requiresApproval: true` without submitting an approval. Because the swap cannot be estimated safely in that state, the preview omits the gas estimate. A live routed ERC-20 trade may confirm an approval transaction before estimating and submitting the swap. If the later swap step fails, that approval remains on-chain. `--simulate` broadcasts neither transaction. ### Examples ```bash theme={null} npx fibx@latest trade 0.1 ETH USDC ``` ```bash theme={null} npx fibx@latest trade 1 HYPE USDC --chain hyperevm ``` ```bash theme={null} npx fibx@latest trade 1 MON USDC --chain monad ``` ```bash theme={null} npx fibx@latest trade 0.1 ETH USDC --slippage 1.0 ``` ```bash theme={null} npx fibx@latest trade 0.1 ETH USDC --simulate ``` *** ## aave — Aave V3 (Base Only) Manage Aave V3 lending positions on Base. Supply assets to earn yield, borrow against collateral, repay debt, or withdraw. Aave V3 operations always target **Base**. The global `--chain` option does not change the Aave network, so omit it for `aave` commands. ```bash theme={null} npx fibx@latest aave [amount] [token] [--simulate] [--json] ``` | Parameter | Type | Required | Description | | ---------- | ------ | -------------------------------- | ------------------------------------------------------------ | | `action` | string | Yes | `status`, `markets`, `supply`, `borrow`, `repay`, `withdraw` | | `amount` | string | Yes (except `status`, `markets`) | Amount or `max` for full repay/withdraw | | `token` | string | Yes (except `status`, `markets`) | Token symbol or supported contract address | | `simulate` | flag | No | Return a request-only, no-broadcast preview | | `json` | flag | No | Output as JSON | ### Actions | Action | Description | Example | | ---------- | -------------------------------------------------------- | --------------------------------------- | | `status` | Health factor, collateral, debt, and available borrowing | `npx fibx@latest aave status` | | `markets` | Browse reserves with APY and supply/borrow totals | `npx fibx@latest aave markets` | | `supply` | Deposit assets; ETH input can auto-wrap to WETH | `npx fibx@latest aave supply 1 ETH` | | `borrow` | Borrow against collateral; the ETH market returns WETH | `npx fibx@latest aave borrow 50 USDC` | | `repay` | Repay debt; ETH input can auto-wrap to WETH | `npx fibx@latest aave repay max ETH` | | `withdraw` | Withdraw assets; ETH input can auto-unwrap WETH to ETH | `npx fibx@latest aave withdraw max ETH` | ### ETH ↔ WETH Auto-Wrap For the ETH market, `supply` and `repay` can wrap ETH to WETH, while `withdraw` can unwrap WETH to ETH. Borrowing the ETH market returns WETH; the borrowed asset is not auto-unwrapped. ```bash theme={null} npx fibx@latest aave supply 1 ETH # Auto-wraps ETH → WETH and supplies npx fibx@latest aave supply 100 USDC # Supply ERC-20 directly npx fibx@latest aave markets # Browse reserves with APY and supply/borrow totals npx fibx@latest aave borrow 50 USDC # Borrow npx fibx@latest aave repay 50 USDC # Repay partial USDC debt npx fibx@latest aave repay max ETH # Auto-wraps ETH and repays full WETH debt npx fibx@latest aave withdraw max ETH # Withdraws WETH and auto-unwraps to ETH npx fibx@latest aave supply 1 ETH --simulate # Preview the request only ``` An Aave `--simulate` result summarizes the normalized request without broadcasting it. It does not perform on-chain validation, simulate the contract call, or estimate gas. A live `supply` or `repay` may submit wrap and approval transactions before the Aave call. An ETH `withdraw` submits the Aave withdrawal before a separate unwrap transaction; the reported `txHash` is the Aave withdrawal hash. If a later step fails, earlier transactions remain on-chain. In particular, `aave withdraw max ETH` unwraps the wallet's entire WETH balance after the withdrawal, including WETH held before the command. ### Health Factor Before borrowing, always check `aave status`. The Health Factor indicates liquidation risk: * **Above 1.5** — Lower liquidation risk, but not risk-free * **Between 1.1 and 1.5** — Liquidation risk warning * **Below 1.1** — High liquidation risk, proceed with extreme caution `max` is supported only for `repay` and `withdraw`; `supply max` and `borrow max` are rejected. Use `max` when fully repaying debt or withdrawing a supplied position to avoid dust residuals. *** ## config — RPC Configuration View and modify local fibx CLI configuration. Used primarily to set custom RPC URLs when hitting rate limits on public endpoints. ```bash theme={null} npx fibx@latest config [chain] [url] ``` | Subcommand | Description | Example | | ----------- | ---------------------------------------- | -------------------------------------------------------------- | | `set-rpc` | Set a custom RPC URL for a chain | `npx fibx@latest config set-rpc base https://mainnet.base.org` | | `get-rpc` | View the current RPC URL for a chain | `npx fibx@latest config get-rpc base` | | `reset-rpc` | Reset one chain or all chains to default | `npx fibx@latest config reset-rpc base` | | `list` | List all custom configurations | `npx fibx@latest config list` | | Parameter | Type | Required | Description | | --------- | ------ | --------------- | -------------------------------------------------------------- | | `chain` | string | Conditional | Required for `set-rpc` and `get-rpc`; optional for `reset-rpc` | | `url` | string | Yes (`set-rpc`) | Full HTTP(S) RPC endpoint URL | Configuration is stored in the OS-specific FibX config directory and persists across sessions. Typical paths are `~/.config/fibx-nodejs/config.json` on Linux and `~/Library/Preferences/fibx-nodejs/config.json` on macOS. ### Examples ```bash theme={null} # Handle rate limit on Base npx fibx@latest config set-rpc base https://mainnet.base.org # Check configured RPC npx fibx@latest config get-rpc base # Reset Base RPC to default npx fibx@latest config reset-rpc base # Reset all custom RPCs npx fibx@latest config reset-rpc # List all configurations npx fibx@latest config list ``` *** ## tx-status — Transaction Status Check the on-chain status of a transaction and retrieve the block explorer link. ```bash theme={null} npx fibx@latest tx-status [--chain ] [--json] ``` | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------ | | `hash` | string | Yes | Transaction hash (`0x...`) | | `chain` | string | No | Must match the chain of the original transaction | | `json` | flag | No | Output as JSON | Always use the same `--chain` flag that was used for the original transaction. A Base transaction hash will not be found on Monad. ### JSON Output ```json theme={null} { "status": "success", "blockNumber": "12345", "gasUsed": "21000", "from": "0x...", "to": "0x...", "txHash": "0x...", "explorer": "https://basescan.org/tx/0x...", "chain": "base" } ``` *** ## Error Reference Common errors across all commands: | Error | Cause | Resolution | | ---------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------- | | `Not authenticated` | No active session | Run `auth setup` (or `auth connect` / `auth login` / `auth import`) first | | `POLICY_BLOCKED` | The local signing policy refused the transaction | The rule and limit are named; change them with `policy set` or `policy clear` | | Rejected in wallet | The WalletConnect wallet declined the request | Nothing was sent; retry when ready | | `Insufficient balance` | Not enough tokens for the operation | Check `balance` and adjust the amount | | `Simulation failed` | An RPC estimate or contract preflight rejected the request | Verify parameters and token availability | | `No route found` | No liquidity path exists for the token pair | Try a different pair or check the chain | | `Slippage exceeded` | Price moved beyond tolerance | Retry or increase slippage with `--slippage` | | `Session expired` | Privy session timed out (7 days) | Re-authenticate with `auth login` | | `Invalid address` | Recipient address is malformed | Verify the address starts with `0x` and is valid | | `Rate limit` | Too many requests in a short period | Retry shortly; set a custom RPC if 429 errors persist | # What is FibX? Source: https://docs.fibrous.finance/fibx-agent/index A command-line tool, MCP server and agent skill framework for executing DeFi operations across multiple chains, powered by Fibrous aggregation. FibX is a DeFi execution layer for developers and AI agents — token swaps, transfers, balance checks, cross-chain portfolio inspection, and Aave V3 position management — across **Base, HyperEVM, and Monad**. One published package serves three surfaces: `fibx ` for people, `fibx mcp-start` for agents, and, in hosts that render [MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps) UI, **the FibX app** inside the chat. It combines [Fibrous](https://fibrous.finance) aggregation for optimal swap routing with a choice of how transactions are signed: your own wallet over WalletConnect, a server-managed wallet via [Privy](https://privy.io), or a private key imported onto the machine — every path bounded by a [signing policy](/fibx-agent/signing) that lives in a file you own. ## Core Capabilities In Claude Desktop and other hosts that render MCP Apps UI, one tool opens the whole app in the chat — wallet, balances, signing policy, and a swap form with the Fibrous route. The model opens it; you press Simulate and Swap. Consolidated cross-chain portfolio view with USD valuations, token balances, Aave collateral and debt, and total net worth across all supported chains. Optimal routing via Fibrous aggregation with configurable slippage (default: 0.5%). Supports the tokens and integrated DEX liquidity available through Fibrous on each chain. Send native tokens (ETH, HYPE, MON) or ERC-20 tokens to an address, with command-specific preflight and preview support. Supply, borrow, repay, withdraw, and browse active markets on Base. ETH supply and repay can auto-wrap, ETH withdraw can auto-unwrap, and borrowing the ETH market returns WETH. Eleven pre-built skills that allow AI agents to check prices, authenticate, set a signing policy, inspect balances and portfolios, trade, send, manage Aave positions, verify transactions, and configure RPC endpoints — all through natural language. ## How It Works FibX runs as a CLI tool (`npx fibx@latest`) or as a stdio MCP server (`npx fibx mcp-start`). Both talk to the Fibrous aggregation stack and to the chain RPCs directly. Where a transaction is signed depends on the signing path: on the user's phone over WalletConnect, at Privy through `fibx-server`, or locally with an imported key. In every case the local signing policy is checked before a signature is requested. Transaction paths use command-specific estimates or contract simulations where implemented, but those checks do not guarantee that an on-chain operation will succeed. ```mermaid theme={null} flowchart LR A[User, AI agent, or the FibX app] --> B[fibx CLI / MCP server] B --> P{Local signing policy} P --> W[Your wallet over WalletConnect] P --> S[fibx-server → Privy Server Wallets] P --> K[Imported key, encrypted locally] W --> F[Fibrous Aggregation API] S --> F K --> F F --> G[Blockchain] ``` ## Supported Chains | Chain | Native Token | CLI Flag | Aave V3 | | -------- | ------------ | ------------------ | ------- | | Base | ETH | `--chain base` | Yes | | HyperEVM | HYPE | `--chain hyperevm` | No | | Monad | MON | `--chain monad` | No | Citrea was delisted by Fibrous on 2026-08-10 and withdrawn from FibX in v0.10.0. `--chain citrea` is refused. ## Security Model FibX moves real funds. Treat client confirmation, preview output, the signing policies, and backend credentials as separate controls; none replaces reviewing the final transaction request. A JSON file on the user's machine — a native-value cap per chain, an allowed-chain list, an allowed-destination list, and an expiry — evaluated before every signature on all three signing paths. It bounds the native `value` of a transaction, not ERC-20 amounts encoded in calldata; `allowedDestinations` is what bounds where tokens may go. A refusal comes back as `POLICY_BLOCKED` with the rule named. See [Signing paths and the local policy](/fibx-agent/signing). On the Privy path, new wallets are attached to a default-deny policy whose rules allowlist configured chain IDs and cap the native `value` field, evaluated by Privy at signing time on top of the local policy. Message and typed-data requests also rely on `fibx-server` validation. A custom `WALLET_POLICY_ID` is checked for existence, not compared with the default rule set. Transactional MCP tools carry the `destructiveHint` annotation. MCP clients may use this metadata to request confirmation, depending on the client and its configuration. The FibX app executes nothing on its own: Simulate and Swap are buttons the user presses. Over WalletConnect the wallet app approves every transaction and nothing is signed on this machine. In Privy mode, signing returns a signed payload to the CLI; the raw key is not returned, and `fibx-server` with the Privy app secret remains the trust boundary. In private-key mode, FibX encrypts the imported key at rest with AES-256-GCM and signs locally — there the local policy is the only bound. `--simulate` and `simulate=true` provide no-broadcast previews for supported write paths, but the returned checks are command-specific. Gas estimates are included only where they can be calculated safely, and an Aave action preview does not perform on-chain validation. A preview does not guarantee that later execution will succeed. The policies are defense in depth on the normal signing path, not a containment guarantee. The local policy is a file, so it is worth nothing against something that can already write to the user's disk; the Privy app credentials authorize both signing and policy administration, so the backend that holds them is the administrative trust boundary on that path. ## Typical Workflow A typical wallet workflow follows five steps: Run `fibx auth setup`. It presents the three paths with their trade-offs — your own wallet over WalletConnect, a Privy server wallet via email OTP, or an imported private key — and creates a session that persists across commands. Set a signing policy with `fibx policy set`. On the imported-key path this is the only limit there is; on the others it sits in front of the wallet's own approval or Privy's policy. Query native and ERC-20 token balances on the target chain, or inspect the full cross-chain portfolio with USD valuations. Review the amount, tokens, destination, chain, and any approval. Use the command-specific preview options where appropriate, then submit the operation on-chain. Over WalletConnect, approve it on your phone. Check the transaction status and obtain the block explorer link. ## Quick Example ```bash theme={null} # Check a price first — no wallet, no login required npx fibx@latest quote 0.01 ETH USDC # Choose a signing path (interactive) npx fibx@latest auth setup # Cap what this wallet may sign on Base npx fibx@latest policy set base.maxValue 0.05 # Check balance on Base npx fibx@latest balance # View your cross-chain portfolio npx fibx@latest portfolio # Swap 0.01 ETH for USDC npx fibx@latest trade 0.01 ETH USDC # Verify the transaction npx fibx@latest tx-status 0xabc...def ``` ## Three Ways to Use FibX Run commands directly in your terminal. Ideal for developers who want programmatic access to DeFi operations or need to script workflows. ```bash theme={null} npx fibx@latest portfolio --json npx fibx@latest trade 0.05 ETH USDC --chain base --simulate ``` Add `npx fibx mcp-start` to Cursor, Claude Desktop, VS Code, Windsurf or Antigravity and the model gets 19 typed tools. In a host that renders MCP Apps UI — Claude Desktop today — asking about your wallet, a price or a swap opens the FibX app inline, pre-filled from the conversation. See [MCP Configuration](/fibx-agent/mcp-configuration). ```json theme={null} { "mcpServers": { "fibx": { "command": "npx", "args": ["-y", "fibx", "mcp-start"] } } } ``` Import the [fibx-skills](https://github.com/Fibrous-Finance/fibx-skills) into your AI agent's skill registry. The agent interprets natural language prompts and maps them to the appropriate CLI commands. | User Prompt | Skill Triggered | | ------------------------------- | --------------------- | | "How much USDC for 0.1 ETH?" | `quote` | | "Connect my own wallet" | `authenticate-wallet` | | "Cap this wallet at 0.05 ETH" | `policy` | | "What's my wallet address?" | `wallet-info` | | "Swap 0.05 ETH to USDC" | `trade` | | "Check my balance on Monad" | `balance` | | "Show me my portfolio" | `portfolio` | | "Send 10 USDC to 0x123..." | `send` | | "Supply 100 USDC to Aave" | `aave` | | "I'm getting rate limit errors" | `config` | ## Telegram Bot [fibx-telegram-bot](https://github.com/Fibrous-Finance/fibx-telegram-bot) puts the same execution layer in a chat window. It drives the FibX MCP server, exposing capabilities such as quotes, swaps, transfers, portfolio, and Aave through natural language rather than CLI flags. * **Bring your own model.** Choose OpenAI, Claude or Gemini and supply your own API key. There is no shared key and no centralized inference billing; keys are encrypted at rest. `/deletekey` clears the provider configuration and encrypted key, FibX session/config/cache, pending authentication, and chat history; price alerts remain active. * **Per-user runtime state.** Every active user gets a dedicated MCP process and separate HOME/XDG paths. These processes still run under the same OS account, so this is application-level separation rather than an OS sandbox. * **Price alerts.** `/alert ETH above 4000` notifies you once when the price is reached — no login or AI key required. ## Resources fibx v0.10.0 — install and version history Eleven pre-built skills for AI agent integration Connect FibX to Cursor, Claude Desktop, VS Code, Windsurf, and Antigravity — and open the FibX app in the chat Your own wallet, Privy, or an imported key — and the local file that bounds all three Listed as `finance.fibrous/fibx` Chat-based DeFi execution with your own AI model # Installation and Setup Source: https://docs.fibrous.finance/fibx-agent/installation Requirements, installation, and the three ways to authenticate the fibx CLI. ## Requirements * **Node.js** v18 or higher * **npm** (included with Node.js) * A running [fibx-server](https://github.com/Fibrous-Finance/fibx-server) instance only if you use Privy-managed wallet operations No global installation is needed. All commands use `npx fibx@latest`, which always fetches the latest version (currently **v0.10.0**). ## Installation Options Run FibX directly with `npx`: ```bash theme={null} npx fibx@latest status ``` Or install it globally: ```bash theme={null} npm install -g fibx ``` ## Installing Agent Skills To add fibx skills to your AI agent, use the Vercel Skills CLI: ```bash theme={null} npx skills add Fibrous-Finance/fibx-skills ``` This installs the pre-built skill definitions from the [fibx-skills repository](https://github.com/Fibrous-Finance/fibx-skills) into your agent's skill registry. No separate installation of `fibx` is needed — all skills execute via `npx fibx@latest`. ## Verify Your Environment ```bash theme={null} node --version # Must be v18.0.0 or higher npm --version ``` ## Try It Without a Wallet Before setting anything up, you can check live prices — `quote` needs no session, wallet, or keys: ```bash theme={null} npx fibx@latest quote 0.01 ETH USDC npx fibx@latest quote 1 MON USDC --chain monad ``` ## Authentication Commands that inspect or act on a wallet — including `address`, `wallets`, `balance`, `portfolio`, `send`, `trade`, `aave status`, and Aave actions — need an active session. Public or local commands such as `quote`, `status`, `tx-status`, `config`, `policy`, and `aave markets` can run without one. Three signing paths are available, and they are peers — `auth setup` presents the choice with the trade-offs explained. The full comparison is on [Signing Paths and the Local Policy](/fibx-agent/signing). ```bash theme={null} npx fibx@latest auth setup ``` ### Your Own Wallet (WalletConnect) Keep your keys in the wallet you already use. The CLI shows a QR code and a `wc:` URI; scan it with your wallet app and approve the pairing. Every later transaction is approved on your phone, so this path does not run unattended. ```bash theme={null} # Shows a QR code and waits for the wallet to approve npx fibx@latest auth connect # Confirm the session is active npx fibx@latest status ``` ### Private Key Import If you already have a wallet with a private key and want FibX to act without you, this is the most direct path. The key is encrypted at rest with AES-256-GCM and used to sign locally. This mode does not require `fibx-server`. With an imported key, the local signing policy is the **only** thing bounding what this wallet signs. Set one (`fibx policy set base.maxValue 0.05`) before the first transaction, and only use this path on a trusted device. ```bash theme={null} # Interactive prompt — paste your private key when asked npx fibx@latest auth import # Confirm the session is active npx fibx@latest status ``` ### Email OTP (Privy Server Wallets) If you do not have a private key or prefer a managed wallet, authenticate via email OTP. This creates a server-managed wallet through [Privy](https://privy.io). Signing is requested through `fibx-server`, and the private key itself is not returned to the CLI. This mode requires `fibx-server` to be running and reachable. ```bash theme={null} # Step 1: Request an OTP code npx fibx@latest auth login user@example.com # Step 2: Enter the code received via email npx fibx@latest auth verify user@example.com 123456 # Step 3: Confirm the session is active npx fibx@latest status ``` ### Session Management ```bash theme={null} # Check current session status npx fibx@latest status # Get the active wallet address npx fibx@latest address # End the session (also ends a WalletConnect pairing) npx fibx@latest auth logout ``` ## Set a Signing Policy A file you own, checked before every signature on all three paths. On the imported-key path it is the only limit there is. ```bash theme={null} # Cap the native value of one transaction on Base npx fibx@latest policy set base.maxValue 0.05 # Only allow Base and Monad npx fibx@latest policy set allowedChains base,monad # See what is set npx fibx@latest policy show ``` `maxValue` bounds the native value only — an ERC-20 transfer reaches the policy with `value: 0`. Use `.allowedDestinations` to bound where tokens may go. Details on [Signing Paths and the Local Policy](/fibx-agent/signing). ## Common Command Options These flags are available where shown in the command reference: | Flag | Description | Default | | ------------- | ---------------------------------------------------------------- | ------- | | `-c, --chain` | Target chain: `base`, `hyperevm`, `monad` | `base` | | `--json` | Output results as JSON (useful for scripting) | `false` | | `--simulate` | Command-specific preview; behavior varies by command (see below) | `false` | ### Chain Selection Commands that accept `--chain` default to **Base** unless their reference says otherwise. ```bash theme={null} # Explicit chain selection npx fibx@latest balance --chain hyperevm npx fibx@latest trade 1 MON USDC --chain monad # Default: Base npx fibx@latest balance ``` ## First Transaction After authenticating, run through a complete workflow to verify everything is working: ```bash theme={null} npx fibx@latest balance ``` ```bash theme={null} npx fibx@latest trade 0.001 ETH USDC ``` The CLI checks the signing policy, finds a route via Fibrous, handles any required token approval, estimates the swap where supported, and submits it. Over WalletConnect, approve it on your phone. ```bash theme={null} npx fibx@latest tx-status ``` This returns the on-chain status, gas used, and a block explorer link. ## Preview Behavior `send --simulate`, `trade --simulate`, and Aave actions with `--simulate` return a no-broadcast preview. Review the result and the command-specific limitations before submitting the live operation. ```bash theme={null} npx fibx@latest send 0.1 0xRecipient --simulate npx fibx@latest trade 0.1 ETH USDC --simulate npx fibx@latest aave supply 1 ETH --simulate ``` Preview output varies by path. If an ERC-20 trade needs approval, `trade --simulate` reports `requiresApproval: true` without submitting the approval or returning a gas estimate. An Aave preview returns the normalized request only; it does not perform on-chain validation or estimate gas. Preview success does not guarantee that later execution will succeed. # MCP Configuration Source: https://docs.fibrous.finance/fibx-agent/mcp-configuration Configure FibX as an MCP server for AI editors — Cursor, Claude Desktop, Antigravity, and other MCP-compatible clients — and open the FibX app in the chat. FibX includes a built-in [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that exposes DeFi operations as callable tools. AI editors like **Cursor**, **Claude Desktop**, **Antigravity**, and any MCP-compatible client can connect to FibX and execute trades, transfers, and DeFi operations through natural language. In hosts that render [MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps) UI — Claude Desktop today — the server also serves **the FibX app**: one document showing the wallet, balances, the signing policy, and a swap form with the Fibrous route, opened by the `open_fibx` tool and pre-filled from the conversation. The model opens it; the user presses Simulate and Swap. ## Quick Start ```bash theme={null} npx fibx mcp-start ``` This starts an MCP server over **stdio** (standard input/output). The server speaks JSON-RPC 2.0 and is designed to be launched by an AI editor, not run manually. ## How It Works 1. Your AI editor spawns `npx fibx mcp-start` as a subprocess. 2. The editor communicates with FibX over **stdin/stdout** using JSON-RPC 2.0 messages. 3. Wallet-dependent tools read the local session file. Run `fibx auth setup` (or `auth connect`, `auth login`, `auth import`) before using those tools, or pair a wallet from inside the app with `connect_wallet`; public tools such as quotes, the token list, the policy, and Aave market discovery do not need a session. 4. Transactional tools execute against live blockchains and carry the MCP `destructiveHint` annotation. A client may use that hint to request confirmation, depending on its behavior and configuration. Every transaction also passes the [local signing policy](/fibx-agent/signing) before a signature is requested. 5. `open_fibx` is bound to the resource `ui://fibx/app.html`. A host that renders MCP Apps shows the app inline and the tool's JSON result seeds it; a host that does not simply gets the JSON — a complete snapshot of chain, session, balances, policy and quote — and the model reads that instead. `stderr` is used for logging, while `stdout` is reserved for JSON-RPC protocol messages. ## Editor Setup Add the FibX MCP server to your AI editor. FibX uses **stdio** transport — the editor spawns `npx fibx mcp-start` and communicates over standard input/output. Open MCP settings with Command + Shift + P and search for "Open MCP settings". Create or edit `.cursor/mcp.json` in your project root: ```json theme={null} { "mcpServers": { "fibx": { "command": "npx", "args": ["-y", "fibx", "mcp-start"] } } } ``` Test by asking Cursor: *"What tools do you have available?"* — it should list the FibX MCP server. Add to your `claude_desktop_config.json`: ```json theme={null} { "mcpServers": { "fibx": { "command": "npx", "args": ["-y", "fibx", "mcp-start"] } } } ``` Quit Claude Desktop fully after editing the config (Cmd + Q on macOS — the server process starts at launch and is not restarted by closing a window). Claude Desktop renders the FibX app inline: ask about your wallet, a price or a swap and the app opens in the chat. You can pair a wallet from inside it, or authenticate first with `fibx auth setup`. Create or edit `.vscode/mcp.json` in your project: ```json theme={null} { "mcpServers": { "fibx": { "command": "npx", "args": ["-y", "fibx", "mcp-start"] } } } ``` Reload the window or restart VS Code to activate the MCP server. Open the MCP configuration in Windsurf settings and add: ```json theme={null} { "mcpServers": { "fibx": { "command": "npx", "args": ["-y", "fibx", "mcp-start"] } } } ``` Add to `~/.gemini/antigravity/mcp_config.json`: ```json theme={null} { "mcpServers": { "fibx": { "command": "npx", "args": ["-y", "fibx", "mcp-start"] } } } ``` ChatGPT and other tools without MCP support cannot connect to FibX directly. Use one of these alternatives: * **CLI**: Run `npx fibx@latest` commands directly in your terminal. * **Agent Skills**: Install [fibx-skills](https://github.com/Fibrous-Finance/fibx-skills) for AI agents that support the Agent Skills format. * **MCP-capable editor**: Use Cursor, Claude Desktop, VS Code, or Windsurf with the config above. Wallet operations need a session. Create one with `fibx auth setup` in a terminal, or — over MCP — with `connect_wallet`, which pairs your own wallet by QR. The FibX app offers the same pairing from its Connect button. ## The FibX App `open_fibx` is the entry point in any host that renders MCP Apps UI. The server's own instructions tell the model so: a question about the wallet, a balance, a price or a swap opens the whole app, pre-filled with whatever the conversation supplied — chain, tokens, amount. Inside it: * the header shows the chain and the connected address, or a **Connect** button that pairs a wallet by QR; * two token boxes with balances, a rate chip, and the Fibrous route; * one primary button whose label is the state — *Connect wallet*, *Enter an amount*, *Insufficient ETH balance*, **Simulate**, **Swap**, *Waiting…*, *Confirmed* — so a swap cannot skip its simulation; * the signing policy as a collapsible section, editable in place, and a refusal from it shown with the rule named. The app executes nothing on its own. A swap leaves it only when the user presses Swap, after Simulate, and it still passes through the local signing policy. The model never gets to press the button; what it receives is a sentence describing the state (*quoted*, *broadcast*, *settled*, *reverted*, *unresolved*) so it can report honestly. In a text-only host the same call returns a JSON snapshot the model can summarise, and the headless tools below do the rest. ## Available Tools FibX exposes **19 tools**. The reference below groups them by the app, read-only, transactional, and session behavior. ### The App | Tool | Description | Auth Required | | ------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------- | | `open_fibx` | Open the FibX app — wallet, balances, signing policy and a swap form — pre-filled from `chain`, `from`, `to`, `amount` | No | | `list_tokens` | List the tokens Fibrous supports on a chain, with address, decimals and USD price where known | No | ### Read-Only | Tool | Description | Auth Required | | -------------------- | ------------------------------------------------------------- | ------------- | | `get_quote` | Get a swap price quote, exchange rate, and route info | No | | `get_auth_status` | Check session, signing path, and Fibrous API health | No | | `get_connect_status` | Poll a pairing started by `connect_wallet` | No | | `get_policy` | Read the local signing policy that bounds every transaction | No | | `get_tx_status` | Check transaction receipt and status | No | | `get_aave_markets` | List Aave V3 reserves with APY, supply/borrow totals, and LTV | No | | `get_balance` | Get native and ERC-20 token balances | Yes | | `get_portfolio` | Get cross-chain portfolio and DeFi positions | Yes | | `get_aave_status` | Get Aave V3 position health on Base | Yes | `get_quote` needs no wallet and no session. An agent can answer "what would 1 ETH get me in USDC?" before the user has authenticated at all — useful as a first interaction. ### Transactional These tools carry the MCP `destructiveHint` annotation. Clients may use the hint to request confirmation, but confirmation behavior is client-dependent. All three accept `simulate=true`; its behavior is specific to each tool. | Tool | Description | | ------------- | ------------------------------------------------------- | | `swap_tokens` | Swap tokens via Fibrous aggregator with optimal routing | | `send_tokens` | Send native or ERC-20 tokens to a recipient | | `aave_action` | Supply, borrow, repay, or withdraw on Aave V3 (Base) | `simulate=true` returns a no-broadcast preview, but the available checks differ by tool. If a swap needs ERC-20 approval, the preview reports `requiresApproval: true` without submitting the approval or estimating swap gas. `aave_action` returns normalized request metadata without on-chain validation or a gas estimate. A preview does not guarantee that later execution will succeed. ### Session and Configuration These change local state rather than chain state. `set_policy_rule`, `clear_policy_rule`, and `logout` also carry `destructiveHint` — each can remove a bound that was protecting the wallet, or end the session outright. | Tool | Description | | ------------------- | ---------------------------------------------------------------------------- | | `connect_wallet` | Start a WalletConnect pairing; **replaces the active session** on approval | | `config_action` | Set or view custom RPC URLs to avoid rate limits | | `set_policy_rule` | Set one rule on the local signing policy — replaces an existing rule's value | | `clear_policy_rule` | Remove one policy rule, or the whole policy with `all: true` | | `logout` | End the WalletConnect pairing and clear the local session | ## Tool Details ### open\_fibx Open the FibX app. In a host that renders MCP Apps UI this is the entry point for anything about the wallet, a balance, a quote or a swap. | Parameter | Type | Required | Description | | ---------- | ------ | -------- | ----------------------------------------------- | | `chain` | string | No | `base`, `hyperevm`, or `monad` (default `base`) | | `from` | string | No | Source token symbol, to pre-fill a swap | | `to` | string | No | Destination token symbol | | `amount` | string | No | Amount of the source token | | `slippage` | number | No | Slippage tolerance in percent (default `0.5`) | **Output:** `chain`, `auth` (as `get_auth_status` reports it), `balances` (`null` without a session), `policy`, `terms` (the resolved `from`/`to`/`amount`), `quote` (the Fibrous route when all three were given) and `quoteError`. A quote that could not be fetched sets `quoteError` rather than failing the call, so the app still opens. The app requests one host permission, `clipboardWrite`, for the Copy link button on the pairing screen. **Example prompts:** "What's in my wallet?", "How much USDC would 0.01 ETH get me?", "Swap 0.01 ETH to USDC" ### list\_tokens List the tokens Fibrous supports on a chain. Feeds the app's token picker; useful headlessly to resolve a symbol before `get_quote` or `swap_tokens`. | Parameter | Type | Required | Description | | --------- | ------ | -------- | ----------------------------------------------- | | `chain` | string | No | `base`, `hyperevm`, or `monad` (default `base`) | **Output:** `chain` and `tokens`, each with `symbol`, `name`, `address`, `decimals`, and `price` where known. ### get\_quote Get a swap quote without a wallet or session. | Parameter | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------------------------- | | `amount` | string | Yes | Amount of the source token to quote | | `from_token` | string | Yes | Source token symbol (e.g. `ETH`, `USDC`) | | `to_token` | string | Yes | Target token symbol (e.g. `USDC`, `DAI`) | | `chain` | string | No | `base`, `hyperevm`, or `monad` | | `slippage` | number | No | Slippage tolerance in percent (default: `0.5`) | **Output:** Routed swaps return `input`, `output`, `rate`, `slippage`, `router`, `chain`, and a nested `quote` with `outputAmount`, `minReceived`, `usdIn`, `usdOut`, `priceImpact`, and `route` — the Fibrous route with protocol names, as the FibX app draws it. Direct native/wrapped-native pairs return `input`, `output`, `rate`, `operation` (`wrap` or `unwrap`), and `chain`. ### get\_auth\_status Check whether FibX is authenticated, which signing path is active, and whether the Fibrous API is reachable. | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------ | | `chain` | string | No | `base`, `hyperevm`, or `monad` | **Output:** Object with `authenticated`, `walletAddress`, `sessionType` (`walletconnect`, `privy`, or `private-key`), `authType`, `requiresApprovalPerTransaction` (`true` for a WalletConnect session — the wallet itself prompts for every transaction), `chain`, `fibrousStatus` ### connect\_wallet Start a WalletConnect pairing. Returns immediately; show the QR, then poll with `get_connect_status`. On approval the pairing **replaces** the active session, whatever path it used. | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------------- | | none | n/a | n/a | No input required | **Output:** `uri` (the `wc:` link), `qrDataUri` (a PNG data URI of the QR), `pairingId` ### get\_connect\_status Poll a pairing started by `connect_wallet` by its `pairingId`. Reports whether the wallet has approved, and the connected address once it has. ### get\_policy Read the local signing policy without changing it. No session needed. **Output:** `state` (`active`, `absent`, or `unreadable`), `rules`, `path`, `message`. `absent` means nothing limits what this wallet will sign; `unreadable` means a file exists but could not be parsed, which refuses every transaction until it is fixed or removed. **Example prompts:** "What's my current signing policy?" or "Is anything limiting what fibx can sign?" ### get\_balance Fetch token balances for the active wallet. The native-token entry is returned even when its balance is zero; ERC-20 entries are limited to non-zero balances. | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------ | | `chain` | string | No | `base`, `hyperevm`, or `monad` | **Output:** Object with `wallet`, `chain`, and `balances` (e.g. ETH, USDC with amounts) ### get\_portfolio Get a consolidated portfolio across all supported chains, including USD-valued token holdings and DeFi positions. | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------------- | | none | n/a | n/a | No input required | **Output:** Object with total portfolio USD value, per-chain assets, and DeFi position summaries **Example prompts:** "Show me my portfolio" or "What's my total net worth across all chains?" ### swap\_tokens Execute a token swap through Fibrous. Handles routing and any required ERC-20 approval. | Parameter | Type | Required | Description | | ------------ | ------- | -------- | ----------------------------------------------------- | | `amount` | string | Yes | Amount of the source token to swap | | `from_token` | string | Yes | Source token symbol (e.g. `ETH`, `USDC`) | | `to_token` | string | Yes | Target token symbol (e.g. `USDC`, `DAI`) | | `chain` | string | No | `base`, `hyperevm`, or `monad` | | `slippage` | number | No | Slippage tolerance in percent (default 0.5), 0.01–50 | | `simulate` | boolean | No | Return a no-broadcast preview; gas may be unavailable | **Execution output:** `txHash`, `amountIn`, `amountOut`, `tokenIn`, `tokenOut`, `router`, `chain`, and `explorer` when available. **Preview output:** Direct wrap/unwrap previews return `success`, `mode`, `operation`, `amountIn`, `tokenIn`, `tokenOut`, and `chain`. Routed previews also return `amountOut`, `router`, and `requiresApproval`; `estimatedGas` is included only when the swap can be estimated without first broadcasting an approval. A live routed ERC-20 swap may confirm an approval transaction before estimating and submitting the swap. If the later swap step fails, that approval remains on-chain. `simulate=true` broadcasts neither transaction. **Example prompt:** "Swap 0.1 ETH to USDC on Base" ### send\_tokens Transfer native or ERC-20 tokens. | Parameter | Type | Required | Description | | ----------- | ------- | -------- | -------------------------------------------- | | `amount` | string | Yes | Amount to send | | `recipient` | string | Yes | Recipient address (0x-prefixed) | | `token` | string | No | Token symbol (omit for native token) | | `chain` | string | No | `base`, `hyperevm`, or `monad` | | `simulate` | boolean | No | Preflight the transfer without submitting it | **Execution output:** `txHash`, `amount`, `token`, `recipient`, `chain`, and `explorer` when available. **Preview output:** Both paths return `success`, `mode`, `amount`, `token`, `recipient`, and `chain`. Native-token previews also return `estimatedGas`; ERC-20 previews validate the transfer contract call without a gas field. **Example prompt:** "Send 50 USDC to 0x1234..." ### get\_tx\_status Look up a transaction receipt by hash. | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------ | | `hash` | string | Yes | Transaction hash (0x-prefixed) | | `chain` | string | No | Must match the chain of the original transaction | **Output:** Object with `hash`, `status`, `blockNumber`, `from`, `to`, `gasUsed`, `chain`, and `explorer` when available. ### get\_aave\_status Get Aave V3 account health on Base. | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------------- | | none | n/a | n/a | No input required | **Output:** Object with `wallet`, `healthFactor`, `totalCollateralUSD`, `totalDebtUSD`, `availableBorrowsUSD` ### get\_aave\_markets List Aave V3 reserve markets on Base. No wallet or session is required. | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------------- | | none | n/a | n/a | No input required | **Output:** Object with `chain`, `marketCount`, and `markets`. Each market includes `symbol`, `supplyAPY`, `borrowAPY`, `totalSupply`, `totalBorrow`, `ltv`, and `isFrozen`. ### aave\_action Execute an Aave V3 operation on Base. ETH supply and repay can auto-wrap, ETH withdraw can auto-unwrap, and borrowing the ETH market returns WETH. Use `max` only for full repay or withdraw. | Parameter | Type | Required | Description | | ---------- | ------- | -------- | --------------------------------------------------------------------- | | `action` | string | Yes | `supply`, `borrow`, `repay`, or `withdraw` | | `amount` | string | Yes | Amount; `max` is allowed only for repay/withdraw | | `token` | string | Yes | Token symbol (`ETH`, `USDC`, `DAI`, etc.) | | `simulate` | boolean | No | Return an action preview without submitting it; does not estimate gas | **Execution output:** `action`, `amount`, `token`, `txHash`, `chain`, and `explorer` when available. A repay with no remaining debt instead returns `status` and no transaction hash. **Preview output:** `success`, `mode` (`PREVIEW (no TX sent)`), `action`, `amount`, `token`, `chain`, and `note`. The note states that no on-chain validation, gas estimate, or transaction was performed. Live wrap, approval, Aave, and unwrap steps are separate transactions, so an earlier step remains on-chain if a later one fails. For an ETH withdrawal, the output transaction hash identifies the Aave withdrawal transaction, not the separate unwrap transaction. With `action: "withdraw"`, `amount: "max"`, and `token: "ETH"`, FibX unwraps the wallet's entire post-withdraw WETH balance, including WETH held before the request. **Example prompts:** "Supply 0.5 ETH to Aave" or "Repay max USDC on Aave" ### config\_action Manage custom RPC URLs. Useful when encountering rate limits on public endpoints. | Parameter | Type | Required | Description | | --------- | ------ | ----------- | -------------------------------------------- | | `action` | string | Yes | `set-rpc`, `get-rpc`, `reset-rpc`, or `list` | | `chain` | string | Conditional | Required for `set-rpc` and `get-rpc` | | `url` | string | Conditional | Required for `set-rpc` — full RPC endpoint | **Output:** Object with `action`, `chain`, `url`, or `rpcUrls` depending on the action **Example prompts:** "I'm getting rate limited on Base, set a custom RPC" or "Reset all RPCs to default" ### set\_policy\_rule Set one rule on the local signing policy — `expiry`, `allowedChains`, `.maxValue`, or `.allowedDestinations`. Lists are comma-separated. | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------ | | `rule` | string | Yes | The rule name | | `value` | string | Yes | The value; comma-separated for lists | **Output:** `ok`, `rule`, `value`, and the resulting `rules` Setting a rule that already exists **replaces** its value — a cap can be widened as easily as it was tightened, which is why this tool carries `destructiveHint`. `maxValue` bounds only the native value of a transaction; use `allowedDestinations` to bound where tokens may go. **Example prompts:** "Cap Base transactions at 0.05 ETH" or "Only allow sending to my own address on Base" ### clear\_policy\_rule Remove one rule from the local signing policy, or the whole policy. | Parameter | Type | Required | Description | | --------- | ------- | -------- | --------------------------------- | | `rule` | string | One of | The rule to remove | | `all` | boolean | One of | `true` to remove the whole policy | **Output:** `ok`, `changed`, `rule`, the remaining `rules`, and a `message` ### logout End the WalletConnect pairing, if any, and clear the local session. | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------------- | | none | n/a | n/a | No input required | ## Supported Chains | Chain | Native Token | Fibrous Network | | -------- | ------------ | --------------- | | Base | ETH | base | | HyperEVM | HYPE | hyperevm | | Monad | MON | monad | ## Environment Variables | Variable | Description | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `FIBX_API_URL` | Custom fibx-server URL (for Privy wallet operations) | | `FIBX_SESSION_SECRET` | Custom encryption key for the session file (64-char hex); auto-generated per machine when unset | | `FIBX_WC_PROJECT_ID` | WalletConnect Cloud project id for `connect_wallet`; a shared id ships in the package, set your own from [cloud.reown.com](https://cloud.reown.com) if pairing fails on quota | If using Privy authentication, ensure `fibx-server` is running and accessible before starting the MCP server. ## Troubleshooting | Problem | Solution | | -------------------------- | ------------------------------------------------------------------------------------------------------ | | Server will not start | Ensure Node.js 18+ is installed and `npx fibx --version` works | | "Not authenticated" errors | Run `fibx auth setup` before using wallet-dependent tools, or pair with `connect_wallet` | | `POLICY_BLOCKED` | The local signing policy refused it and named the rule; change it with `set_policy_rule` or in the app | | Wallet operations fail | Ensure `fibx-server` is running when using Privy-managed wallets | | Rate limit errors | Use `config_action` to set a custom RPC URL | | Editor cannot connect | Verify the MCP config JSON syntax and restart the editor | | The app does not appear | The host does not render MCP Apps; the model gets `open_fibx`'s JSON snapshot instead | | The app is out of date | Quit the host fully (`Cmd+Q`) — the server process only starts at app launch | # Signing Paths and the Local Policy Source: https://docs.fibrous.finance/fibx-agent/signing How FibX signs — your own wallet over WalletConnect, a Privy server wallet, or an imported key — and the signing policy file that bounds all three. Every FibX transaction is signed through one of three paths. They are peers, not a default with fallbacks, and `fibx auth setup` presents the choice: | Path | Command | Key held by | Runs while you are away | Bounded by | | -------------------- | ---------------------------- | ----------------------- | ------------------------------------------------ | --------------------------------------------- | | Your own wallet | `auth connect` | your wallet app | No — every transaction is approved on your phone | the wallet, plus the local policy | | Privy server wallet | `auth login` + `auth verify` | Privy, server-side | Yes | Privy's signing policy, plus the local policy | | Imported private key | `auth import` | this machine, encrypted | Yes | **the local policy alone** | Keeping your own wallet *and* having FibX act unattended needs ERC-7715, which wallets do not yet expose over WalletConnect. `fibx auth setup` explains the closest options. ## Choosing a path ```bash theme={null} npx fibx@latest auth setup ``` The prompt offers four choices and a cancel: * **Connect a wallet I already have** — runs `auth connect`. * **Create a wallet FibX can use on its own** — runs the Privy email flow. * **Import a private key onto this machine** — runs `auth import`. * **None of these — I want my own wallet AND unattended operation** — explains the ERC-7715 gap and the nearest alternatives. Any of these **replaces** the active session, and ends a WalletConnect pairing it is replacing. ### Your own wallet, over WalletConnect ```bash theme={null} npx fibx@latest auth connect ``` The CLI prints a QR code and a `wc:` URI, then waits. Scan the QR with your wallet app (or paste the URI into it) and approve the pairing. From then on the wallet prompts for **every** transaction: a `trade` or `send` blocks until you approve it on your phone, and a rejection there is normal — nothing is sent. Nothing is signed on the machine running FibX. `--json` prints `{ "uri": "wc:…" }` instead of the QR, for a host that renders its own. A shared WalletConnect project id ships in the package; set `FIBX_WC_PROJECT_ID` to your own from [cloud.reown.com](https://cloud.reown.com) if pairing starts failing on quota. ### A Privy server wallet, via email OTP ```bash theme={null} npx fibx@latest auth login user@example.com npx fibx@latest auth verify user@example.com 123456 ``` Creates a server-managed wallet through [Privy](https://privy.io). Signing is requested through [fibx-server](https://github.com/Fibrous-Finance/fibx-server); the private key is never returned to the CLI. Privy evaluates its own signing policy — chain allowlist, native-value cap, key-export denial — at signing time, on top of the local policy below. Sessions are JWTs with a 7-day expiry. ### An imported private key ```bash theme={null} npx fibx@latest auth import ``` Interactive: paste the key at the prompt; it cannot be passed as an argument. The key is encrypted at rest with AES-256-GCM and used to sign locally. This path runs unattended and needs no server — and **the local policy is the only thing bounding what it signs**. Set one before the first transaction. With an imported key, no policy means nothing limits what this wallet will sign. `fibx policy show` says so in as many words. ## The local signing policy A JSON file the user owns, stored beside the session as `policy.json` in the FibX config directory (`~/.config/fibx-nodejs/` on Linux, `~/Library/Preferences/fibx-nodejs/` on macOS), written with mode `0600`. FibX evaluates it **before every signature on all three paths** — in a wrapper around the local-key and Privy signers, and in the WalletConnect provider before a request reaches the relay. | Rule | Meaning | Example | | ----------------------------- | ---------------------------------------------------------- | ---------------------------------------- | | `.maxValue` | Largest native value (ETH / HYPE / MON) in one transaction | `base.maxValue 0.05` | | `allowedChains` | Chains anything may be signed on | `allowedChains base,monad` | | `.allowedDestinations` | Addresses anything may be sent to on that chain | `base.allowedDestinations 0xAbC…,0xDeF…` | | `expiry` | When the whole policy stops applying (ISO-8601) | `expiry 2026-12-31T00:00:00Z` | ```bash theme={null} # Show the active policy, or that there is none npx fibx@latest policy show # Set one rule — replaces that rule's previous value npx fibx@latest policy set base.maxValue 0.05 npx fibx@latest policy set allowedChains base,monad npx fibx@latest policy set base.allowedDestinations 0xAbC...,0xDeF... # Remove one rule, or the whole policy (asks for confirmation) npx fibx@latest policy clear base.maxValue npx fibx@latest policy clear ``` Three states, not two: * **Absent** — no file. Everything is permitted. * **Active** — the rules apply. A transaction outside them is refused before any signature is requested, with `POLICY_BLOCKED` and the rule and limit named. * **Unreadable** — a file exists but cannot be parsed. **Everything is refused** until it is fixed or cleared. This is deliberately distinct from absent; a corrupt policy must not fail open. **`maxValue` bounds the native value only.** An ERC-20 transfer reaches the policy as a call to the token contract with `value: 0`, so the cap never sees the token amount. `allowedDestinations` is what bounds where tokens may go. The product argument is that this file is the user's, on the user's machine, in front of every signing path — including the one where a misbehaving model is the threat it exists for. It is a file, so it is worth nothing against something that can already write to the user's disk. Over MCP the same file is read and edited by `get_policy`, `set_policy_rule` and `clear_policy_rule`, and the FibX app shows it as a collapsible section. ## Session management ```bash theme={null} # Which path is active, the address, and Fibrous API health npx fibx@latest status # The active wallet address npx fibx@latest address # End the session (also ends a WalletConnect pairing) npx fibx@latest auth logout ``` Sessions live in `session.json` beside the policy. Set `FIBX_SESSION_SECRET` (64-char hex) to use a custom encryption key instead of the per-machine one, for CI or Docker. # Supported Chains Source: https://docs.fibrous.finance/fibx-agent/supported-chains Chain-specific reference for FibX — native tokens, CLI flags, feature availability, and block explorers. FibX supports three EVM-compatible chains. Commands that accept `--chain` default to **Base**; portfolio spans all supported chains, while Aave always targets Base. ## Chain Overview | Chain | Native Token | Chain ID | CLI Flag | Aave V3 | | -------- | ------------ | -------- | ------------------ | ------- | | Base | ETH | 8453 | `--chain base` | Yes | | HyperEVM | HYPE | 999 | `--chain hyperevm` | No | | Monad | MON | 143 | `--chain monad` | No | Citrea was delisted by Fibrous on 2026-08-10 and withdrawn from FibX in v0.10.0. `--chain citrea` is refused, and the portfolio no longer queries it. ## Chain Details Base is Coinbase's Layer 2 network built on the OP Stack. It is the default for chain-aware FibX commands and the only chain with Aave V3 support. | Property | Value | | ------------ | -------------------------------- | | Native Token | ETH | | Chain ID | 8453 | | CLI Flag | `--chain base` | | Aave V3 | Yes | | Explorer | [BaseScan](https://basescan.org) | ```bash theme={null} # Base-default commands, cross-chain portfolio, and Base-only Aave npx fibx@latest balance npx fibx@latest portfolio npx fibx@latest trade 0.1 ETH USDC npx fibx@latest aave markets npx fibx@latest aave supply 100 USDC ``` HyperEVM is the EVM-compatible execution environment within the Hyperliquid ecosystem, enabling smart contract deployment alongside Hyperliquid's high-performance order book. | Property | Value | | ------------ | ---------------------------------------- | | Native Token | HYPE | | Chain ID | 999 | | CLI Flag | `--chain hyperevm` | | Aave V3 | No | | Explorer | [HyperEVM Scan](https://hyperevmscan.io) | ```bash theme={null} npx fibx@latest balance --chain hyperevm npx fibx@latest trade 1 HYPE USDC --chain hyperevm npx fibx@latest send 0.5 0xRecipient HYPE --chain hyperevm ``` Monad is a high-performance EVM-compatible Layer 1 blockchain designed for parallel transaction execution, delivering high throughput while maintaining full Ethereum compatibility. | Property | Value | | ------------ | --------------------------------------- | | Native Token | MON | | Chain ID | 143 | | CLI Flag | `--chain monad` | | Aave V3 | No | | Explorer | [Monad Vision](https://monadvision.com) | ```bash theme={null} npx fibx@latest balance --chain monad npx fibx@latest trade 1 MON USDC --chain monad npx fibx@latest send 5 0xRecipient MON --chain monad ``` ## Feature Availability by Chain | Feature | Base | HyperEVM | Monad | | ------------------- | ---- | -------- | ----- | | Balance Check | Yes | Yes | Yes | | Portfolio View | Yes | Yes | Yes | | Token Transfers | Yes | Yes | Yes | | Token Swaps | Yes | Yes | Yes | | Signing Policy Cap | Yes | Yes | Yes | | Aave V3 | Yes | No | No | | Aave Markets | Yes | No | No | | Tx Status | Yes | Yes | Yes | | Send/Trade Preview | Yes | Yes | Yes | | Aave Action Preview | Yes | No | No | | JSON Output | Yes | Yes | Yes | ## Selecting a Chain Use `--chain` with chain-aware commands such as `quote`, `status`, `balance`, `send`, `trade`, and `tx-status`. Aave commands always target Base, `portfolio` queries every supported chain, and `address`/`wallets` are chain-independent. ```bash theme={null} # Explicit chain selection npx fibx@latest trade 0.1 ETH USDC --chain base npx fibx@latest balance --chain monad # Shorthand with -c npx fibx@latest balance -c hyperevm ``` # 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 |