WebSocket Gateway (yqmev)

The yqmev gateway is a WebSocket JSON-RPC 2.0 proxy that sits between clients and the MEV engine. It translates WebSocket JSON-RPC calls into upstream HTTP requests, manages subscriptions, and handles response normalization.

Architecture

┌──────────┐    WebSocket     ┌───────────┐     HTTP       ┌────────────┐
│  Client   │ ──────────────► │  Gateway   │ ─────────────► │ MEV Engine │
│ (wscat,   │  JSON-RPC 2.0   │  (yqmev)   │  REST / RPC    │            │
│  SDK,     │ ◄────────────── │  :9099     │ ◄───────────── │  :8080     │
│  TUI)     │   responses +   │            │                │            │
│           │   subscriptions │            │                │            │
└──────────┘                  └───────────┘                └────────────┘

Clients connect via WebSocket at ws://host:9099/ws and send standard JSON-RPC 2.0 requests. The gateway maps each method to the appropriate upstream HTTP endpoint, forwards the request, and returns the response. For non-JSON upstream responses, the gateway wraps them in a valid JSON-RPC response using a json.Valid() guard.

Method Routes

The gateway maps 27 JSON-RPC methods to upstream HTTP endpoints:

Bundle Operations

MethodUpstreamDescription
mev_sendBundlePOST /searcher/bundleSubmit a bundle
mev_getBundleGET /searcher/bundle/{bundle_id}Get bundle by ID
mev_getAuctionGET /searcher/auctionCurrent auction pool
mev_simulateBundlePOST /simulateBundleSimulate a bundle
mev_simulateTxPOST /simulateTransactionSimulate a transaction
mev_listBundlesGET /store/bundlesList stored bundles

Protected Transactions (OFA)

MethodUpstreamDescription
mev_protectTxPOST /protect/txSubmit OFA-protected tx
mev_getProtectStatusGET /protect/tx/{tx_id}Protection status
mev_getProtectRebatesGET /protect/rebates?originator_id={id}Query rebates

Intent Operations

MethodUpstreamDescription
mev_submitIntentPOST /intentSubmit intent
mev_getIntentGET /intent/{id}Get intent by ID
mev_submitSolutionPOST /intent/{intent_id}/solveSubmit solver solution
mev_getSolutionsGET /intent/{id}/solutionsList solutions
mev_registerSolverPOST /solver/registerRegister as solver
mev_listSolversGET /solver/listList solvers

Relay Operations

MethodUpstreamDescription
mev_relayRegisterPOST /relay/registerRegister relay
mev_relayListGET /relay/listList relays
mev_relayStatsGET /relay/marketplace/statsRelay stats
mev_relayGetGET /relay/marketplace/{id}Get relay by ID

Query / System

MethodUpstreamDescription
mev_listBlocksGET /store/blocksList recent blocks
mev_getBlockGET /store/blocks/{id}Block by ID
mev_healthGET /healthHealth check
mev_authStatsGET /auth/statsAuth statistics
mev_simCacheStatsGET /simulator/cacheSimulation cache stats
mev_orderflowSummaryGET /orderflow/summaryOrderflow summary

Aliases (yq_ prefix)

MethodMaps ToDescription
yq_getProtectionStatusmev_getProtectStatusProtection status alias
yq_getRebateHistorymev_getProtectRebatesRebate history alias
yq_getStatsGET /v1/ofa/statsOFA statistics

Subscription Topics

The gateway supports 5 subscription topics via mev_subscribe / mev_unsubscribe (or yq_subscribe / yq_unsubscribe):

TopicDescriptionEvent Payload
auctionLive auction eventsBid submitted, block built, winner declared
mempoolMempool activityNew pending transactions
blocksNew blocksBlock number, MEV extracted, bundles included
protectOFA protection eventsIntercepted tx, backrun status, rebate
intentsIntent lifecycleSubmitted, solving, filled, expired

Subscribe Example

// Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "mev_subscribe",
  "params": ["auction"]
}

// Response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "sub_0x1a2b3c"
}

// Subscription events
{
  "jsonrpc": "2.0",
  "method": "mev_subscription",
  "params": {
    "subscription": "sub_0x1a2b3c",
    "result": {
      "type": "bid_submitted",
      "auction_id": 4821,
      "bidder": "0xA3f2...",
      "amount": "84700000000000000"
    }
  }
}

Non-JSON Response Handling

Some upstream endpoints return non-JSON responses (e.g., Prometheus metrics as plain text). The gateway uses a json.Valid() guard to detect these cases and wraps them:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content_type": "text/plain",
    "body": "# HELP mev_bundles_total ...\nmev_bundles_total 1423\n"
  }
}

Docker Deployment

The gateway is included in the combined Docker Compose stack:

# docker-compose.combined.yaml
services:
  gateway:
    image: yoorquezt/yqmev-gateway:latest
    ports:
      - "9099:9099"
    environment:
      - YQMEV_UPSTREAM_URL=http://engine:8080
      - YQMEV_API_KEY=${YQMEV_API_KEY}
      - YQMEV_LOG_LEVEL=info
    depends_on:
      engine:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:9099/health"]
      interval: 10s
      timeout: 5s
      retries: 3
docker compose -f docker-compose.combined.yaml up gateway

Code Examples

wscat

# Connect (note the /ws path)
wscat -c ws://localhost:9099/ws

# Submit a bundle
> {"jsonrpc":"2.0","id":1,"method":"mev_sendBundle","params":[{"txs":["0xsigned1","0xsigned2"],"blockNumber":"0x1296F00","chain":"ethereum"}]}

# Subscribe to auctions
> {"jsonrpc":"2.0","id":2,"method":"mev_subscribe","params":["auction"]}

# Check health
> {"jsonrpc":"2.0","id":3,"method":"mev_health","params":[]}

# Get orderflow summary
> {"jsonrpc":"2.0","id":4,"method":"mev_orderflowSummary","params":[]}

TypeScript

import { MEVGatewayClient } from "@yoorquezt/sdk-mev";

const gw = new MEVGatewayClient("ws://localhost:9099/ws", {
  apiKey: process.env.YQMEV_API_KEY,
});

// Submit bundle
const result = await gw.submitBundle({
  txs: ["0xsigned1", "0xsigned2"],
  blockNumber: 19482300,
  chain: "ethereum",
});
console.log("Bundle hash:", result.bundleHash);

// Subscribe to auction events
const sub = await gw.subscribe("auction");
sub.on("data", (event) => {
  console.log("Auction event:", event);
});

Go

package main

import (
    "context"
    "fmt"
    "github.com/yoorquezt-labs/yoorquezt-sdk-mev-go"
)

func main() {
    c, err := yqmev.Dial(context.Background(), "ws://localhost:9099/ws", client.Options{})
    if err != nil {
        panic(err)
    }
    defer c.Close()

    // Call a method
    var result map[string]interface{}
    err = c.Call(context.Background(), "mev_health", nil, &result)
    if err != nil {
        panic(err)
    }
    fmt.Println("Health:", result)
}

Configuration

VariableDescriptionDefault
YQMEV_LISTEN_ADDRGateway listen address:9099
YQMEV_UPSTREAM_URLMEV engine HTTP URLhttp://localhost:8080
YQMEV_API_KEYAPI key for auth(none)
YQMEV_MAX_CONNECTIONSMax concurrent WS connections1000
YQMEV_LOG_LEVELLog levelinfo
YQMEV_READ_TIMEOUTWebSocket read timeout60s
YQMEV_WRITE_TIMEOUTWebSocket write timeout10s
Edit this page