基于Jupiter实现SOL兑换USDC报错如何排查与解决?
报错根因
你遇到的TypeError: Cannot read properties of undefined (reading 'address')是Array.find()匹配失败导致的:自定义的getTokens()返回的代币列表没有覆盖目标代币,或是你配置的environment.swap.WrappedSolAddress值错误,导致inputToken/outputToken为undefined,后续读取.address属性时直接触发报错。
Solana主网Wrapped SOL(wSOL)的合约地址是固定值So11111111111111111111111111111111111111112,不需要从自定义代币列表里匹配获取。
SOL兑换USDC的实现逻辑
原生SOL是Solana网络的原生资产,不是SPL代币,包括Jupiter在内的所有Solana DEX聚合器、AMM池都只支持SPL代币交易,因此原生SOL兑换的本质是:
- 兑换时自动将指定数量的原生SOL包装为等值wSOL(SPL格式的包装SOL,和原生SOL1:1锚定)
- 用wSOL通过路由池兑换为USDC
- 兑换完成后自动将残留的少量wSOL(如果有)解包换回原生SOL退回钱包
整个包装、解包流程Jupiter SDK默认自动处理,不需要手动编写wSOL兑换逻辑。
修复后的可运行代码
import { Jupiter } from "@jup-ag/core"; import { PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js"; // 主网固定合约地址,无需修改 const WSOL_MINT = new PublicKey("So11111111111111111111111111111111111111112"); const USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); // 初始化Jupiter实例 const jupiter = await Jupiter.load({ connection: this.connection, cluster: "mainnet-beta", user: wallet, // wrapUnwrapSOL默认值为true,自动处理SOL的包装解包,不需要额外配置 }); // 计算兑换路由 const routes = await jupiter.computeRoutes({ inputMint: WSOL_MINT, outputMint: USDC_MINT, inputAmount: LAMPORTS_PER_SOL * 1, // 兑换1枚SOL slippage: 1, // 滑点1%,可根据需求调整 }); // 校验路由可用性 if (!routes.routesInfos?.length) { throw new Error("无可用兑换路由,请稍后重试或调整滑点"); } // 执行兑换 const { execute } = await jupiter.exchange({ routeInfo: routes.routesInfos[0], // 取最优路由(路由列表默认按兑换收益从高到低排序) }); const swapResult = await execute(); console.log("兑换交易完成,结果:", swapResult);
注意事项
- 不要提前手动将SOL兑换为wSOL再发起交易,SDK自动处理包装解包的逻辑会优先使用钱包原生SOL,手动兑换的wSOL可能不会被识别为输入资产
- 钱包内需要留存至少0.005 SOL作为交易手续费,不要将全部SOL都计入兑换金额,否则会触发余额不足报错
- 如果在devnet测试,不要使用主网的wSOL、USDC地址,devnet的测试代币地址需要从官方水龙头获取,主网地址在测试网无法匹配到路由
- 若路由计算失败,可适当调大滑点参数,主网SOL/USDC交易深度足够,正常情况下0.5%滑点即可完成交易
内容的提问来源于stack exchange,提问作者Harold Castro Castillo
相关产品推荐
相关产品推荐

