Skip to main content
Alpha Preview — Endpoints, response shape, and supported routes may change without notice.
Full API reference as one Markdown file: bridge-all.md. Copy it, or feed it to your LLM as context for the entire bridge surface in one paste.
This page is one self-contained TypeScript file that calls the Mobula Bridge API directly (no SDK). It exposes a single bridge() function that handles every origin chain — EVM, Solana, and HyperLiquid — and the bottom of the page calls it for several different routes you can mix and match. The flow is: GET /quote (preview) → for evm:* and hl:mainnet origins, sign the returned EIP-712 typedData and re-call /quote to commit the signature → broadcast the returned deposit → long-poll GET /status/{intentId}/wait until terminal. (Solana origins skip the signature — the depositor-signed memo carries the binding.)

Install

bridge.ts

Copy this entire block as one file. It exports bridge(params, signers, apiKey) which works for every supported route.

Multi-route example

This is one driver script that bridges across four different route shapes using the bridge() function above. It exercises every code path (native, direct-bridge token with approval, swap-and-bridge, Solana, HyperLiquid).

How each route maps to a code path

The bridge() function above auto-dispatches by inspecting quote.deposit and quote.steps — you don’t pick the path manually.

Notes worth knowing

  • No client-side sleep when polling /status/{id}/wait. The server already blocks server-side and resolves the long-poll the instant the intent goes terminal (default 30 s window, capped 60 s). Re-firing the request immediately keeps one connection always waiting on the next state change.
  • Approvals are MAX_UINT256. One approve per (token, spender) is enough forever — read the on-chain allowance(owner, spender) and skip the approve step if it’s already non-zero (or above your amount).
  • Stale /wait responses. If you start a new bridge while a previous /wait is in flight, the previous response can land after your new intentId is active. Track the active intent on your side and discard any /wait result that doesn’t match it.
  • Hyperliquid fills complete before their tx hash exists. An HL-destination fill is final the moment the funds leave HL, but HL assigns the canonical L1 hash a moment later — so a filled response can carry fillTxHash: null with fillTxHashPending: true. Show “complete” as soon as status is filled; don’t block on the hash. Fetch the hash afterward with a second long-poll, GET /status/{id}/wait?waitForFillTxHash=true, and patch your explorer link when it lands. See Bridge Status → best practice.
  • No fixed per-intent cap. The old maxTradeUsd: 400 limit was removed — trade size is now bounded by the solver’s available inventory on the destination route. An intent the solver can’t source is refunded, so always handle the refunded terminal state rather than assuming a fixed ceiling.
  • Optional integrator fee (feeBps + feeWallet). Pass both to skim a cut for yourself: feeBps is your fee in basis points (0–500, i.e. up to 5%) and feeWallet is where it’s paid. The fee is paid in USDC on the destination chain at fill time, so feeWallet must be a valid destination-ecosystem address (0x for EVM/HL destinations, base58 for Solana) — a mismatch is rejected. It’s already folded into the signed minAmountOut, so the recipient still receives exactly estimatedAmountOut; the fee comes out of the bridged amount, not on top. When set, the quote’s fees object echoes back integratorFeeBps and integratorFeeUsd.
  • Honor recommendedSlippage or risk a refund. Every quote returns a recommendedSlippage (%) — the measured price impact of the quote’s swap leg(s) plus any fee-on-transfer tax plus a 1% drift buffer, with a 2% floor on native-token destinations (bridge fee and gas are already deducted from the quoted output, not part of slippage). The solver refunds any fill that lands below the signed minAmountOut (failure code slippage), so signing with a tolerance under recommendedSlippage is a near-guaranteed refund. The bridge() function above re-quotes at the recommendation automatically.
  • Fees are real and already deducted from estimatedAmountOut. The quote’s fees object breaks them down: bridgeFeeUsd (protocol fee, bridgeFeeBps, currently 5), destFillGasUsd (what the solver pays to fill on the destination chain), and destActivationCostUsd (present only when the destination needs a one-off account-creation cost — e.g. Solana ATA rent for a first-time recipient). gasFeeUsd equals destFillGasUsd, and totalFeeUsd is bridgeFeeUsd + gasFeeUsd (+ the integrator cut when you set one) — activation cost is deducted from the output but not folded into totalFeeUsd. estimatedAmountOut / estimatedAmountOutUsd are net of every fee — the recipient receives exactly that. The user additionally pays only origin-chain gas to broadcast the deposit; the solver pays the destination fill gas itself.

See also