Історія цін NFT у мобільному додатку
NFT-колекція виглядає як набір JPEG, поки не бачиш, як її floor price виріс з 0.05 до 12 ETH за три тижні. Саме ціна історія перетворює трекер NFT зі статичного каталогу в аналітичний інструмент.
Джерело історії цін
Блокчейн сам по собі не зберігає «історію цін» як сутність. Продаж NFT — це Transfer-подія в смарт-контракті ERC-721 плюс рух ETH між адресами в тій же транзакції. Щоб побудувати price history, потрібно агрегувати on-chain eventi. Самостійно парсити Ethereum — дорого. Тому використовують спеціалізовані API:
OpenSea API v2 (/api/v2/events/collection/{slug}) повертає eventi типу sale з ціною в wei та timestamp. Обмеження — 4 запити на секунду на безплатному ключі. Для історії глибше 30 днів потрібен платний план.
Reservoir API (/sales/v6) — щедріший за глибиною історії та rate limits. Підтримує кілька маркетплейсів одночасно (OpenSea, Blur, X2Y2). Пагінація через continuation токен.
Alchemy NFT API (/getNFTSales) — зручний, якщо вже використовуєте Alchemy для інших on-chain запитів.
На Flutter типовий репозиторій виглядає так:
class NftSalesRepository {
final Dio _dio;
final String _reservoirKey;
Future<List<NftSale>> getSalesHistory({
required String contractAddress,
required String tokenId,
DateTime? from,
}) async {
final params = {
'tokens': '$contractAddress:$tokenId',
'startTimestamp': from?.millisecondsSinceEpoch ~/ 1000,
'limit': 100,
};
final resp = await _dio.get(
'https://api.reservoir.tools/sales/v6',
queryParameters: params,
options: Options(headers: {'x-api-key': _reservoirKey}),
);
return (resp.data['sales'] as List)
.map((e) => NftSale.fromJson(e))
.toList();
}
}
Ціна приходить в ETH (або інших нативних валютах мережі), але користувачі очікують бачити USD. Курс ETH/USD потрібно підтягувати окремо — через CoinGecko API або Alchemy Price API, кешувати з TTL 60 секунд та застосувати до історичних точок постфактум.
Візуалізація
Для рендерингу графіка на Flutter добре працює fl_chart. Дані продажів потрібно нормалізувати перед рендером: видалити очевидні wash-trade викиди (продаж між пов'язаними гаманцями по позаринковій ціні), агрегувати за днями або тижнями залежно від глибини історії.
На React Native — Victory Native XL (працює на Reanimated 3, без перерисовки через bridge) або react-native-gifted-charts.
LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(
spots: sales.map((s) => FlSpot(
s.timestamp.toDouble(),
s.priceUsd,
)).toList(),
isCurved: true,
gradient: LinearGradient(colors: [Colors.purple, Colors.blue]),
belowBarData: BarAreaData(show: true, color: Colors.purple.withOpacity(0.1)),
),
],
titlesData: FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) => _formatDate(value),
),
),
),
),
)
Що входить до роботи
- Інтеграція Reservoir API або OpenSea API з пагінацією
- Моделі даних:
NftSale,PricePointз конвертацією wei → ETH → USD - Кешування в SQLite (drift/floor) з TTL
- Графік з вибором часового діапазону (7d / 30d / All)
- Обробка пустої історії та помилок мережі
Терміни
Реалізація від 2 до 4 робочих днів залежно від платформи та складності дизайну графіка. Вартість розраховується індивідуально після аналізу вимог.







