Hyperliquid Source
A Drasi source that connects to Hyperliquid's public APIs to stream real-time DeFi perpetual and spot market data as a continuously-queryable graph. No API keys required.
What You Can Build
- Price alert bots — trigger when BTC crosses $100k or ETH drops 5% in a minute
- Whale watchers — detect trades over $1M in real time
- Spread monitors — alert when bid-ask spread widens beyond a threshold
- Funding rate dashboards — track which coins have extreme funding
- Liquidation feeds — monitor liquidation cascades across assets
- Cross-asset correlation — join trades, prices, and funding through graph traversal
Quick Start
use ;
use LogReaction;
use ;
use Arc;
async
Graph Model
All data flows through a Coin-centric graph. Every market data entity connects back to a Coin node, enabling graph traversal queries that correlate across data types.
┌───────────┐
│ Coin │
│ (anchor) │
└─────┬─────┘
┌────────┬─────┼─────┬──────────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Trade MidPrice │ Liquidation FundingRate
OrderBook
See GRAPH_SCHEMA.md for complete property tables, ID formats, and relationship details.
Example Queries
🐋 Whale Detection — Large Trades in Real Time
Continuously alert on trades over $100k notional value:
MATCH (t:Trade)-[:TRADED_ON]->(c:Coin)
WHERE t.price * t.size > 100000
RETURN c.name AS coin, t.side AS side,
t.price AS price, t.size AS size,
t.price * t.size AS notional
Every time a whale trade lands, your reaction fires with the coin, direction, and size.
📊 Spread Monitor — Bid-Ask Spread Alert
Alert when any coin's spread widens beyond 0.1%:
MATCH (ob:OrderBook)-[:BOOK_OF]->(c:Coin),
(m:MidPrice)-[:PRICE_OF]->(c)
WHERE (ob.best_ask_price - ob.best_bid_price) / m.price > 0.001
RETURN c.name AS coin,
ob.best_bid_price AS bid, ob.best_ask_price AS ask,
ob.best_ask_price - ob.best_bid_price AS spread,
m.price AS mid_price
💰 Funding Arbitrage Scanner
Find coins with extreme funding rates (potential arbitrage opportunity):
MATCH (f:FundingRate)-[:FUNDING_OF]->(c:Coin),
(m:MidPrice)-[:PRICE_OF]->(c)
WHERE f.rate > 0.01 OR f.rate < -0.01
RETURN c.name AS coin, f.rate AS funding_rate,
f.mark_price AS mark, m.price AS mid,
f.mark_price - m.price AS basis,
f.open_interest AS oi
🔥 Liquidation Cascade Detector
Monitor liquidation events alongside funding rates to spot cascades:
MATCH (l:Liquidation)-[:LIQUIDATED_ON]->(c:Coin),
(f:FundingRate)-[:FUNDING_OF]->(c)
RETURN c.name AS coin, l.side AS liq_side,
l.price AS liq_price, l.size AS liq_size,
f.rate AS funding, f.open_interest AS oi
📈 Multi-Asset Price Dashboard
Track real-time prices for your watchlist with leverage info:
MATCH (m:MidPrice)-[:PRICE_OF]->(c:Coin)
RETURN c.name AS coin, c.max_leverage AS leverage,
c.market_type AS type, m.price AS price
🔗 Cross-Entity Correlation — Price vs Mark vs Funding
Join mid-price, order book, and funding through the Coin node in one query:
MATCH (m:MidPrice)-[:PRICE_OF]->(c:Coin {name: "ETH"}),
(ob:OrderBook)-[:BOOK_OF]->(c),
(f:FundingRate)-[:FUNDING_OF]->(c)
RETURN m.price AS mid_price,
ob.best_bid_price AS bid, ob.best_ask_price AS ask,
f.mark_price AS mark, f.rate AS funding,
f.open_interest AS open_interest
🏦 Open Interest Monitor
Alert when a coin's open interest crosses a threshold:
MATCH (f:FundingRate)-[:FUNDING_OF]->(c:Coin)
WHERE f.open_interest > 10000000
RETURN c.name AS coin, f.open_interest AS oi, f.volume_24h AS vol_24h
⚡ High-Leverage Coin Scan
Find all coins offering 50x+ leverage with their current metrics:
MATCH (f:FundingRate)-[:FUNDING_OF]->(c:Coin),
(m:MidPrice)-[:PRICE_OF]->(c)
WHERE c.max_leverage >= 50
RETURN c.name AS coin, c.max_leverage AS leverage,
m.price AS price, f.rate AS funding, f.volume_24h AS volume
Configuration
let source = builder
.with_network // or Testnet, or Custom { rest_url, ws_url }
.with_coins // or .with_all_coins()
.with_trades // trade events (high volume)
.with_order_book // L2 book snapshots (high volume)
.with_mid_prices // mid-market prices (moderate)
.with_funding_rates // funding rate polling (low volume)
.with_liquidations // liquidation events (sporadic)
.with_funding_poll_interval_secs // poll every 30s instead of default 60s
.start_from_beginning // or .start_from_now() / .start_from_timestamp(ms)
.build?;
Config Reference
| Field | Type | Default | Description |
|---|---|---|---|
network |
HyperliquidNetwork |
Mainnet |
API environment |
coins |
CoinSelection |
All |
Specific { coins } or All |
enable_trades |
bool |
false |
Trade event stream |
enable_order_book |
bool |
false |
L2 order book stream |
enable_mid_prices |
bool |
true |
Mid-price stream |
enable_funding_rates |
bool |
false |
Funding rate polling |
enable_liquidations |
bool |
false |
Liquidation event stream |
funding_poll_interval_secs |
u64 |
60 |
Funding poll interval |
initial_cursor |
InitialCursor |
StartFromNow |
Where to start streaming |
Bootstrap & Streaming
Bootstrap (REST): When a query subscribes with enable_bootstrap, the source fetches a snapshot of the relevant current data via Hyperliquid's /info REST endpoints. Coin and SpotPair nodes are always included. MidPrice, FundingRate, and OrderBook are bootstrapped only when their respective streams are enabled.
Streaming (WebSocket + REST polling): The source opens a WebSocket connection and subscribes to enabled channels. Funding rates are polled via REST at the configured interval.
| Data | Bootstrap | Streaming | Update Pattern |
|---|---|---|---|
| Coin | ✅ Always | — | Insert once, never updated |
| SpotPair | ✅ Always | — | Insert once, never updated |
| MidPrice | ✅ If enabled | WebSocket allMids |
Insert first, then update |
| OrderBook | ✅ If enabled | WebSocket l2Book |
Insert first, then update |
| FundingRate | ✅ If enabled | REST poll | Insert first, then update |
| Trade | — | WebSocket trades |
Insert per event (append-only) |
| Liquidation | — | WebSocket liquidations |
Insert per event (append-only) |
State Persistence
When a StateStoreProvider is available:
- Trade deduplication — persists last seen
tidper coin; prevents duplicates on WebSocket reconnect - Funding snapshots — persists last funding state; skips redundant updates when data hasn't changed
Testing
# Unit tests (no network)
# Integration test against live mainnet (requires internet)
Troubleshooting
| Symptom | Check |
|---|---|
| REST API unreachable | Verify connectivity to https://api.hyperliquid.xyz/info |
| WebSocket errors | wscat -c wss://api.hyperliquid.xyz/ws |
| No changes detected | Set RUST_LOG=debug, confirm channels are enabled |
| Too much data | Reduce coin list or disable high-volume streams (trades, l2Book) |
| Duplicate events on restart | Ensure a StateStoreProvider is configured |
Limitations
- No historical replay — WebSocket starts from current data
- Funding rates are polled, not pushed in real time
- Subscribing to all trades + order books for all coins is very high volume
- SpotPair nodes have no relationships (standalone metadata)