Type/to search
Built-in Functions
Structures
Built-in Variables and Constants
Conventions
Exchanges
Capability Matrix
Centralized Exchanges
Decentralized Exchanges (DEX)
Hyperliquid
Lighter
edgeX
Aster
Aevo
Pendle
WOOFi Pro
Uniswap / PancakeSwap
Aerodrome / Velodrome
exchange.IO("lp.stake", ...)
exchange.IO("lp.unstake", ...)
exchange.IO("lp.claim", ...)
KyberSwap
1inch
EVM DEX Common Commands
Jupiter
OKX DEX
DEX Strategy Examples
Prediction Markets
Securities and Futures
On-chain & Custom

The Aerodrome and Velodrome exchange objects use the same contracts, each connecting to that exchange's pools on one chain and mapping on-chain swaps onto the spot trading functions; pool kinds, swaps and LP work the same way, so they share this page. The chain is fixed; the configuration has no Chain option (an old-style configuration carrying another Chain fails at startup). Uses Slipstream concentrated-liquidity pools (both the old and the new deployment, pools distinguished by tick spacing, fees set by each pool) and basic pools (volatile is constant product, stable is the stablecoin curve). Basic pools support exact input only: limit buys (filled by the amount bought) can only go through Slipstream pools. Both kinds support LP and staking in gauges for rewards. The differences:

AspectAerodromeVelodrome
ChainBaseOP Mainnet
Gauge reward tokenAEROVELO
Slipstream position IDsaero:number (old factory), aero2:number (new factory)velo:number (old factory), velo2:number (new factory)
This exchange's contracts in exchange.IO("contracts")aerodromevelodrome

Each swap takes the best-quoted route among the direct routes through all available pools and the two-hop routes through hub tokens. The basic pools and the two Slipstream generations each have their own router contract, and tokens are approved to the router used by the swap at hand.

The same implementation also serves Uniswap / PancakeSwap and the swap aggregators KyberSwap and 1inch, with the same token table, balances, approvals, orders, cancels, transfers and bridge. Aerodrome and Velodrome used to be options of the Uniswap exchange's "DEX" setting and are separate exchanges since October 2026; configurations that chose them on the Uniswap exchange fail at startup, so add the dedicated exchange instead.

Names and Configuration
exchange.GetName()TypeAliases
AerodromeSpotAero
VelodromeSpotVelo
FieldRequiredDefault
---
Private KeyYes—
Rpc AddressNoAerodrome: https://mainnet.base.org,https://base-rpc.publicnode.com; Velodrome: https://mainnet.optimism.io,https://optimism-rpc.publicnode.com
Rpc Api KeyNo—

The rest of the longer descriptions in the table:

  • Rpc Address: Order states need a node that returns receipts of mined transactions; the publicnode public nodes for Base, BNB Chain and Arbitrum cannot (archive access is required), so do not use them alone.

Trading Pairs and Contract Codes

Pair examples: ETH_USDC, WETH_USDC

Pairs are written as ETH_USDC; the native coin (ETH) and its wrapped token (WETH) are different assets.

Tokens outside the token table can be used in pairs after registering them with exchange.IO("token", name, address).

Exchange-specific IO Commands
CommandArgumentsDescriptionReturns
transferto, amount[, token]Transfer the native coin or an ERC20 token out of the configured wallet (token is a token name or contract address, the native coin when omitted); amount may be all (the native coin keeps the fee). Waits for the broadcast only, not for confirmation. See the sub-page exchange.IO("transfer", ...).{txHash, from, to, token, tokenAddress, amount, raw}
receipttxHash[, waitMs]Query the receipt of any transaction on this chain (not only those sent by this exchange object), optionally waiting for confirmation (up to 10 minutes). For an order, pass the transaction hash after the comma in the order ID. See the sub-page exchange.IO("receipt", ...).{txHash, status, blockNumber, gasUsed, fee} once mined (status is success or reverted), {txHash, pending: true, known} otherwise.
routesymbol, side, qtyQuote only, no order: lists the quote of every candidate route of a swap and the best route. qty is always in the base token: sell sells qty as exact input and buy buys qty as exact output (unlike a market buy, which is sized in the quote token). See the sub-page exchange.IO("route", ...).{symbol, side, qty, best, quote, price, candidates}
simulatesymbol, side, qty[, price[, stateOverride[, route]]]Build the swap transaction with the order logic (route selection, quoting, price protection) and only simulate it with eth_call; nothing is signed, broadcast or paid. See the sub-page exchange.IO("simulate", ...).{route, exactIn, amountIn, amountOut, quoted, executed, value, calls}, plus allowanceOverride when an allowance was supplied.
token[name, address]Register a token so it can be used in pairs; without arguments, list the token table. See the sub-page exchange.IO("token", ...).{symbol, address, decimals} when registering, an array of {symbol, address, decimals, native} when listing.
wrapamountWrap the native coin into its wrapped token (e.g. ETH→WETH), 1:1 without slippage, gas only; all is not accepted (gas must remain). See the sub-page exchange.IO("wrap", ...).{txHash, action, from, to, amount, raw}
unwrapamountUnwrap the wrapped token into the native coin (e.g. WETH→ETH); amount may be all. See the sub-page exchange.IO("unwrap", ...).{txHash, action, from, to, amount, raw}
approve["exact" | "max"]Token approval mode: exact (default) approves only what the swap needs, max grants an unlimited allowance. Queries when called without an argument. See the sub-page exchange.IO("approve", ...).The current mode.
slippage[ratio]Slippage protection of market orders, range [0, 0.5), default 0.005 (0.5%). Queries when called without an argument. See the sub-page exchange.IO("slippage", ...).The current slippage ratio.
deadline[seconds]Transaction deadline in seconds, 10 to 86400, default 120. Queries when called without an argument. See the sub-page exchange.IO("deadline", ...).The current deadline (seconds).
cancelWait[seconds]How long a cancel waits for the result, in seconds, 0 to 600, default 30; 0 returns right after the cancel transaction is sent. Queries when called without an argument. See the sub-page exchange.IO("cancelWait", ...).The current wait time (seconds).
gasMultiplier[x]Gas limit multiplier, 1 to 5, default 1.2; a transaction's gasLimit is the node's gas estimate times this value. See the sub-page exchange.IO("gasMultiplier", ...).The current multiplier.
base[url]Without an argument, returns the current node address; with an address, switches the node. Several nodes are written as one comma-separated string (with an array only the first address is used). After a switch, the first request checks which chain the node is on and fails if it is not the configured chain.The previous address.
sendBaseurlSet a node used only to broadcast transactions (a private transaction channel). Unlike Web3, it does not return the previous address, does not query when called without an argument, and an empty string does not clear the setting.true
address—The wallet address of the configured private key (lowercase, starting with 0x).—
contracts—The exchange's deployment on its chain; contract addresses, fee tiers and the built-in token list snapshot.An object: dex, chainId, chain, router, quoterV2, v3Factory, v3Fees, positionManager, v2Factory, v2Fee (in millionths, 3000 = 0.3%), wrappedNative, v4, tokenList (the token list snapshot's build time embeddedAt, token count tokens and common-token count core); deployments absent on the chain are null. (more below the table)
lp.poolstoken[, quote]Lists every Slipstream and basic pool of a token (against the given quote, or the chain's wrapped native, USDC and USDT) with fee tier, tick spacing, current price, liquidity, both token balances of the pool and TVL; 24h volume and fees come from GeckoTerminal (null when unavailable; cached in the process for 5 minutes and shared with lp.select and lp.plan, with one retry after a pause when rate-limited). See the sub-page exchange.IO("lp.pools", ...).[{id, protocol, dex, symbol, fee, feeRate, tickSpacing, tick, price, liquidity, reserveBase, reserveQuote, tvlQuote, tvlUsd, volume24hUsd, fees24hUsd, empty}], where price is quote per token. (more below the table)
lp.selecttoken, budget[, options]Picks a pool by rule among those lp.pools lists: with options.fee, the pool of that fee tier is used when it meets the liquidity threshold (only that tier when exact is true); otherwise, among pools whose TVL is at least max($5000, budget), the one with the largest 24h volume, or the largest TVL without volume data. See the sub-page exchange.IO("lp.select", ...).One lp.pools row with an extra reason.
lp.poolpoolIdLive state of a pool. See the sub-page exchange.IO("lp.pool", ...).{id, protocol, currency0, currency1, token0, token1, fee, tickSpacing, tick, sqrtPriceX96, price0, price1, liquidity}, where price0 is token1 per token0.
lp.tickspoolId, tickLower, tickUpper[, step]Liquidity distribution over a tick range, with each segment's liquidity and amounts of both tokens (summed over initialized ticks inside it); step is the segment width in ticks (the tick spacing by default). Ranges wider than 120 bitmap words are refused. See the sub-page exchange.IO("lp.ticks", ...).{pool, tick, token0, token1, segments: [{tickLower, tickUpper, price0Lower, price0Upper, liquidity, amount0, amount1, current}]}
lp.planparamsA position plan (read-only, costs nothing). See the sub-page exchange.IO("lp.plan", ...).{params, symbol, pool, protocol, fee, tickSpacing, tick, price, shape, budget, budgetUsd, positions: [{tickLower, tickUpper, priceLower, priceUpper, liquidity, amountBase, amountQuote, share}], needBase, needQuote, haveBase, haveQuote, swap, payWith, shortfall, shareOfPool, volume24hUsd, estDailyFeesUsd, slippageBps, layers, layersRequested, warning?}; swap is the swap needed before adding ({side, amount, currency} or null). (more below the table)
lp.simulateplan[, stateOverride]Runs the plan's add-liquidity transaction with eth_call (no signing, no broadcast) to confirm it executes and see the amounts used. See the sub-page exchange.IO("lp.simulate", ...).{pool, positions: [{liquidity, amountBase, amountQuote}], value, swapNeeded, note}
lp.addplanAdds liquidity by the plan, swapping first with a market order when needed, approving, and creating every position in one transaction; returns after it is mined. See the sub-page exchange.IO("lp.add", ...).{txHash, swapTxHash, pool, positions: [{id, tickLower, tickUpper, priceLower, priceUpper, liquidity, amountBase, amountQuote}]}
lp.increasepositionId, budget[, options]Adds to a position, splitting budget (in the quote token) by the position's range and the current price and swapping first for whichever token is short. See the sub-page exchange.IO("lp.increase", ...).{txHash, swapTxHash, id, liquidity, amountBase, amountQuote}
lp.decreasepositionId, ratio[, options]Withdraws a ratio (0 to 1) of a position's liquidity and collects all its fees; the position stays. See the sub-page exchange.IO("lp.decrease", ...).{txHash, positions: [{id, symbol, principalBase, principalQuote, feesBase, feesQuote, receivedBase, receivedQuote}], sells}
lp.collectpositionIds[, sell]Collects fees, several positions in one transaction; with sell true the collected token is sold for the quote. Staked positions earn no trading fees (they go to voters), so they fail with a hint to claim the rewards with lp.claim; basic pools collect the fees accrued to the wallet's LP tokens with the pool's claimFees, one transaction per pool. See the sub-page exchange.IO("lp.collect", ...).Same as lp.decrease.
lp.removepositionIds[, ratio[, sell]]Withdraws liquidity and collects fees, several positions in one transaction; ratio defaults to 1 (withdraw everything and burn the position NFT), below 1 only that share is withdrawn; with sell true the returned token is sold for the quote. See the sub-page exchange.IO("lp.remove", ...).Same as lp.decrease.
lp.positions[filter[, wallet]]Every Slipstream and basic-pool position of the wallet with range, in-range flag, liquidity, current amounts and value, and uncollected fees. See the sub-page exchange.IO("lp.positions", ...).[{id, pool, protocol, symbol, fee, tickLower, tickUpper, priceLower, priceUpper, price, tick, inRange, liquidity, amountBase, amountQuote, value, feesBase, feesQuote, feesValue, closed}], with value and feesValue in the quote token.
lp.historypositionIdA position's cash flow: deposits, withdrawn principal, collected fees, and PnL valued at the current pool price (current value + collected fees + withdrawn principal − deposits, gas excluded). Needs a node that serves historical logs; public nodes often do not. Basic-pool LP tokens have no per-position events and are not supported. See the sub-page exchange.IO("lp.history", ...).{id, symbol, events: [{action, block, txHash, liquidity, amountBase, amountQuote}], depositedBase, depositedQuote, withdrawnBase, withdrawnQuote, feesCollectedBase, feesCollectedQuote, price, pnlQuote, note}
lp.trackpositionIdsRegisters Slipstream positions ((Aerodrome: aero:number, aero2:number; Velodrome: velo:number, velo2:number); a prefix that does not match the exchange object is an error) and basic pool addresses so that lp.positions checks them (ownership is verified on chain each time, staked positions by their staker; transferred-away positions are not listed). See the sub-page exchange.IO("lp.track", ...).Every position ID remembered by this process.
lp.stakepositionIdsStakes positions in their pool's gauge for rewards, one transaction per position. See the sub-page exchange.IO("lp.stake", ...).{positions: [{id, gauge, approveTxHash, txHash, feesBase, feesQuote}]}; for basic pools {id, gauge, txHash, lpTokens}.
lp.unstakepositionIdsTakes positions out of the gauge. A Slipstream position NFT comes back together with its accrued rewards; a basic pool returns all staked LP tokens and leaves the rewards in the gauge for lp.claim. One transaction per position. See the sub-page exchange.IO("lp.unstake", ...).{positions: [{id, gauge, txHash, rewards}]}, where rewards is the reward tokens received in that transaction; basic pools also have lpTokens.
lp.claimpositionIds[, sell]Claims rewards with one Voter.claimRewards covering the wallet's rewards in the gauges of these positions (the wallet's other staked positions in the same gauges are claimed too); with sell true the reward token is sold for USDC at market. See the sub-page exchange.IO("lp.claim", ...).{txHash, gauges, rewardToken, rewards, sell}, where rewardToken is (Aerodrome: AERO; Velodrome: VELO).
bridge.chains—Chains supported by the bridge (LI.FI): EVM chains and Solana, cached for an hour. See the sub-page exchange.IO("bridge.*", ...).An array of {id, key, name, chainType, nativeToken}, chainType being EVM or SVM.
bridge.tokens[chain]Tokens LI.FI knows on a chain (this chain by default), cached for an hour. See the sub-page exchange.IO("bridge.*", ...).An array of {symbol, address, decimals, name, priceUSD}.
bridge.quoteparamsA bridge quote (read-only) from this exchange object's chain. See the sub-page exchange.IO("bridge.*", ...).{tool, toolName, fromChain, toChain, toChainName, fromToken, toToken, fromAmount, toAmount, toAmountMin, fromAmountRaw, toAmountRaw, toAmountMinRaw, fromAmountUSD, toAmountUSD, slippage, toAddress, feeCosts, gasCosts, executionDuration, approvalAddress, steps, transactionId, request}: amounts are in token units (*Raw in the smallest unit); toAmountMin is the amount guaranteed after slippage; feeCosts is [{name, amount, token, amountUSD, percentage, included}] (fees with included false are paid on top); gasCosts estimates source-chain gas; executionDuration is the expected time in seconds; approvalAddress is the contract to approve (null for the native coin and on Solana); steps lists the steps (cross bridges, swap swaps); request echoes the parameters.
bridge.simulateparams|quote[, stateOverride]Re-quotes and runs LI.FI's transaction with eth_call: nothing is signed, broadcast or paid. See the sub-page exchange.IO("bridge.*", ...).The bridge.quote result plus simulated (true), to, value and walletBalance, and allowanceOverride when an allowance was supplied.
bridge.sendparams|quoteBridges out: re-quotes → checks the balance → approves LI.FI's approvalAddress when the token allowance is short (following exchange.IO("approve") exact/max, resetting USDT-like tokens to zero first, waiting for the approval to be mined and re-quoting after it) → simulates with eth_call → signs and broadcasts, with a gas limit of the larger of the eth_estimateGas estimate × gasMultiplier and LI.FI's suggested gasLimit (bridge contracts call into other contracts, so the estimate can fall short; only the gas used is charged). See the sub-page exchange.IO("bridge.*", ...).{txHash, tool, fromChain, toChain, toChainName, fromToken, toToken, fromAmount, toAmount, toAmountMin, toAddress, value, transactionId}; txHash is the source-chain transaction, whose receipt receipt returns.
bridge.statustxHash[, options]Bridge progress (LI.FI /status) for the source-chain transaction hash returned by bridge.send; options may give {toChain, bridge} to speed up the lookup. See the sub-page exchange.IO("bridge.*", ...).{status, substatus, substatusMessage, tool, sending, receiving, fromAddress, toAddress, explorer, bridgeExplorer}: status is NOT_FOUND, INVALID, PENDING, DONE or FAILED; when DONE, substatus is COMPLETED (delivered as quoted), PARTIAL (a different token arrived) or REFUNDED; sending and receiving are {txHash, txLink, chainId, amount, amountRaw, token, timestamp}, with receiving.amount and receiving.token being what actually arrived.
bridge.apiKey[key]Sets the LI.FI API key (header x-lifi-api-key, for this exchange object only, never echoed); "" clears it and no argument just queries. Without a key requests are rate-limited per outgoing IP, see below. See the sub-page exchange.IO("bridge.*", ...).Whether a key is set (a boolean).

The rest of the longer descriptions in the table:

  • contracts returns: router is the basic-pool Router, quoterV2 and v3Factory are the first Slipstream generation's QuoterV2 and factory, v3Fees is empty and v2Fee 0, and v2Factory, positionManager and v4 are null; this exchange's contracts are under (Aerodrome: aerodrome; Velodrome: velodrome): the basic-pool router and poolFactory, and each Slipstream generation's factory, swapRouter, quoterV2 and tickSpacings.

For the common command currency see exchange.IO.

The common command api is not supported (the call fails with an error and returns null).

Function Support

Not supported (the call fails with an error and returns null): exchange.GetTickers, exchange.GetHistoryOrders, exchange.ModifyOrder, exchange.CreateConditionOrder, exchange.ModifyConditionOrder, exchange.CancelConditionOrder, exchange.GetConditionOrder, exchange.GetConditionOrders, exchange.GetHistoryConditionOrders.

Served through a fallback:

  • exchange.GetRecords: Native periods are 1m, 5m, 15m, 1h, 4h, 12h, 1d (GeckoTerminal's timeframes); other periods are synthesized by the docker: periods of a minute or longer are merged from native periods, and second-level periods are accumulated from the on-chain trades of exchange.GetTrades() (the first call has only the bars covered by the trades of roughly the last 10 minutes, and later calls keep accumulating; with no trade seen yet the call fails saying so, and when fetching trades fails the error carries that cause).

Notes
FunctionBehavior
exchange.GetTicker()Bid and ask are executable prices for about $1000; on-chain pools have no 24h statistics. Each side takes its own best pool, and when they occasionally cross both sides report the mid price, with Info.crossed giving how far they crossed
exchange.GetDepth()Derived from on-chain quotes at increasing sizes, from about $1000 up to $1 million; 5 levels by default, at most 10. Each side takes its own best pool, so the book can occasionally cross across pools (best bid above best ask); crossed prices are then reported at the mid price with quantities unchanged, and Info.crossed gives the mid price and how far it crossed
exchange.GetTrades()On-chain trades of all pools of the pair in roughly the last 10 minutes of blocks, at most 500 per call
exchange.GetRecords()K-lines come from GeckoTerminal's pool-level data: the pair's pool on this exchange with the largest USD liquidity on GeckoTerminal (Slipstream and basic pools are all compared, and a pair written with the native coin also counts the wrapped-token pools; the chosen pool is cached for an hour). Prices are that pool's trade prices (including the pool fee, so they may differ from the mid price of exchange.GetTicker() by about one pool fee) in quote per base, and Volume is in the base token; periods without trades repeat the previous close with zero volume, and the last bar may still be open. GeckoTerminal data lags by tens of seconds up to a minute and its public API allows about 10 requests per minute: bars of the same period are cached for a minute, requests queue inside the docker and wait and retry when rate-limited, and fail if that still does not succeed. Fails when GeckoTerminal lists no pool of the pair on this exchange
exchange.GetMarkets()Pairs of built-in and registered tokens that actually have a pool on chain; pairs with the wrapped token also get a row written with the native coin. TickSize is fixed at 1e-8, PricePrecision is 8, AmountPrecision is the token's decimals and MinNotional is 0
exchange.GetOrders()Only the swaps sent by this process that are not mined yet (kept in memory, cleared on restart)
exchange.GetAssets()Wallet balances of the native coin and of the tokens in the token table
exchange.CreateOrder()Swaps on chain immediately: a limit price is the worst acceptable fill, and an order whose limit the current quote cannot reach fails without sending a transaction; market orders are protected by the slippage setting; a market buy is sized in the quote currency. The order extra parameter slippage overrides the slippage for that order, and route restricts the route type: v2 is the basic pools and v3 Slipstream, hop and direct two-hop and direct routes (v4 does not apply)
exchange.GetOrder()The order ID looks like ETH_USDC,0x… (the pair, a comma, then the transaction hash); the state comes from the transaction receipt, and the order is reported as canceled once the nonce of the original transaction has been taken by the cancel transaction (or another transaction). The ID does not carry the chain, so Info contains chainId and the chain name chain for telling orders apart when aggregating across chains; querying on an exchange object of another chain fails with "not found on <chain>"
exchange.CancelOrder()Sends a replacement transaction with the same nonce (a zero-value transfer to itself) and waits for the result (at most 30 seconds by default, see exchange.IO("cancelWait", ...)): returns true if the cancel transaction lands first; if the original order is already mined or lands first, it returns false (the cancel did not happen, but this is not a call error), with the reason in GetLastError(); returns true on timeout, meaning the cancel has been submitted
Concentrated liquidity (LP)

The exchange.IO("lp.*", ...) commands provide concentrated liquidity on Slipstream and basic pools: pool selection, planning and simulation, adding, increasing and decreasing, fee collection, withdrawal and position queries, plus gauge staking for rewards. Slipstream pools (both factory generations) are concentrated-liquidity pools whose positions are NFTs of each generation's PositionManager, written prefix:number (old factory) or prefix2:number (new factory), the prefix being aero on Aerodrome and velo on Velodrome; each pool sets its own fee (possibly dynamic), and fee is the current value. An unstaked Slipstream position gives part of its fees (the pool's unstakedFee, mostly 5% today) to the gauge.

Basic pools (volatile, stable) are full-range: lp.plan without a range plans for a basic pool, both tokens are deposited in the reserve ratio, and the position is the pool's LP token with the pool address as id.

Gauge staking: lp.stake puts positions into the gauge for rewards, lp.unstake takes them out and lp.claim claims the rewards. While staked, trading fees go to voters and the position earns only the reward token (AERO on Aerodrome, VELO on Velodrome), and an out-of-range Slipstream position earns nothing; staked positions cannot be increased, decreased or have fees collected until taken out (lp.remove takes them out automatically). rewardAprPct in lp.pools extrapolates the current per-second rewards over the staked TVL and moves with the reward token's price and the staked amount; rewards are paid in the reward token, whose price is volatile, and sell in lp.claim converts them to USDC.

Write commands (lp.add, lp.increase, lp.decrease, lp.collect, lp.remove, lp.stake, lp.unstake, lp.claim) return after the transaction is mined, and for the next minute on-chain reads are pinned to no earlier than that transaction's block (load-balanced public nodes may otherwise answer from a machine that has not reached it), so the next command right after does not build its transaction on stale state. When adding liquidity the native coin keeps about 3 million gas at the current gas price for fees; the rest can be used for the position.

Monitoring and exits are left to the strategy: lp.positions reports whether each position is in range, its current value and uncollected fees, and the strategy decides when to rebalance or stop out (for a complete strategy that re-centers after leaving the range see LP Auto-Rebalancing; more in DEX Strategy Examples).

Risks:

  • Impermanent loss: the further the price moves from the entry price, the more the position lags simply holding; as the price rises the position sells the token, as it falls it buys.
  • Once the price leaves the range the position holds only one token and earns no fees until the price returns.
  • Every add, rebalance, collect and withdrawal is an on-chain transaction; frequent rebalancing can cost more gas than it earns in fees.
  • The estimated daily fees in a plan extrapolate the last 24h volume at the current pool share and do not predict future income.

For a complete strategy that stakes into a gauge and compounds the rewards, see Gauge Staking and Compounding.

Cross-chain bridge

exchange.IO("bridge.*", ...) bridges tokens from this exchange object's chain to another chain through the bridges LI.FI aggregates (Across, Stargate, CCTP, deBridge, Mayan, Relay, NEAR Intents and more), between EVM chains and between EVM and Solana (from this exchange object's chain). LI.FI supplies the quote and transaction, and the docker approves, simulates with eth_call, signs and broadcasts. Requests carry the integrator tag integrator=fmz and add no fee; fees in a quote such as LIFI Fixed Fee are LI.FI's and the bridges' own and are already deducted from toAmount.

Typical flow: bridge.quote for a quote → bridge.simulate to simulate → bridge.send to send → bridge.status every 10 to 30 seconds until DONE or FAILED.

  • Bridging is asynchronous: when bridge.send returns, only the source-chain transaction has been broadcast; delivery takes seconds to tens of minutes (see executionDuration in the quote) and must be confirmed by polling bridge.status; PARTIAL means a different token arrived on the destination chain and REFUNDED that the funds went back to the source chain.
  • Cross-VM transfers (EVM↔Solana) require toAddress, checked against the destination chain's address format; funds sent to a wrong address cannot be recovered.
  • Risks: the security of bridge contracts and cross-chain messaging rests with each bridge; quotes move, and bridge.send re-quotes before sending; the destination wallet needs gas to use what arrives. Test with a small amount first.
  • Rate limits: without an API key LI.FI limits by outgoing IP, /quote to 75 requests per 2 hours (bridge.quote, bridge.simulate and bridge.send use one each, plus one more when re-quoting after an approval) and other endpoints to 100 per minute; strategies on the same docker share the quota. With a key set through exchange.IO("bridge.apiKey", key) the limit is 100 per minute. A rate-limited call fails with rate limited (HTTP 429 …).

In this sectionRead the whole section

NameDescription
exchange.IO("lp.stake", ...)Aerodrome and Velodrome: stakes positions in their pool's gauge to earn the reward token (AERO or VELO) instead.
exchange.IO("lp.unstake", ...)Aerodrome and Velodrome: takes staked positions out of the gauge; Slipstream positions also claim their accrued rewards.
exchange.IO("lp.claim", ...)Aerodrome and Velodrome: claims the reward tokens accrued in the gauges of staked positions, optionally selling them for USDC.