Cross-Chain

x402 Bridge

Move USDC across chains instantly using the x402 payment protocol

The x402 Bridge lets users and AI agents transfer USDC between supported networks without waiting for canonical bridges. Instead of 2–5 minute delays, RelAI uses a liquidity network model — the destination wallet receives funds immediately from a pre-funded pool, while the source payment is settled on-chain via x402.

Supported networks are defined in a central config (networks.js). Adding a new network requires no changes to bridge routes or API endpoints — the GET /v1/bridge/networks endpoint always reflects the current set.

~3s
Instant Payout
No waiting for canonical bridge confirmation
0.1%
Bridge Fee
10 bps deducted from output amount
Native
Native USDC
No wrapped tokens — native USDC on every supported chain

How It Works

Every bridge transfer follows the same two-step flow regardless of which networks are involved:

Generic bridge flow
1. User pays USDC on source network via x402
↓ RelAI facilitator verifies payment on-chain
2. RelAI immediately sends USDC from the destination pool to the user's wallet
↓ response includes both tx hashes (payment + payout)
3. Pool rebalances asynchronously in the background via Circle CCTP

The x402 payment scheme depends on the source network type:

SVM networks (e.g. Solana)
SPL token transfer signed by user, submitted by RelAI fee-payer (gas-free for user)
scheme: svm-exact
EVM networks (e.g. SKALE Base, Base)
EIP-3009 transferWithAuthorization — gasless signed approval
scheme: exact

Liquidity guard: Before requesting payment, the bridge verifies destination pool balance. If insufficient, a 503 insufficient_liquidity error is returned before any payment — the user is never charged for an unavailable route.

Supported Networks

The list of supported networks is always current — query GET /v1/bridge/networks to get available directions at runtime. The bridge UI and SDK use this endpoint automatically.

NetworkTypex402 SchemeTokenStatus
SolanaSVMsvm-exactUSDCLive
SKALE BaseEVMexactUSDCLive
BaseEVMexactUSDCLive

Adding a new network

Add a network object to server/src/services/bridge/networks.js with its id, type (solana or evm), token address, RPC, and payout() / getBalance() functions. No changes to routes or API endpoints required.

Liquidity & Rebalancing

RelAI maintains pre-funded USDC wallets on each supported network. After every payout, the system checks if the destination pool has fallen below the rebalance threshold. If so, it automatically rebalances via Circle CCTP.

Rebalance: Solana → SKALE Base
  1. Burn USDC on Solana via Circle CCTP
  2. Wait for Circle attestation (~20s)
  3. Mint native USDC on Base
  4. Deposit to SKALE Base via SKALE IMA
Rebalance: SKALE Base → Solana
  1. Burn USDC on Base via Circle CCTP
  2. Wait for Circle attestation (~20s)
  3. Receive + mint native USDC on Solana

Rebalance runs asynchronously — it does not block bridge payouts. Current liquidity is available via the GET /v1/bridge/balances endpoint.

Using the Bridge UI

The bridge is available at /bridge. It supports Phantom wallet (Solana) and MetaMask / any injected EVM wallet (SKALE Base).

  1. 1Select direction: Solana → SKALE Base or SKALE Base → Solana
  2. 2Connect your source wallet (Phantom or MetaMask)
  3. 3Enter amount and destination wallet address
  4. 4Click Bridge — approve the x402 payment in your wallet. USDC arrives on the destination chain within seconds.

Management API

All bridge operations are available via the v1 Management API. Requires an X-Service-Key header. Routes are config-driven — new networks are added without changing endpoints.

GET
/v1/bridge/networks

List all enabled bridge directions (config-driven)

GET
/v1/bridge/quote

Get fee and net output for a given USD amount (params: amount, from, to)

GET
/v1/bridge/balances

Current USDC liquidity on all enabled networks

POST
/v1/bridge/:direction

Bridge between networks (e.g. solana-to-skale-base). Returns 402, pay with x402.

List available routes
curl https://api.relai.fi/v1/bridge/networks \
  -H "X-Service-Key: sk_live_..."

# Response
{
  "directions": [
    { "id": "solana-to-skale-base", "from": { "id": "solana", "label": "Solana" }, "to": { "id": "skale-base", "label": "SKALE Base" } },
    { "id": "skale-base-to-solana", "from": { "id": "skale-base", "label": "SKALE Base" }, "to": { "id": "solana", "label": "Solana" } }
  ]
}
Successful bridge response
{
  "success": true,
  "direction": "solana-to-skale-base",
  "from": "solana",
  "to": "skale-base",
  "destinationWallet": "0xYourSkaleAddress",
  "amountOut": 9990000,
  "amountOutUsd": 9.99,
  // Payout tx on destination chain (SKALE Base)
  "txHash": "0xabc123...",
  "explorerUrl": "https://skale-base-explorer.skalenodes.com/tx/0xabc123...",
  // Payment tx on source chain (Solana)
  "paymentTxHash": "5Kq7...",
  "paymentExplorerUrl": "https://solscan.io/tx/5Kq7..."
}

SDK Integration

Use createX402Client from @relai-fi/x402 — it handles the 402 payment automatically. The direction string comes from /v1/bridge/networks.

Solana → SKALE Base (Node.js agent)
import { createX402Client } from '@relai-fi/x402';
import { Keypair } from '@solana/web3.js';

const keypair = Keypair.fromSecretKey(Buffer.from(process.env.SOLANA_KEY!, 'base64'));
const x402 = createX402Client({
  wallets: {
    solana: {
      publicKey: keypair.publicKey,
      signTransaction: async (tx: any) => { tx.sign([keypair]); return tx; },
    },
  },
  defaultHeaders: { 'X-Service-Key': process.env.RELAI_SERVICE_KEY! },
});

const res = await x402.fetch(
  'https://api.relai.fi/v1/bridge/solana-to-skale-base',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ amount: 10.0, destinationWallet: '0xYourSkaleBaseAddress' }),
  }
);
const result = await res.json();
// result.paymentTxHash  — Solana payment tx
// result.txHash         — SKALE Base payout tx
// result.explorerUrl    — SKALE Base explorer link
console.log('Payment:', result.paymentExplorerUrl);
console.log('Payout:', result.explorerUrl);
SKALE Base → Solana (Node.js agent)
import { ethers } from 'ethers';
import { createX402Client } from '@relai-fi/x402';

const provider = new ethers.JsonRpcProvider(process.env.SKALE_RPC_URL);
const signer = new ethers.Wallet(process.env.EVM_KEY!, provider);

const x402 = createX402Client({
  wallets: {
    evm: {
      address: signer.address,
      signTypedData: (domain: any, types: any, message: any) =>
        signer.signTypedData(domain, types, message),
    },
  },
  defaultHeaders: { 'X-Service-Key': process.env.RELAI_SERVICE_KEY! },
});

const res = await x402.fetch(
  'https://api.relai.fi/v1/bridge/skale-base-to-solana',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ amount: 5.0, destinationWallet: 'YourSolanaAddress' }),
  }
);
const result = await res.json();
// result.paymentTxHash  — SKALE Base payment tx
// result.txHash         — Solana payout tx
console.log('Payout:', result.explorerUrl); // solscan.io

Fees & Limits

Bridge fee1% (100 bps) of input amount, minimum $0.01
Gas feesSponsored by RelAI facilitator — $0 for user
Minimum$0.05 USDC
Maximum$1 USDC per transaction (beta)
Settlement time~3 seconds (payout on destination chain)

Error Handling

503insufficient_liquidity

The destination pool does not have enough USDC for this transfer. Returned before any payment is requested. Check /v1/bridge/balances and retry when liquidity is restored.

402Payment Required

Standard x402 response. Use the RelAI SDK createX402Client to handle this automatically.

400Validation error

Invalid amount or destinationWallet format. Check that the destination address matches the target chain format (EVM 0x... or Solana base58).

SDK error handling
try {
  const result = await mgmt.bridgeSolanaToSkale(100.0, '0x...', x402);
} catch (err) {
  if (err.message.includes('insufficient_liquidity')) {
    const { skaleBase } = await mgmt.getBridgeBalances();
    console.log(`Retry later. Available: $${skaleBase.usd} USDC`);
  }
}