如何通过钱包地址获取Solana NFT转账历史?有无可用API?
Solana钱包NFT转入转出历史获取方案
要获取钱包的NFT转账记录,getSignaturesForAddress本身只返回交易签名,需要解析交易里的指令数据才能筛选出NFT相关操作;另外也可以用第三方增强API直接拿到结构化结果,以下是具体方案:
方案一:解析官方RPC交易数据
通过官方RPC先拿签名,再逐个解析交易,筛选Token Transfer指令并验证是否为NFT:
步骤说明
- 用
getSignaturesForAddress获取目标地址的交易签名列表 - 遍历签名,调用
getTransaction获取完整交易详情 - 筛选出Token程序(
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)的Transfer指令(指令标识字节为03) - 解析Token账户数据,判断
decimals是否为0(NFT的Token decimal都是0) - 通过Metaplex工具验证该mint是否有NFT Metadata,确认是NFT
- 根据Transfer指令的
source和destination判断是转入还是转出
代码示例
import { Connection, PublicKey } from '@solana/web3.js'; import { Metaplex } from '@metaplex-foundation/js'; // 初始化连接和Metaplex实例 const connection = new Connection('https://api.devnet.solana.com'); const targetWallet = new PublicKey('Hhnij5YTq9oSE9EmXd8zM6L5CZboLpmmowRaeGtmm9b7'); const metaplex = Metaplex.make(connection); async function fetchNftTransferHistory() { // 获取最近50条交易签名 const sigList = await connection.getSignaturesForAddress(targetWallet, { limit: 50 }); const transferRecords = []; for (const sigInfo of sigList) { try { // 获取完整交易,指定支持的交易版本 const tx = await connection.getTransaction(sigInfo.signature, { maxSupportedTransactionVersion: 0, commitment: 'confirmed' }); if (!tx?.transaction?.message?.instructions) continue; // 遍历交易中的所有指令 for (const instr of tx.transaction.message.instructions) { // 筛选Token Transfer指令 const tokenProgramId = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'; if (instr.programId.toString() !== tokenProgramId) continue; if (instr.data.slice(0, 1).toString('hex') !== '03') continue; // Transfer指令标识 // 解析Transfer指令涉及的账户:source、destination、tokenAccount const source = new PublicKey(instr.accounts[0]); const destination = new PublicKey(instr.accounts[1]); const tokenAccount = new PublicKey(instr.accounts[2]); // 获取Token账户信息,提取mint地址和decimals const tokenAccountData = await connection.getAccountInfo(tokenAccount); if (!tokenAccountData) continue; const dataBuf = Buffer.from(tokenAccountData.data); const mintAddr = new PublicKey(dataBuf.slice(0, 32)); const decimals = dataBuf.readUInt8(64); // 只处理decimals为0的Token(NFT特征) if (decimals !== 0) continue; // 验证是否为NFT(存在Metadata) const nft = await metaplex.nfts().findByMint({ mintAddress: mintAddr }); // 判断转账类型 const transferType = destination.equals(targetWallet) ? '转入' : source.equals(targetWallet) ? '转出' : null; if (transferType) { transferRecords.push({ txSignature: sigInfo.signature, type: transferType, mint: mintAddr.toString(), nftName: nft.name, timestamp: sigInfo.blockTime ? new Date(sigInfo.blockTime * 1000) : '未知' }); } } } catch (err) { // 跳过无效交易或非NFT交易 continue; } } return transferRecords; } // 调用并打印结果 fetchNftTransferHistory().then(console.log).catch(console.error);
方案二:使用第三方增强RPC API
第三方服务商提供了结构化的NFT交易查询接口,无需手动解析交易,效率更高:
示例:Helius API
Helius支持直接筛选NFT转账记录,返回结构化数据:
async function fetchNftHistoryWithHelius() { const apiKey = '你的Helius API密钥'; const endpoint = `https://api.helius.xyz/v0/addresses/${targetWallet.toString()}/transactions?api-key=${apiKey}`; const response = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ types: ['NFT_TRANSFER'], limit: 50, network: 'devnet' }) }); const result = await response.json(); return result.transactions.map(tx => ({ txSignature: tx.signature, type: tx.nftTransfers[0].toUserAccount === targetWallet.toString() ? '转入' : '转出', mint: tx.nftTransfers[0].mint, nftName: tx.nftTransfers[0].nft.name, timestamp: new Date(tx.timestamp * 1000) })); }
类似的服务商还有QuickNode(提供qn_getNFTTransactions端点)、Alchemy,都能快速拿到NFT转账历史。
方案三:模仿Solana Explorer逻辑
Solana Explorer也是基于官方RPC,通过解析交易中的Token和Metadata指令来展示NFT历史,你可以参考它的解析逻辑,但更推荐用上述两种方案,稳定性和效率更高。
内容的提问来源于stack exchange,提问作者oijafoijf asnjksdjn
相关产品推荐
相关产品推荐

