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

Jupiter API能否单笔交易完成代币兑换并直接转至商户账户?

Jupiter API集成:单笔交易兑换代币并直接转至商户账户问题排查

问题概述

尝试通过Jupiter API实现单笔交易完成代币兑换,并将兑换后的代币直接发送至商户账户,按文档设置destinationTokenAccount为商户钱包主地址后交易失败。失败交易签名:37GAcwzCfEbydZknATZXRMjDEzMPKV5b3TF3VtM2JUD5y6cKoKWipQD5qfpB2MLtmkDsLgVhzyWrU5kdHRi9HRqh

核心问题排查

1. destinationTokenAccount参数错误

Jupiter API的destinationTokenAccount要求传入输出代币对应的关联代币账户地址,而非商户的主钱包地址。你当前传入的ANJt85VAVGhknPAhKBaS2qWVZUWW59rkQSbAg4sW4dFA是商户主地址,主地址本身不是USDC的代币账户,直接传递会触发InvalidAccountData错误,这是交易失败的主要原因。

2. 交易签名逻辑错误

在sendTransaction函数中,你已完成交易签名得到signedTransaction,但后续模拟和发送时使用的是未签名的原始transaction,会导致交易因缺少有效签名而失败。

3. 交易块哈希覆盖问题

Jupiter返回的swapTransaction已包含有效块哈希,手动覆盖transaction.recentBlockhash会破坏交易的有效性。

修正方案

步骤1:获取商户的输出代币关联账户地址

使用@solana/spl-token库计算商户主地址对应的USDC关联账户地址:

import { getAssociatedTokenAddress } from '@solana/spl-token';

// 计算商户的USDC关联账户地址
const merchantUsdcAccount = await getAssociatedTokenAddress(
  new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDC mint地址
  new PublicKey("ANJt85VAVGhknPAhKBaS2qWVZUWW59rkQSbAg4sW4dFA"), // 商户主地址
  false
);

将该地址作为destinationTokenAccount传入Jupiter的swap接口。

步骤2:修复交易签名与发送逻辑

修改sendTransaction函数,使用签名后的交易进行模拟和发送:

const sendTransaction = async (swapTransaction: string, walletAdapter: WalletAdapter) => {
  const versionedMessage = VersionedMessage.deserialize(Buffer.from(swapTransaction, 'base64'));
  const transaction = new VersionedTransaction(versionedMessage);
  
  // Jupiter返回的交易已包含有效块哈希,无需手动覆盖
  transaction.feePayer = walletAdapter.publicKey;
  
  // 签名交易
  const signedTransaction = await walletAdapter.signTransaction(transaction);
  
  // 模拟签名后的交易
  const simulation = await connection.simulateTransaction(signedTransaction, { commitment: "finalized" });
  if (simulation.value.err) {
    throw new Error(`Simulation failed: ${simulation.value.err.toString()}`);
  }

  // 发送签名后的交易
  try {
    const signature = await connection.sendRawTransaction(signedTransaction.serialize(), {
      maxRetries: 5,
      skipPreflight: false, // 开启预检查提前发现问题
      preflightCommitment: "finalized",
    });

    // 确认交易
    const confirmation = await connection.confirmTransaction({
      signature,
      blockhash: transaction.message.recentBlockhash,
      lastValidBlockHeight: transaction.message.lastValidBlockHeight,
    }, "finalized");

    if (confirmation.value.err) {
      throw new Error(`Transaction not confirmed: ${confirmation.value.err.toString()}`);
    }

    console.log("Confirmed: ", signature);
  } catch (error) {
    console.error("Failed: ", error);
    throw error;
  }
};

步骤3:调整swap接口请求参数

将skipUserAccountsRpcCalls设为false,让Jupiter自动处理账户检查与创建逻辑:

const requestBody = {
  userPublicKey: walletAddress.toBase58(),
  destinationTokenAccount: merchantUsdcAccount.toBase58(), // 使用计算出的关联账户地址
  useSharedAccounts: true,
  quoteResponse: swapInfo.quoteResponse,
  skipUserAccountsRpcCalls: false,
};

功能可行性确认

Jupiter API完全支持单笔交易完成兑换并直接将代币发送至第三方账户的场景,只要正确传递destinationTokenAccount为目标代币的关联账户地址,即可实现该功能。

内容的提问来源于stack exchange,提问作者creative pioneer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:38:14