Парсинг даних NFT-колекцій: floor price, volume, holders та аналітика

Парсинг даних NFT-колекцій (floor price, volume, holders) OpenSea API повертає floor price із затримкою 5-15 хвилин та агрегує дані за своєю методологією. Для торгових ботів, аналітичних платформ та minting dApps, яким потрібен реальний floor — це неприйнятно. **Ми розробляємо парсери, які читают

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1451
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1270
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1011

Парсинг даних NFT-колекцій (floor price, volume, holders)

OpenSea API повертає floor price із затримкою 5-15 хвилин та агрегує дані за своєю методологією. Для торгових ботів, аналітичних платформ та minting dApps, яким потрібен реальний floor — це неприйнятно. Ми розробляємо парсери, які читають події прямо з блокчейну, забезпечуючи точність до секунди. Це єдиний спосіб отримати актуальний floor без затримок.

Наш досвід — 5+ років у блокчейн-розробці та десятки проєктів з парсингу NFT-даних. Ми знаємо всі тонкощі: реорганізації ланцюжків, rate limits валідаторів, wash trading та як їх обробляти. Гарантуємо стабільну роботу парсера навіть на високонавантажених колекціях.

У цій статті розберемо повну архітектуру парсера NFT-даних: вибір стеку, індексування подій, обчислення floor price, зберігання в ClickHouse та типові проблеми. Також покажемо, що входить у наше рішення під ключ.

Джерела даних: що звідки брати

On-chain події

Для ERC-721/ERC-1155 колекцій всі продажі видно через події маркетплейсів. Кожен маркетплейс емітує власну подію:

  • OpenSea Seaport: OrderFulfilled(...) — контракт 0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC
  • Blur: TakerAsk / TakerBid на 0x000000000000Ad05Ccc4F10045630fb830B95127
  • LooksRare v2: TakerAsk / TakerBid
  • X2Y2: EvInventory

Floor price не можна отримати з подій напряму — події показують виконані ордери, а не активні лістинги. Для актуального floor потрібно або індексувати active listings через маркетплейс API, або використовувати агрегатори.

Holders та transfers

Transfer(address indexed from, address indexed to, uint256 indexed tokenId) — стандарт ERC-721. Повний граф володіння будується через replay всіх Transfer подій від блоку деплою. Unique holders = унікальні адреси to за вирахуванням адрес, які потім перевели токени на іншу адресу.

Для ERC-1155: TransferSingle та TransferBatch. Тут володіння — це баланс, не бінарний стан: balanceOf(address, tokenId).

Як ми обчислюємо floor price?

Два підходи:

1. Маркетплейс API агрегація — запитуємо floor у OpenSea, Blur, LooksRare, беремо мінімум. Проблема: rate limits та кешування на стороні API. Ми використовуємо кеш на 60 секунд і fallback при перевищенні лімітів.

2. Orderbook індексування — підписуємося на події створення/скасування ордерів. Seaport: OrderValidated (створення), OrderCancelled, OrderFulfilled (виконання). Будуємо локальний orderbook, обчислюємо floor самостійно. Точніше, але складніше в підтримці при оновленнях контрактів маркетплейса. Ми рекомендуємо перший підхід для більшості проєктів, другий — для торгових ботів із субсекундним відгуком.

Метод Точність Складність Затримка
API агрегація Середня Низька ~60 сек
Orderbook Висока Середня <5 сек

Архітектура парсера

Стек

ethereum-node (Alchemy/Infura/Quicknode) → ethers.js / viem (event filtering) → message queue (Redis Streams / BullMQ) → PostgreSQL / ClickHouse (storage) → REST/WebSocket API (видача даних) 

Для історичних даних — getLogs з фільтром по address та topics[0]. Блоки батчимо по 2000 (обмеження більшості RPC провайдерів на 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)); } 

Для real-time: WebSocket підписка через provider.on(filter, callback) або Alchemy eth_subscribe newLogs.

Зберігання та запити

ClickHouse ефективніший за PostgreSQL для time-series NFT даних — аналітичні запити на мільйонах рядків у 10-50x швидші. Схема:

Колонка Тип Опис
block_number UInt64 Блок події
tx_hash FixedString(66) Хеш транзакції
contract FixedString(42) Адреса колекції
token_id UInt256 ID токена
from FixedString(42) Продавець/відправник
to FixedString(42) Покупець/отримувач
price_wei UInt256 Ціна в wei
marketplace LowCardinality(String) Маркетплейс
timestamp DateTime Час блоку

Партиціонування по місяцях (toYYYYMM(timestamp)), сортувальний ключ (contract, timestamp).

Чому on-chain дані точніші за OpenSea API?

OpenSea API використовує власний пул ордерів і кешує floor price із затримкою до 15 хвилин. Це критично для арбітражних ботів та аналітики в реальному часі. On-chain дані — єдине джерело істини. Ми гарантуємо точність до останнього підтвердженого блоку (фіналізація за 2 епохи — 64 блоки на Ethereum PoS).

Вирішення типових проблем

Rate limits

Alchemy Free — 330 CUPS, Growth — 660 CUPS. При історичному парсингу великої колекції (BAYC: 500k+ Transfer подій) без throttling отримаємо 429. Реалізуємо exponential backoff + queue з concurrency control.

Як уникнути rate limits при історичному парсингу? Використовуйте exponential backoff та кілька RPC ендпоінтів. Ми налаштовуємо чергу з максимум 5 паралельними запитами та таймаутом 30 секунд.

Реорганізації блокчейну

Події з останніх 12 блоків потрібно позначати як «pending» і підтверджувати тільки після finality. Для Ethereum PoS — 2 епохи (64 блоки) для економічного finality.

Wash trading

Обсяг за адресами з циклічними переказами спотворює статистику. Базова евристика: угоди де from і to — пов'язані адреси (отримували ETH з одного джерела) позначаються прапорцем.

Що входить у роботу

  • Архітектура парсера під ваше завдання
  • Код на TypeScript з використанням ethers.js/viem
  • Налаштування ClickHouse для зберігання та аналітики
  • Дашборд у Grafana з ключовими метриками (floor price, volume, holders)
  • REST/WebSocket API для інтеграції з вашим додатком
  • Повна документація та навчання команди
  • Підтримка після запуску

Ми надаємо рішення під ключ. Оцінимо ваш проєкт за 1 день.

Орієнтири за термінами

Парсер Transfer подій + holders tracker — 1 день. Додавання floor price через маркетплейс API + кеш — ще півдня. Історичний бекфіл для великої колекції + дашборд — 2-3 дні сумарно.

Зв'яжіться з нами, щоб отримати консультацію та точну оцінку для вашого проєкту.