基于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
相关产品推荐
相关产品推荐

