Live two-panel dashboard visualizing Hyperliquid's priority-fee mechanisms (April 2026 alpha) via Quicknode's ORDER_PRIORITY and GOSSIP_PRIORITY gRPC streams.
- Panel 1 — READ PRIORITY: the gossip Dutch auctions (decaying ask from
gossipPriorityAuctionStatuspolls, bid events from the stream, resets, recent winners). - Panel 2 — WRITE PRIORITY: the order queue (each priority order is a block offset by ≈45ms/bp, mempool ghosts solidify on confirmation, a YOUR ORDER slider, session stats).
- Sonification: Tone.js layer, off until clicked. Drone tracks the ask, plucks for bids, percussive hits per order scaled by bps, quantized to a 16th grid @112 BPM (toggleable to realtime).
pnpm install
cp relay/.env.example relay/.env # fill in your Quicknode endpoint + token
# drop Quicknode's streaming.proto into relay/proto/streaming.protopnpm dev:relay # gRPC → WS relay on ws://localhost:8788
pnpm dev:web # dashboard on http://localhost:5173Order-priority adoption is early and live events can be sparse. Record a session once and replay it anytime to work with a consistent, busy dataset:
pnpm --filter relay dev -- --record # writes recordings/session-<ts>.ndjson
pnpm --filter relay dev -- --replay recordings/session-<ts>.ndjson # optional: --speed 2Replay mode is announced in the relay's hello message and the frontend shows a persistent REPLAY badge — replayed data is never presented as live.
No credentials yet? A synthetic sample session is committed — try the full UI with:
pnpm --filter relay dev -- --replay fixtures/sample-session.ndjson(relay/scripts/make-fixture.mjs regenerates it.)
- The gossip ask decays linearly from
startGastoendGasoverdurationSecondsper the API (in the wildendGasisstartGas / 10;currentGasis set while the auction is live and null once it has cleared). The UI interpolates the price smoothly between 4s polls. - A new cycle's
startGasis 10× the previous winner — the winners table is derived from resets. - GOSSIP_PRIORITY surfaces bids, not delivery speed; nothing here measures actual latency improvement. The "≈45ms per bp" figure is Hyperliquid's published estimate.
- If the Quicknode HTTP endpoint rejects
gossipPriorityAuctionStatus, the relay falls back to the public HL API for that one call and warns loudly.
block_time/first_seen_timeare naive ISO strings with nanosecond precision and no timezone — treat as UTC (trim the fraction to ms, appendZ). Either can be null; the relay normalizes tots= first non-null of (first_seen_time,block_time, relay receive time) as epoch ms.block_numbercan be null even for replica_cmds — never sort or key on it. Mempool→confirmed matching usestx_hash.px/sz/startGas/endGasarrive as strings; the relay parses them to numbers (null when absent/unparseable).pcan be as small as 1 (0.0001 bp) — the UI shows sub-0.1 values as<0.1bp.outcomeis an open set ("error" observed, with a siblingerrormessage string; "filled" and others assumed). The UI categorizes known values and renders unknowns neutrally — it never crashes on new ones.- Non-IOC events appear on mainnet (observed
tif: "Alo") carrying apgrouping even though priority applies to IOC only — they render dimmed rather than being filtered, and the fees-paid stat counts only fill outcomes.