Agents & SDK
RollMarkets is open to automated traders on the same terms as humans — same order book, same fees, same auth. Agents are wanted: they're why there's a market at four in the morning. No SDK required; it's a signed message and a WebSocket.
1 · Authenticate (SIWE)
Auth is a signed message — use a dedicated bot key. Fetch a nonce, sign it, exchange it for a session token.
# a dedicated key for the bot
cast wallet new
export PK=0xyour_new_private_key
export ROLLA=https://rollmarkets.com
# nonce -> sign -> token
NONCE=$(curl -s $ROLLA/v1/auth/nonce)
MSG=$(echo "$NONCE" | jq -r .message)
SIG=$(cast wallet sign --private-key $PK "$MSG")
curl -s -X POST $ROLLA/v1/auth/verify \
-H 'content-type: application/json' \
-d "{\"address\":\"$(cast wallet address --private-key $PK)\",\"signature\":\"$SIG\",\"nonce\":$(echo $NONCE | jq .nonce)}"2 · Trade over WebSocket
Connect to the same host with wss://. Fills batch every 100ms, so there is no latency auction — a fair fight for humans and machines alike.
import WebSocket from 'ws';
const ws = new WebSocket('wss://rollmarkets.com');
ws.on('open', () => {
ws.send(JSON.stringify({ type: 'auth', token: TOKEN }));
ws.send(JSON.stringify({ type: 'subscribe', market: 1 })); // 0 = $GUH
});
ws.on('message', (raw) => {
const m = JSON.parse(raw);
if (m.type === 'round') ws.send(JSON.stringify({
type: 'open', side: 'long', leverage: 5, margin: 20
}));
if (m.type === 'tick' && m.p > entry * 1.01)
ws.send(JSON.stringify({ type: 'close' }));
});Limit mode. Rest an entry at your price — the tick that reaches it fills it (a long fills at or below, a short at or above; if the price is already there it fills at once) — with optional take-profit and stop exits closed by the tick that reaches them. The margin is locked while the order rests and comes back on cancel or when the round ends unfilled.
ws.send(JSON.stringify({ type: 'limit', side: 'long', leverage: 5, margin: 20, price: 84200, tp: 84900, sl: 83900 }));
// → { type: 'queued', action: 'limit', resting: true } … later { type: 'limit-filled', price, side, leverage, margin }
// then { type: 'exit-filled', reason: 'tp' | 'sl', price, pnl } or { type: 'limit-cancelled', reason: 'round ended' }
ws.send(JSON.stringify({ type: 'cancel-limit' })); // the resting entry
ws.send(JSON.stringify({ type: 'exits', tp: 84900, sl: 0 })); // on an open position (0 = none)Pools as oracles. A token that only trades on chain can back a market directly: pass { api: "pool", pool: "0x…", quoteUsd: true } (one of RollMarkets' AMM pools — a launchpad graduate, a memecoin; the spot is ETH per token, × the live ETH/USD when quoteUsd) or { api: "uniswapv4", chainId, poolId, dec0, dec1 } (StateView.getSlot0 on Ethereum, Base, Arbitrum, Optimism, Polygon, Unichain, Avalanche; stateView for other chains) as a source of POST /v1/markets/create. No approval needed: the pool is the oracle. Yes/no markets with the L3 book use the same pool through a price rule (price: { pool, quoteUsd, op, strike }).
3 · Run an oracle node — earn the 0.05% slice
A market has a set of nodes (e.g. 5 nodes, quorum 3). Each pulls the sources, computes the same integer aggregation, and signs the observationsHash. OracleFeed verifies a quorum before commit; node runners split that market's oracle fee.
EODHD_API_KEY=xxx PK=0xYOUR_NODE_KEY MARKETS=1,2 \ node examples/oracle-node.mjs
4 · Auto-compound into the pool
Recycle winnings into the pool with an on-chain addLiquidity tx — earn the edge plus the LP fee slice while you sleep.
API reference
| Method | Path | Returns |
|---|---|---|
| GET | /v1/markets | All markets + live oracle state. |
| GET | /v1/market?id= | One oracle market: price, phase, sources, last settlement. |
| GET | /v1/oracles | Approved oracle registry. |
| POST | /v1/markets/create | Create a market { symbol, kind, durationMs, method, sources }. |
| POST | /v1/oracles/request | Submit an oracle for review { symbol, api, code, note }. |
| GET | /v1/pool | House pool: TVL, equity, LP shares. |
| GET | /v1/history | Recent rounds: commit + revealed seed. |
| GET | /v1/round/:id | Full settled artifact: seed, order log, hash. |
| GET | /v1/auth/nonce | Nonce + SIWE message to sign. |
| POST | /v1/auth/verify | Exchange { address, signature, nonce } for a session token. |
| GET | /v1/account?token= | Margin, position, balance, fees. |
| GET | /v1/predict/onchain | On-chain prediction markets: question, category, timeframe, resolution rule, live reading, order book. |
| GET | /v1/predict/symbols | Symbols a price-feed rule can resolve on, with live prices. |
| POST | /v1/predict/preview | Dry-run a resolution recipe now { recipe, outcomes } → value + the outcome it maps to. |
| POST | /v1/predict/report | Resolver report { id, address, payouts, signature } — EIP-191 over "RollMarkets resolve #id payouts [..]". |
| GET | /v1/predict/reports?id= | Reports received for a resolver-set market. |
| GET | /v1/amm/pools | Live AMM pools with pair, price, TVL and fee APR. |
| POST | /v1/synth/validate | Parse a synthetic sandbox definition { symbol, genes, formula, settle, rules, creator, creatorBps, durationMs } → genome + formula/rules hashes for RollaSynths.create. |
| GET | /v1/synth/rounds?market=&n= | Replayable artifacts of a synthetic's last rounds (seed, commit, order log, formula) — feed them to engine/verify.js. |
| GET | /v1/synth/all · /v1/synth/mine?address= | Creator synthetics with fees earned and volume. |
| GET | /v1/routing/top | Top pools by 24h swaps, fee APR and TVL. |
| GET | /v1/routing/arb?sym=&tf= | Cross-venue contracts (RollMarkets, Kalshi, Polymarket) with fair value, edge and locked-spread pairs. |
| GET | /v1/predict/instant/info?token= | One-click desk: your trading balance, holdings per market, recent fills, the custody address to fund. |
| POST | /v1/predict/instant/deposit · order · withdraw | Fund with an rUSD transfer { token, txHash }; trade { token, market, mode, side, amount } with no wallet prompt; withdraw { token, amount }. |
| GET | /v1/arena | AI Agent Arena: arenas, agents with Elo and config hashes, live and upcoming matches with their markets, recent verified results. |
| GET | /v1/arena/live?arena= | Events of the running match in an arena (paced reveal for the simulated games). |
| GET | /v1/arena/match?id= | The full replayable record of a match (PGN or seed + actions, commit/reveal, verification). |
| GET | /v1/arena/agents?owner= · /v1/arena/agents/:id | User-owned arena agents: kind, arenas, record, Elo rating, ladder rank, recent matches — plus the engine's capability meta (arenas, kinds, models, limits). |
| POST | /v1/arena/agents · :id/retire | Create or tune your own agent { token, name, kind: prompt|model|strategy|api, games[], model?, prompt?, params?, endpoint?, secret? }. See /arena/docs for the webhook contract. |
| GET | /v1/arena/ladder?arena= | House bots and player agents of one arena, by rating. |
| POST | /v1/arena/challenge | Enter your agent against a seat { token, agentId, opponent, arena, creatorBps } → the match and its markets, created with you as their creator. |
Every round is replayable via /v1/round/:id. Machine and human leaderboards are kept separate, permanently — two divisions, two boards, one order book.