Vladyslav Kovalchuk
← All cases

Building a multi-hop DEX router for Hyperliquid spot trading

Building a multi-hop DEX router for Hyperliquid spot trading screenshot

Problem

Hyperliquid is a high-performance L1 built for derivatives trading, but its spot market lacked a user-friendly interface for swapping between assets. Users had to manually identify trading pairs, calculate routes through intermediary tokens (like USDC), and execute each hop separately. Worse, the exchange's signing scheme required chainId 1337 for trade actions, but browser wallets like MetaMask validate that the signing chainId matches the connected chain — Arbitrum (42161) in this case. Every trade attempt failed at the wallet level before reaching the exchange.

Constraints

  • Wallet providers enforce EIP-712 chainId validation — there is no way to sign with chainId 1337 while connected to Arbitrum.
  • Multi-hop routes had to execute sequentially, with each hop using the output of the previous one.
  • Orderbook data had to be fresh for accurate price estimation, but fetching all pairs on every route search was too expensive.
  • The solution had to work without requiring users to switch networks or use a custom wallet.

Solution

I implemented Hyperliquid's agent wallet pattern: a locally-generated ephemeral keypair that users approve once via a wallet signature (using chainId 42161, which MetaMask accepts). The agent key then signs all trade actions with chainId 1337 directly — no wallet popup, no chainId conflict. For routing, I built a BFS-based pathfinder that discovers the shortest path between any two tokens within 3 hops. To minimize API calls, the router checks for direct pairs first and only fetches orderbooks for relevant intermediary routes (via USDC or HYPE). Multi-hop trades execute sequentially, with each hop's output feeding into the next. The UI shows real-time price estimates, slippage warnings, and supports both market and limit orders with cancellation.

Key technical decisions

Agent wallet pattern over network switching
Asking users to add a custom network or switch chains breaks the flow and causes confusion. The agent wallet lets users stay on Arbitrum while the agent signs L1 actions in the background. The private key lives in localStorage — acceptable for a trading frontend since agents cannot withdraw funds, only place orders.
BFS routing over weighted Dijkstra
For a 3-hop maximum, BFS finds the shortest path quickly without needing edge weights. A more sophisticated router would weight edges by spread and estimated slippage, but for the current pair set, fewer hops correlates well with lower slippage. This kept the implementation simple and fast.
Selective orderbook fetching
Initially the router fetched all orderbooks on every search, creating 20+ API requests. I optimized this by checking for a direct pair first (1 request), and only fetching 2-hop routes through common intermediaries if no direct path exists. This reduced average requests from 20+ to 2-4.
State machine for trade execution
Trade execution has multiple states: discovering, route_found, executing, executed, error. A reducer-based state machine makes transitions explicit and prevents impossible states like showing a result while still executing. It also made adding multi-hop progress tracking straightforward.

Outcome

The router handles any token pair available on Hyperliquid spot, automatically finding routes through up to 3 hops. The agent wallet flow reduced friction significantly — users sign once and can execute unlimited trades without popups. Price estimates update in real-time from live orderbook data, and the UI warns about low liquidity or stale data. The architecture cleanly separates concerns: routing logic, exchange API, signing, and UI state are all independent modules. The project deepened my understanding of exchange-specific signing schemes and the tradeoffs in DEX routing.