MEV SDK — TypeScript

The @yoorquezt/sdk-mev package provides TypeScript clients for both the Q AI API and the MEV Gateway WebSocket.

Installation

npm install @yoorquezt/sdk-mev
# or
yarn add @yoorquezt/sdk-mev
# or
pnpm add @yoorquezt/sdk-mev

QMEVClient

The QMEVClient connects to the Q AI API for natural language chat and tool access.

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

const client = new QMEVClient({
  baseUrl: "http://localhost:9100",
  apiKey: "your-api-key",
  role: "operator",
});

chat

Send a message and receive a complete response.

const response = await client.chat("What's the profit from the last 24 hours?");

console.log(response.content);
// "Total profit (24h): 2.847 ETH across 142 landed bundles."

console.log(response.toolsUsed);
// ["analyst_profit"]

chatStream

Stream a response token-by-token.

const stream = client.chatStream("Analyze relay performance");

for await (const event of stream) {
  switch (event.type) {
    case "content_delta":
      process.stdout.write(event.delta);
      break;
    case "tool_use":
      console.log(`\n[Using tool: ${event.tool}]`);
      break;
    case "tool_result":
      console.log(`[Tool result: ${event.tool}]`);
      break;
    case "confirmation_required":
      console.log(`\nAction requires confirmation: ${event.message}`);
      break;
    case "message_end":
      console.log(`\n[Tokens: ${event.usage.inputTokens} in, ${event.usage.outputTokens} out]`);
      break;
  }
}

listTools

List all tools available to your role.

const tools = await client.listTools();

for (const tool of tools) {
  console.log(`${tool.name} (${tool.category}) - ${tool.description}`);
  if (tool.mutating) console.log("  [MUTATING - requires confirmation]");
}

health

Check Q AI API health.

const health = await client.health();
console.log(health.status); // "healthy"

MEVGatewayClient

The MEVGatewayClient connects to the MEV Gateway via WebSocket for direct engine interaction.

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

const gw = new MEVGatewayClient("ws://localhost:9099", {
  apiKey: "your-api-key",
});

submitBundle

const result = await gw.submitBundle({
  txs: ["0xsigned_tx_1", "0xsigned_tx_2"],
  blockNumber: 19482300,
  chain: "ethereum",
});

console.log(result.bundleHash); // "0x9f8e7d..."
console.log(result.status);     // "pending"

getBundleStatus

const status = await gw.getBundleStatus("0x9f8e7d...");

console.log(status.status);  // "landed"
console.log(status.block);   // 19482301
console.log(status.profit);  // "0.0312 ETH"

simulateBundle

const sim = await gw.simulateBundle({
  txs: ["0xsigned_tx_1", "0xsigned_tx_2"],
  blockNumber: 19482300,
  chain: "ethereum",
});

console.log(sim.success);    // true
console.log(sim.gasUsed);    // 248000
console.log(sim.profit);     // "0.0312 ETH"
console.log(sim.logs);       // [...transaction logs]

getMempoolSnapshot

const mempool = await gw.getMempoolSnapshot();

console.log(mempool.pending);  // 142
console.log(mempool.txs);      // [...pending transactions]

getRelayStats

const stats = await gw.getRelayStats();

for (const relay of stats.relays) {
  console.log(`${relay.name}: ${relay.status} (${relay.latencyMs}ms)`);
}

getOFAStats

const ofa = await gw.getOFAStats();

console.log(ofa.protectedTxs);   // 1423
console.log(ofa.totalRebates);   // "12.34 ETH"

getProfitHistory

const history = await gw.getProfitHistory({
  range: "7d",
  chain: "ethereum",
  groupBy: "day",
});

for (const entry of history) {
  console.log(`${entry.date}: ${entry.profitEth} ETH (${entry.bundles} bundles)`);
}

subscribe

Subscribe to real-time events.

const sub = await gw.subscribe("auction");

sub.on("data", (event) => {
  console.log("Auction event:", event.type, event);
});

sub.on("error", (err) => {
  console.error("Subscription error:", err);
});

// Unsubscribe
await sub.unsubscribe();

Available topics: auction, bundles, blocks, mempool, protection.

Types

TypeDescription
QMEVClientConfigConfiguration for QMEVClient (baseUrl, apiKey, role, model)
ChatResponseResponse from chat() (id, content, toolsUsed, usage)
StreamEventStreaming event (content_delta, tool_use, tool_result, etc.)
ToolTool definition (name, description, category, mutating, parameters)
BundleSubmitRequestBundle submission parameters
BundleSubmitResultBundle submission result
BundleStatusBundle status response
SimulationResultBundle simulation result
MempoolSnapshotMempool state snapshot
RelayStatsRelay statistics
OFAStatsOFA protection statistics
ProfitEntryProfit history entry
SubscriptionEventReal-time subscription event

Error Handling

The SDK throws QMEVError for all error conditions:

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

try {
  await gw.getBundleStatus("0xinvalid");
} catch (err) {
  if (err instanceof QMEVError) {
    console.error(`Error ${err.code}: ${err.message}`);
    // Error 1002: Bundle not found

    switch (err.code) {
      case 1001: // Engine unavailable
        console.log("Retry later");
        break;
      case 1002: // Not found
        console.log("Resource does not exist");
        break;
      case 1003: // Rate limited
        console.log(`Retry after ${err.retryAfter}s`);
        break;
    }
  }
}

Full Example

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

async function main() {
  // Q AI for natural language
  const ai = new QMEVClient({
    baseUrl: "http://localhost:9100",
    apiKey: process.env.YQMEV_API_KEY!,
    role: "operator",
  });

  // Gateway for direct engine access
  const gw = new MEVGatewayClient("ws://localhost:9099", {
    apiKey: process.env.YQMEV_API_KEY!,
  });

  // Check health
  const health = await ai.health();
  console.log("Q AI:", health.status);

  // Ask Q AI about profit
  const response = await ai.chat("Show me today's profit by strategy");
  console.log(response.content);

  // Stream a complex query
  const stream = ai.chatStream("Generate a forensic report for the last 100 blocks");
  for await (const event of stream) {
    if (event.type === "content_delta") {
      process.stdout.write(event.delta);
    }
  }

  // Direct bundle submission via gateway
  const result = await gw.submitBundle({
    txs: ["0xsigned_tx_1", "0xsigned_tx_2"],
    blockNumber: 19482300,
    chain: "ethereum",
  });
  console.log("\nBundle submitted:", result.bundleHash);

  // Watch for the bundle to land
  const sub = await gw.subscribe("bundles");
  sub.on("data", (event) => {
    if (event.bundleHash === result.bundleHash) {
      console.log("Bundle status:", event.status);
      if (event.status === "landed" || event.status === "failed") {
        sub.unsubscribe();
      }
    }
  });
}

main().catch(console.error);
Edit this page