Skip to main content
Socket supports swapping assets from any EVM chain to Solana and from Solana to any EVM chain. This guide walks you through swapping assets between EVM chains and Solana using Socket, including supported chains, transaction options, and current limitations.

Quick Start

Solana Chain ID

The chain ID for Solana queries is 89999.

Key differences

Here’s what’s different when integrating Solana compared to standard EVM chains: Transaction Flow
  • No token approvals are needed on Solana
API Behavior
  • Both userAddress and receiverAddress required for quotes
  • Fee collection only works from EVM to Solana
  • Native Tokens across all Chains (0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee): Use this address to represent native tokens on any chain (ETH, SOL, etc.)
  • Wrapped SOL (wSOL) (So11111111111111111111111111111111111111112): The SPL token address for wrapped SOL on Solana

Integration Steps

  1. Select Chains: Users choose the source and destination chains, which determine the tokens available for bridging.
  2. Fetch Quote: Call the /quote endpoint which returns an autoRoute object containing txData, requestHash, and optionally approvalData.
  3. Handle Token Approval (EVM only): For EVM transactions, check if approvalData exists. Solana transactions do not require approvals.
  4. Submit Transaction: Execute the transaction using txData from the quote response.
  5. Track Transaction Status: Poll the /status endpoint using the source txHash until the bridging process is complete.
For Solana quotes, please ensure both userAddress and receiverAddress are defined.Solana does not require token approvals.

Examples

Queries

https://public-backend.bungee.exchange/api/v1/bungee/quote?userAddress=0x3e8cB4bd04d81498aB4b94a392c334F5328b237b&originChainId=8453&destinationChainId=89999&inputAmount=100000000&inputToken=0x833589fcd6edb6e08f4c7c32d4f71b54bda02913&enableManual=true&receiverAddress=7BchahMyqpBZYmQS3QnbY3kRweDLgPCRpWdo1rxWmJ3g&refuel=false&outputToken=6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN

Scripts

import dotenv from "dotenv";
dotenv.config();

import { privateKeyToAccount } from "viem/accounts";
import { createPublicClient, http, createWalletClient } from "viem";
import { base } from "viem/chains";
import {
  Keypair,
  Connection,
  PublicKey,
  TransactionInstruction,
  TransactionMessage,
  VersionedTransaction,
} from "@solana/web3.js";
import bs58 from "bs58";

if (!process.env.PRIVATE_KEY || !process.env.SOLANA_PRIVATE_KEY) {
  console.error("Set PRIVATE_KEY and SOLANA_PRIVATE_KEY");
  process.exit(1);
}

const account = privateKeyToAccount(process.env.PRIVATE_KEY.trim());
const publicClient = createPublicClient({ chain: base, transport: http() });
const walletClient = createWalletClient({ account, chain: base, transport: http() });

const solanaKeypair = Keypair.fromSecretKey(bs58.decode(process.env.SOLANA_PRIVATE_KEY));
const solanaAddress = solanaKeypair.publicKey.toBase58();

const BUNGEE_API_BASE_URL = "https://public-backend.bungee.exchange";
const SOLANA_RPC_URL = "https://api.mainnet-beta.solana.com";

// Solana → EVM
const originChainId = 89999;
const destinationChainId = 8453;
const inputToken = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; // Native SOL
const outputToken = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; // USDC on Base
const inputAmount = "170000000"; // ~$15 of SOL (9 decimals)

const quoteParams = {
  userAddress: originChainId === 89999 ? solanaAddress : account.address,
  receiverAddress: destinationChainId === 89999 ? solanaAddress : account.address,
  originChainId,
  destinationChainId,
  inputToken,
  outputToken,
  inputAmount,
};

async function getQuote(params) {
  const url = `${BUNGEE_API_BASE_URL}/api/v1/bungee/quote?${new URLSearchParams(params)}`;
  const response = await fetch(url);
  const data = await response.json();
  if (!data.success || !data.result?.autoRoute) {
    throw new Error(`Quote failed: ${data.message}`);
  }
  return {
    quoteId: data.result.autoRoute.quoteId,
    requestHash: data.result.autoRoute.requestHash,
    txData: data.result.autoRoute.txData,
    approvalData: data.result.autoRoute.approvalData,
  };
}

async function main() {
  console.log("Starting Socket Solana Swap...");
  console.log(`Solana Address: ${solanaAddress}`);
  console.log(`EVM Address: ${account.address}`);

  const quoteResponse = await getQuote(quoteParams);
  console.log("Quote ID:", quoteResponse.quoteId);
  console.log("Transaction Type:", quoteResponse.txData.type);

  // Submit transaction based on type and poll /status with quoteResponse.requestHash
}

main();