如何获取Solana上特定Metaplex Auction House的所有挂售NFT
特定Metaplex Auction House挂售状态NFT拉取实现方案
所有方案的核心逻辑一致:Metaplex Auction House的挂售状态对应链上有效Listing账户——只要挂单没有被卖家取消、没有被成交、没有过有效期,就属于在售状态,不需要额外做复杂状态判断。
方案1:官方SDK+RPC直连扫链(适合挂单量千级以内的小型Auction House,无第三方依赖)
- 先引入Metaplex官方JS SDK,初始化连接和目标Auction House实例,优先用私有RPC节点,公共RPC限流严重基本跑不通全量拉取:
import { Metaplex } from "@metaplex-foundation/js"; import { Connection, PublicKey } from "@solana/web3.js"; // 替换成自己的私有RPC地址 const connection = new Connection("你的RPC节点地址", "confirmed"); const metaplex = Metaplex.make(connection); // 替换成目标Auction House的链上地址 const TARGET_AH_ADDRESS = new PublicKey("目标Auction House地址"); const auctionHouse = await metaplex .auctionHouse() .findAuctionHouseByAddress({ address: TARGET_AH_ADDRESS });
- 翻页拉取所有有效挂单,SDK内置的
findListings方法会自动过滤已取消、已成交、已过期的无效挂单,不需要自己解析账户状态:
const activeListings = []; let currentPage = 1; const PAGE_SIZE = 1000; while (true) { const { results, hasNextPage } = await metaplex.auctionHouse().findListings({ auctionHouse, page: currentPage, limit: PAGE_SIZE }); activeListings.push(...results); if (!hasNextPage) break; currentPage++; }
- 返回的Listing结果里自带
asset字段,包含对应NFT的mint地址、元数据、图片、属性、挂单价格、卖家地址全量信息,不需要额外请求NFT账户做二次查询。
方案2:基于链上索引服务查询(适合挂单量过万的中大型Auction House,查询速度快)
如果用RPC直连扫链速度太慢,可以直接对接链上索引服务做查询,核心过滤条件写对就能直接拿到结果:
- 查询Listing表时固定加四个过滤规则:
auctionHouse字段等于目标AH地址、canceledAt字段为空(未取消)、purchase字段为空(未成交)、expiry字段值大于当前链上时间戳(未过期) - 关联查询对应mint地址的NFT元数据,和挂单价格、卖家地址拼接后就是完整的在售NFT数据
注意:索引服务普遍有1-3个区块的同步延迟,对实时性要求极高的场景,需要对最新区块的事件用RPC做二次校验。
方案3:自建索引实时同步(适合有长期运维需求、定制化要求高的场景)
如果需要长期稳定获取该AH的在售数据,最可控的方案是自己搭轻量索引服务:
- 服务启动时先按方案1的逻辑全量拉取一次当前所有有效挂单,作为基线数据存入本地数据库
- 之后持续订阅该Auction House地址的三类链上事件:
ListingCreated(新挂单,新增记录)、ListingCanceled(取消挂单,删除对应记录)、SaleExecuted(成交,删除对应记录) - 监听到新挂单事件时同步拉取对应NFT的元数据存在本地,后续查询直接读本地库即可,数据延迟可以控制在1个区块以内
注意:要定期(比如每24小时)做一次本地数据和链上数据的全量对账,避免因为节点丢块、漏监听事件导致数据不准。
避坑提醒:Listing账户在挂单取消、成交之后不会被链上销毁,只会在账户字段里打对应的状态标记,不要自己手动解析所有Listing账户判断状态,很容易漏判字段把无效挂单算成在售,优先用SDK封装好的状态解析逻辑。
内容的提问来源于stack exchange,提问作者Pratik.js
相关产品推荐
相关产品推荐

