Skip to Content
HyperQuote is live on HyperEVM — Start trading →
MakersRelay Connection

Relay Connection

Makers connect to the HyperQuote relay via a persistent WebSocket connection. The relay is the message broker that delivers RFQ broadcasts to makers and forwards signed quotes back to takers.

Relay URL

The relay WebSocket endpoint defaults to:

ws://127.0.0.1:8080

Set via the RELAY_WS_URL environment variable in production. The relay also exposes REST endpoints on the same port for polling (GET /rfqs, GET /quotes?rfqId=..., GET /health).

WebSocket Handshake

Open a standard WebSocket connection to the relay URL. No special handshake headers or subscription messages are required — all connected clients immediately receive RFQ_BROADCAST messages.

import WebSocket from "ws"; const ws = new WebSocket("ws://127.0.0.1:8080"); ws.on("open", () => { console.log("Connected to relay"); });

Upon connection, the relay logs the client and begins forwarding all active RFQ broadcasts. There is no authentication step in V1 — any WebSocket client that connects will receive broadcasts.

In production, the relay enforces rate limiting (default: 30 messages per minute per IP). Exceeding this limit will result in an ERROR message from the relay.

Message Protocol

All messages are JSON objects with a type field and a data field:

interface RelayMessage { type: "RFQ_SUBMIT" | "RFQ_BROADCAST" | "QUOTE_SUBMIT" | "QUOTE_BROADCAST" | "PING" | "PONG" | "ERROR"; data: unknown; }

Makers primarily interact with three message types:

Message TypeDirectionPurpose
RFQ_BROADCASTRelay -> MakerNew RFQ available for quoting
QUOTE_SUBMITMaker -> RelaySubmit a signed quote for an RFQ
QUOTE_BROADCASTRelay -> MakerA quote was submitted (by any maker)
PINGRelay -> MakerKeepalive check
PONGMaker -> RelayKeepalive response
ERRORRelay -> MakerValidation or rate limit error

Ping/Pong Heartbeat

The maker bot should send a PING message every 30 seconds to keep the connection alive. The relay responds to PING with PONG, and the relay also sends its own PING messages that the maker must respond to with PONG.

// Send keepalive PING every 30 seconds const pingInterval = setInterval(() => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: "PING", data: {} })); } }, 30_000); // Respond to relay PING with PONG ws.on("message", (raw) => { const msg = JSON.parse(raw.toString()); if (msg.type === "PING") { ws.send(JSON.stringify({ type: "PONG", data: {} })); } }); // Clean up on disconnect ws.on("close", () => clearInterval(pingInterval));

Error Handling

The relay sends ERROR messages when validation fails or rate limits are exceeded:

ws.on("message", (raw) => { const msg = JSON.parse(raw.toString()); if (msg.type === "ERROR") { console.error("Relay error:", msg.data.message); } });

Common error messages include:

  • "Rate limit exceeded" — Too many messages in the current window.
  • "RFQ not found or expired" — The referenced RFQ is no longer active.
  • "Invalid Quote EIP-712 signature" — Signature verification failed on the relay.
  • "Duplicate quote from this maker for this RFQ" — Only one quote per maker per RFQ is allowed.

Auto-Reconnect with Exponential Backoff

The relay connection can drop due to network issues or relay restarts. Implement auto-reconnect with exponential backoff to recover gracefully:

const MAX_RECONNECT_ATTEMPTS = 5; const BASE_DELAY_MS = 1000; let attempt = 0; function connect() { const ws = new WebSocket("ws://127.0.0.1:8080"); ws.on("open", () => { console.log("Connected to relay"); attempt = 0; // Reset on successful connection }); ws.on("close", () => { if (attempt >= MAX_RECONNECT_ATTEMPTS) { console.error("Max reconnect attempts reached. Exiting."); process.exit(1); } const delay = BASE_DELAY_MS * Math.pow(2, attempt); attempt++; console.log(`Disconnected. Reconnecting in ${delay}ms (attempt ${attempt}/${MAX_RECONNECT_ATTEMPTS})...`); setTimeout(connect, delay); }); ws.on("error", (err) => { console.error("WebSocket error:", err.message); }); // ... message handlers } connect();

The default maker relay bot (makerRelay.ts) uses a simpler fixed 3-second reconnect delay. For production, exponential backoff with jitter is recommended.

Connection Status

Monitor relay health via the REST endpoint:

curl http://127.0.0.1:8080/health

Returns:

{ "status": "ok", "chainId": 31337, "engineAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "activeRfqs": 2, "totalQuotes": 5, "connectedClients": 3, "uptime": 1234 }

This is useful for monitoring dashboards and alerting on relay downtime.

Last updated on