Solana provides a default public RPC endpoint, but for production use, it's strongly recommended to run your own or use a third-party provider like Helius.
import{Connection}from"@solana/web3.js";// You can replace this with your own or a third-party RPC URLconstconnection=newConnection("https://api.mainnet-beta.solana.com");
1. Fetch a Quote
Start by sending a GET request to the 0x /quotes endpoint to get a quotes for a specific tokens and chains pair with selected amount. You may use 'solana' or '999999999991' as the originChain.
Example response
2. Sign and submit transaction
In the next step, you need to build VersionedTransaction based on returned transaction data, sign it with your wallet, and send it to the Solana network, and wait for transaction confirmation.
3. 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.
Example response
Extra - using alternative gas payer
One thing that is specific to cross chain swaps originating from Solana is the ability to specify an alternative wallet as a gas payer. When requesting a /quote, you need to pass an extra gasPayer parameter, equal to base58-encoded pubkey of the gas payer. Then, when processing the response, you need to additionally sign the transaction with the gas payer wallet.
In the examples repo, you can find a dedicated end-to-end example utilising a gas payer functionality.
const quotesParams = new URLSearchParams({
originChain: 'solana', // Solana mainnet
destinationChain: '8453' // Base mainnet
sellToken: 'So11111111111111111111111111111111111111112', // WSOL on Solana
buyToken: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', // USDC on Base
sellAmount: '100000000000000000000', // Amount of sellToken in base units
originAddress: '$USER_TAKER_ADDRESS', // Solana Pubkey that will make the trade
destinationAddress: '$USER_RECEIVER_ADDRESS', // Base address that will receive the output
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());
const serializedTx = quote.transaction.details.serializedTransaction;
const transactionBuffer = Buffer.from(serializedTx, "base64");
const transaction = VersionedTransaction.deserialize(transactionBuffer);
// Sign transaction with both keypairs
console.log("✍️ Signing transaction with gas payer and user keypairs...");
transaction.sign([gasPayerKeypair, keypair]);