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
| Method | Upstream | Description |
|---|
mev_sendBundle | POST /searcher/bundle | Submit a bundle |
mev_getBundle | GET /searcher/bundle/{bundle_id} | Get bundle by ID |
mev_getAuction | GET /searcher/auction | Current auction pool |
mev_simulateBundle | POST /simulateBundle | Simulate a bundle |
mev_simulateTx | POST /simulateTransaction | Simulate a transaction |
mev_listBundles | GET /store/bundles | List stored bundles |
Protected Transactions (OFA)
| Method | Upstream | Description |
|---|
mev_protectTx | POST /protect/tx | Submit OFA-protected tx |
mev_getProtectStatus | GET /protect/tx/{tx_id} | Protection status |
mev_getProtectRebates | GET /protect/rebates?originator_id={id} | Query rebates |
Intent Operations
| Method | Upstream | Description |
|---|
mev_submitIntent | POST /intent | Submit intent |
mev_getIntent | GET /intent/{id} | Get intent by ID |
mev_submitSolution | POST /intent/{intent_id}/solve | Submit solver solution |
mev_getSolutions | GET /intent/{id}/solutions | List solutions |
mev_registerSolver | POST /solver/register | Register as solver |
mev_listSolvers | GET /solver/list | List solvers |
Relay Operations
| Method | Upstream | Description |
|---|
mev_relayRegister | POST /relay/register | Register relay |
mev_relayList | GET /relay/list | List relays |
mev_relayStats | GET /relay/marketplace/stats | Relay stats |
mev_relayGet | GET /relay/marketplace/{id} | Get relay by ID |
Query / System
| Method | Upstream | Description |
|---|
mev_listBlocks | GET /store/blocks | List recent blocks |
mev_getBlock | GET /store/blocks/{id} | Block by ID |
mev_health | GET /health | Health check |
mev_authStats | GET /auth/stats | Auth statistics |
mev_simCacheStats | GET /simulator/cache | Simulation cache stats |
mev_orderflowSummary | GET /orderflow/summary | Orderflow summary |
Aliases (yq_ prefix)
| Method | Maps To | Description |
|---|
yq_getProtectionStatus | mev_getProtectStatus | Protection status alias |
yq_getRebateHistory | mev_getProtectRebates | Rebate history alias |
yq_getStats | GET /v1/ofa/stats | OFA statistics |
Subscription Topics
The gateway supports 5 subscription topics via mev_subscribe / mev_unsubscribe (or yq_subscribe / yq_unsubscribe):
| Topic | Description | Event Payload |
|---|
auction | Live auction events | Bid submitted, block built, winner declared |
mempool | Mempool activity | New pending transactions |
blocks | New blocks | Block number, MEV extracted, bundles included |
protect | OFA protection events | Intercepted tx, backrun status, rebate |
intents | Intent lifecycle | Submitted, 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
| Variable | Description | Default |
|---|
YQMEV_LISTEN_ADDR | Gateway listen address | :9099 |
YQMEV_UPSTREAM_URL | MEV engine HTTP URL | http://localhost:8080 |
YQMEV_API_KEY | API key for auth | (none) |
YQMEV_MAX_CONNECTIONS | Max concurrent WS connections | 1000 |
YQMEV_LOG_LEVEL | Log level | info |
YQMEV_READ_TIMEOUT | WebSocket read timeout | 60s |
YQMEV_WRITE_TIMEOUT | WebSocket write timeout | 10s |