Real-time price spread visualization between Hyperliquid and Lighter perpetual DEXs.
✅ Real-time WebSocket Connections to both Hyperliquid and Lighter ✅ Mark Price Comparison - Uses stable mark prices from both exchanges ✅ 5-Minute Aggregated Charts - Smooth visualization with Lightweight Charts ✅ Local Data Storage - IndexedDB stores all price updates for analysis ✅ Multi-Pair Tracking - Add/remove pairs on demand ✅ Live Spread Monitoring - See percentage spreads in real-time ✅ Data Export - Download your data as JSON
- Hyperliquid: Subscribes to
allMidschannel (gets all coin mid prices) - Lighter: Subscribes to
market_stats/allchannel (gets mark prices for all markets)
spread = lighter_mark_price - hyperliquid_mid_price
spread_percentage = (spread / hyperliquid_mid_price) * 100
- Raw updates stored in IndexedDB
- Aggregated into 5-minute buckets for chart display
- Shows: avg spread, min spread, max spread per bucket
npm installnpm run devOpen http://localhost:3000 in your browser.
npm run build
npm start- Connect: App automatically connects to both WebSocket APIs on load
- Add Pairs: Click "Add Pair" to select trading pairs you want to track
- Monitor: Watch real-time price spreads in the Live Prices panel
- Analyze: View 5-minute aggregated spread charts for each pair
- Export: Click "Export Data" to download all stored price data
┌─────────────────────────────────────────────────────┐
│ Next.js App │
├─────────────────────────────────────────────────────┤
│ Components │
│ ├── PairSelector (Add/remove pairs) │
│ ├── LivePrices (Real-time spreads) │
│ ├── SpreadChart (5-min aggregated chart) │
│ └── ConnectionStatus (WebSocket status) │
├─────────────────────────────────────────────────────┤
│ State Management (Zustand) │
│ ├── Selected pairs │
│ ├── Latest prices │
│ └── Connection status │
├─────────────────────────────────────────────────────┤
│ WebSocket Managers │
│ ├── HyperliquidWebSocket (wss://api.hyperliquid) │
│ └── LighterWebSocket (wss://mainnet.zklighter) │
├─────────────────────────────────────────────────────┤
│ Data Layer │
│ ├── DataAggregator (5-min buckets) │
│ └── IndexedDB (Dexie.js) │
└─────────────────────────────────────────────────────┘
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- Charts: Lightweight Charts (TradingView)
- State: Zustand
- Storage: IndexedDB (Dexie.js)
- WebSockets: Native WebSocket API
The app automatically matches pairs between exchanges:
| Symbol | Hyperliquid Coin | Lighter Market ID |
|---|---|---|
| ETH-USD | ETH | 0 |
| BTC-USD | BTC | 1 |
| SOL-USD | SOL | 2 |
| ARB-USD | ARB | 3 |
More pairs can be added via API discovery or manual configuration in lib/pairMapping.ts.
- Raw Updates: Every price update stored with timestamp
- Aggregated Data: 5-minute buckets with avg/min/max spreads
- Cleanup: Automatically removes data older than 7 days
- Export: Download as JSON for external analysis
- Automatic reconnection on disconnect
- Max 5 attempts with exponential backoff
- Visual connection status indicators
Edit lib/dataAggregator.ts:
private readonly INTERVAL_MS = 5 * 60 * 1000; // Change to 1 min, 15 min, etc.Edit lib/pairMapping.ts:
export const KNOWN_PAIR_MAPPINGS: PairInfo[] = [
// Add your custom mapping
{
symbol: 'CUSTOM-USD',
hyperliquidCoin: 'CUSTOM',
lighterMarketId: 99,
lighterSymbol: 'CUSTOM-USD'
}
];Edit components/SpreadChart.tsx - Lightweight Charts configuration.
- Check browser console for errors
- Ensure no firewall/proxy blocking WebSocket connections
- Both exchanges must be accessible
- Ensure you've selected at least one pair
- Wait a few seconds for initial price updates
- Check Connection Status panel (both should be green)
- Click Export Data to backup
- Clear browser data for the site
- Or adjust cleanup interval in code
perpdexs_arb/
├── app/ # Next.js app directory
│ ├── page.tsx # Main page
│ ├── layout.tsx # Root layout
│ └── globals.css # Global styles
├── components/ # React components
├── lib/ # Core logic
│ ├── types.ts # TypeScript types
│ ├── database.ts # IndexedDB wrapper
│ ├── store.ts # Zustand store
│ ├── pairMapping.ts # Pair matching logic
│ ├── dataAggregator.ts # 5-min aggregation
│ └── websocket/ # WebSocket managers
├── package.json
└── tsconfig.json
MIT
Feel free to open issues or submit PRs for improvements!
- Hyperliquid - High-performance perpetual DEX
- Lighter - zkSync-based perpetual DEX
- Lightweight Charts - TradingView charting library