API Reference

WebSocket Events

Makers connect to ws://localhost:4000/ws/maker (live: wss://hyperdex.onrender.com/ws/maker) for real-time RFQ delivery. Everything below is handled for you by the maker-sdk — this page documents the wire protocol for reference.

Use the SDK: In practice you never write this by hand. Run npm run dev <name>; the SDK connects, authenticates, signs, and replies. You only implement a MakerEngine. See Pricing Engines.

Connection & Auth

Authentication is done with an Authorization: Bearer header on the WebSocket upgrade request — there is no separate auth message. A bad key is rejected during the handshake.

const ws = new WebSocket("wss://hyperdex.onrender.com/ws/maker", {
  headers: { Authorization: "Bearer sk_live_xxx" },
});

ws.onmessage = ({ data }) => {
  const msg = JSON.parse(data);
  switch (msg.type) {
    case "connected": console.log("Connected as", msg.makerName); break;
    case "rfq":       handleRfq(msg); break;
    case "trade":     onTradeConfirmed(msg); break;
    case "ping":      ws.send(JSON.stringify({ type: "pong" })); break;
  }
};

Handling an RFQ

On an rfq message, price it, build the quote, sign SHA256(XDR(quote)) with your ed25519 key, and send an rfqQuote back over the same socket (bids are not REST). Send rfqError to skip.

function handleRfq(msg) {
  // msg.message: { quoteId, tokenIn, tokenOut, amountIn, takerAddress }
  const amountOut = engine.getQuote(msg.message);        // stroops, or null to skip
  if (!amountOut) {
    ws.send(JSON.stringify({ type: "rfqError",
      message: { quoteId: msg.message.quoteId, reason: "no_inventory" } }));
    return;
  }
  const quote     = buildQuote({ ...msg.message, amountOut });
  const signature = signQuote(quote);                    // SHA256(XDR(quote)) + ed25519
  ws.send(JSON.stringify({ type: "rfqQuote",
    message: { quoteId: msg.message.quoteId, quote, signature } }));
}

Message Types

TypeDirectionDescription
connectedServer → MakerHandshake accepted; includes makerName
errorServer → MakerAuth or protocol error; includes a reason
rfqServer → MakerNew RFQ — { quoteId, tokenIn, tokenOut, amountIn, takerAddress }
rfqQuoteMaker → ServerSigned sealed bid — { quoteId, quote, signature }
rfqErrorMaker → ServerSkip this RFQ — { quoteId, reason: "no_inventory" | "rate_limit" }
priceLevelsMaker → ServerResting book update (streamed ~every 3s) — { tokenIn, tokenOut, levels[] }
tradeServer → MakerA won quote settled on-chain — { tradeEventId, txHash, amountIn, amountOut }
tradeAckMaker → ServerAcknowledge receipt of a trade event — { tradeEventId }
ping / pongServer ↔ MakerKeepalive every 30s — respond to ping with pong or the connection drops
HyperDex | Trade Without Limits