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

使用@solana-labs/web3.js发送USDC时无法获取钱包签名器报错

Solana使用钱包适配器发送USDC报错解决

你遇到的报错信息如下:

Argument of type 'WalletAdapter' is not assignable to parameter of type 'Signer'. Property 'secretKey' is missing in type 'WalletAdapter' but required in type 'Signer'.

报错原因

旧版@solana/spl-token的Token类构造函数要求传入的签名器必须包含secretKey私钥属性,而浏览器钱包适配器(如Phantom、Solflare等)出于安全设计不会暴露用户私钥,因此不可能拿到符合要求的Signer实例,你原来的代码写法只适用于服务端持有私钥的签名场景,不适合前端接入用户钱包的场景。

修正方案

不用实例化Token类,直接构造转账交易,调用钱包提供的签名方法完成签名即可,参考代码如下:

import { Connection, PublicKey, Transaction, clusterApiUrl } from '@solana/web3.js';
import { getAssociatedTokenAddress, createTransferCheckedInstruction, createAssociatedTokenAccountInstruction, TOKEN_PROGRAM_ID } from '@solana/spl-token';

const connection = new Connection(clusterApiUrl("devnet"));
// 注意:此处为Solana主网USDC铸币地址,devnet测试请替换为对应测试币地址
const USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const USDC_DECIMALS = 6; // USDC固定为6位小数

async function sendUSDC(toAddress, amount) {
  const toPubkey = new PublicKey(toAddress);
  // 1. 获取发送方USDC关联代币账户地址
  const fromTokenAccount = await getAssociatedTokenAddress(
    USDC_MINT,
    wallet.publicKey
  );
  // 2. 获取接收方USDC关联代币账户地址
  const toTokenAccount = await getAssociatedTokenAddress(
    USDC_MINT,
    toPubkey
  );

  const transaction = new Transaction();
  // 3. 若接收方无对应USDC账户,先添加创建账户指令
  const toAccountInfo = await connection.getAccountInfo(toTokenAccount);
  if (!toAccountInfo) {
    transaction.add(
      createAssociatedTokenAccountInstruction(
        wallet.publicKey,
        toTokenAccount,
        toPubkey,
        USDC_MINT
      )
    );
  }

  // 4. 添加USDC转账指令
  transaction.add(
    createTransferCheckedInstruction(
      fromTokenAccount,
      USDC_MINT,
      toTokenAccount,
      wallet.publicKey,
      amount * Math.pow(10, USDC_DECIMALS), // 金额需换算为最小单位
      USDC_DECIMALS
    )
  );

  // 5. 补充交易必填参数
  const latestBlockhash = await connection.getLatestBlockhash();
  transaction.recentBlockhash = latestBlockhash.blockhash;
  transaction.feePayer = wallet.publicKey;

  // 6. 调用钱包签名并发送交易
  const signedTx = await wallet.signTransaction(transaction);
  const txId = await connection.sendRawTransaction(signedTx.serialize());
  await connection.confirmTransaction(txId);
  
  return txId;
}

注意事项

  • 测试环境下请替换为devnet对应的USDC测试币铸币地址,使用主网地址在devnet环境会报错
  • 转账金额需要乘以USDC的小数位(6位),比如转1枚USDC对应的数值为1000000
  • 确保钱包已授权连接,且wallet实例已正常获取到用户公钥

内容的提问来源于stack exchange,提问作者Drey Sven

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:24:04