Інтеграція з Dune Analytics API
Dune давно перестав бути лише інструментом для ручного аналізу в браузері. З випуском Dune API стало можливо вбудовувати on-chain аналітику прямо в продукт: дашборди, звіти, алерти — без підняття власного індексера та без написання SQL з нуля.
Що насправді робить Dune API
API надає два основні сценарії: виконання запиту за його ID (POST /execute/{queryId}) та отримання результатів останнього виконання (GET /results/{queryId}). Другий варіант значно дешевший за кредитами — якщо дані достатньо свіжі, немає потреби запускати нове виконання.
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 — параметризація. Запит у браузері можна зробити універсальним через синтаксис {{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"}
)
Кешування — обов'язково. Кредити витрачаються на кожне виконання, не на читання. Схема для більшості дашбордів:
- Дані за останні 24 години: оновлення раз в годину через cron
- Історичні дані (>7 днів): оновлення раз на добу
- Результати зберігаються в Redis або PostgreSQL з TTL
Dune також повертає result_metadata.execution_started_at — використовуйте це як timestamp кешу, щоб показувати користувачеві актуальність даних.
Обмеження та обхідні шляхи
Rate limits: на безплатному плані — 40 запитів на місяць, на Plus — 2000, на Premium — 15000+. Для production з кількома користувачами — Plus мінімум.
Розмір відповіді: за замовчуванням повертає до 25000 рядків. Для більших наборів даних — пагінація через параметри offset та limit у запиті результатів.
Затримка: GET /results/{queryId} без перезапуску (кешовані результати) повертає миттєво. Використовуйте цей endpoint для read-heavy інтеграцій та запускайте нове виконання лише за розписанням.
Інтеграція від нуля до працюючого дашборду з кешуванням — 1–2 дні.







