SDK reference
omnious-sdk: payments from a key or any signer, sessions, the agent tool loop, and spend caps.
omnious-sdk is the TypeScript client for API-driven use: everything the web frontend and CLI can do, from any Node or Bun process. Install it with bun add omnious-sdk (or npm), construct a client, and ask:
import { OmniousClient } from "omnious-sdk";
const omnious = new OmniousClient({
routerUrl: "https://your-router.example.com",
walletKey: process.env.OMNIOUS_WALLET_KEY as `0x${string}`, // omit on mock chains
spendCaps: { perQueryUsd: 0.05, perDayUsd: 5 },
});
const res = await omnious.ask("Why is truthful bidding dominant in an Omnious auction?", {
model: "qwen3-72b-instruct",
onDelta: (d) => process.stdout.write(d),
});Payments
Paid methods POST unpaid first; the SDK catches the 402, signs a gas-sponsored HyperEVM USDC authorization (EIP-3009 exact or Permit2 upto), and retries with the x402 v2 PAYMENT-SIGNATURE header. Metering bills only what streamed; overage refunds at epoch close. Three ways to hold the key: walletKey (a raw EVM key for server-side processes), signer (any { address, signTypedData } backend: a viem account, a KMS shim, a Privy server wallet), or nothing at all on mock-chain dev routers. Only typed-data signing is ever needed; no transaction is sent and no gas is spent by you.
Sessions, with auto-rotation
const session = omnious.session({ budgetUsd: 1, model: "qwen3-72b-instruct" });
await session.ask("Read this contract and summarize it: ...");
await session.ask("Now list the termination clauses"); // cached rate, no new 402
console.log(session.remaining); // budget left, base units
await session.close(); // unspent budget refunds at epoch closeTurns share one budget authorization and stick to the cache-holding incumbent at locked cached rates; history threads automatically. If a session id burns (router 409 session_used or 402 session_dead), the SDK rotates to a fresh session and retries the turn once. SessionBurnedError only escapes if the retry fails too.
The agent tool loop
const res = await omnious.ask("What's AAPL trading at, and 6.2% of that?", {
tools: true, // shared registry: local tools + data tools
web: false, // open-web tools are OPT-IN: untrusted text
executors: { // your own tools win by name over the registry
lookup_order: async (argsJson) =>
JSON.stringify(await db.orders.find(JSON.parse(argsJson).id)),
},
maxToolRounds: 3, // each round is its own paid RFQ; past the cap the SDK stops paying
});
res.toolCalls; // [{ name, arguments, output }]
res.requestIds; // one paid request per roundTool definitions and executors are the same registry the CLI uses. Results return as role:"tool" messages and each follow-up round is its own auction, so an agent loop is a sequence of cleared prices, not one opaque bill.
Spend caps
spendCaps takes perQueryUsd, perHourUsd, and perDayUsd. They bind on the 402's worst case before anything is signed: a query that would blow a window is refused with no payment made, throwing OmniousError with code spend_cap. The ledger is in-memory; persist it across processes with spendLedger() out and spendLedger in. The router additionally enforces maxPriceUsd per turn server-side, in-auction.
Images and every read surface
generateImage(prompt, opts) returns { b64, revisedPrompt } through the same 402 flow. Every read endpoint of the market has a typed method: receipts, request and session economics, the book, stats, candles, the composite index, points, provider reports, and best-execution through your x-api-key. Forward locks and patient orders are there too (createLock, placeOrder).
OmniousError with { status, code?, message }. Notable codes: spend_cap (client-side refusal, nothing signed) and provider_failed (you were not charged; retrying re-runs the auction).The wire logic imports from the router's own client modules, so the SDK and CLI share one source of truth, and the test suite drives every feature above against the real router on the mock chain.
- sdk/README.md the full method reference
- router/src/tools.ts the shared tool registry