Docs / Nitro Routing API

Nitro Routing API

Real-time RPC racing, H3-aware intent routing, and cryptographically-verified task execution on 0G mainnet.

01 — Overview

What is Nitro?

Nitro is Opacus's real-time network infrastructure layer. It provides three core capabilities:

Live on 0G mainnet. All endpoints read from real chain data. Block numbers, prices, and latency figures are real — no mock data, no testnet.

02 — RPC Pool

0G RPC Pool

The pool is an in-memory registry of 0G RPC endpoints. On every provider request, all healthy endpoints race via Promise.any(). The winner is selected by first-response latency.

EndpointNotes
https://0g-rpc.publicnode.comTypically fastest (~80–130ms from Asia/EU). Recommended primary.
https://evmrpc.0g.aiOfficial 0G Foundation node, higher latency (~1500–2500ms) but always-available fallback.
GET

/v1/nitro/ping

Returns live round-trip latency for each endpoint in the pool, the winning endpoint, and the current 0G block number. No authentication required.

Response Schema

FieldTypeDescription
okbooleanAlways true on success
rttMsnumberRound-trip time of winning request in milliseconds
blockNumberstringCurrent 0G mainnet block number (hex, as returned by eth_blockNumber)
winnerstringFull URL of the winning RPC endpoint
pool[].urlstringRPC endpoint URL
pool[].latencyMsnumberRound-trip latency for this endpoint in ms
pool[].healthybooleantrue if endpoint responded within timeout
GEThttps://opacus.xyz/api/v1/nitro/ping
{
  "ok": true,
  "rttMs": 94,
  "blockNumber": "0x1D3E7A2",
  "winner": "https://0g-rpc.publicnode.com",
  "pool": [
    { "url": "https://0g-rpc.publicnode.com", "latencyMs": 94,   "healthy": true },
    { "url": "https://evmrpc.0g.ai",          "latencyMs": 1843, "healthy": true }
  ]
}
CLI
curl https://opacus.xyz/api/v1/nitro/ping | jq .

03 — Intent Routing

H3 Intent Routing

Tasks are classified into one of two routing modes before handoff:

Node geography is encoded as H3 cells at resolution 5 (~252km² per cell). The handoff algorithm finds the minimum Haversine distance between the agent's H3 cell and each Nitro node's cell.

POST

/v1/nitro/handoff

Routes an intent to the optimal Nitro node. Returns a QUIC address for direct connection.

Request Body

FieldTypeDescription
intentstring requiredNatural-language intent, e.g. "swap USDC to W0G on Jaine"
chainstring optional"0g" or "base". Inferred from intent if omitted.
latitudenumber optionalAgent latitude (decimal degrees). Falls back to server-side geo-IP if omitted.
longitudenumber optionalAgent longitude (decimal degrees).

Response Schema

FieldTypeDescription
okbooleanRequest succeeded
quicEndpointstringQUIC address for direct Nitro connection, e.g. quic://sg-sin-1.0g.network:4433
nitroLabelstringHuman-readable node label, e.g. "Singapore Nitro"
anchor_modestring"execution" or "interactive"
reasonstringRouting explanation for debugging
failoverstringLabel of fallback Nitro node
latency_p50_msnumberExpected p50 round-trip in ms to selected node
POST/api/v1/nitro/handoff — execution intent (Istanbul)
// Request
{ "intent": "swap USDC to W0G on Jaine", "chain": "0g", "latitude": 41.0082, "longitude": 28.9784 }

// Response
{
  "ok": true,
  "quicEndpoint": "quic://sg-sin-1.0g.network:4433",
  "nitroLabel": "Singapore Nitro",
  "anchor_mode": "execution",
  "reason": "Execution anchor: 0G Jaine infra on Singapore (AWS ap-southeast-1)",
  "failover": "Mumbai Nitro",
  "latency_p50_ms": 16
}
POST/api/v1/nitro/handoff — interactive intent (Berlin)
// Request
{ "intent": "analyze my portfolio risk", "latitude": 52.5200, "longitude": 13.4050 }

// Response
{
  "ok": true,
  "quicEndpoint": "quic://eu-fra-1.0g.network:4433",
  "nitroLabel": "Frankfurt Nitro",
  "anchor_mode": "interactive",
  "reason": "Read-only analysis, no execution anchor needed. Nearest node to Frankfurt selected.",
  "failover": "Amsterdam Nitro",
  "latency_p50_ms": 9
}

04 — Task Signing

Ed25519 Task Signing

Every task result is signed using Ed25519 via Node.js node:crypto. Consumers can verify agent identity and detect tampering — zero extra packages required.

TSGenerate agent keypair (once at registration)
import { generateKeyPairSync } from 'node:crypto';

const { privateKey, publicKey } = generateKeyPairSync('ed25519');
const privDer = privateKey.export({ type: 'pkcs8', format: 'der' });
const pubDer  = publicKey.export({ type: 'spki', format: 'der' });
TSSign a task result
import { sign } from 'node:crypto';

const payload   = Buffer.from(JSON.stringify({ taskId, result, timestamp }));
const signature = sign(null, payload, privateKey).toString('hex');

const signedResult = { taskId, result, timestamp, agentPubKey: pubDer.toString('hex'), sig: signature };
TSVerify a signed result
import { verify, createPublicKey } from 'node:crypto';

function verifyTaskResult(r) {
  const payload = Buffer.from(JSON.stringify({ taskId: r.taskId, result: r.result, timestamp: r.timestamp }));
  const pubKey  = createPublicKey({ key: Buffer.from(r.agentPubKey, 'hex'), format: 'der', type: 'spki' });
  return verify(null, payload, pubKey, Buffer.from(r.sig, 'hex'));
}

05 — Spam Protection

H3 Spam Filter

Agent submissions are rate-limited per H3 cell at resolution 5 (~252km² per cell). Each cell has an independent token bucket — spam in one region cannot affect others.

ParameterValueNotes
burst limit100 requestsMax submissions per 100ms window per H3 cell
window100msRolling token bucket
violation threshold5Violations before automatic slash
slash penaltyquarantine + stake deduction1-hour minimum cooldown on slash
resolutionH3 res-5~252km² average cell area
Slash is automatic and on-chain. After 5 window violations the agent's wallet is quarantined. No manual override — the agent must wait for the cooldown period to expire.

06 — Full Example

End-to-End Integration

TSRPC racing + intent routing + verified execution
const API = 'https://opacus.xyz/api';
const KEY = 'YOUR_API_KEY';

async function runTask(intent: string, lat: number, lng: number) {
  // 1. Race the RPC pool
  const ping = await fetch(`${API}/v1/nitro/ping`).then(r => r.json());
  console.log(`Best RPC: ${ping.winner} @ ${ping.rttMs}ms  block #${parseInt(ping.blockNumber, 16)}`);

  // 2. Get optimal Nitro node
  const handoff = await fetch(`${API}/v1/nitro/handoff`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ intent, latitude: lat, longitude: lng })
  }).then(r => r.json());

  console.log(`→ ${handoff.nitroLabel} (${handoff.anchor_mode})  ${handoff.quicEndpoint}`);

  // 3. Execute
  const exec = await fetch(`${API}/v1/task-execution`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ intent, nitroEndpoint: handoff.quicEndpoint })
  }).then(r => r.json());

  // 4. Verify Ed25519 signature
  if (exec.sig && exec.agentPubKey) {
    const valid = verifyTaskResult(exec);
    console.log(`Signature: ${valid ? '✓ valid' : '✗ INVALID'}`);
  }
  return exec;
}

runTask('swap 10 USDC to W0G on Jaine', 41.0082, 28.9784);

07 — Error Codes

Error Reference

HTTPCodeMeaning
401UNAUTHORIZEDMissing or invalid Authorization: Bearer … header
402BUDGET_EXHAUSTEDProject balance below $10 minimum lock
429H3_SPAM_LIMITH3 cell burst limit exceeded. Retry after 100ms.
451AGENT_SLASHEDAgent quarantined after 5 H3 violations. On-chain cooldown applies.
503NO_HEALTHY_RPCAll RPC pool endpoints unreachable. Very rare — 0G Foundation node is always a backstop.
Need help? Join discord.gg/opacus or read the Agent Kernel docs.