Solana Integration
This guide covers Solana integration with SwapKit, including wallet connections, SOL transfers, SPL token operations, and cross-chain swaps.
Overview
Section titled “Overview”Solana is a high-performance blockchain known for fast transactions and low fees. SwapKit provides comprehensive Solana support through:
- Solana Toolbox: Native Solana operations with sub-second finality
 - SPL Token Support: Full support for Solana’s token standard
 - Cross-Chain Swaps: Seamless swaps with other cryptocurrencies
 - Program Interaction: Execute Solana program instructions
 - Multi-Wallet Support: Compatible with Phantom, Solflare, and hardware wallets
 
Getting Started
Section titled “Getting Started”Installation
Section titled “Installation”# Full SDK (recommended)bun add @swapkit/sdk
# Individual packages for smaller bundlesbun add @swapkit/toolboxes @swapkit/pluginsBasic Setup
Section titled “Basic Setup”// @noErrorValidationimport { createSwapKit, Chain } from '@swapkit/sdk';
const swapKit = createSwapKit();
const solWallet = await swapKit.getWallet(Chain.Solana);// @noErrorValidationimport { getSolanaToolbox } from '@swapkit/toolboxes/solana';
const solToolbox = await getSolanaToolbox({  phrase: "your twelve word mnemonic phrase here",
  derivationPath: [44, 501, 0, 0]});
const solToolbox = await getSolanaToolbox({  keypair: customSolanaKeypair,  network: "mainnet-beta"});Solana Toolbox
Section titled “Solana Toolbox”Wallet Connection
Section titled “Wallet Connection”Connect to Solana using various wallet types:
// @noErrorValidationimport { Chain, FeeOption } from "@swapkit/sdk";
await swapKit.connectKeystore([Chain.Solana], "your mnemonic phrase");
await swapKit.connectPhantom([Chain.Solana]);
await swapKit.connectSolflare([Chain.Solana]);
await swapKit.connectLedger([Chain.Solana]);Address Generation
Section titled “Address Generation”Solana addresses are base58-encoded public keys:
// @noErrorValidation
const solanaAddress = swapKit.getAddress(Chain.Solana);
console.log("Solana address:", solanaAddress);
import { validateSolanaAddress } from "@swapkit/toolboxes/solana";
const isValidAddress = validateSolanaAddress(solanaAddress);console.log("Valid SOL address:", isValidAddress);
const publicKey = await solToolbox.getPublicKey();console.log("Public key:", publicKey);SOL Transfers
Section titled “SOL Transfers”// @noErrorValidationimport { AssetValue } from "@swapkit/sdk";
const txHash = await swapKit.transfer({  recipient: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",  assetValue: AssetValue.from({    chain: Chain.Solana,    value: "0.1",  }),  feeOptionKey: FeeOption.Fast,  memo: "Payment for services",});
console.log(`Solana transaction signature: ${txHash}`);
const priorityTx = await solToolbox.transfer({  recipient: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",  assetValue: AssetValue.from({ chain: Chain.Solana, value: "0.05" }),  priorityFee: 10000,  memo: "Priority transfer",});
const batchTransfer = async () => {  const recipients = [    { address: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", amount: "0.01" },    { address: "AaLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", amount: "0.02" },    { address: "BbBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", amount: "0.015" },  ];
  const batchTx = await solToolbox.batchTransfer({    recipients: recipients.map((r) => ({      address: r.address,      assetValue: AssetValue.from({ chain: Chain.Solana, value: r.amount }),    })),    priorityFee: 5000,  });
  console.log("Batch transfer completed:", batchTx);};SPL Token Operations
Section titled “SPL Token Operations”Solana Program Library (SPL) tokens are equivalent to ERC-20 on Ethereum:
// @noErrorValidation
const usdcTransfer = await swapKit.transfer({  recipient: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",  assetValue: AssetValue.from({    chain: Chain.Solana,    symbol: "USDC",    address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",    value: "100",  }),  feeOptionKey: FeeOption.Average,});
const tokenBalance = await solToolbox.getTokenBalance(  "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",  "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
console.log(`USDC balance: ${tokenBalance} USDC`);
const tokenAccounts = await solToolbox.getTokenAccounts(  swapKit.getAddress(Chain.Solana));
console.log("SPL token accounts:");tokenAccounts.forEach((account) => {  console.log(`${account.mint}: ${account.amount} tokens`);});
const createTokenAccount = async (mintAddress: string) => {  const tokenAccountTx = await solToolbox.createAssociatedTokenAccount({    mint: mintAddress,    owner: swapKit.getAddress(Chain.Solana),    payer: swapKit.getAddress(Chain.Solana),  });
  console.log("Token account created:", tokenAccountTx);  return tokenAccountTx;};Program Interactions
Section titled “Program Interactions”Interact with Solana programs (smart contracts):
// @noErrorValidation
const jupiterSwap = await solToolbox.executeProgram({  programId: "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",  instruction: {    keys: [      { pubkey: "sourceTokenAccount", isSigner: false, isWritable: true },      { pubkey: "destinationTokenAccount", isSigner: false, isWritable: true },      {        pubkey: swapKit.getAddress(Chain.Solana),        isSigner: true,        isWritable: false,      },    ],    data: Buffer.from("swap_instruction_data", "hex"),  },  signers: [],});
const serumTrade = await solToolbox.executeProgram({  programId: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",  instruction: {    keys: [],    data: Buffer.from("place_order_instruction", "hex"),  },});
const programAccount = await solToolbox.getProgramAccount(  "11111111111111111111111111111112",  "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM");
console.log("Program account data:", programAccount);Transaction History and Status
Section titled “Transaction History and Status”// @noErrorValidation
const transactions = await solToolbox.getTransactionHistory(  swapKit.getAddress(Chain.Solana),  20);
console.log("Recent Solana transactions:");transactions.forEach((tx) => {  console.log(`${tx.signature}: ${tx.slot} (${tx.blockTime})`);  console.log(`  Fee: ${tx.meta.fee} lamports`);  console.log(`  Status: ${tx.meta.err ? "Failed" : "Success"}`);});
const txDetails = await solToolbox.getTransaction(  "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW");
console.log("Transaction details:", {  slot: txDetails.slot,  fee: txDetails.meta.fee,  computeUnitsConsumed: txDetails.meta.computeUnitsConsumed,  preBalances: txDetails.meta.preBalances,  postBalances: txDetails.meta.postBalances,});
const confirmationStatus = await solToolbox.getTransactionConfirmation(  "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW");
console.log("Confirmation status:", confirmationStatus);Cross-Chain Swaps
Section titled “Cross-Chain Swaps”Solana is supported in cross-chain swaps via various protocols:
// @noErrorValidation
const solToBtcQuote = await swapKit.getQuote({  sellAsset: "SOL.SOL",  sellAmount: "10",  buyAsset: "BTC.BTC",  senderAddress: swapKit.getAddress(Chain.Solana),  recipientAddress: swapKit.getAddress(Chain.Bitcoin),});
console.log("SOL -> BTC quote:", {  expectedOutput: solToBtcQuote.expectedOutput,  fees: solToBtcQuote.fees,  timeEstimate: solToBtcQuote.timeEstimate,});
const swapTx = await swapKit.swap({  route: solToBtcQuote.routes[0],  feeOptionKey: FeeOption.Fast,});
const usdcBridge = await swapKit.getQuote({  sellAsset: "SOL.USDC-EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",  sellAmount: "1000",  buyAsset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",  senderAddress: swapKit.getAddress(Chain.Solana),  recipientAddress: swapKit.getAddress(Chain.Ethereum),});
const solToStable = await swapKit.getQuote({  sellAsset: "SOL.SOL",  sellAmount: "5",  buyAsset: "SOL.USDC-EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",  senderAddress: swapKit.getAddress(Chain.Solana),  recipientAddress: swapKit.getAddress(Chain.Solana),  providers: ["JUPITER"],});Advanced Solana Features
Section titled “Advanced Solana Features”Jupiter DEX Integration
Section titled “Jupiter DEX Integration”// @noErrorValidation
const jupiterAdvancedSwap = async () => {  const quote = await solToolbox.getJupiterQuote({    inputMint: "So11111111111111111111111111111111111111112",    outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",    amount: 1000000000,    slippageBps: 50,  });
  const swapTx = await solToolbox.executeJupiterSwap({    quote,    userPublicKey: swapKit.getAddress(Chain.Solana),    priorityFee: 10000,  });
  console.log("Jupiter swap executed:", swapTx);};
const getAllRoutes = async () => {  const routes = await solToolbox.getJupiterRoutes({    inputMint: "So11111111111111111111111111111111111111112",    outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",    amount: 1000000000,  });
  routes.forEach((route, index) => {    console.log(`Route ${index + 1}:`);    console.log(`  Output: ${route.outAmount}`);    console.log(`  Price impact: ${route.priceImpactPct}%`);    console.log(      `  Market infos:`,      route.marketInfos.map((m) => m.label)    );  });};Staking Operations
Section titled “Staking Operations”// @noErrorValidation
const stakeSol = async () => {  const validators = await solToolbox.getValidators();
  const goodValidator = validators.find(    (v) =>      v.commission < 10 && v.activatedStake > 1000000 * 1e9 && !v.delinquent  );
  if (!goodValidator) {    throw new Error("No suitable validator found");  }
  const stakeAccountTx = await solToolbox.createStakeAccount({    stakeAmount: AssetValue.from({ chain: Chain.Solana, value: "10" }),    validatorVoteAccount: goodValidator.votePubkey,    stakePubkey: solToolbox.generateStakeAccount(),    authorizedStaker: swapKit.getAddress(Chain.Solana),    authorizedWithdrawer: swapKit.getAddress(Chain.Solana),  });
  console.log(`Staked 10 SOL with ${goodValidator.name}:`, stakeAccountTx);};
const delegateStake = async (stakeAccount: string) => {  const delegateTx = await solToolbox.delegateStake({    stakeAccount,    validatorVoteAccount: "ValidatorVoteAccount111111111111111111111111",    authorizedStaker: swapKit.getAddress(Chain.Solana),  });
  console.log("Stake delegated:", delegateTx);};
const withdrawStake = async (stakeAccount: string) => {  const deactivateTx = await solToolbox.deactivateStake({    stakeAccount,    authorizedStaker: swapKit.getAddress(Chain.Solana),  });
  console.log("Stake deactivated:", deactivateTx);
  setTimeout(async () => {    const withdrawTx = await solToolbox.withdrawStake({      stakeAccount,      withdrawerPubkey: swapKit.getAddress(Chain.Solana),      amount: AssetValue.from({ chain: Chain.Solana, value: "10" }),    });
    console.log("Stake withdrawn:", withdrawTx);  }, 2 * 24 * 60 * 60 * 1000);};NFT Operations
Section titled “NFT Operations”// @noErrorValidation
const getNFTs = async () => {  const nfts = await solToolbox.getNFTs(swapKit.getAddress(Chain.Solana));
  console.log("Owned NFTs:");  nfts.forEach((nft) => {    console.log(`${nft.name}: ${nft.mint}`);    console.log(`  Collection: ${nft.collection}`);    console.log(`  Image: ${nft.image}`);  });
  return nfts;};
const transferNFT = async (nftMint: string, recipient: string) => {  const transferTx = await solToolbox.transferNFT({    mint: nftMint,    from: swapKit.getAddress(Chain.Solana),    to: recipient,    owner: swapKit.getAddress(Chain.Solana),  });
  console.log("NFT transferred:", transferTx);};
const listNFT = async (nftMint: string, price: number) => {  const listingTx = await solToolbox.createMagicEdenListing({    mint: nftMint,    seller: swapKit.getAddress(Chain.Solana),    price: price * 1e9,    expiry: Date.now() + 7 * 24 * 60 * 60 * 1000,  });
  console.log("NFT listed:", listingTx);};Network Configuration
Section titled “Network Configuration”Custom RPC Setup
Section titled “Custom RPC Setup”// @noErrorValidationimport { SKConfig } from '@swapkit/sdk';
SKConfig.setRpcUrl(Chain.Solana, [  "https:  "https:  "https:]);
const customSolanaRpc = "https:SKConfig.setRpcUrl(Chain.Solana, customSolanaRpc);
const heliusRpc = "https:SKConfig.setRpcUrl(Chain.Solana, heliusRpc);Working with Solana Devnet
Section titled “Working with Solana Devnet”// @noErrorValidation
SKConfig.setRpcUrl(Chain.Solana, "https:SKConfig.setEnv('isMainnet', false);
const devnetToolbox = await getSolanaToolbox({  phrase: "your mnemonic",  network: "devnet"});
const airdrop = await devnetToolbox.requestAirdrop(  swapKit.getAddress(Chain.Solana),  2 * 1e9);
console.log("Airdrop transaction:", airdrop);Error Handling
Section titled “Error Handling”Handle Solana-specific errors:
// @noErrorValidationimport { SwapKitError } from "@swapkit/sdk";
try {  await swapKit.transfer({    /* ... */  });} catch (error) {  if (error instanceof SwapKitError) {    switch (error.code) {      case "toolbox_solana_insufficient_funds":        console.error("Insufficient SOL balance");        break;      case "toolbox_solana_invalid_address":        console.error("Invalid Solana address format");        break;      case "toolbox_solana_transaction_failed":        console.error("Transaction failed:", error.cause);        break;      case "toolbox_solana_account_not_found":        console.error("Account not found or not initialized");        break;      case "toolbox_solana_insufficient_compute_units":        console.error("Insufficient compute units for transaction");        break;      case "toolbox_solana_blockhash_expired":        console.error("Transaction blockhash expired");        break;      default:        console.error("Unknown Solana error:", error);    }  }}Performance Optimization
Section titled “Performance Optimization”Transaction Optimization
Section titled “Transaction Optimization”// @noErrorValidation
const optimizeTransaction = {  fast: { priorityFee: 10000 },  normal: { priorityFee: 1000 },
  computeUnitLimit: 200000,  computeUnitPrice: 1,
  async getOptimalBlockhash() {    const recentBlockhash = await solToolbox.getRecentBlockhash();    return recentBlockhash.blockhash;  },};
const optimizedTransfer = await solToolbox.transfer({  recipient: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",  assetValue: AssetValue.from({ chain: Chain.Solana, value: "0.1" }),  priorityFee: optimizeTransaction.fast.priorityFee,  computeUnitLimit: optimizeTransaction.computeUnitLimit,  recentBlockhash: await optimizeTransaction.getOptimalBlockhash(),});Batch Operations
Section titled “Batch Operations”// @noErrorValidation
const batchOptimization = async () => {  const instructions = [    await solToolbox.createTransferInstruction({      from: swapKit.getAddress(Chain.Solana),      to: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",      amount: 0.1 * 1e9,    }),
    await solToolbox.createTokenTransferInstruction({      mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",      from: await solToolbox.getAssociatedTokenAddress(        "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",        swapKit.getAddress(Chain.Solana)      ),      to: await solToolbox.getAssociatedTokenAddress(        "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",        "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"      ),      amount: 100 * 1e6,      owner: swapKit.getAddress(Chain.Solana),    }),  ];
  const batchTx = await solToolbox.sendTransaction({    instructions,    signers: [],    priorityFee: 5000,  });
  console.log("Batch transaction:", batchTx);};Best Practices
Section titled “Best Practices”- 
Use Priority Fees Wisely:
const smartPriorityFee = async (urgency: "low" | "medium" | "high") => {const baseFee = await solToolbox.getEstimatedFees();const multipliers = {low: 1,medium: 2,high: 5,};return baseFee * multipliers[urgency];}; - 
Monitor Compute Units:
const monitorComputeUnits = async (signature: string) => {const tx = await solToolbox.getTransaction(signature);console.log(`Compute units used: ${tx.meta.computeUnitsConsumed}`);if (tx.meta.computeUnitsConsumed > 800000) {console.warn("High compute usage - consider optimizing instructions");}}; - 
Handle Token Accounts Properly:
const ensureTokenAccount = async (mint: string, owner: string) => {const tokenAccount = await solToolbox.getAssociatedTokenAddress(mint,owner);try {await solToolbox.getTokenAccountBalance(tokenAccount);return tokenAccount;} catch {await solToolbox.createAssociatedTokenAccount({mint,owner,payer: owner,});return tokenAccount;}}; - 
Use Versioned Transactions:
const versionedTx = await solToolbox.createVersionedTransaction({instructions: [/* your instructions */],version: 0,addressLookupTableAccounts: [],}); 
API Reference Summary
Section titled “API Reference Summary”Core Methods
Section titled “Core Methods”getBalance()- Get SOL balance in SOLtransfer()- Send SOL with optimizationsgetTokenBalance()- Get SPL token balancetransferToken()- Send SPL tokens
Program Methods
Section titled “Program Methods”executeProgram()- Execute program instructionsgetProgramAccount()- Read program account datacreateAssociatedTokenAccount()- Create token accounts
Staking Methods
Section titled “Staking Methods”createStakeAccount()- Create new stake accountdelegateStake()- Delegate stake to validatordeactivateStake()- Deactivate stake accountwithdrawStake()- Withdraw from stake account
Jupiter DEX Methods
Section titled “Jupiter DEX Methods”getJupiterQuote()- Get swap quote from JupiterexecuteJupiterSwap()- Execute swap via JupitergetJupiterRoutes()- Get all available routes
Transaction Methods
Section titled “Transaction Methods”getTransaction()- Get transaction detailsgetTransactionHistory()- Get transaction historysendTransaction()- Send custom transactiongetRecentBlockhash()- Get recent blockhash
NFT Methods
Section titled “NFT Methods”getNFTs()- Get owned NFTstransferNFT()- Transfer NFT ownershipcreateMagicEdenListing()- List NFT on Magic Eden
Next Steps
Section titled “Next Steps”- Learn about Cross-Chain Swaps using Solana
 - Explore other blockchain integrations like Radix
 - Check out Production Best Practices
 - Read about Transaction Optimization