Интеграция с Dune Analytics API
Dune давно перестал быть только инструментом для ручного анализа в браузере. С выходом Dune API появилась возможность встраивать on-chain аналитику напрямую в продукт: дашборды, отчёты, алерты — без поднятия собственного индексера и без написания SQL с нуля. Мы, как инженерная команда с опытом интеграции более чем 10 проектов, постоянно сталкиваемся с тем, что клиенты приносят сырые дампы транзакций и хотят быстро получить работающий аналитический модуль. Dune API даёт production-ready решение с минимальными затратами на инфраструктуру.
Что реально делает Dune API
API предоставляет два основных сценария: выполнение запроса по его ID (POST /execute/{queryId}) и получение результатов последнего выполнения (GET /results/{queryId}). Второй вариант существенно дешевле по credits — если данные достаточно свежие, незачем запускать новое выполнение.
import requests, time DUNE_API_KEY = "your_api_key" QUERY_ID = 3540604 # пример: Uniswap V3 pool stats def get_query_results(query_id: int, params: dict = None) -> list[dict]: headers = {"X-Dune-API-Key": DUNE_API_KEY} # Запускаем выполнение с параметрами execute_resp = requests.post( f"https://api.dune.com/api/v1/query/{query_id}/execute", headers=headers, json={"query_parameters": params or {}} ) execution_id = execute_resp.json()["execution_id"] # Ждём завершения while True: status_resp = requests.get( f"https://api.dune.com/api/v1/execution/{execution_id}/status", headers=headers ) state = status_resp.json()["state"] if state == "QUERY_STATE_COMPLETED": break if state == "QUERY_STATE_FAILED": raise RuntimeError(f"Query failed: {status_resp.json()}") time.sleep(2) results = requests.get( f"https://api.dune.com/api/v1/execution/{execution_id}/results", headers=headers ) return results.json()["result"]["rows"] Типичное время выполнения запроса: от 5 секунд до нескольких минут. Для production систем это неприемлемо как синхронный вызов — нужны либо кешированные результаты, либо фоновое обновление.
Почему важно кэшировать результаты Dune API?
Credits расходуются за каждое выполнение запроса, а не за чтение кэшированных данных. Мы применяем трёхуровневую схему:
- Данные за последние 24 часа обновляются каждый час через cron.
- Исторические данные (старше 7 дней) обновляются раз в сутки.
- Результаты хранятся в Redis или PostgreSQL с TTL, равным интервалу обновления.
Dune также отдаёт result_metadata.execution_started_at — мы используем это как timestamp кэша, чтобы показывать пользователю актуальность данных. Такой подход гарантирует, что ваш дашборд не тормозит и не сжигает квоту.
Параметризованные запросы: как переиспользовать один SQL для тысяч токенов
Сильная сторона Dune API — параметризация. Запрос в браузере можно сделать универсальным через {{param}} синтаксис, и передавать значения через API. Это позволяет одним SQL покрывать, например, любой ERC-20 адрес:
SELECT date_trunc('day', block_time) AS day, sum(amount / 1e18) AS volume FROM erc20_ethereum.evt_Transfer WHERE contract_address = {{token_address}} AND block_time >= now() - interval '{{days}}' day GROUP BY 1 ORDER BY 1 DESC Вызов с параметрами:
results = get_query_results( query_id=MY_QUERY_ID, params={"token_address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "days": "30"} ) Мы часто сталкиваемся с ситуацией, когда клиент хочет видеть аналитику по сотням токенов. Параметризация сокращает количество запросов в Dune до одного шаблона — вы просто подставляете адреса на своей стороне.
Сравнение тарифов Dune API
| Тариф | Запросов в месяц | Рекомендация |
|---|---|---|
| Free | 40 | Только прототипирование |
| Plus | 2000 | Небольшой production (до 5 дашбордов) |
| Premium | 15000+ | Высоконагруженные проекты с требованием к свежести данных |
Для типового проекта с дашбордом на 10–20 виджетов хватает Plus, но мы всегда советуем клиентам начинать с Premium на этапе активной разработки — чтобы не заблокироваться лимитами в критический момент.
Как мы ускоряем интеграцию?
Наш опыт показывает, что самую большую боль вызывают rate limits и латентность. Мы настраиваем библиотеку dune-client с пулом соединений и ретраями. В production используем асинхронный вызов через очередь задач (Celery / RabbitMQ): новый запрос ставится в очередь, а пользователь видит последний кэшированный срез. Периодически фоновая задача проверяет, не пора ли обновить.
Также мы следим за версиями API — Dune изредка вносит breaking changes (например, переход с v1 на v2). В наших интеграциях заложена прослойка-адаптер, которая позволяет переключаться между версиями без правок в коде дашборда.
Что входит в работу по интеграции Dune API?
- Анализ требований к дашборду и выбор метрик
- Написание и оптимизация SQL-запросов под API (учёт лимитов, пагинация)
- Реализация кэширования с настраиваемым TTL
- Интеграция с бэкендом (REST/gRPC/WebSocket) и фронтендом (React/Vue)
- Настройка автоматического обновления через cron или очередь задач
- Документация по API-слою для команды
- Обучение ваших разработчиков работе с Dune API (1–2 сессии)
- Гарантия поддержки в течение 30 дней после сдачи
Ограничения и обходные пути
Rate limits: на бесплатном плане — 40 запросов в месяц, на Plus — 2000, на Premium — 15000+. Для production с несколькими пользователями — Plus минимум.
Размер ответа: по умолчанию возвращается до 25000 строк. Для больших датасетов — пагинация через offset и limit параметры в запросе к результатам.
Латентность: GET /results/{queryId} без перезапуска (cached results) возвращает мгновенно. Используйте этот endpoint для read-heavy интеграций и запускайте новое выполнение только по расписанию.
Интеграция от нуля до работающего дашборда с кэшированием — 1–2 дня. Если у вас есть специфические требования (например, real-time данные через WebSocket), срок может увеличиться, но мы всегда даём точную оценку после бесплатного аудита вашего проекта. Обращайтесь — обсудим детали.







