Solana Devnet Raydium兑换报错:如何解决无效公钥问题?
解决Solana Devnet Raydium兑换中的无效公钥错误
错误原因分析
你的代码存在两个核心问题导致"invalid public key"错误:
1. Token构造函数参数错误
Raydium SDK的Token类第四个参数是可选的代币符号字符串(比如"SOL"、"USDC"),但你传入了wallet.publicKey(PublicKey对象),这会导致SDK在处理时错误地将其当作公钥解析,引发无效公钥报错。
2. PoolKeys参数不完整且错误
你仅传入了id字段,且使用的是Raydium的OWNER地址而非实际的SOL-USDC池地址。Raydium的Liquidity模块需要完整的池密钥信息,而非单个地址。
修复后的完整代码
const { Connection, Keypair, PublicKey } = require('@solana/web3.js'); const { Liquidity, TokenAmount, Token, Percent, DEVNET_PROGRAM_ID } = require('@raydium-io/raydium-sdk'); // 替换为你的钱包私钥数组 const privateKey = []; const wallet = Keypair.fromSecretKey(new Uint8Array(privateKey)); const devnetConnection = new Connection('https://api.devnet.solana.com'); // Devnet上的正确代币地址 const SOL_MINT = new PublicKey('So11111111111111111111111111111111111111112'); // Devnet官方USDC地址 const USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'); async function main() { // 自动获取Devnet上SOL-USDC池的完整密钥信息 const poolKeys = await Liquidity.getPoolKeys({ connection: devnetConnection, baseMint: SOL_MINT, quoteMint: USDC_MINT, programId: DEVNET_PROGRAM_ID.AmmV3, }); if (!poolKeys) { throw new Error('未找到SOL-USDC池,请确认网络和代币地址正确'); } // 正确构造Token实例:第四个参数为可选代币符号字符串 const SOL_TOKEN = new Token(devnetConnection, SOL_MINT, 9, 'SOL'); const USDC_TOKEN = new Token(devnetConnection, USDC_MINT, 6, 'USDC'); // 输入1 SOL(转换为最小单位) const rawAmountIn = 1; const amountIn = new TokenAmount(SOL_TOKEN, rawAmountIn * 10**SOL_TOKEN.decimals, false); // 设置滑点为0.5% const slippage = new Percent(50, 10000); const poolInfo = await Liquidity.fetchInfo(devnetConnection, poolKeys); const { minAmountOut } = Liquidity.computeAmountOut(poolInfo, amountIn, USDC_TOKEN, slippage); // 构建兑换交易 const { transaction, signers } = await Liquidity.makeSwapTransaction({ connection: devnetConnection, poolKeys, userKeys: { owner: wallet.publicKey, // 自动获取用户的代币账户 tokenAccounts: await Liquidity.getAssociatedTokenAccounts({ connection: devnetConnection, owner: wallet.publicKey, mints: [SOL_MINT, USDC_MINT], }), }, amountIn, amountOut: minAmountOut, fixedSide: 'in', programId: DEVNET_PROGRAM_ID.AmmV3, }); // 完善交易签名信息 transaction.recentBlockhash = (await devnetConnection.getLatestBlockhash()).blockhash; transaction.sign(wallet, ...signers); // 发送交易 const signature = await devnetConnection.sendRawTransaction(transaction.serialize()); console.log(`Transaction hash: ${signature}`); await devnetConnection.confirmTransaction(signature); console.log(`Transaction confirmed: ${signature}`); } main().catch(error => { console.error(error); });
关键修复点说明
- 修正Token构造参数:将第四个参数改为代币符号字符串(或省略),不再传入PublicKey对象。
- 获取正确PoolKeys:使用
Liquidity.getPoolKeys方法自动获取Devnet池的完整密钥,避免手动填写错误地址。 - 完善交易结构:显式设置
recentBlockhash并完成签名,确保交易格式符合Solana要求。 - 指定Devnet程序ID:使用
DEVNET_PROGRAM_ID.AmmV3适配测试网环境,避免主网程序ID导致的兼容性问题。
额外注意事项
- 确保钱包私钥数组正确填充,且钱包在Devnet上有足够SOL用于手续费和兑换。
- 如果Devnet上SOL-USDC池不存在,可通过Raydium Devnet界面创建测试池,或更换其他已存在的交易对。
内容的提问来源于stack exchange,提问作者Nico Nico
相关产品推荐
相关产品推荐

