Type/to search
Built-in Functions
Structures
Built-in Variables and Constants
Conventions
Exchanges
Capability Matrix
Centralized Exchanges
Decentralized Exchanges (DEX)
Prediction Markets
Securities and Futures
On-chain & Custom

Bridge tokens from Solana to EVM chains through bridges aggregated by LI.FI: list chains and tokens, quote, simulate, send and track progress.

exchange.IO(k)
exchange.IO(k, chain)
exchange.IO(k, params)
exchange.IO(k, signature)
exchange.IO(k, signature, options)
exchange.IO(k, key)

Examples

  • List the supported chains and find USDC on Arbitrum (read-only).

    javascript
    function main() { var chains = exchange.IO("bridge.chains") if (!chains) { Log("Query failed:", GetLastError()) return } Log(chains.length, "chains:", chains.slice(0, 8).map(function(c) { return c.key }).join(",")) var tokens = exchange.IO("bridge.tokens", "arb") || [] var usdc = tokens.filter(function(t) { return t.symbol == "USDC" })[0] Log("USDC on Arbitrum:", usdc ? usdc.address : "not found") }
  • Quote bridging 50 USDC to Arbitrum and simulate it (read-only).

    javascript
    var TO = "" // your recipient address on Arbitrum (0x...) function main() { if (!TO) { Log("Set TO to your address on the destination chain first") return } var q = exchange.IO("bridge.quote", {toChain: "arb", fromToken: "USDC", toToken: "USDC", amount: 50, toAddress: TO}) if (!q) { Log("Quote failed:", GetLastError()) return } Log("via", q.toolName, "receive", q.toAmount, "at least", q.toAmountMin, "in about", q.executionDuration, "s") q.feeCosts.forEach(function(f) { Log("fee", f.name, f.amount, f.token, f.included ? "included" : "extra") }) var sim = exchange.IO("bridge.simulate", q) Log("Simulation:", sim ? "passed, compute units " + sim.unitsConsumed : GetLastError()) }
  • Full flow: quote → simulate → send → poll the progress.

    javascript
    var TO = "" // your recipient address on Base (0x...) function main() { if (!TO) { Log("Set TO to your address on the destination chain first") return } var params = {toChain: "base", fromToken: "USDC", toToken: "USDC", amount: 20, toAddress: TO} var q = exchange.IO("bridge.quote", params) if (!q || !exchange.IO("bridge.simulate", q)) { Log("Quote or simulation failed:", GetLastError()) return } var r = exchange.IO("bridge.send", q) if (!r) { Log("Send failed:", GetLastError()) return } Log("Sent", r.txHash, "expected", r.toAmount, "USDC") while (true) { Sleep(20 * 1000) var s = exchange.IO("bridge.status", r.txHash, {toChain: "base", bridge: r.tool}) if (!s) { continue } LogStatus(_D(), s.status, s.substatus || "") if (s.status == "DONE" || s.status == "FAILED" || s.status == "INVALID") { Log("Result", s.status, s.substatus, "received", s.receiving ? s.receiving.amount : "-") break } } }

Returns

TypeDescription

array / object / bool / null value

bridge.chains and bridge.tokens return arrays, bridge.apiKey whether a key is set, the others objects; fields in the remarks. A null value is returned for bad parameters, no route, a failed simulation or a rate-limited request, with the reason in GetLastError().

Arguments

NameTypeRequiredDescription

k

string

Yes

The command: bridge.chains, bridge.tokens, bridge.quote, bridge.simulate, bridge.send, bridge.status or bridge.apiKey.

chain

string / number

No

The chain bridge.tokens lists: a chain ID, a LI.FI chain key (such as arb) or a chain name; Solana by default.

params

object

No

The bridge parameters {toChain, fromToken, toToken, amount, toAddress, slippage, order, allowBridges, denyBridges} of bridge.quote, bridge.simulate and bridge.send, see the remarks; the latter two also accept a bridge.quote result.

signature

string

No

For bridge.status: the source-chain transaction signature txHash returned by bridge.send.

options

object

No

{toChain, bridge} for bridge.status, to speed up the lookup.

key

string

No

For bridge.apiKey: the LI.FI API key, "" to clear it; without it, query only.

See Also

Remarks

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.

Quotes and transactions come from LI.FI (aggregating Across, Stargate, CCTP, deBridge, Mayan, Relay, NEAR Intents and other bridges); LI.FI returns a serialized Solana transaction, which the docker signs with this wallet (refusing one this wallet does not sign), simulates and broadcasts through the Solana node. Requests carry the integrator tag integrator=fmz and no extra fee; fees such as LIFI Fixed Fee in a quote belong to LI.FI and the bridges and are already counted in toAmount.

Bridge parameters
KeyRequiredDescription
toChainyesDestination chain: a chain ID, a LI.FI chain key (such as arb) or a name (such as Arbitrum or Base, case-insensitive). It cannot be Solana (this chain; swap on the same chain with exchange.CreateOrder())
fromTokenyesA token on Solana: a name in the token table or a mint address
toTokenyesA token on the destination chain: a name or address resolved by LI.FI to its canonical token (USDC on Arbitrum is native USDC, not USDC.e)
amountyesThe amount of fromToken in token units; digits beyond the token's decimals are dropped
toAddressyesThe recipient on the destination chain (an 0x address, checked for format); all destinations are EVM chains where this wallet has no address, so it must be given
slippagenoSlippage ratio, [0, 0.5), defaults to the exchange.IO("slippage") value
ordernoCHEAPEST or FASTEST
allowBridges, denyBridgesnoUse only, or never, these bridges (LI.FI bridge names, an array or comma-separated)

Unknown keys are errors. Given a bridge.quote result, the quote is redone from its request (the parameters as given).

Results
  • bridge.chains: [{id, key, name, chainType, nativeToken}], chainType being EVM or SVM, cached for an hour.
  • bridge.tokens: [{symbol, address, decimals, name, priceUSD}], cached for an hour.
  • bridge.quote: {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 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 null on Solana; steps lists the steps (cross bridges, swap swaps, protocol is LI.FI's fee).
  • bridge.simulate: re-quotes, signs with this wallet and runs simulateTransaction (with signature verification) without broadcasting; returns the bridge.quote result plus simulated (true), unitsConsumed and signature. A failed simulation is an error whose message gives the reason (AccountNotFound means the wallet has no SOL) and the wallet balance.
  • bridge.send: re-quotes → checks the balance → signs → simulates → broadcasts, without waiting for confirmation; returns {txHash, tool, fromChain, toChain, toChainName, fromToken, toToken, fromAmount, toAmount, toAmountMin, toAddress, transactionId}, txHash being the source-chain signature, whose state exchange.IO("receipt") returns. Quotes move; the new quote at sending applies.
  • bridge.status: LI.FI's /status, returning {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 (returned to the source chain); sending and receiving are {txHash, txLink, chainId, amount, amountRaw, token, timestamp}. Right after broadcasting LI.FI may not have indexed the transfer and returns NOT_FOUND; keep polling.
  • bridge.apiKey: sets the LI.FI API key (header x-lifi-api-key, for this exchange object only, never echoed) and returns whether a key is set (a boolean).

Rate limits and risks
  • Without an API key LI.FI rate-limits by outgoing IP: /quote 75 times per two hours (bridge.quote, bridge.simulate and bridge.send each use one), other endpoints 100 per minute, shared by the strategies on one docker; with a key, 100 per minute. A rate-limited call fails with rate limited (HTTP 429 …).
  • Bridging is asynchronous: when bridge.send returns only the source transaction has been broadcast; delivery takes seconds to tens of minutes (see the quote's executionDuration), so poll bridge.status to confirm.
  • Funds sent to a wrong address cannot be recovered; bridge contracts and cross-chain messaging carry each bridge's own security risk; the destination wallet needs gas to use what arrives. Test with a small amount first.