Orkid

Cross-chain bridge

Bridge tokens between chains — non-custodial settlement via Across.

Orkid's bridge endpoints proxy Across for cross-chain settlement between Ethereum, Base, Arbitrum, and Polygon. The flow is non-custodial: Orkid never receives or holds user funds. The user signs the approval and deposit transactions directly against canonical Across contracts from their own wallet.

How it works

  1. GET /api/v1/bridge/chains — supported chains (all four Orkid chains)
  2. GET /api/v1/bridge/tokens?chainId= — curated bridgeable assets per chain
  3. POST /api/v1/bridge/quote — executable approvalTxns + swapTx the user signs
  4. GET /api/v1/bridge/status — deposit lifecycle (pending → filled / expired / refunded)
  5. POST /api/v1/bridge/track — register a submitted deposit for tracking

Unlike same-chain swaps, bridging does not use Permit2 and is not gasless in v1 — the user pays origin-chain gas and submits plain approve + deposit transactions.

Honest risk note: after the deposit transaction confirms, funds sit in Across escrow until a relayer fills (usually seconds). If a deposit can't be filled, it is refunded to the depositor's wallet on the origin chain — refunds can take a few hours. Orkid has zero custody at every step, but bridge settlement time is protocol-inherent.

GET /api/v1/bridge/chains

List the chains that support bridging. The list is filtered server-side to Orkid's production chains.

GET https://orkidlabs.xyz/api/v1/bridge/chains
X-ORKID-API-Key: <key>
{
  "ok": true,
  "chains": [
    { "chainId": 1, "name": "Ethereum", "publicRpcUrl": "...", "explorerUrl": "https://etherscan.io", "logoUrl": "..." },
    { "chainId": 8453, "name": "Base", "publicRpcUrl": "...", "explorerUrl": "https://basescan.org", "logoUrl": "..." },
    { "chainId": 42161, "name": "Arbitrum", "publicRpcUrl": "...", "explorerUrl": "https://arbiscan.io", "logoUrl": "..." },
    { "chainId": 137, "name": "Polygon", "publicRpcUrl": "...", "explorerUrl": "https://polygonscan.com", "logoUrl": "..." }
  ]
}

GET /api/v1/bridge/tokens

List curated bridgeable assets on a chain. Bridging is restricted to major assets — arbitrary tokens are rejected.

GET https://orkidlabs.xyz/api/v1/bridge/tokens?chainId=8453
X-ORKID-API-Key: <key>
ParameterTypeRequiredDescription
chainIdnumberYes1, 8453, 42161, or 137
{
  "ok": true,
  "tokens": [
    { "chainId": 8453, "address": "0x833589fc...", "symbol": "USDC", "name": "USD Coin", "decimals": 6 },
    { "chainId": 8453, "address": "0x42000000...", "symbol": "WETH", "name": "Wrapped Ether", "decimals": 18 }
  ]
}

POST /api/v1/bridge/quote

Get an executable bridge quote. Returns the transactions the user must sign — ERC20 approvalTxns first (if required), then the swapTx deposit.

Every returned transaction is validated server-side before reaching you: canonical Across contract targets only, depositor and recipient embedded in calldata, refund pinned to the depositor on the origin chain, quote expiry enforced, and upstream simulation must succeed.

Request

POST https://orkidlabs.xyz/api/v1/bridge/quote
Content-Type: application/json
X-ORKID-API-Key: <key>

{
  "originChainId": 8453,
  "destinationChainId": 1,
  "inputToken": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
  "outputToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
  "amount": "25000000",
  "depositor": "0xYourWalletAddress"
}
FieldTypeRequiredDescription
originChainIdnumberYesChain the funds leave from
destinationChainIdnumberYesChain the funds arrive on (must differ)
inputTokenstringYesOrigin token address or symbol (curated set)
outputTokenstringYesDestination token address or symbol (curated set)
amountstringYesRaw base-unit amount as a decimal string
depositorstringYesUser wallet — signs the txs, receives refunds
recipientstringNoDestination recipient (defaults to depositor)
tradeTypestringNoexactInput (default), minOutput, exactOutput
slippagenumber | "auto"NoDefaults to auto

Response

{
  "ok": true,
  "quote": {
    "id": "0x…",
    "inputToken": { "symbol": "USDC", "decimals": 6, "…": "…" },
    "outputToken": { "symbol": "USDC", "decimals": 6, "…": "…" },
    "inputAmount": "25000000",
    "expectedOutputAmount": "24875000",
    "minOutputAmount": "24850000",
    "expectedFillTime": 7,
    "quoteExpiryTimestamp": 1730000000,
    "fees": { "…": "per-facet breakdown including the Orkid app fee" },
    "checks": {
      "allowance": { "balance": "…", "token": "…", "spender": "…" },
      "balance": { "balance": "…", "token": "…" }
    },
    "approvalTxns": [
      { "chainId": 8453, "to": "0x833589fc…", "data": "0x095ea7b3…" }
    ],
    "swapTx": {
      "chainId": 8453,
      "to": "0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64",
      "data": "0x…",
      "value": "0",
      "simulationSuccess": true
    },
    "recipient": "0xYourWalletAddress",
    "refundAddress": "0xYourWalletAddress",
    "refundOnOrigin": true
  }
}

Executing

  1. For each approvalTxns[i], send { to, data } from depositor on chainId and wait for confirmation.
  2. Send swapTx ({ to, data, value }) from depositor — this is the Across deposit.
  3. Poll /api/v1/bridge/status until filled.

Reject and re-quote if simulationSuccess is false or Date.now() / 1000 >= quoteExpiryTimestamp.

Fees

Bridge quotes carry an Orkid app fee of 10 bps (appFee=0.001), taken in the output token on the destination chain and disclosed inside fees in the response. Relayer and LP fees from Across are itemized there as well.

GET /api/v1/bridge/status

Track a deposit through its lifecycle.

ParameterTypeRequiredDescription
depositTxnRefstringEither/orOrigin deposit transaction hash
originChainId + depositIdnumber + stringEither/orAcross deposit id pair
GET https://orkidlabs.xyz/api/v1/bridge/status?depositTxnRef=0x…
X-ORKID-API-Key: <key>
{
  "ok": true,
  "deposit": {
    "status": "filled",
    "depositId": "…",
    "depositTxHash": "0x…",
    "fillTx": "0x…",
    "destinationChainId": 1
  }
}
StatusMeaning
pendingDeposit seen, waiting for a relayer fill
filledFunds delivered on the destination chain (fillTx)
expiredFill deadline passed — refund will process on origin
refundedRefund executed to the depositor's origin wallet

POST /api/v1/bridge/track

Register a submitted deposit for status reconciliation and volume attribution. Metadata only — call after the origin transaction confirms.

POST https://orkidlabs.xyz/api/v1/bridge/track
Content-Type: application/json
X-ORKID-API-Key: <key>

{
  "originChainId": 8453,
  "destinationChainId": 1,
  "depositor": "0x…",
  "recipient": "0x…",
  "inputToken": "0x833589fc…",
  "outputToken": "0xa0b86991…",
  "amountInRaw": "25000000",
  "expectedOutRaw": "24875000",
  "quoteId": "0x…",
  "originTxHash": "0x…"
}
{ "ok": true, "settlementId": "…" }

Error responses

CodeCause
MALFORMED_REQUESTInvalid chain ids, token addresses, amounts, or addresses
UNSUPPORTED_CHAINOrigin/destination outside the four supported chains
UNSUPPORTED_TOKENToken outside the curated bridge set
QUOTE_EXPIREDQuote expiry passed — re-quote
SIMULATION_FAILEDAcross could not simulate the deposit — check balance/allowance and retry
UPSTREAM_ERRORAcross API failure — safe to retry

SDK & CLI

  • SDK: getBridgeChains(), getBridgeTokens(chainId), getBridgeQuote(req), getBridgeStatus(params), trackBridgeDeposit(req) — see SDK
  • CLI: orkid bridge …, orkid bridge-status 0x… — see CLI

On this page