Local dashboard and data pipeline for analyzing 1inch Router orderflow — who sends orders where, and how they get routed through the MEV stack.
The main view is a 6-layer interactive Sankey:
User Class → Frontend → Solver → Mempool → OFA → Builder
This lets you answer questions like:
- Which frontends route volume through 1inch?
- What share of flow is private mempool vs public?
- Which OFA mechanisms (or none) are used?
- Which builders construct the final blocks?
Additional pages break down user segments (labeled addresses, smart wallets, EOAs, EIP-7702 delegated accounts).
- Backend: Rust (Axum, SQLite, async Dune API client)
- Frontend: Vanilla HTML/JS with ECharts Sankey — no build step
- Data: Dune Analytics queries over Flashbots-indexed 1inch transaction data
cargo build --release
export DUNE_API_KEY=<your key from dune.com/settings/api>
./target/release/orderflow fetch # pull data from Dune → SQLite cache
./target/release/orderflow serve # start server at http://127.0.0.1:3000fetch runs the default 1inch Sankey query (Q7428851) automatically — no
extra env vars required. Set DUNE_QUERY_1INCH_SANKEY only if you want to
point at a different query ID.
If you just want to demo the UI without running fetch (and without a Dune API key), this repo includes a prebuilt SQLite snapshot at database/orderflow.db.
Run the server using that DB:
./target/release/orderflow serve --db database/orderflow.dbNotes:
- The demo DB is a time-window snapshot, not live data.
- If you want fresh data, run
orderflow fetchto rebuild your own local cache.
The UI can run without a server: JSON under web/data/ replaces /api/*.
./scripts/build_github_pages.sh # needs database/orderflow.db (bundled demo OK)
# open web/index.html via a local static server, or push to GitHub PagesOn push to main, .github/workflows/github-pages.yml builds summary.json + addresses.json from the demo DB and deploys the web/ folder.
Repo settings: Settings → Pages → Source: GitHub Actions.
orderflow serve still works: the frontend tries data/*.json first, then falls back to the Rust API.
Integrators / Recipients on Pages uses only known wallet labels (Coinbase, Rabby, Zerion) — not the full ~72k tx corpus. The snapshot lives in data/github_pages/integrator_recipients.json (~25 KB). Regenerate after refreshing fee decode data:
python3 scripts/build_integrator_recipient_sankey.py \
--txs results.csv --fees integrator_fee_recipients_mini.csv \
--labeled-only --max-hashes 100 --no-other \
--out data/github_pages/integrator_recipients.json| Command | Description |
|---|---|
orderflow fetch |
Execute Dune queries and write results to local SQLite cache |
orderflow serve |
Serve the web UI and GET /api/summary JSON endpoint |
orderflow export |
Write the current snapshot to a JSON file (same shape as /api/summary) |
orderflow export-web |
Write web/data/summary.json + addresses.json for GitHub Pages |
Common flags:
--db <path> SQLite database path (default: ~/.cache/oneinch-orderflow/orderflow.db)
--host <addr> Bind address for serve (default: 127.0.0.1)
--port <n> Port for serve (default: 3000)
--demo Serve even if cache is empty (shows placeholder data)
All flags can be set via environment variables (see orderflow --help).
| Variable | Required | Description |
|---|---|---|
DUNE_API_KEY |
Yes | API key from dune.com/settings/api |
DUNE_QUERY_1INCH_SANKEY |
No | Override the Sankey query ID (default: 7428851) |
ORDERFLOW_DB |
No | Override the SQLite database path |
DUNE_HTTP_TIMEOUT_SECS |
No | HTTP timeout in seconds (default: 600) |
DUNE_HTTP_RETRIES |
No | Retry attempts on transient errors (default: 5) |
DUNE_MAX_WAIT_SECS |
No | Max seconds to wait for a Dune execution (default: 3600) |
ORDERFLOW_WEB_ROOT |
No | Override the web static files directory |
All data comes from the single 1inch_sankey query (Q7428851). Each fetch run executes only that query. The cached rows include both Sankey edges and per-address data used for the address modal and EIP-7702 enrichment.
Sankey edge rows (edge_level = "L1>L2" … "L5>L6"):
| Field | Type | Description |
|---|---|---|
edge_level |
string | e.g. "L1>L2" through "L5>L6" |
source |
string | Source node label |
target |
string | Target node label |
tx_count |
number | Transaction count |
volume_m_usd |
number | Volume in millions USD |
Address-level rows (edge_level = "USER_ADDR"):
| Field | Type | Description |
|---|---|---|
source |
string | L1 user class, e.g. "User: EOA (Unlabeled)" |
target |
string | L2 frontend bucket, e.g. "Frontend: 1inch Integrators" |
user_addr |
string | EOA address |
tx_count |
number | Transaction count for this address |
volume_m_usd |
number | Volume in millions USD for this address |
The Sankey query classifies user addresses into three buckets:
- Labeled — best-effort join to a public labels table
- Smart wallet — Safe or other known contract wallets
- EOA — unlabeled externally owned accounts, further bucketed by activity pattern
EIP-7702 delegated accounts are enriched locally from eoa_7702_resolved.csv.
One table: raw_rows(kind, payload, ingested_at). Each fetch overwrites all rows for the given kind.
| File | Query ID | Purpose |
|---|---|---|
dune/queries/07_1inch_sankey.sql |
7428851 |
Main query — 6-layer Sankey edges, per-address data (USER_ADDR rows), and time range (META row). Covers all 1inch Router flow (not just Fusion). |
dune/queries/00_flashbots_reference.sql |
— | Reference: Flashbots source table schema |
dune/queries/01_orderflow_view.sql |
3184593 |
Legacy reference only — Fusion-only per-tx view, not used by the dashboard |
dune/queries/03_frontend_resolver.sql |
— | Maps addresses to frontend names |
dune/queries/04_topn_pairs.sql |
— | High-volume trading pairs |
dune/queries/05_volume_timeseries.sql |
— | Time-bucketed volume trends |
dune/queries/06_wallet_app.sql |
— | Wallet integration metrics |
dune/queries/08_integrator_txs.sql |
— | 1inch integrator/partner transactions |
The main query reads from dune.flashbots.result_overall_of — a materialized table maintained by Flashbots. If max(block_time) looks stale, check whether that upstream table is still updating.
Inspired by Orderflow.art by Flashbots and Barter — the original work that made orderflow routing visible and legible across the Ethereum block-building stack. The flow model, layer taxonomy, and general framing used here are directly informed by their approach. This project applies the same lens to 1inch-specific flow.
MIT