LIQUAPRO
◇ DREWLESS · 7-SLF

API DOCS

every relayer endpoint · REST + WebSocket · live-try buttons
CONFIG ORDERS TRADES CHAT AMM MATCHMAKER EXTERNAL HEALTH ADMIN/DEBUG WEBSOCKET

CONFIG

GET /api/config Single source of truth — addresses, EIP-712 domain, tokens, market, MM wallets, fee. Frontend's first call.

response (sample)

{
  "chainId": 31337,
  "exchange": "0x9fE4…a6e0",
  "infinityPool": "0x61c3…33e1",
  "matchmaker": "0x6101…D788",
  "liquaToken": "0x0B30…7016",
  "liquaStaking": "0x9599…07B1",
  "domain": { "name": "Liqua", "version": "1", ... },
  "tokens": [{"symbol":"mUSDC",...}, {"symbol":"mWETH",...}],
  "market": {"base":"0x…WETH", "quote":"0x…USDC"},
  "fee": {"takerFeeBps":0, "feeRecipient":"0x…staking", "max_bps":100},
  "mmWallets": {"quoter":{...}, "arber":{...}}
}
curl -s http://localhost:8080/api/config

ORDERS

GET/api/orders Live orderbook · filter by ?makerToken= ?takerToken= ?maker= · annotated with watcher's lastRemaining.

response

{
  "orders": [{
    "orderHash": "0x…",
    "order": {"maker":..., "makerToken":..., ... , "epoch":"0"},
    "signature": "0x…65 bytes",
    "remaining": "…takerToken units…",
    "createdAt": 1780000000000
  }],
  "count": 24, "watcherLastBlock": 42
}
curl -s http://localhost:8080/api/orders | head -c 400
POST/api/orders Submit a maker-signed EIP-712 order. Three gates run server-side: SCHEMA-GATE · SIG-GATE · EPOCH-GATE. The same sig is re-verified on-chain at fill.

request body

{
  "order": {"maker":"0x…", "makerToken":"0x…", "takerToken":"0x…",
            "makerAmount":"1000000000000000000", "takerAmount":"2000000000",
            "expiry":"1800000000", "salt":"…256-bit…", "epoch":"0"},
  "signature": "0x…65 bytes EIP-712"
}

response · 200

{ "ok": true, "orderHash": "0x…" }

response · 400 (gate reject)

{ "ok": false, "error": "signature does not recover to maker" }
DELETE/api/orders/:hash Soft-remove from book (UX hint). The on-chain Cancel event is the source of truth; relayer prunes automatically too.

response

{ "ok": true }

TRADES

GET/api/trades?limit=50 Trade tape · Fill events observed by the chain watcher · capped 500 in-memory.

response

{
  "trades": [{"orderHash":..., "maker":..., "taker":..., "makerToken":..., "takerToken":...,
              "makerFilledAmount":..., "takerFilledAmount":...,
              "blockNumber":..., "txHash":..., "ts":...}],
  "count": 12, "watcherLastBlock": 42
}

CHAT

GET/api/chat?limit=100 In-memory chat ring buffer (200 cap, persisted across restarts via the kernel).
{ "chat": [{"address":..., "message":..., "ts":..., "sig":...}], "count":3, "cap":200 }
POST/api/chat Post a wallet-signed chat message. Sig payload = "Liqua chat\n{address-lowercase}\n{ts-seconds}\n{message}". ts must be within ±300s of server.

request body

{
  "address": "0x…",
  "message": "hello",
  "ts": 1780000000,
  "signature": "0x…65 bytes personal_sign"
}

AMM (InfinityPool · UniV2-style)

GET/api/amm Pool address, reserves, mid (quote/base), fee, watcher block.
{
  "pool":..., "factory":..., "token0":..., "token1":...,
  "reserves": {"reserve0":"200000000000", "reserve1":"100000000000000000000", "ts":...},
  "mid": 2000, "fee_bps": 30, "watcherLastBlock": 42
}
GET/api/amm/swaps?limit=50AMM Swap event tape (capped 200).

MATCHMAKER (orderbook ↔ AMM crosses)

GET/api/matchmakerMatchmaker address + recent atomic crosses (orderbook order filled by flash-swapping AMM, profit to keeper).
GET/api/matchmaker/crosses?limit=50Capped cross tape (100). Each entry: keeper, takerFilled, makerReceived, ammRepaid, profit, txHash.

EXTERNAL FEED

GET/api/external/binance Live Binance ETH/USDT depth20 @ 1s · mid · mirror keeper stats (ticks/posted/rejected).
{
  "source": "binance", "pair": "ETHUSDT", "connected": true,
  "mid": 1857.83, "depth": {"bids":[...], "asks":[...]},
  "lastTickAt": ..., "ageMs": 412, "reconnects": 0,
  "mirror": {"enabled":true, "wallet":"0x…quoter", "ticks":4, "posted":24, ...}
}

HEALTH · MOLECULAR TELEMETRY

GET/api/healthHormones, somatic state (33-state classifier), ledger (boot count + hash), watcher, book/trades/chat/amm/matchmaker/external/mirror/ws counters, fleet roster, DNA versions.

ADMIN / DEBUG

POST/api/reloadRe-read shared/deployment.json without restarting the relayer (after a fresh deploy).
GET/api/transitionsLast 100 R3-labelled transitions (in-memory tracer). Useful for debugging.

WEBSOCKET

WSws://localhost:8080/wsSingle fan-out endpoint · subscribe by connecting · messages are { type, payload, ts }.

topics (server → client)

hello — sent on connect: chainId, fleets, current binance mid

order — new order accepted into the book

trade — Fill event observed by watcher

cancel — Cancel event observed by watcher

chat — new chat message accepted

external — Binance depth tick (~1s cadence)

health — hormones + somatic + watcher block (every 5s)

quickstart

// In browser:
const ws = new WebSocket("ws://localhost:8080/ws");
ws.onmessage = e => { const m = JSON.parse(e.data); console.log(m.type, m.payload); };
not connected