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

如何在Solana中快速获取主版NFT的所有衍生版?

问题

尝试获取某主版NFT(Master Edition NFT)的所有衍生版。根据文档,存在一个PDA(程序派生地址)用于关联衍生版与主版,但无法通过Metaplex/Solana SDK以编程方式找到该关联关系。

当前解决方案是解析主版NFT的所有交易,筛选出创建衍生版的记录,但交易数量大时速度极慢。代码如下:

import {JsonMetadata, Metadata, Metaplex, TaskStatus} from "@metaplex-foundation/js";
import {Connection, PublicKey, ConfirmedSignatureInfo} from "@solana/web3.js";
import * as fs from "fs";

const RPC_URL = 'https://...';
const MASTER_EDITION_ADDRESS = '';

(async () => {
    const connection = new Connection(RPC_URL);
    const metaplex = new Metaplex(connection);

    const start = new Date().toISOString()

    // Paginate transactions from Master Edition

    const signatures: { signature: string; }[] = []
    let before: string | undefined = undefined;
    while (true) {
        const sigs: ConfirmedSignatureInfo[] = await metaplex.connection.getSignaturesForAddress(
            new PublicKey(MASTER_EDITION_ADDRESS),
            {
                before: before
            },
            'finalized'
        )
        if (!sigs.length) break
        signatures.push(...sigs)
        before = sigs[sigs.length - 1].signature
    }

    // Parse Transactions and find new edition mints

    const hashlist: string[] = []
    for (let i = 0; i < signatures.length; i++) {
        console.log(`${i}/${signatures.length}`);
        await metaplex.connection.getParsedTransaction(signatures[i].signature).then(tx => {
            if (!tx) return

            if (JSON.stringify(tx).toLowerCase().includes('error')) return

            if (JSON.stringify(tx).includes('Mint New Edition from Master Edition')) {
                console.log(JSON.stringify(tx, null, 4))
                hashlist.push(tx.transaction.message.accountKeys[1].pubkey.toString());
            }
        });
    }

    console.log('found:', hashlist.length, 'items')
})()

前提假设:

  • 首个创建者并非该集合独有(非Candy Machine创建)
  • 更新权限并非该集合独有,可用于其他集合

请问是否存在快速可靠的实现方式?

解决方案

可以通过直接查询关联主版NFT的衍生版PDA来快速获取所有衍生版,无需遍历全部交易,具体实现如下:

1. 核心原理

Metaplex的Token Metadata程序中,每个衍生版(Edition)账户的PDA会存储主版NFT的MasterEdition账户地址作为parent字段。我们可以利用Solana RPC的getProgramAccounts方法,批量过滤出所有引用目标主版MasterEdition地址的Edition账户,直接提取衍生版的Mint地址。

2. 优化后的代码实现

import { Connection, PublicKey } from "@solana/web3.js";
import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from "@metaplex-foundation/mpl-token-metadata";

const RPC_URL = "https://...";
const MASTER_EDITION_ADDRESS = ""; // 填入目标主版的MasterEdition账户地址

(async () => {
  const connection = new Connection(RPC_URL);
  
  // 构建过滤器:匹配所有parent字段为目标MasterEdition地址的Edition账户
  const filters = [
    {
      dataSize: 67, // Edition账户的固定数据大小:1字节判别符 + 32字节parent + 32字节mint
    },
    {
      memcmp: {
        offset: 1, // parent字段从第1字节开始(跳过1字节的账户判别符)
        bytes: MASTER_EDITION_ADDRESS,
      },
    },
  ];

  // 查询所有符合条件的Edition账户
  const editionAccounts = await connection.getProgramAccounts(
    TOKEN_METADATA_PROGRAM_ID,
    { filters }
  );

  // 提取每个Edition对应的衍生版Mint地址
  const derivativeMints = editionAccounts.map(account => {
    // Mint地址存储在data的第33-65字节位置(1+32字节之后)
    const mintPubkey = new PublicKey(account.account.data.slice(33, 65));
    return mintPubkey.toString();
  });

  console.log("找到衍生版数量:", derivativeMints.length);
  console.log("衍生版Mint列表:", derivativeMints);
})();

3. 优势说明

  • 速度极快:直接通过RPC批量过滤账户,无需遍历历史交易,处理大规模数据时效率远超原方案。
  • 准确性高:基于Metaplex账户结构的固定规则查询,不会遗漏或误判衍生版。
  • 可扩展性强:如果需要衍生版的元数据,可基于获取到的Mint地址,通过Metaplex SDK的findMetadataByMint方法进一步查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:24:29