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

如何使用solana/web3.js v2获取钱包中代币的mint地址

Solana Web3.js 2.0 提取钱包代币Mint地址解决方案

问题描述

能获取钱包内的代币账户数据,但无法从中提取Mint地址,需要拿到所有代币的Mint地址用于API调用,当前使用Solana Web3.js 2.0版本,相关示例较少。

现有代码:

const TOKEN_PROGRAM_ID = address('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')
const { value: tokensInWallet} = await rpc
  .getTokenAccountsByOwner(
    address('XXX'),
    { programId: TOKEN_PROGRAM_ID },
    { encoding: 'base64'}
  )
  .send();
console.log(tokensInWallet);

//expect mint jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL for JTO token
tokensInWallet.map(tokenAccount => {
  const encoded = getBase64Encoder().encode(tokenAccount.account.data[0]);
  console.log(encoded);
  //now turn into this format of the mint
  //base58 encode
  const mint = getBase58Encoder().encode(tokenAccount.pubkey);
  console.log(Buffer.from(mint).toString('base64'));
})

尝试对数据编码/解码但没有进展,返回的代币账户数据结构如下:

[
  {
    "account": {
      "data": [
        "Cvz4louNq4hIHi0q5onJUsdXrrpkPjkZ6J8uVXlcdsEpwCylBRLH6qBLpURZ/jc3h9wTxgzMrD4rEPcp06WvvwAoa+4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
        "base64"
      ],
      "executable": false,
      "lamports": 2039280n,
      "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
      "rentEpoch": 18446744073709551615n,
      "space": 165n
    },
    "pubkey": "3UoZPNLp1eynjjCEEcKyv3VcXtoZCe5GdEt2agDezD31"
  }
]

解决方案

方法1:使用@solana/spl-token库解析(推荐)

Solana的SPL Token库提供了现成的账户布局解析工具,无需手动处理字节:

  1. 首先安装依赖:
npm install @solana/spl-token
  1. 修改代码如下:
import { address, Connection } from '@solana/web3.js';
import { AccountLayout } from '@solana/spl-token';

const TOKEN_PROGRAM_ID = address('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const rpc = new Connection('https://api.mainnet-beta.solana.com'); // 替换为你的RPC地址

async function getWalletTokenMints(walletAddress: string) {
  const { value: tokensInWallet } = await rpc
    .getTokenAccountsByOwner(
      address(walletAddress),
      { programId: TOKEN_PROGRAM_ID },
      { encoding: 'base64' }
    )
    .send();

  const mintAddresses = tokensInWallet.map(tokenAccount => {
    // 将base64数据转换为Buffer
    const dataBuffer = Buffer.from(tokenAccount.account.data[0], 'base64');
    // 用AccountLayout解析Token账户数据
    const accountInfo = AccountLayout.decode(dataBuffer);
    // 提取并转换为base58格式的Mint地址
    const mintAddress = address(accountInfo.mint);
    return mintAddress;
  });

  console.log('所有代币Mint地址:', mintAddresses);
  return mintAddresses;
}

// 调用函数,替换为目标钱包地址
getWalletTokenMints('XXX');

方法2:手动解析字节(无需额外依赖)

如果不想安装额外库,可以手动解析Token Account的二进制数据:Token Account数据中,Mint地址从第32字节开始,连续占32字节(前32字节为账户所有者地址)。

修改代码如下:

import { address, Connection, bs58 } from '@solana/web3.js';

const TOKEN_PROGRAM_ID = address('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const rpc = new Connection('https://api.mainnet-beta.solana.com');

async function getWalletTokenMints(walletAddress: string) {
  const { value: tokensInWallet } = await rpc
    .getTokenAccountsByOwner(
      address(walletAddress),
      { programId: TOKEN_PROGRAM_ID },
      { encoding: 'base64' }
    )
    .send();

  const mintAddresses = tokensInWallet.map(tokenAccount => {
    const dataBuffer = Buffer.from(tokenAccount.account.data[0], 'base64');
    // 截取32-64字节的Mint地址二进制数据
    const mintBuffer = dataBuffer.slice(32, 64);
    // 转换为base58格式
    const mintAddress = bs58.encode(mintBuffer);
    return mintAddress;
  });

  console.log('所有代币Mint地址:', mintAddresses);
  return mintAddresses;
}

getWalletTokenMints('XXX');

说明

  • 推荐使用方法1,SPL Token库会处理更多边界情况,后续Token账户结构更新也无需手动调整代码。
  • 确保Web3.js版本为2.x,address函数和rpc调用方式符合2.x规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:21:04