如何获取Solana钱包用户创建的代币?Helius接口数据缺失求助
问题:如何准确获取Solana用户创建的代币?
我尝试通过Helius的searchAssets接口获取Solana上某用户创建的代币,仅筛选FungibleToken类型(排除NFT),代码如下:
const fetchAssets = async (creatorAddress) => { try { const response = await axios.post( `https://mainnet.helius-rpc.com/?api-key=43fc-98b3-e8e33881664d`, { jsonrpc: "2.0", id: "helius-test", method: "searchAssets", params: { ownerAddress: creatorAddress, tokenType: "all", }, }, { headers: { "Content-Type": "application/json", }, } ); const items = response.data?.result?.items || []; // Ensure items array exists // Filter for only FungibleToken interface const fungibleTokens = items.filter( (item) => item.interface === "FungibleToken" ); console.log(items) const getAllMetadataSymbols = () => { return fungibleTokens .map((token) => token.content?.metadata?.symbol) // Extract metadata.symbol .filter((symbol) => symbol) // Remove undefined or null values .sort((a, b) => a.localeCompare(b)); // Sort alphabetically }; console.log(fungibleTokens) console.log(getAllMetadataSymbols()) } catch (error) { console.error(error); // Handle error } };
但实际查询发现,pump.fun显示该用户创建了20个代币,而接口返回的筛选后数组有71个代币,还漏掉了多个pump.fun上的代币。
请教:
- 如何通过Helius接口准确获取用户创建的代币?
- 是否有Helius之外的可行方法?
解决方案
1. 修正Helius接口调用逻辑
你当前代码的核心错误是用了ownerAddress参数——这个参数是获取用户持有的代币,而非用户创建的代币,这就是数量远超预期且遗漏创建代币的原因。
调整调用参数,改用creatorAddress并添加验证状态筛选:
const fetchAssets = async (creatorAddress) => { try { const response = await axios.post( `https://mainnet.helius-rpc.com/?api-key=43fc-98b3-e8e33881664d`, { jsonrpc: "2.0", id: "helius-test", method: "searchAssets", params: { creatorAddress: creatorAddress, verified: true, // 筛选已验证的创建者(pump.fun代币通常会标记) tokenType: "fungible", // 直接指定 FungibleToken,无需后续过滤 }, }, { headers: { "Content-Type": "application/json", }, } ); const items = response.data?.result?.items || []; // 直接使用返回结果,因为tokenType已限定为fungible const getAllMetadataSymbols = () => { return items .map((token) => token.content?.metadata?.symbol) .filter(Boolean) .sort((a, b) => a.localeCompare(b)); }; console.log(items); console.log(getAllMetadataSymbols()); } catch (error) { console.error(error); } };
如果仍有遗漏,可以尝试去掉verified: true,但需要注意:这会包含用户作为未验证创建者的代币,可能混入非用户主导创建的资产,需结合其他条件(比如创建者是第一个签名方)二次筛选。
2. 其他可行方法
方法一:直接调用Solana RPC的getProgramAccounts
针对Token Metadata Program(地址:metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s),通过内存比较筛选目标创建者的代币账户:
const fetchCreatedTokens = async (creatorAddress) => { try { const response = await axios.post( "https://api.mainnet-beta.solana.com/", { jsonrpc: "2.0", id: 1, method: "getProgramAccounts", params: [ "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", { filters: [ // 筛选创建者地址匹配的账户 { memcmp: { offset: 32, // 创建者地址在metadata账户中的偏移位置 bytes: creatorAddress, }, }, // 筛选已验证的创建者(可选) { memcmp: { offset: 33, // 验证状态的偏移位置 bytes: "1", }, }, // 筛选Fungible Token的metadata账户(固定大小679) { dataSize: 679, } ] } ] } ); // 解析账户数据可使用Metaplex SDK简化,避免手动处理二进制 const tokens = response.data.result.map(account => { // 示例:提取代币mint地址(metadata账户前32字节) const mint = bs58.encode(account.account.data.slice(0, 32)); return { mint }; }); console.log(tokens); } catch (error) { console.error(error); } };
方法二:使用Metaplex SDK
@metaplex-foundation/js提供了更简洁的查询方法,自动处理创建者筛选和类型区分:
import { Metaplex, keypairIdentity } from "@metaplex-foundation/js"; import { Connection, Keypair } from "@solana/web3.js"; const fetchCreatedTokens = async (creatorAddress) => { const connection = new Connection("https://api.mainnet-beta.solana.com"); const metaplex = Metaplex.make(connection); // 查询目标地址作为已验证创建者的Fungible Token const tokens = await metaplex.nfts().findAllByCreator({ creator: creatorAddress, verified: true, type: "fungible", }); console.log(tokens.map(token => ({ symbol: token.symbol, mint: token.address }))); };
内容的提问来源于stack exchange,提问作者Prabhat kumar
相关产品推荐
相关产品推荐

