Parser of NFT Collections Data (Floor Price, Volume, Holders)
The OpenSea API returns floor price with a 5–15 minute delay and aggregates data according to its own methodology. For trading bots, analytical platforms, and minting dApps that need a real floor, this is unacceptable. We build parsers that read events directly from the blockchain, providing accuracy down to the second. This is the only way to get an up-to-date floor without delays.
Our experience — 5+ years in blockchain development and dozens of NFT data parsing projects. We know all the nuances: chain reorganizations, validator rate limits, wash trading, and how to handle them. We guarantee stable parser operation even on high-traffic collections.
In this article we'll break down the full architecture of an NFT data parser: stack selection, event indexing, floor price calculation, storage in ClickHouse, and typical pitfalls. We'll also show what's included in our turnkey solution.
Data Sources: Where to Get What
On-Chain Events
For ERC-721/ERC-1155 collections, all sales are visible through marketplace events. Each marketplace emits its own event:
- OpenSea Seaport:
OrderFulfilled(...)— contract0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC - Blur:
TakerAsk/TakerBidon0x000000000000Ad05Ccc4F10045630fb830B95127 - LooksRare v2:
TakerAsk/TakerBid - X2Y2:
EvInventory
Floor price cannot be obtained directly from events — events show executed orders, not active listings. For an up-to-date floor, you need to either index active listings via marketplace API or use aggregators.
Holders and Transfers
Transfer(address indexed from, address indexed to, uint256 indexed tokenId) — ERC-721 standard. The full ownership graph is built by replaying all Transfer events from the deployment block. Unique holders = unique to addresses minus addresses that later transferred the token to another address.
For ERC-1155: TransferSingle and TransferBatch. Here ownership is a balance, not a binary state: balanceOf(address, tokenId).
How We Compute Floor Price?
Two approaches:
1. Marketplace API aggregation — query floor from OpenSea, Blur, LooksRare, take the minimum. Problem: rate limits and caching on the API side. We use a 60-second cache and fallback when limits are exceeded.
2. Orderbook indexing — subscribe to order creation/cancellation events. Seaport: OrderValidated (creation), OrderCancelled, OrderFulfilled (execution). Build a local orderbook, compute floor yourself. More accurate, but harder to maintain when marketplace contracts update. We recommend the first approach for most projects, the second for trading bots requiring sub-second response.
| Method | Accuracy | Complexity | Latency |
|---|---|---|---|
| API aggregation | Medium | Low | ~60 sec |
| Orderbook | High | Medium | <5 sec |
Parser Architecture
Stack
ethereum-node (Alchemy/Infura/Quicknode) → ethers.js / viem (event filtering) → message queue (Redis Streams / BullMQ) → PostgreSQL / ClickHouse (storage) → REST/WebSocket API (data delivery) For historical data — getLogs with filter by address and topics[0]. Batch blocks by 2000 (limit of most RPC providers on eth_getLogs):
async function fetchTransferEvents( contract: string, fromBlock: number, toBlock: number, provider: JsonRpcProvider ) { const iface = new Interface(['event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)']); const filter = { address: contract, topics: [iface.getEventTopic('Transfer')], fromBlock, toBlock, }; const logs = await provider.getLogs(filter); return logs.map(log => iface.parseLog(log)); } For real-time: WebSocket subscription via provider.on(filter, callback) or Alchemy eth_subscribe newLogs.
Storage and Queries
ClickHouse is more efficient than PostgreSQL for time-series NFT data — analytical queries on millions of rows are 10–50x faster. Schema:
| Column | Type | Description |
|---|---|---|
block_number |
UInt64 | Block of event |
tx_hash |
FixedString(66) | Transaction hash |
contract |
FixedString(42) | Collection address |
token_id |
UInt256 | Token ID |
from |
FixedString(42) | Seller/sender |
to |
FixedString(42) | Buyer/recipient |
price_wei |
UInt256 | Price in wei |
marketplace |
LowCardinality(String) | Marketplace |
timestamp |
DateTime | Block time |
Partitioning by month (toYYYYMM(timestamp)), sorting key (contract, timestamp).
Why On-Chain Data Is More Accurate Than OpenSea API?
OpenSea API uses its own order pool and caches floor price with a delay of up to 15 minutes. This is critical for arbitrage bots and real-time analytics. On-chain data is the single source of truth. We guarantee accuracy up to the last confirmed block (finality in 2 epochs — 64 blocks on Ethereum PoS).
Solving Typical Problems
Rate Limits
Alchemy Free — 330 CUPS, Growth — 660 CUPS. When historically parsing a large collection (BAYC: 500k+ Transfer events) without throttling you'll get 429. We implement exponential backoff + queue with concurrency control.
How to avoid rate limits during historical parsing?
Use exponential backoff and multiple RPC endpoints. We configure a queue with a maximum of 5 parallel requests and a 30-second timeout.Blockchain Reorganizations
Events from the last 12 blocks should be marked as "pending" and confirmed only after finality. For Ethereum PoS — 2 epochs (64 blocks) for economic finality.
Wash Trading
Volume from addresses with circular transfers distorts statistics. Basic heuristic: trades where from and to are related addresses (received ETH from the same source) are flagged.
What's Included
- Parser architecture tailored to your task
- TypeScript code using ethers.js/viem
- ClickHouse setup for storage and analytics
- Grafana dashboard with key metrics (floor price, volume, holders)
- REST/WebSocket API for integration with your application
- Full documentation and team training
- Post-launch support
We provide a turnkey solution. We'll assess your project in 1 day.
Timeline Estimates
Parser for Transfer events + holders tracker — 1 day. Adding floor price via marketplace API + cache — another half day. Historical backfill for a large collection + dashboard — 2-3 days total.
Contact us for a consultation and an accurate estimate for your project.







