Dune Analytics API
A skill for querying and analyzing blockchain data via the Dune Analytics API.
Setup
CODEBLOCK0
Set DUNE_API_KEY via environment variable, .env file, or agent config.
Best Practices
- 1. Read references first — The reference files contain critical table names, anti-patterns, and chain-specific gotchas that aren't obvious from table names alone. Reading the right reference before writing SQL prevents common mistakes like using
dex.trades for wallet analysis (which inflates volume ~30%) or missing Solana's dedup requirement.
- 2. Prefer private queries — Creating queries with
is_private=True keeps the user's workspace clean and avoids polluting the public Dune namespace. Fall back to public if it fails (free plan limitation), and let the user know.
- 3. Reuse before creating — Dune charges credits per execution. Reusing or updating an existing query avoids unnecessary duplicates and makes credit tracking easier. Only create new queries when the user explicitly asks.
- 4. Confirm before updating — Modifying an existing query's SQL is destructive (previous version isn't saved by default). A quick confirmation avoids overwriting work the user might want to keep.
- 5. Track credits — Each execution costs credits depending on the performance tier and data scanned. Reporting credits consumed helps the user manage their budget. See query-execution.md.
Scripts — Common Operations
For common operations, use the scripts in scripts/ to avoid writing boilerplate code every time. All scripts read DUNE_API_KEY from the environment automatically.
| Script | Command | What it does |
|---|
| INLINECODE6 | INLINECODE7 | Execute a saved query (supports --params, --performance, --format) |
| INLINECODE11 |
get_latest --query-id ID | Get cached result without re-execution |
|
dune_query.py |
get_sql --query-id ID | Print query SQL |
|
dune_query.py |
update_sql --query-id ID --sql "..." | Update query SQL |
|
dune_discover.py |
search --keyword "uniswap" | Search tables by keyword |
|
dune_discover.py |
schema --table "dex.trades" | Show table columns and types |
|
dune_discover.py |
list_schemas --namespace "uniswap_v3" | List tables in a namespace |
|
dune_discover.py |
contract --address "0x..." | Find decoded tables by contract address |
|
dune_discover.py |
docs --keyword "dex" | Search Dune documentation |
|
dune_upload.py |
upload_csv --file data.csv --table-name tbl | Quick CSV upload (overwrites) |
|
dune_upload.py |
create_table --table-name tbl --namespace ns --schema '[...]' | Create table with explicit schema |
|
dune_upload.py |
insert --file data.csv --table-name tbl --namespace ns | Append data to existing table |
Example:
CODEBLOCK1
Reference Selection
Before writing any SQL, route to the correct reference file(s) based on your task:
| Task involves... | Read this reference |
|---|
| Finding tables / inspecting schema / discovering protocols | table-discovery.md |
| Finding decoded tables by contract address |
table-discovery.md |
| Searching Dune documentation / guides / examples |
table-discovery.md |
| Wallet / address tracking / router identification |
wallet-analysis.md |
| Table selection / common table names |
common-tables.md |
| SQL performance / complex joins / array ops |
sql-optimization.md |
| API calls / execution / caching / parameters |
query-execution.md |
| Uploading CSV/NDJSON data to Dune |
data-upload.md |
If your task spans multiple categories, read all relevant files. The references contain critical details (e.g., specialized tables, anti-patterns) that aren't covered in this overview — guessing table names or query patterns leads to subtle bugs.
Quick Start
CODEBLOCK2
Subscription Tiers
| Method | Description | Plan |
|---|
| INLINECODE33 | Execute saved query (supports {{param}}) | Free |
| INLINECODE35 |
Execute SQL directly (no params) | Plus |
Key Concepts
dex.trades vs dex_aggregator.trades
| Table | Use Case | Volume |
|---|
| INLINECODE36 | Per-pool analysis | ⚠️ Inflated ~30% (multi-hop counted multiple times) |
| INLINECODE37 |
User/wallet analysis | Accurate |
Why this matters: If you're analyzing a specific wallet's trading activity and use dex.trades, you'll see inflated volume because a single swap through an aggregator gets split into multiple pool-level trades. dex_aggregator.trades captures the user-level intent — one row per user swap. See wallet-analysis.md for full patterns.
Solana has no dex_aggregator_solana.trades. Dedupe by tx_id:
CODEBLOCK3
Data Freshness
| Layer | Delay | Example |
|---|
| Raw | < 1 min | INLINECODE42 , INLINECODE43 |
| Decoded |
15-60 sec |
uniswap_v3_ethereum.evt_Swap |
| Curated | ~1 hour+ |
dex.trades,
dex_solana.trades |
Query previous day's data after UTC 12:00 for completeness.
References
Detailed documentation is organized in the references/ directory:
API patterns: execute, update, cache, multi-day fetch, credits tracking, subqueries |
|
common-tables.md | Quick reference of commonly used tables: raw, decoded, curated, community data |
|
sql-optimization.md | SQL optimization: CTE, JOIN strategies, array ops, partition pruning |
|
wallet-analysis.md | Wallet tracking: Solana/EVM queries, multi-chain aggregation, fee analysis |
|
data-upload.md | Data upload: CSV/NDJSON upload, create table, insert data, manage tables, credits |
Dune Analytics API
通过 Dune Analytics API 查询和分析区块链数据的技能。
设置
bash
pip install dune-client
通过环境变量、.env 文件或代理配置设置 DUNEAPIKEY。
最佳实践
- 1. 先阅读参考资料 — 参考文件中包含关键的表名、反模式以及仅从表名无法看出的特定链的注意事项。在编写 SQL 之前阅读正确的参考资料可以避免常见错误,例如使用 dex.trades 进行钱包分析(会使交易量膨胀约 30%)或遗漏 Solana 的去重要求。
- 2. 优先使用私有查询 — 使用 is_private=True 创建查询可以保持用户工作区整洁,避免污染公共 Dune 命名空间。如果失败(免费计划限制),则回退到公共查询,并告知用户。
- 3. 先复用再创建 — Dune 每次执行都会消耗积分。复用或更新现有查询可以避免不必要的重复,并使积分跟踪更容易。仅在用户明确要求时创建新查询。
- 4. 更新前确认 — 修改现有查询的 SQL 是不可逆的(默认不保存先前版本)。快速确认可以避免覆盖用户可能想要保留的工作。
- 5. 跟踪积分 — 每次执行消耗的积分取决于性能层级和扫描的数据量。报告消耗的积分有助于用户管理预算。请参阅 query-execution.md。
脚本 — 常见操作
对于常见操作,使用 scripts/ 中的脚本以避免每次都编写样板代码。所有脚本都会自动从环境中读取 DUNEAPIKEY。
| 脚本 | 命令 | 功能 |
|---|
| dunequery.py | execute --query-id ID | 执行已保存的查询(支持 --params、--performance、--format) |
| dunequery.py |
get_latest --query-id ID | 获取缓存结果,无需重新执行 |
| dune
query.py | getsql --query-id ID | 打印查询 SQL |
| dune
query.py | updatesql --query-id ID --sql ... | 更新查询 SQL |
| dune_discover.py | search --keyword uniswap | 按关键字搜索表 |
| dune_discover.py | schema --table dex.trades | 显示表列和类型 |
| dune
discover.py | listschemas --namespace uniswap_v3 | 列出命名空间中的表 |
| dune_discover.py | contract --address 0x... | 按合约地址查找解码表 |
| dune_discover.py | docs --keyword dex | 搜索 Dune 文档 |
| dune
upload.py | uploadcsv --file data.csv --table-name tbl | 快速 CSV 上传(覆盖) |
| dune
upload.py | createtable --table-name tbl --namespace ns --schema [...] | 使用显式模式创建表 |
| dune_upload.py | insert --file data.csv --table-name tbl --namespace ns | 将数据追加到现有表 |
示例:
bash
使用参数执行查询
python scripts/dune_query.py execute --query-id 123456 --params {token:ETH} --format table
私有上传 CSV
python scripts/dune
upload.py uploadcsv --file wallets.csv --table-name my_wallets --private
参考资料选择
在编写任何 SQL 之前,根据任务路由到正确的参考文件:
table-discovery.md |
| 搜索 Dune 文档 / 指南 / 示例 |
table-discovery.md |
| 钱包 / 地址跟踪 / 路由器识别 |
wallet-analysis.md |
| 表选择 / 常见表名 |
common-tables.md |
| SQL 性能 / 复杂连接 / 数组操作 |
sql-optimization.md |
| API 调用 / 执行 / 缓存 / 参数 |
query-execution.md |
| 上传 CSV/NDJSON 数据到 Dune |
data-upload.md |
如果任务跨越多个类别,请阅读所有相关文件。参考资料包含本概述中未涵盖的关键细节(例如,专用表、反模式)——猜测表名或查询模式会导致细微的错误。
快速开始
python
from dune_client.client import DuneClient
from dune_client.query import QueryBase
import os
client = DuneClient(apikey=os.environ[DUNEAPI_KEY])
执行查询
result = client.run
query(query=QueryBase(queryid=123456), performance=medium, ping_frequency=5)
print(f行数: {len(result.result.rows)})
获取缓存结果(无需重新执行)
result = client.get
latestresult(query_id=123456)
获取/更新 SQL
sql = client.get_query(123456).sql
client.update
query(queryid=123456, query_sql=SELECT ...)
上传 CSV 数据(快速,覆盖现有)
client.upload_csv(
data=col1,col2\nval1,val2,
description=我的数据,
table
name=mytable,
is_private=True
)
创建表 + 插入(支持追加)
client.create_table(
namespace=my_user,
table
name=mytable,
schema=[{name: col1, type: varchar}, {name: col2, type: double}],
is_private=True
)
import io
client.insert_data(
namespace=my_user,
table
name=mytable,
data=io.BytesIO(bcol1,col2\nabc,1.5),
content_type=text/csv
)
订阅层级
| 方法 | 描述 | 计划 |
|---|
| runquery | 执行已保存的查询(支持 {{param}}) | 免费 |
| runsql |
直接执行 SQL(无参数) | Plus |
关键概念
dex.trades 与 dex_aggregator.trades
| 表 | 用例 | 交易量 |
|---|
| dex.trades | 按池分析 | ⚠️ 膨胀约 30%(多跳交易被多次计数) |
| dex_aggregator.trades |
用户/钱包分析 | 准确 |
为什么这很重要: 如果您分析特定钱包的交易活动并使用 dex.trades,您会看到膨胀的交易量,因为通过聚合器的单次交换会被拆分为多个池级交易。dexaggregator.trades 捕获用户级意图——每个用户交换对应一行。请参阅 wallet-analysis.md 了解完整模式。
Solana 没有 dexaggregatorsolana.trades。通过 tx_id 去重:
sql
SELECT txid, MAX(amountusd) as amount_usd
FROM dex_solana.trades
GROUP BY tx_id
数据新鲜度
| 层级 | 延迟 | 示例 |
|---|
| 原始 | < 1 分钟 | ethereum.transactions、solana.transactions |
| 解码 |
15-60 秒 | uniswap
v3ethereum.evt_Swap |
| 策展 | ~1 小时+ | dex.trades、dex_solana.trades |
在 UTC 12:00 之后查询前一天的数据以确保完整性。
参考资料
详细文档组织在 references/ 目录中:
API 模式:执行、更新、缓存、多天获取、积分跟踪、子查询 |
|
common-tables.md | 常用表的快速参考:原始、解码、策展、社区数据 |
|
sql-optimization.md | SQL 优化:CTE、JOIN 策略、数组操作、分区修剪 |
|
wallet-analysis.md | 钱包跟踪:Solana/EVM 查询