The 0x Cross Chain API is a fast, flexible API that lets developers programatically access tokens across various blockchains, enabling cross-chain swap functionality in any app or wallet.
Whether you're building a new application, or expanding the offering of your existing product, this API helps you integrate cross-chain token swaps with minimal overhead and maximum efficiency.
Steps to Cross Chain Swap Tokens
This guide will walk you through using the /quotes and /status endpoints on 0x’s Cross Chain API to:
Fetch a quote
Set allowance
Sign and send a transaction
Monitor the status of the cross chain swap
In our example, we will be swapping WETH on Base to USDC on Arbitrum.
To interact with that RPC, we will use a popular TS library, viem.
1. Fetch a Quote
Start by sending a GET request to the 0x /quotes endpoint to get a quote for a specific tokens and chains pair with selected amount.
Example response
2. Set a token allowance
It is possible, that you will need to set proper token allowance to 0x's AllowanceHolder contract. In cases where allowance will be needed, it will be reported in issues in the response.
Below you can find an example on how to set proper token allowance for received quote.
3. Sign and submit a transaction
Now that we have both the approval and the quote, we can construct, sign, and submit the transaction. Optionally, after the approval, you might want to re-fetch a fresh quote.
Code below will construct, sign, and submit the transaction based on the quote response.
4. Monitor the cross chain execution
The last step is to monitor the execution of the cross chain transaction, including the fill on the destination chain. For that, we will use the /status endpoint.
In your application, you might need to monitor the status repeatedly, as bridging operation might take several seconds or minutes to complete.
import { createWalletClient, http } from "viem";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
const PRIVATE_KEY = 'your_private_key'
const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient(
{
account,
chain: base,
transport: http(configuration.rpcUrls.base),
}
)
const quotesParams = new URLSearchParams({
originChain: '8453', // Base mainnet
destinationChain: '42161' // Arbitrum mainnet
sellToken: '0x4200000000000000000000000000000000000006', // WETH on Base
buyToken: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', // USDC on Arbitrum
sellAmount: '100000000000000000000', // Amount of sellToken in base units
originAddress: '$USER_TAKER_ADDRESS', // Address that will make the trade
sortQuotesBy: 'price' // Prefer the quote that will result in the best price / output
maxQuotes: 1 // only the best quote
});
const headers = {
'0x-api-key': '[api-key]', // Get your live API key from the 0x Dashboard (https://dashboard.0x.org/apps)
};
const quoteResponse = await fetch('https://api.0x.org/cross-chain/quotes' + quoteParams.toString(), { headers });
console.log(await quoteResponse.json());
// Example assumes that you've set up your walletClient with viem
import { erc20Abi } from "viem";
...
// Code that fetches a valid quoteResponse
...
const approveTxHash = await walletClient.writeContract({
address: quoteResponse.sellToken as `0x${string}`,
abi: erc20Abi,
functionName: "approve",
args: [
quoteResponse.quote.issues.allowance.spender as `0x${string}`,
BigInt(quoteResponse.sellAmount),
],
});
await walletClient.waitForTransactionReceipt({
hash: approveTxHash,
confirmations: 1,
});
// Prepare a transaction request
const txRequest = {
to: quoteResponse.quotes[0].transaction.details.to as `0x${string}`,
to: quoteResponse.quotes[0].transaction.details.to as `0x${string}`,
data: quoteResponse.quotes[0].transaction.details.data as `0x${string}`,
value: BigInt(quoteResponse.quotes[0].transaction.details.value),
gas: quoteResponse.quotes[0].transaction.details.gas
? BigInt(quoteResponse.quotes[0].transaction.details.gas)
: undefined,
};
// Sign and submit the transaction request
const txHash = await walletClient.sendTransaction(txRequest);
// Wait for confirmation on Base
const receipt = await walletClient.waitForTransactionReceipt({
hash: txHash,
confirmations: 2,
});
console.log(`✅ Transaction confirmed in block: ${receipt.blockNumber}`);
console.log(`🔗 View on BaseScan: https://basescan.org/tx/${txHash}`);
const statusParams = new URLSearchParams({
originChain: 8453, // origin chain
originTxHash, // transaction hash of the origin chain transaction, submitted in previous step
quoteId, // the quote ID of the submitted quote, equivalent to quoteResponse.quotes[0].quoteId
});
const headers = {
'0x-api-key': '[api-key]', // Get your live API key from the 0x Dashboard (https://dashboard.0x.org/apps)
};
const statusResponse = await fetch('https://api.0x.org/cross-chain/status' + statusParams.toString(), { headers });
console.log(await quoteResponse.json());