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

如何在Solana链交易数据中精准筛选获取NFT转账记录

Solana 接收NFT交易的筛选判断方法

不能仅通过是否属于SPL-Token交易判断NFT,所有Solana上的同质化代币(USDC、RAY等)同样基于SPL-Token标准实现,仅判断SPL交易会混入大量普通代币转账记录。

核心判断标识

需要同时满足以下3个条件,才能判定为有效NFT转账交易:

  • 对应SPL Mint资产的基础参数校验:Mint账户的总供应量supply严格等于1,小数位数decimals严格等于0,这是NFT非同质化的基础属性要求,可直接过滤掉99%以上的同质化代币
  • 元数据标准校验:Solana生态绝大多数NFT遵循Metaplex标准,每个合规NFT的Mint地址会派生固定规则的元数据PDA账户,派生所用程序ID为metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s,派生种子为["metadata", 元数据程序ID, Mint公钥],只有能查询到对应有效元数据账户的资产,才是正规NFT,可排除恶意发行的单枚零小数SPL代币冒充NFT的情况
  • 交易有效性与方向校验:仅统计meta.err为空的成功交易,且通过对比交易前后preTokenBalances和postTokenBalances的差值,确认目标钱包对应Token账户的资产余额增加量为1(零小数场景下1代表1枚完整NFT),避免统计到钱包向外转出NFT、或同笔交易内无关地址的代币变动。

现有代码的问题

你当前实现存在以下漏判、误判问题:

  1. 未对Mint资产做参数校验,会把所有SPL代币转账都纳入统计,包含大量普通同质化币记录
  2. 仅读取交易后余额,未对比交易前后余额差值,无法判断转账方向,会误计入钱包转出交易、同交易无关地址的代币记录
  3. 未过滤失败交易,链上回滚的失败交易也会被统计
  4. 未做Metaplex元数据校验,无法区分正规NFT和随意发行的单枚SPL测试币

修正后的参考实现代码

import {
    clusterApiUrl,
    Connection,
    PublicKey,
    ParsedTransactionWithMeta,
} from '@solana/web3.js';
import fs from 'fs';
import path from 'path';

const WALLET = "<WALLET>"; // 接收NFT的钱包地址
const METADATA_PROGRAM_ID = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s");

(async () => {
    const connection = new Connection(clusterApiUrl('mainnet-beta'));
    const targetWallet = new PublicKey(WALLET);
    const nftTransfers = [];

    // 拉取地址相关交易签名
    const signatures = await connection.getConfirmedSignaturesForAddress2(targetWallet, {
        limit: 100,
    });

    for (const sigInfo of signatures) {
        const tx: ParsedTransactionWithMeta | null = await connection.getParsedTransaction(sigInfo.signature, 'finalized');
        if (!tx || tx.meta?.err) continue; // 跳过失败交易、空交易

        // 整理交易前余额映射:key为<Mint地址_owner地址>,value为余额
        const preBalanceMap = new Map();
        tx.meta.preTokenBalances?.forEach(balance => {
            const key = `${balance.mint}_${balance.owner}`;
            preBalanceMap.set(key, Number(balance.uiTokenAmount.amount));
        });

        // 遍历交易后余额,找目标钱包余额增加的记录
        for (const postBalance of tx.meta.postTokenBalances || []) {
            if (postBalance.owner !== targetWallet.toString()) continue;
            
            const key = `${postBalance.mint}_${postBalance.owner}`;
            const preAmount = preBalanceMap.get(key) || 0;
            const postAmount = Number(postBalance.uiTokenAmount.amount);
            const delta = postAmount - preAmount;

            // 余额增加量不是1的直接跳过(NFT转1枚)
            if (delta !== 1) continue;

            const mintPubkey = new PublicKey(postBalance.mint);
            // 1. 校验Mint参数:supply=1,decimals=0
            const mintInfo = await connection.getParsedAccountInfo(mintPubkey);
            if (!mintInfo.value) continue;
            const mintData = mintInfo.value.data as any;
            if (
                mintData.parsed.info.decimals !== 0 ||
                Number(mintData.parsed.info.supply) !== 1
            ) continue;

            // 2. 校验Metaplex元数据账户存在
            const [metadataPDA] = await PublicKey.findProgramAddress(
                [Buffer.from("metadata"), METADATA_PROGRAM_ID.toBuffer(), mintPubkey.toBuffer()],
                METADATA_PROGRAM_ID
            );
            const metadataAccount = await connection.getAccountInfo(metadataPDA);
            if (!metadataAccount) continue;

            // 所有校验通过,记录为有效NFT转入
            nftTransfers.push({
                signature: sigInfo.signature,
                blockTime: tx.blockTime,
                mint: postBalance.mint,
                slot: tx.slot
            });
        }
    }

    fs.writeFileSync(
        path.join(process.cwd(), 'nft-transfers.json'),
        JSON.stringify(nftTransfers, null, 2)
    );
})();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:30:52