You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于TypeScript的Solana Raydium SDK SOL兑换USDC实现问询

Solana主网通过Raydium SDK实现SOL转USDC的Swap功能实现步骤

你已完成环境配置、链连接及钱包初始化,以下是Swap功能的具体实现步骤及完整代码:

现有基础代码

import bs58 from 'bs58';
import dotenv from 'dotenv';
import { Liquidity, Token, TOKEN_PROGRAM_ID, BN } from '@raydium-io/raydium-sdk';
import { Connection, Keypair, Transaction, PublicKey, sendAndConfirmTransaction } from '@solana/web3.js';

// 加载环境变量(从.env文件读取RPC URL和私钥)
dotenv.config();

// 创建Solana链连接
const connection = new Connection(process.env.RPC_URL!, 'confirmed');

// 初始化钱包
const secretKey = bs58.decode(process.env.PRIVATE_KEY!);
const wallet = Keypair.fromSecretKey(secretKey);

console.log("钱包公钥:", wallet.publicKey.toBase58());

// Swap配置
const swapConfig = {
  tokenAAmount: 0.01, // 要兑换的SOL数量
  tokenAAddress: "So11111111111111111111111111111111111111112", // SOL主网标准地址(替换你之前的旧地址)
  tokenBAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC主网地址
  maxLamports: 1000000, // 最大手续费lamports
  direction: "in" as "in" | "out", // 输入SOL、输出USDC
  liquidityFile: "https://api.raydium.io/v2/sdk/liquidity/mainnet.json", // Raydium流动性数据地址
  maxRetries: 10 // 失败重试次数
};

具体实现步骤

1. 加载Raydium流动性池数据

从配置的地址获取全量流动性池信息,用于定位SOL-USDC交易池:

async function loadLiquidityPools() {
  const response = await fetch(swapConfig.liquidityFile);
  return await response.json();
}

2. 筛选目标交易对的池信息

从全量池中找到SOL与USDC对应的官方流动性池:

async function getTargetPool(pools: any) {
  return pools.find((pool: any) => 
    (pool.baseMint === swapConfig.tokenAAddress && pool.quoteMint === swapConfig.tokenBAddress) ||
    (pool.baseMint === swapConfig.tokenBAddress && pool.quoteMint === swapConfig.tokenAAddress)
  );
}

3. 构建Swap交易指令

将代币数量转换为最小单位,再通过Raydium SDK生成Swap所需的交易指令:

async function buildSwapTransaction(pool: any) {
  // 初始化Token对象(注意小数位数:SOL为9位,USDC为6位)
  const tokenA = new Token(TOKEN_PROGRAM_ID, new PublicKey(swapConfig.tokenAAddress), 9, "SOL", "Solana");
  const tokenB = new Token(TOKEN_PROGRAM_ID, new PublicKey(swapConfig.tokenBAddress), 6, "USDC", "USD Coin");

  // 将输入SOL数量转换为最小单位(lamports)
  const inputAmount = new BN(swapConfig.tokenAAmount * Math.pow(10, tokenA.decimals));

  // 获取用户的关联Token账户地址
  const userTokenAAccount = await Token.getAssociatedTokenAddress(
    tokenA.associatedProgramId,
    tokenA.programId,
    tokenA.mint,
    wallet.publicKey
  );
  const userTokenBAccount = await Token.getAssociatedTokenAddress(
    tokenB.associatedProgramId,
    tokenB.programId,
    tokenB.mint,
    wallet.publicKey
  );

  // 生成Swap交易指令
  const swapInstruction = await Liquidity.makeSwapInstruction({
    connection,
    poolKeys: pool,
    userKeys: {
      tokenAccountIn: userTokenAAccount,
      tokenAccountOut: userTokenBAccount,
      owner: wallet.publicKey
    },
    amountIn: inputAmount,
    amountOut: new BN(0), // 设为0表示自动计算最小输出量
    fixedSide: "in",
    config: {
      bypassAssociatedCheck: false
    }
  });

  // 组装交易并设置基础参数
  const transaction = new Transaction();
  transaction.add(...swapInstruction.instructions);
  const latestBlockhash = await connection.getLatestBlockhash();
  transaction.recentBlockhash = latestBlockhash.blockhash;
  transaction.feePayer = wallet.publicKey;

  return transaction;
}

4. 发送交易并处理重试逻辑

实现带重试机制的交易发送函数,应对链上临时拥堵情况:

async function sendSwapTransaction(transaction: Transaction, retries: number = 0) {
  try {
    const signature = await sendAndConfirmTransaction(
      connection,
      transaction,
      [wallet],
      { commitment: 'confirmed', skipPreflight: false }
    );
    console.log("Swap交易完成,签名:", signature);
    return signature;
  } catch (error) {
    if (retries < swapConfig.maxRetries) {
      console.log(`交易失败,重试第${retries + 1}次...`);
      await new Promise(resolve => setTimeout(resolve, 2000)); // 间隔2秒重试
      return sendSwapTransaction(transaction, retries + 1);
    } else {
      console.error("重试次数耗尽,交易失败:", error);
      throw error;
    }
  }
}

5. 整合所有步骤执行Swap

async function executeSwap() {
  try {
    const pools = await loadLiquidityPools();
    const targetPool = await getTargetPool(pools);
    
    if (!targetPool) {
      throw new Error("未找到SOL-USDC流动性池");
    }

    const transaction = await buildSwapTransaction(targetPool);
    await sendSwapTransaction(transaction);
  } catch (error) {
    console.error("Swap执行失败:", error);
  }
}

// 触发Swap执行
executeSwap();

注意事项

  • 确认SOL主网地址为So11111111111111111111111111111111111111112,替换你之前配置的旧地址
  • 确保钱包中有足够SOL支付手续费和兑换金额
  • 可提前通过Raydium接口预估输出USDC数量,避免滑点超出预期

内容的提问来源于stack exchange,提问作者Murodxon Ramazonov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 02:25:18