{s}omniamarkets

@somnia-chain/markets-sdk


@somnia-chain/markets-sdk / index / SomniaMarkets

Class: SomniaMarkets

Defined in: unified/exchange.ts:137

The exchange — the SDK's single entry point. One instance per chain; wraps the native engine (watches, local books, one-round-trip writes) behind symbols, fetch*/watch* verbs, and human-unit structs — the idioms every exchange bot already speaks (ccxt users will feel at home, down to the field names).

Remarks

Verb conventions:

  • fetch* — one-shot (a chain or indexer round-trip).
  • watch* — streaming: each await resolves on the NEXT update of that channel, served from the zero-round-trip local store (the first call hydrates the ref-counted market watch).
  • create* / cancel* — writes (fixed fees, one-round-trip confirm).

Numbers are human units — right for strategy and display code; every struct carries the raw native payload under info for exact math. The native engine stays reachable at SomniaMarkets.client (bigint-exact reads) and SomniaMarkets.trader (raw writes) for everything the unified surface doesn't cover — it is not separately constructible.

Each instance is fully isolated — its own config, live store, and lazily opened WebSocket (an indexer-only exchange never opens one) — so one process can run several: a bot per chain, per-request servers, parallel tests. Call SomniaMarkets.close to release the watches when done.

Example

Load the market registry, stream a book, place a limit order.

import { SomniaMarkets } from "@somnia-chain/markets-sdk";

const exchange = new SomniaMarkets({
  chain,        // a viem Chain
  wsRpcUrl,     // wss:// RPC of that chain
  indexerUrl,   // the Envio/Hasura GraphQL endpoint
  addresses,    // contract addresses (e.g. from @somnia-chain/deployments)
  privateKey,   // optional — only createOrder & friends need a signer
});
await exchange.loadMarkets();

const book  = await exchange.watchOrderBook("BTC-95000-31DEC26/USDC#YES"); // live, zero RTT
const order = await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 10, 0.62);
await exchange.close();

Constructors

Constructor

new SomniaMarkets(config): SomniaMarkets

Defined in: unified/exchange.ts:201

Parameters

config

SomniaMarketsConfig

Returns

SomniaMarkets

Properties

client

readonly client: SomniaMarketsClient

Defined in: unified/exchange.ts:139

The native engine — bigint-exact, address-keyed. The escape hatch.


markets

markets: Record<string, UnifiedMarket> = {}

Defined in: unified/exchange.ts:141

Unified markets keyed by MARKET symbol (populated by loadMarkets).


symbols

symbols: string[] = []

Defined in: unified/exchange.ts:143

All market symbols (populated by loadMarkets).


has

readonly has: object

Defined in: unified/exchange.ts:149

Capability map — which unified verbs this venue supports (the ccxt exchange.has convention, for capability-probing bot code). Every listed verb is implemented here, so every flag is true.

fetchMarkets

readonly fetchMarkets: true = true

SomniaMarkets.fetchMarkets

fetchOrderBook

readonly fetchOrderBook: true = true

SomniaMarkets.fetchOrderBook

fetchTrades

readonly fetchTrades: true = true

SomniaMarkets.fetchTrades

fetchOHLCV

readonly fetchOHLCV: true = true

SomniaMarkets.fetchOHLCV

fetchBalance

readonly fetchBalance: true = true

SomniaMarkets.fetchBalance

fetchOpenOrders

readonly fetchOpenOrders: true = true

SomniaMarkets.fetchOpenOrders

fetchMyTrades

readonly fetchMyTrades: true = true

SomniaMarkets.fetchMyTrades

fetchStatus

readonly fetchStatus: true = true

SomniaMarkets.fetchStatus

createOrder

readonly createOrder: true = true

SomniaMarkets.createOrder

cancelOrder

readonly cancelOrder: true = true

SomniaMarkets.cancelOrder

watchOrderBook

readonly watchOrderBook: true = true

SomniaMarkets.watchOrderBook

watchTrades

readonly watchTrades: true = true

SomniaMarkets.watchTrades

watchOrders

readonly watchOrders: true = true

SomniaMarkets.watchOrders

watchMyTrades

readonly watchMyTrades: true = true

SomniaMarkets.watchMyTrades

fetchPositions

readonly fetchPositions: true = true

SomniaMarkets.fetchPositions

fetchFundingRate

readonly fetchFundingRate: true = true

SomniaMarkets.fetchFundingRate

watchPrice

readonly watchPrice: true = true

SomniaMarkets.watchPrice

fetchPrice

readonly fetchPrice: true = true

SomniaMarkets.fetchPrice

fetchPriceOHLCV

readonly fetchPriceOHLCV: true = true

SomniaMarkets.fetchPriceOHLCV

Accessors

trader

Get Signature

get trader(): Trader

Defined in: unified/exchange.ts:214

The raw write tier bound to this exchange's signer — bigint-exact placeOrder/mintSet/faucet/… for anything the unified verbs don't cover. Built lazily; throws if no signer was configured.

Returns

Trader


walletAddress

Get Signature

get walletAddress(): `0x${string}` | undefined

Defined in: unified/exchange.ts:220

The authenticated wallet address, if a signer was configured.

Returns

`0x${string}` | undefined

Methods

loadMarkets()

loadMarkets(reload?): Promise<Record<string, UnifiedMarket>>

Defined in: unified/exchange.ts:241

Load (or reload) the market registry: every market as a unified, symbol-keyed market object. Call once before anything symbol-based.

Parameters

reload?

boolean = false

Returns

Promise<Record<string, UnifiedMarket>>


market()

market(ref): Tradable

Defined in: unified/exchange.ts:360

Resolve any handle (symbol, tradable symbol, pool/market address, market id) to its tradable. Requires loadMarkets().

Parameters

ref

string

Returns

Tradable


priceToPrecision()

priceToPrecision(ref, price): number

Defined in: unified/exchange.ts:368

Snap a price to the market's tick grid (rounds down; binary prices are also clamped inside (0, 1)). Use before createOrder with computed prices.

Parameters

ref

string

price

number

Returns

number


amountToPrecision()

amountToPrecision(ref, amount): number

Defined in: unified/exchange.ts:380

Snap an amount to the market's lot grid (rounds down).

Parameters

ref

string

amount

number

Returns

number


fetchMarkets()

fetchMarkets(): Promise<UnifiedMarket[]>

Defined in: unified/exchange.ts:393

Every market as an array — loadMarkets (called if needed), minus the symbol keying. The ccxt-shaped sibling for list-style consumers.

Returns

Promise<UnifiedMarket[]>


fetchOrderBook()

fetchOrderBook(ref, limit?): Promise<UnifiedOrderBook>

Defined in: unified/exchange.ts:445

One-shot book read from the contract (head-fresh; no watch needed). For a continuously-current zero-round-trip book, use watchOrderBook.

Parameters

ref

string

limit?

number = 10

Returns

Promise<UnifiedOrderBook>


fetchTrades()

fetchTrades(ref, since?, limit?): Promise<UnifiedTrade[]>

Defined in: unified/exchange.ts:455

Recent public trades (indexer, newest first).

Parameters

ref

string

since?

number

limit?

number = 50

Returns

Promise<UnifiedTrade[]>


fetchOHLCV()

fetchOHLCV(ref, timeframe?, since?, limit?): Promise<UnifiedOHLCV[]>

Defined in: unified/exchange.ts:486

OHLCV candles (indexer), oldest first as [ms,o,h,l,c,vol] rows. Timeframes: 1m 5m 15m 1h 4h 1d.

Parameters

ref

string

timeframe?

string = "5m"

since?

number

limit?

number = 500

Returns

Promise<UnifiedOHLCV[]>

Example

The last 24 hourly candles, destructured per row.

const candles = await exchange.fetchOHLCV("SOMI/USDC", "1h", undefined, 24);
for (const [ts, open, high, low, close, volume] of candles) {
  console.log(new Date(ts).toISOString(), open, high, low, close, volume);
}

fetchBalance()

fetchBalance(): Promise<UnifiedBalances>

Defined in: unified/exchange.ts:517

Wallet balances for every currency the loaded markets use (+ native). free === total: funds escrowed in resting orders live in the pools, not the wallet, so they simply don't appear here.

Returns

Promise<UnifiedBalances>

Example

ERC-20s key by currency code; binary outcome holdings key by TRADABLE symbol.

const bal = await exchange.fetchBalance();
console.log(bal.USDC?.total);                              // collateral in the wallet
console.log(bal["BTC-95000-31DEC26/USDC#YES"]?.total);     // YES shares held

fetchOpenOrders()

fetchOpenOrders(ref?): Promise<UnifiedOrder[]>

Defined in: unified/exchange.ts:557

Open orders (indexer view — lags the chain slightly; a trading loop should prefer watchOrders).

Parameters

ref?

string

Returns

Promise<UnifiedOrder[]>


fetchMyTrades()

fetchMyTrades(ref?, since?, limit?): Promise<UnifiedTrade[]>

Defined in: unified/exchange.ts:628

My historical trades (indexer portfolios).

Parameters

ref?

string

since?

number

limit?

number = 50

Returns

Promise<UnifiedTrade[]>


fetchStatus()

fetchStatus(): Promise<{ status: "error" | "ok" | "connecting"; updated: number; info: TailStatus; }>

Defined in: unified/exchange.ts:678

Exchange health: "ok" unless a live watch is missing its socket — "connecting" while the first WS handshake is still in flight (~1s after a watch opens), "error" once a previously-live socket is lost.

Returns

Promise<{ status: "error" | "ok" | "connecting"; updated: number; info: TailStatus; }>


watchOrderBook()

watchOrderBook(ref, limit?): Promise<UnifiedOrderBook>

Defined in: unified/exchange.ts:789

Streaming book off the local store: zero round-trips, current to the last block; each await resolves on the next book change.

Parameters

ref

string

limit?

number = 10

Returns

Promise<UnifiedOrderBook>

Example

A quoting loop: wake on every book change, read the touch.

while (true) {
  const book = await exchange.watchOrderBook("SOMI/USDC", 5);
  const [bestBid] = book.bids[0] ?? [];
  const [bestAsk] = book.asks[0] ?? [];
  console.log(`bid ${bestBid} / ask ${bestAsk}`);
}

watchTrades()

watchTrades(ref, limit?): Promise<UnifiedTrade[]>

Defined in: unified/exchange.ts:814

Streaming public trades (the live tape), newest first.

Parameters

ref

string

limit?

number = 50

Returns

Promise<UnifiedTrade[]>

Example

Print each fill as it lands ([0] is always the latest).

while (true) {
  const [latest] = await exchange.watchTrades("SOMI/USDC", 1);
  if (latest) console.log(`${latest.side ?? "?"} ${latest.amount} @ ${latest.price}`);
}

watchOrders()

watchOrders(ref, limit?): Promise<UnifiedOrder[]>

Defined in: unified/exchange.ts:846

Streaming view of MY orders on this tradable (authenticated). This is how you learn a resting order filled: its status flips to "closed".

Parameters

ref

string

limit?

number = 100

Returns

Promise<UnifiedOrder[]>

Example

Place a limit order, then block until it fully fills (or dies).

const placed = await exchange.createOrder(symbol, "limit", "buy", 10, 0.62);
while (placed.status === "open") {
  const orders = await exchange.watchOrders(symbol); // resolves on the next change
  const mine = orders.find((o) => o.id === placed.id);
  if (!mine || mine.status !== "open") break; // filled, canceled, or expired
}

watchMyTrades()

watchMyTrades(ref, limit?): Promise<UnifiedTrade[]>

Defined in: unified/exchange.ts:883

Streaming view of MY fills on this tradable (authenticated).

Parameters

ref

string

limit?

number = 50

Returns

Promise<UnifiedTrade[]>


watchPrice()

watchPrice(asset): Promise<UnifiedPrice>

Defined in: unified/exchange.ts:928

Streaming price off the local price store: zero round-trips, current to the last pushed tick; each await resolves on the next price change. First call hydrates the ref-counted feed watch. Requires config.priceFeed to be set.

Parameters

asset

string

Returns

Promise<UnifiedPrice>


fetchPrice()

fetchPrice(asset): Promise<UnifiedPrice | null>

Defined in: unified/exchange.ts:942

One-shot current price (indexer HTTP read; no watch needed), or null if the feed has no observations yet.

Parameters

asset

string

Returns

Promise<UnifiedPrice | null>


fetchPriceOHLCV()

fetchPriceOHLCV(asset, timeframe?, since?, limit?): Promise<UnifiedOHLCV[]>

Defined in: unified/exchange.ts:952

OHLC price candles (EMA oracle), oldest first as [ms,o,h,l,c,vol] rows — vol is the oracle update count for the bucket (NOT trade volume). Timeframes: 1m 1h 1d (aliases for the feed's M1/H1/D1).

Parameters

asset

string

timeframe?

string = "1m"

since?

number

limit?

number = 500

Returns

Promise<UnifiedOHLCV[]>


createOrder()

createOrder(ref, type, side, amount, price?, params?): Promise<UnifiedOrder>

Defined in: unified/exchange.ts:984

Place an order. Works identically for every market kind: the tradable symbol carries the outcome, side is plain buy/sell, prices and amounts are human units in the tradable's own terms (a NO price is the NO probability — the YES-terms complement is handled internally).

type: "market" computes a crossing limit from the best opposite level ± params.slippage (default 1%) and sends it IOC. Resolves once mined, with fills decoded from the same round-trip.

Parameters

ref

string

type

"market" | "limit"

side

"buy" | "sell"

amount

number

price?

number

params?

CreateOrderParams = {}

Returns

Promise<UnifiedOrder>

Example

Rest a bid at 62% on YES, then take the NO book at market.

const rested = await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 25, 0.62);
console.log(rested.status, rested.filled); // "open" 0 — or "closed" if it crossed

const taken = await exchange.createOrder("BTC-95000-31DEC26/USDC#NO", "market", "sell", 10, undefined, {
  slippage: 0.02, // accept up to 2% past the best bid
});

cancelOrder()

cancelOrder(id, ref): Promise<{ id: string; symbol: string; status: "canceled"; info: unknown; }>

Defined in: unified/exchange.ts:1100

Cancel a resting order by id (from createOrder / watchOrders).

Parameters

id

string

ref

string

Returns

Promise<{ id: string; symbol: string; status: "canceled"; info: unknown; }>

Example

const placed = await exchange.createOrder("SOMI/USDC", "limit", "buy", 10, 0.55);
if (placed.status === "open") await exchange.cancelOrder(placed.id, "SOMI/USDC");

fetchFundingRate()

fetchFundingRate(ref): Promise<UnifiedFundingRate>

Defined in: unified/exchange.ts:1118

Live funding-rate + mark/index snapshot for a perp market (chain read).

Parameters

ref

string

Returns

Promise<UnifiedFundingRate>


fetchPositions()

fetchPositions(refs?): Promise<UnifiedPosition[]>

Defined in: unified/exchange.ts:1140

Open perp positions (authenticated; on-chain MarginBank reads). Pass symbols to scope; defaults to every loaded perp market.

Parameters

refs?

string[]

Returns

Promise<UnifiedPosition[]>


depositMargin()

depositMargin(ref, amount): Promise<{ hash: string; info: unknown; }>

Defined in: unified/exchange.ts:1187

Deposit collateral into the perp MarginBank (human quote units, e.g. USDso). One cross-margin balance covers every perp market.

Parameters

ref

string

amount

number

Returns

Promise<{ hash: string; info: unknown; }>


withdrawMargin()

withdrawMargin(ref, amount): Promise<{ hash: string; info: unknown; }>

Defined in: unified/exchange.ts:1203

Withdraw free collateral from the perp MarginBank (human quote units).

Parameters

ref

string

amount

number

Returns

Promise<{ hash: string; info: unknown; }>


mintSet()

mintSet(ref, amount): Promise<{ hash: string; info: unknown; }>

Defined in: unified/exchange.ts:1238

Mint complete sets: amount collateral → amount of EVERY outcome.

Parameters

ref

string

amount

number

Returns

Promise<{ hash: string; info: unknown; }>

Example

Mint 100 sets (100 USDC → 100 YES + 100 NO), then sell the side you don't want.

await exchange.mintSet("BTC-95000-31DEC26/USDC", 100);
await exchange.createOrder("BTC-95000-31DEC26/USDC#NO", "limit", "sell", 100, 0.38);

burnSet()

burnSet(ref, amount): Promise<{ hash: string; info: unknown; }>

Defined in: unified/exchange.ts:1250

Burn complete sets back to collateral.

Parameters

ref

string

amount

number

Returns

Promise<{ hash: string; info: unknown; }>


redeem()

redeem(ref, amount): Promise<{ hash: string; info: unknown; }>

Defined in: unified/exchange.ts:1274

Redeem winning outcome tokens for collateral (post-resolution). Settlement- extraction v2: module-routed by marketId (the winning outcome is read off the BinaryMarket contract when not resolved yet in the indexed row).

Parameters

ref

string

amount

number

Returns

Promise<{ hash: string; info: unknown; }>

Example

After resolution, redeem the winning side found in the balance map.

const bal = await exchange.fetchBalance();
const winning = bal["BTC-95000-31DEC26/USDC#YES"]?.total ?? 0;
if (winning > 0) await exchange.redeem("BTC-95000-31DEC26/USDC", winning);

close()

close(): Promise<void>

Defined in: unified/exchange.ts:1306

Release every watch + channel this exchange holds and stop the client's live machinery. The instance stays usable for one-shot fetch calls.

Returns

Promise<void>