@somnia-chain/markets-sdk / index / SomniaMarketsClient
Interface: SomniaMarketsClient
Defined in: packages/sdk/src/somniaMarketsClient.ts:410
An SDK client — the single handle for all protocol I/O.
This is the raw engine tier, reached through the exchange (new SomniaMarkets(config) → exchange.client). Each exchange's engine is fully
isolated: its own config, live store, and (lazily opened) chain WebSocket,
so several can coexist in one process without sharing state.
The read surface has three tiers — pick by freshness need:
- Live store (
getLive*, synchronous): zero round-trips, updates the moment an event lands on-chain. Requires a watch (watchMarket / watchMarkets) covering the market you read. - Chain (
getBinaryOrderBook,getMarketOnchain, …): oneeth_callround-trip, current to head. Works without any watch. - Indexer (
listMarkets,getPortfolio, …): history and aggregates; lags the chain slightly. Works without any watch or the socket.
Extended by
Properties
config
readonlyconfig:ClientConfig
Defined in: packages/sdk/src/somniaMarketsClient.ts:412
The config this client was built with.
lend
readonlylend:SomniaLendClient
Defined in: packages/sdk/src/somniaMarketsClient.ts:458
The SomniaLend namespace — reads (lend.listReserves(), lend.getAccount())
and the lend.createLender() write factory for the third-party Aave v3
money market on Somnia (mainnet + testnet). Lazily bound to
config.addresses.lend (set SOMNIA_MAINNET_LEND / SOMNIA_TESTNET_LEND
from the root entry); its
methods throw a clear error when those addresses are unset. The root entry
also publishes its types, deployment
constants, ray-math helpers and ABIs; this namespace is the only way to call
it, so a lend read always rides the client's own chain transport.
accounts
readonlyaccounts:SmartAccountsClient
Defined in: packages/sdk/src/somniaMarketsClient.ts:468
The smart-accounts capability — the factory account model of
@somnia-chain/accounts-sdk on this client's chain: derive and discover
accounts, walk ownership, build creation / owner-management / transfer
calls for an executor to send, and read holdings and health. Built
lazily; reads ride this client's own chain transport. See
SmartAccountsClient, and createExecutor({ smartAccount, inner })
for sending AS an account.
Methods
getViemClient()
getViemClient():
object
Defined in: packages/sdk/src/somniaMarketsClient.ts:445
This client's underlying viem client, undecorated — viem's own behaviour, over the socket this client already has.
When to use
Use to reach a contract or RPC method the SDK does not model: your own
contracts, or plain calls like getBalance / getCode /
waitForTransactionReceipt. Reads through it keep VIEM's error contract, so
e instanceof ContractFunctionRevertedError and the rest of your existing
viem error handling still work.
Building your own client instead would open a second WebSocket; this one shares the SDK's.
Details
- Returns: The undecorated viem
PublicClientfor this client's chain.
Gotchas
Reads through this client do NOT get the SDK's decoded protocol errors — a
revert arrives as viem's error, not a ContractRevertError with an
errorName. That is the point of the accessor, but it means you should
prefer the SDK's own methods for protocol contracts, where the decoding is
the value. The two clients are deliberately different: everything reachable
from this interface uses the decoded one.
Calling this opens the WebSocket if it is not already open, and throws
NotConfiguredError on a client built without wsRpcUrl.
Returns
object
watchMarket()
watchMarket(
pool,opts?):Promise<WatchHandle>
Defined in: packages/sdk/src/somniaMarketsClient.ts:537
Watch one market: hydrate a consistent snapshot of it (market row, recent
fills, its full resting order book) and stream its events — order-book
activity plus, for a binary market, its lifecycle/status events. While the
watch is active, every getLive* read for this pool is current to the
last block at zero round-trip cost.
Watches are ref-counted: watching the same pool twice shares one
subscription and one snapshot; each handle's stop() releases one
reference, and the scope is torn down (subscription dropped, heavy rows
purged) shortly after the last release — a brief linger absorbs quick
re-watches (navigation, React remounts) without re-snapshotting.
Resolves once the seam is sealed (snapshot + backfill + buffered replay) — i.e. once reads are live. Rejects (and releases the reference) if hydration fails; the socket dropping later is healed automatically by reconnect + chain backfill.
The React data hooks call this automatically while mounted.
Details
opts opts INTO a chain seed. Omit it and the watch seeds from the indexer
snapshot exactly as before, and getLiveStatus().snapshotBlock keeps its
existing meaning. Pass { seed: "chain", marketId } and the book is drained
from the pool contract at one pinned block instead, so the watch starts with
the indexer unreachable. Supply the marketId the pool currently serves:
pools are recycled across markets and book reads filter on it.
A chain seed also reads the market's row from the BinaryMarketsModule, so
config.addresses.binaryModule must be set — the row is what every later
order and fill event attributes through. It carries what the module answers
(collateral, decimals, nonce, lifecycle state); indexer-only fields such as
the question text, strike/mode and the creation history stay empty or
null and STAY that way — a seeded pool is never re-hydrated, and the row
outlives stop(), so the seeded row persists for the store's lifetime. Read
the indexer directly (getBinaryMarket) when those fields are needed.
A chain seed covers exactly ONE pool.
A chain seed has no per-scope order cap, unlike the indexer snapshot, whose
budget is shared across the scope's pools and drops the OLDEST resting
orders first. It reads getLiveStatus().seedTruncated as true only if the
drain hit its own page budget.
Gotchas
A chain seed loads NO fill history — the chain cannot answer fills from
before the seam. The tape loads on a detached lane, so getLiveFills may be
empty while the book is complete. Branch on getLiveStatus().fillsLoaded,
not on the tape being empty: false means never loaded, true with []
means genuinely no fills. A failed tape read sets failure.operation to
"fill-history" and does not reject this promise.
Seeded orders carry an empty createdAt/txHash: placement history is
indexer-only and the seed does not invent it. userOrders sorts on
createdAt, so they sort last until a snapshot dates them.
Parameters
pool
string
opts?
Returns
Promise<WatchHandle>
Throws
IndexerError If the indexer snapshot fails (default seed only).
Throws
NotConfiguredError If a chain seed is requested with no addresses.binaryModule.
Throws
InvalidInputError If opts.maxCount/opts.maxPages is not a positive safe integer, or opts.marketId is not a bytes32 id.
Throws
ContractRevertError If a chain-seed page read reverts.
Throws
RpcError If a chain read or the subscription fails at the transport.
watchMarkets()
watchMarkets(
opts?):Promise<WatchHandle>
Defined in: packages/sdk/src/somniaMarketsClient.ts:549
Watch every market the indexer currently knows — the whole-protocol tail for list views and multi-market bots. Prefer watchMarket scoped to what you actually trade or render: this variant's cost grows with the protocol (snapshot size, subscription filter width, event volume).
Details
opts.discover: Also watch the MarketCreator factory so markets created AFTER this call join the watch live, in their creation block (requiresconfig.addresses.marketCreator). Off by default.
Parameters
opts?
discover?
boolean
Returns
Promise<WatchHandle>
watchUser()
watchUser(
user):Promise<WatchHandle>
Defined in: packages/sdk/src/somniaMarketsClient.ts:560
Hydrate one account's order/fill history (one indexer fetch) so getLiveUserFills / getLiveUserOrders have depth predating your watches. This does not subscribe to anything by itself: live events are attributed to every account automatically, but only within markets covered by an active watchMarket / watchMarkets — an account's activity in unwatched markets stays at snapshot state. Ref-counted like market watches; supports multiple accounts at once.
Parameters
user
string
Returns
Promise<WatchHandle>
watchPerpMarkets()
watchPerpMarkets(
opts?):Promise<WatchHandle>
Defined in: packages/sdk/src/somniaMarketsClient.ts:596
Watch the perp plane: hydrate the recent liquidation waterfall legs and per-account funding settlements, then stream both live — the same snapshot-then-live guarantee watchMarket gives a book.
ONE scope covers every perp market, and that is forced rather than chosen.
MarginBank and LiquidationEngine are singletons, so the log subscription is one
stream whatever the caller asks for — and the account-level waterfall legs
(AccountLiquidated, ResidualBadDebt, ...) carry no pool at all, so a per-pool
scope would either drop them or attach them to every pool. Filter at read time
with listLiveLiquidations / listLiveFundingPayments instead.
Independent of watchMarket: watching a perp pool gives you its book, funding RATE and open interest; this gives you liquidations and funding SETTLEMENT. Neither implies the other, and a UI showing both wants both watches.
Ref-counted and lingered like the other watches. Resolves once the seam is sealed; a later socket drop is healed by reconnect and chain backfill, with no second indexer touch.
Details
opts.marginBank: The MarginBank to read the plane's wiring from. Normally UNNECESSARY — the address is taken from an indexed perp market row, andMarginBank.getSystemConfig()reports the LiquidationEngine from there. Pass it for the one case that cannot cover: an indexer with no perp rows at all, where there is nothing to ask. It is a FALLBACK, never an override: it is used when the indexer names no bank, including on a scope a read hook acquired moments earlier with no hint to give, and it is ignored when the indexer named one — the hydrated rows are that bank's plane, so streaming another one would splice two venues into one feed.
Parameters
opts?
Returns
Promise<WatchHandle>
Throws
InvalidInputError when opts.marginBank is not an address.
Throws
IndexerError when the plane snapshot fails.
Throws
RpcError when the MarginBank wiring read or the seam's head read fails — the liquidation half cannot be watched without the wiring, and watching the bank alone would stream funding settlements and no liquidations, which reads as a venue with none.
Throws
ContractRevertError when the resolved MarginBank — indexed, or supplied via
opts.marginBank — reverts on getSystemConfig(), i.e. it is not a MarginBank the
SDK can read.
Throws
NotConfiguredError on a client built without wsRpcUrl or indexerUrl.
getWatchStatus()
getWatchStatus(
pool):WatchStatus
Defined in: packages/sdk/src/somniaMarketsClient.ts:604
Per-market watch state: "unwatched" (no active watch — getLive* reads
return empty for this pool, which is how you distinguish "empty book"
from "not watching"), "hydrating" (watch registered; snapshot, seam
backfill, or reconnect in progress), or "live".
Parameters
pool
string
Returns
getPerpPlaneStatus()
getPerpPlaneStatus():
WatchStatus
Defined in: packages/sdk/src/somniaMarketsClient.ts:610
Perp-plane watch state, in the same three values getWatchStatus uses —
so "unwatched" distinguishes "no liquidations happened" from "not watching".
Returns
stopLive()
stopLive():
void
Defined in: packages/sdk/src/somniaMarketsClient.ts:624
Tear down every watch, subscription, timer, and socket this client opened
(tests, shutdown), including the chain WebSocket — so a Node process that
has touched the chain exits on its own afterwards. The store keeps its
last state; getLive* and listLive* reads keep answering (stale), and a later chain
read reopens a connection that the next stopLive() releases in turn.
Ordinary pending indexer reads remain active. Existing observed-read capabilities
are invalidated; create a new one before observing again.
Clients configured with the same wsRpcUrl share one chain socket, which
closes when the last of them stops.
Returns
void
subscribeLive()
subscribeLive(
listener): () =>void
Defined in: packages/sdk/src/somniaMarketsClient.ts:636
Fire listener after every batch of store changes — the "something
changed, re-read" signal (the React hooks subscribe to exactly this).
Re-read with any getLive* method; their results are memoized per store
version, so re-reading without a change returns the same reference.
Details
- Returns: An unsubscribe function.
Parameters
listener
() => void
Returns
() => void
getLiveStatus()
getLiveStatus():
TailStatus
Defined in: packages/sdk/src/somniaMarketsClient.ts:644
The tail's global health: mode ("init" until the first watch hydrates,
then "tailing"), the last seam block, the last locally-materialized
block, the chain head, socket state, and the active watch count. For one
market's state, use getWatchStatus.
Returns
isTailing()
isTailing():
boolean
Defined in: packages/sdk/src/somniaMarketsClient.ts:647
True once at least one watch is live (mode === "tailing").
Returns
boolean
getLiveMarkets()
getLiveMarkets():
Market[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:655
Every market the store knows (spot + binary, as the discriminated Market union) — markets hydrated by any watch, past or present (market rows are kept as metadata after a watch is released). Synchronous, memoized.
Returns
Market[]
getLiveMarketByPool()
getLiveMarketByPool(
pool):Market|null
Defined in: packages/sdk/src/somniaMarketsClient.ts:658
One market by its pool address (either kind), or null if unknown.
Parameters
pool
string
Returns
Market | null
getLiveMarketByAddress()
getLiveMarketByAddress(
marketAddress):BinaryMarket|null
Defined in: packages/sdk/src/somniaMarketsClient.ts:664
One binary market by its BinaryMarket contract address, or null. (Spot markets have no market contract — they are identified by pool.)
Parameters
marketAddress
string
Returns
BinaryMarket | null
getLiveFills()
getLiveFills(
pool,opts?):LiveFill[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:674
The most recent fills on one pool, newest first — the live trade tape. Maker/taker owner + side are back-joined from the order map where known.
Details
opts.limit: Max rows (default 40; the store retains ~400 per pool).
Parameters
pool
string
opts?
limit?
number
Returns
LiveFill[]
getLiveFundingUpdates()
getLiveFundingUpdates(
pool,opts?):LiveFundingUpdate[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:692
Funding settlements the live tail has seen for a perp pool, OLDEST FIRST.
The tail's counterpart to listFundingRateHistory: splice these onto a one-shot query to extend a funding chart past the snapshot block, instead of only seeing the latest value on the market row. Deduped on (block, logIndex), so a reorg replay overwrites rather than appending a phantom point.
Carries less than an indexed row, deliberately: intervalsAccrued needs n from the
parameter-epoch series and the covered span needs the settlement anchor, neither of
which the tail has. Both arrive with the indexed row a moment later.
Details
opts.limit: Max rows (default 500).
Parameters
pool
string
opts?
limit?
number
Returns
listLiveLiquidations()
listLiveLiquidations(
opts?):LiquidationEvent[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:717
Liquidation waterfall legs the tail has seen, newest first — the live counterpart
to getLiquidations, and the SAME LiquidationEvent rows, so the two
merge without translation. The live window is hydrated from the newest indexed rows,
so it OVERLAPS the newest indexed page: merge by id, never by concatenation, or
legs and their amounts are counted twice.
Requires an active watchPerpMarkets. Without one this returns empty, except after stopLive, which keeps the store: the last rows stay readable but stale. Check getPerpPlaneStatus rather than treating a non-empty result as current.
One liquidation is SEVERAL rows sharing a txHash — stages of one waterfall, not
repetitions of one event. Read kind first, and read the field TSDoc on
LiquidationEvent before aggregating anything: only insuranceCovered and
coverageDeclined are flows, while badDebt and deficit are levels that
double-count when summed.
Details
opts.pool: Restrict to one pool. This DROPS the account-level legs, which carry no pool — the same partial view the indexed read's nullablepoolcolumn gives. Filter byaccountfor the whole story.opts.account: Restrict to the LIQUIDATED account. An account assigned into an ADL as the profitable counterparty has no row of its own; it appears incounterpartyinstead.opts.limit: Max rows (default 50; the store retains ~1000 plane rows).
Parameters
opts?
Returns
listLiveFundingPayments()
listLiveFundingPayments(
opts?):FundingPayment[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:735
Per-account funding settlements the tail has seen, newest first — the live counterpart to getFundingPayments, and the same FundingPayment rows.
Requires an active watchPerpMarkets. After stopLive the last rows stay
readable but stale; check getPerpPlaneStatus. Distinct from
getLiveFundingUpdates, which is the per-pool RATE series: this is what each
account actually paid or received. amount is signed, and positive is what the
account pays.
Details
opts.pool: Restrict to one pool.opts.account: Restrict to one account.opts.limit: Max rows (default 50; the store retains ~1000 plane rows).
Parameters
opts?
ListLiveFundingPaymentsOptions
Returns
getLiveUserFills()
getLiveUserFills(
pool,user,opts?):LiveFill[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:745
Fills user participated in (as maker or taker), newest first.
Details
pool: Restrict to one pool, or null for all pools.opts.limit: Max rows (default 50).
Parameters
pool
string | null
user
string
opts?
limit?
number
Returns
LiveFill[]
getLiveUserOrders()
getLiveUserOrders(
pool,user,opts?):LiveOrder[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:757
user's orders on one pool, newest first — every lifecycle state (open,
filled, cancelled, expired), so filter by status === "Open" for a
working-orders view. Includes history hydrated by watchUser plus
everything witnessed live on watched markets.
Details
opts.limit: Max rows (default 100).
Parameters
pool
string
user
string
opts?
limit?
number
Returns
getLiveBinaryOrderBook()
getLiveBinaryOrderBook(
pool,opts?):BinaryOrderBook
Defined in: packages/sdk/src/somniaMarketsClient.ts:771
The locally-materialized resting book of a binary pool, 4-sided
(yesBids/yesAsks plus the NO sides derived as 1 − yesPrice) — the
event-derived book with a per-scope applied-event watermark.
Heads alone do not advance blockNumber. Expiry uses the local wall clock.
Use the pinned chain read for an exact as-of snapshot.
Synchronous; safe to call every render (memoized per store version).
Details
opts.depth: Price levels per side (default 10).
Parameters
pool
string
opts?
depth?
number
Returns
getLiveBinaryOrderBookByMarket()
getLiveBinaryOrderBookByMarket(
marketId,opts?):BinaryOrderBook
Defined in: packages/sdk/src/somniaMarketsClient.ts:788
The locally-materialized resting book of a binary market, resolved by
its marketId rather than its pool address. Because a BinaryPool is
RECYCLED across markets (one pool serves successive markets, never
concurrently), a page keyed on a marketId must never render the pool's
NEXT market's orders once its own market has ended. This read resolves the
market's current pool and, if marketId is no longer the pool's current
binding (stale/ended), returns an EMPTY book — so a stale page renders
nothing rather than the successor market's liquidity. Prefer this over
getLiveBinaryOrderBook when you hold a marketId (not a live pool).
Details
opts.depth: Price levels per side (default 10).
Parameters
marketId
string
opts?
depth?
number
Returns
getLiveSpotOrderBook()
getLiveSpotOrderBook(
pool,opts?):SpotOrderBook
Defined in: packages/sdk/src/somniaMarketsClient.ts:798
The locally-materialized resting book of a spot pool (bids/asks,
best price first) — the zero-round-trip mirror of getSpotOrderBook.
Details
opts.depth: Price levels per side (default 12).
Parameters
pool
string
opts?
depth?
number
Returns
quoteBinaryOrder()
quoteBinaryOrder(
params):BinaryOrderQuote
Defined in: packages/sdk/src/somniaMarketsClient.ts:820
Preview a MARKET order against the live binary book — "you'll pay ~$X,
average Y, slippage Z". Pure over the live store (synchronous); key it by
pool (a live pool) or marketId (recycle-safe — a stale market quotes
against an empty book). Crossing side: BUY_YES/BUY_NO consume the asks,
SELL_YES/SELL_NO the bids; NO prices are the YES book inverted
(oneCollateral − yesPrice). cost is raw collateral paid (buy) / received
(sell); avgPrice the volume-weighted fill price; wouldRest the unfilled
remainder that would rest as a maker order.
Details
params.quantity: Order size in raw outcome-token units.params.depth: Book levels to walk per side (default 10).
Parameters
params
pool?
string
marketId?
string
side
quantity
bigint
depth?
number
Returns
getBinaryBookParams()
getBinaryBookParams(
pool):Promise<BinaryBookParams>
Defined in: packages/sdk/src/somniaMarketsClient.ts:835
A BinaryPool's on-chain order-book grid (tickSize/lotSize/minQuantity)
— the increments the pool validates every order against. One eth_call,
cached per pool for the client's lifetime (the grid is admin-retunable but
never changes per-order). quoteBinaryStake and
quoteBinarySell read it through this cache.
Parameters
pool
string
Returns
Promise<BinaryBookParams>
getClosingPrice()
getClosingPrice(
pool):Promise<ClosingPriceState|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:854
A BinaryPool's captured closing price and close state — the snapshot a
CLOB_SNAPSHOT venue's void pays out against ([p, D−p] at the closing
YES price instead of the uniform half-refund). One eth_call.
Resolves null when the pool predates the capture surface: the selector
doubles as the capability probe, mirroring how the module resolves a
market's void policy at creation. state is "OPEN" until
Trader.captureClose (or a normal resolution) has run.
null is that capability answer and nothing else. A failed read throws:
RpcError on a transport failure, ContractRevertError on a revert that
names an error or a reason.
Parameters
pool
string
Returns
Promise<ClosingPriceState | null>
Throws
RpcError The chain read did not complete.
Throws
ContractRevertError The pool declares closingPrice() and rejected the call.
quoteBinaryStake()
quoteBinaryStake(
params):Promise<BinaryStakeQuote|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:880
Size a stake-denominated market BUY against the live binary book — "bet $50 on Up" → the shares, protective limit, and escrow the order will actually use. The inverse of quoteBinaryOrder: that prices a quantity; this sizes a quantity from a collateral budget, walking the asks cheapest-first while the escrow at the worst level touched stays within the stake. The protective limit is padded with a slippage cushion (so the IOC still crosses a moving book), tick-aligned, and the quantity re-fit and lot-aligned so the escrow never exceeds the stake.
Live store + one cached chain read (getBinaryBookParams); needs an
active watch for the book. The result feeds straight into
trader.placeOrder({ pool, side, price: yesPrice, quantity, orderType: ORDER_TYPE.MARKET }).
Resolves null when nothing is fillable (empty book, or a stake too small
to buy a single lot).
Details
params.side: "BUY_YES" (Up) or "BUY_NO" (Down).params.stake: Collateral budget in raw units — the max loss.params.depth: Book levels to sweep (default 10).params.slippageBps: Protective-limit cushion in bps (default 300 = 3%).params.slippageMinTicks: Minimum cushion in ticks (default 10).
Parameters
params
pool?
string
marketId?
string
side
stake
bigint
depth?
number
slippageBps?
bigint
slippageMinTicks?
bigint
Returns
Promise<BinaryStakeQuote | null>
quoteBinarySell()
quoteBinarySell(
params):Promise<BinarySellQuote|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:907
Build a market SELL that unwinds an outcome position by crossing the
resting bids, with a tick-aligned slippage cushion below the best bid —
the sell-side sibling of quoteBinaryStake (see it for the family's
mental model and tiering). Resolves null when there's no bid to cross or
nothing to sell — disable the Sell control rather than sending a doomed order.
The quote's fillableQuantity/estProceeds report what the crossable bids
can actually absorb — warn on a partial unwind before submitting.
Details
params.side: "SELL_YES" (Up position) or "SELL_NO" (Down position).params.quantity: Outcome tokens to sell, raw units (lot-aligned down).params.depth: Book levels to resolve (default 10).params.slippageBps: Protective-floor cushion in bps (default 300 = 3%).params.slippageMinTicks: Minimum cushion in ticks (default 10).
Parameters
params
pool?
string
marketId?
string
side
quantity
bigint
depth?
number
slippageBps?
bigint
slippageMinTicks?
bigint
Returns
Promise<BinarySellQuote | null>
getMarketStats24h()
getMarketStats24h(
target):Promise<MarketStats24h>
Defined in: packages/sdk/src/somniaMarketsClient.ts:923
A market's trailing-24h stats (volume, trades, price change, high/low/open),
summed from 1h OHLCV candle buckets — cheaper than scanning fills. Key it by
pool or marketId. Prices are raw quote units; volume is raw collateral.
One indexer round-trip.
Parameters
target
pool?
string
marketId?
string
Returns
Promise<MarketStats24h>
getBinaryPositionPnL()
getBinaryPositionPnL(
account,marketId):Promise<BinaryPositionPnL>
Defined in: packages/sdk/src/somniaMarketsClient.ts:960
An account's position + cost basis + PnL in one binary market, RAW units.
Reconstructs cost basis (weighted-average) from the account's order-book
fills on the market folded with complete-set mints/merges, marks the CURRENT
balances to the book-clamped last price (see markYesPrice; the settlement
payout once resolved), and realizes sells against the running average.
Best-effort over indexed fills; see BinaryPositionPnL for the
accounting assumptions. One fan-out of indexer reads plus one top-of-book
eth_call (skipped, falling back to lastPrice alone, when no chain
client is configured).
Every money field is BLENDED across both outcomes; outcomes.yes /
outcomes.no carry each book on its own. Both are needed for a wallet
holding YES and NO, where the blend can read 0 while the legs are large
and opposite. RAW units throughout — format with market.quoteDecimals.
A market that has never traded has NO price to mark against, so every
mark-derived field is null: markValue and unrealizedPnl, and
markPrice / markValue / unrealizedPnl on each leg. Show those as
unknown; do NOT treat them as zero. balance, costBasis, avgCost and
realizedPnl never depend on a mark and stay exact.
- Throws InvalidInputError - the account is unusable.
- Throws InvalidInputError - no binary market with that id, or a voided market carrying a present but invalid payout vector. A legacy row with both vector fields absent keeps the documented half-payout fallback.
- Throws IndexerError - a fills, actions or balances read did not complete,
OR an indexed fill or router action is malformed: an
idthat is not`${blockNumber}_${logIndex}`, or aquantity,fillPriceor mint/mergeamountthat is not an unsigned decimal number. This method fetches those rows itself, so a row it cannot read is corrupt indexed data, never a bad argument; the specific parse failure is oncause. - Throws RpcError - the top-of-book
eth_calldid not complete (only with a chain client configured; a failed read is never marked onlastPriceas if it had succeeded). - Throws ContractRevertError - the pool rejected the top-of-book read.
Parameters
account
string
marketId
string
Returns
Promise<BinaryPositionPnL>
getOpenPositionsWithPnL()
getOpenPositionsWithPnL(
account):Promise<OpenPositionPnL[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:996
PnL for ALL of an account's open binary positions in one call — the batched,
positions-list companion to getBinaryPositionPnL. Each entry is a
OpenPositionPnL: the position's market joined with its reliable
avg-cost PnL (costBasis / avgCost / markValue / unrealizedPnl /
realizedPnl, marked to the book-clamped price), computed identically to
getBinaryPositionPnL per market. Prefer this over deriving PnL from book
stats. Fetched in a bounded number of indexer round-trips (fills + router
actions + top-of-book batched across every open market), not a per-position
loop. Empty array when the account holds nothing.
Still ONE entry per market, with both books on it. To render a row per
outcome, read row.outcomes.yes / row.outcomes.no and keep the legs whose
balance > 0n — the top-level money fields are blended across the two and
belong to neither.
A market that has never traded has NO price to mark against, so its
markValue and unrealizedPnl are null, as are the same fields on each
leg. Show those as unknown; do NOT treat them as zero. A positions list
routinely mixes priced and unpriced markets, so handle null per row.
Errors
- Throws IndexerError when the positions, fills, router actions, or top-of-book request does not complete.
- Throws InvalidInputError when a voided position carries a present but invalid payout vector. A legacy row with both vector fields absent keeps the documented half-payout fallback.
- Throws IndexerError when an indexed fill or router action is malformed —
an
idthat is not`${blockNumber}_${logIndex}`, or aquantity,fillPriceor mint/mergeamountthat is not an unsigned decimal number. This method fetches those rows itself, so a row it cannot read is corrupt indexed data, never a bad argument; the specific parse failure is oncause.
Parameters
account
string
Returns
Promise<OpenPositionPnL[]>
getClaimable()
getClaimable(
account):Promise<ClaimablePosition[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1016
An account's redeemable positions across all SETTLED (resolved/voided)
binary markets, each shaped to feed straight into
trader.redeemMany({ entries }). Winners get amount × (1 − settlementFee);
a voided market pays each side against the payout vector it stored — a half
per side under the UNIFORM void policy, [p, D−p] on a CLOB_SNAPSHOT
void that captured a two-sided close, and never a settlement fee.
Loser-side and still-trading positions are omitted. One portfolio read plus
one fee read per winning market.
Errors
- Throws IndexerError when the portfolio or settlement-fee request does not complete.
- Throws InvalidInputError when a voided position carries a present but invalid payout vector. A legacy row with both vector fields absent keeps the documented half-payout fallback.
Parameters
account
string
Returns
Promise<ClaimablePosition[]>
watchPrice()
watchPrice(
asset):Promise<PriceWatchHandle>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1039
Watch one asset's price (e.g. "BTC", "ETH"): hydrate a snapshot (feed
metadata + current price + recent ticks) to get roughly up to speed, then
stream live over a Hasura WebSocket subscription. While active, every
getLivePrice/getLivePriceTicks read for this asset is current to the
last pushed tick at zero round-trip cost.
Ref-counted like watchMarket: watching the same asset twice shares
one subscription and one snapshot; each handle's stop() releases one
reference, and a brief linger absorbs quick re-watches.
Requires config.priceFeed, INCLUDING its quote: a live watch rejects
with a NotConfiguredError naming config.priceFeed.quote when the feed is
unpinned, because the tick tape's cursor is only unique within one quote (see
PriceFeedConfig.quote). The one-shot fetchPrice* reads still work
unpinned. Rejects (and releases the ref) in either case.
Parameters
asset
string
Returns
Promise<PriceWatchHandle>
watchPrices()
watchPrices(
assets):Promise<PriceWatchHandle>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1049
Watch a batch of assets at once (e.g. ["BTC", "ETH"]). Returns a single
handle whose stop() releases all of them; each asset is independently
ref-counted, so this composes with per-asset watchPrice calls.
Requires a quote-pinned config.priceFeed for the same reason
watchPrice does.
Parameters
assets
string[]
Returns
Promise<PriceWatchHandle>
getPriceStatus()
getPriceStatus(
asset):PriceFeedStatus
Defined in: packages/sdk/src/somniaMarketsClient.ts:1057
Per-asset price-watch state: "unwatched", "hydrating", "live", or
"error". Check it before rendering a live price — on "error" the reads
still answer, but with values that have stopped updating. See
PriceFeedStatus.
Parameters
asset
string
Returns
subscribePrices()
subscribePrices(
listener): () =>void
Defined in: packages/sdk/src/somniaMarketsClient.ts:1069
Fire listener after every batch of price-store changes (React hooks
subscribe to exactly this). Re-read with getLivePrice/getLivePriceTicks;
results are memoized per store version. Independent of subscribeLive
(prices are a separate store/service).
Details
- Returns: An unsubscribe function.
Parameters
listener
() => void
Returns
() => void
getLivePrice()
getLivePrice(
asset):LivePrice|null
Defined in: packages/sdk/src/somniaMarketsClient.ts:1075
The current price of a watched asset (from the live store), or null if unwatched / not yet hydrated. Synchronous, memoized.
Parameters
asset
string
Returns
LivePrice | null
getLivePrices()
getLivePrices(
assets): (LivePrice|null)[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:1081
Current prices for a batch of watched assets, aligned to assets (each entry
null if that asset is unwatched / not yet hydrated). Synchronous.
Parameters
assets
string[]
Returns
(LivePrice | null)[]
getLivePriceTicks()
getLivePriceTicks(
asset,opts?):PricePoint[]
Defined in: packages/sdk/src/somniaMarketsClient.ts:1090
The recent tick tape of a watched asset, newest first. Synchronous, memoized.
Details
opts.limit: Max ticks (default 100; the store retains ~1000).
Parameters
asset
string
opts?
limit?
number
Returns
getLivePriceFeedInfo()
getLivePriceFeedInfo(
asset):PriceFeedInfo|null
Defined in: packages/sdk/src/somniaMarketsClient.ts:1096
Feed metadata + current price for a watched asset (from the live store), or null if unwatched. For a one-shot read without a watch use fetchPriceFeedInfo.
Parameters
asset
string
Returns
PriceFeedInfo | null
fetchPriceFeedInfo()
fetchPriceFeedInfo(
asset):Promise<PriceFeedInfo>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1099
One-shot feed metadata + current price (one HTTP round-trip; no watch needed).
Parameters
asset
string
Returns
Promise<PriceFeedInfo>
fetchPrice()
fetchPrice(
asset):Promise<LivePrice|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1105
One-shot current price (one HTTP round-trip), or null if the feed has no observations yet.
Parameters
asset
string
Returns
Promise<LivePrice | null>
fetchPrices()
fetchPrices(
assets?):Promise<LivePrice[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1112
One-shot current prices for a batch of assets, or ALL tracked assets when
assets is omitted — the multi-asset "price wall" in one request. Assets
with no observations yet are omitted from the result.
Parameters
assets?
string[]
Returns
Promise<LivePrice[]>
listPriceFeeds()
listPriceFeeds():
Promise<PriceFeedInfo[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1118
One-shot feed catalog — metadata + current price for every tracked asset (discovery). One HTTP round-trip; no watch needed.
Returns
Promise<PriceFeedInfo[]>
fetchPriceHistory()
fetchPriceHistory(
asset,opts?):Promise<PricePoint[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1124
Historic ticks for one asset, newest first — window with from/to (unix
seconds, chain time), page with limit (default 500).
Parameters
asset
string
opts?
limit?
number
from?
number
to?
number
Returns
Promise<PricePoint[]>
fetchPriceCandles()
fetchPriceCandles(
asset,resolution,opts?):Promise<PriceCandle[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1130
OHLC candles for one asset + resolution ("M1"/"H1"/"D1"), oldest first
(chart-ready). Window with from/to (unix seconds); page with limit.
Parameters
asset
string
resolution
opts?
limit?
number
from?
number
to?
number
Returns
Promise<PriceCandle[]>
listMarkets()
listMarkets(
opts?):Promise<Market[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1150
List markets, newest first, as the discriminated
Market = SpotMarket | BinaryMarket union.
Details
opts.marketType: Filter to"SPOT"or"BINARY"; omit for both.opts.limit: Max rows (default 50).opts.offset: Row offset for pagination (default 0).
Parameters
opts?
marketType?
limit?
number
offset?
number
Returns
Promise<Market[]>
listRegistryMarkets()
listRegistryMarkets():
Promise<Market[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1158
Registry sweep for the unified tier: every non-binary market plus the binary series that are still live (not finalized), paged until exhausted. Finalized series accumulate without bound; resolve those by pool via the raw-tier lookups instead.
Returns
Promise<Market[]>
listRegistryMarketsChecked()
listRegistryMarketsChecked():
Promise<RegistrySweep>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1172
listRegistryMarkets with the rows the SDK could not parse COUNTED,
as { markets, dropped }.
A malformed row is dropped silently rather than failing the page, so a
caller that treats the sweep as exhaustive — a monitor publishing coverage
over it, say — cannot tell a short answer from a complete one. dropped > 0
says the registry holds markets this read did not return.
Returns
Promise<RegistrySweep>
Throws
IndexerError The indexed read did not complete. The complete union is SomniaMarketsClientListRegistryMarketsCheckedError.
countMarkets()
countMarkets(
opts?):Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1180
Server-side COUNT of markets (optionally one type) for pagination totals.
Needs the privileged _aggregate role (server-only), like countBinaryMarkets.
Without it the count is a row scan capped at 10,000 and a larger total reads
as exactly 10000 — countMarketsBounded reports whether it did.
Parameters
opts?
marketType?
Returns
Promise<number>
countMarketsBounded()
countMarketsBounded(
opts?):Promise<CountResult>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1186
countMarkets with the truncation reported: truncated: true means
the public-role scan hit its cap and count is a lower bound.
Parameters
opts?
marketType?
Returns
Promise<CountResult>
getMarket()
getMarket(
id):Promise<Market|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1192
One market by primary key (bytes32 marketId for binary, pool address for spot), or null if the indexer doesn't have it.
Parameters
id
string
Returns
Promise<Market | null>
listBinaryMarkets()
listBinaryMarkets(
opts?):Promise<BinaryMarket[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1195
listMarkets pre-narrowed to binary markets.
Parameters
opts?
BinaryMarketFilter & object
Returns
Promise<BinaryMarket[]>
listLiveBinaryMarkets()
listLiveBinaryMarkets(
filter?):Promise<BinaryMarket[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1203
Currently-live binary markets (expiry > now), soonest-to-expire first.
Call with no argument for all live markets, or pass a
LiveBinaryMarketsFilter to narrow by operatorId / venueId /
asset / intervalSec / status (e.g. { venueId: "0x4d41494e" }).
Parameters
filter?
Returns
Promise<BinaryMarket[]>
listBinaryVenueIds()
listBinaryVenueIds():
Promise<object[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1210
Distinct (operatorId, venueId) pairs across binary markets — the cheap server-side source for operator/venue filter options (so a UI never fetches every market just to enumerate origins). Excludes null attribution.
Returns
Promise<object[]>
listBinaryAssets()
listBinaryAssets():
Promise<string[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1223
Distinct asset symbols across binary markets — the cheap server-side source for an asset filter's options.
Returns
Promise<string[]>
countBinaryMarkets()
countBinaryMarkets(
opts):Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1231
Server-side COUNT of binary markets matching a filter, split by lifecycle
phase — a total without fetching rows (Hasura _aggregate). On the public
role this is a row scan capped at 10,000, which Market passes in
production during 2026 — countBinaryMarketsBounded says which.
Parameters
opts
BinaryMarketFilter & object
Returns
Promise<number>
countBinaryMarketsBounded()
countBinaryMarketsBounded(
opts):Promise<CountResult>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1238
countBinaryMarkets with the truncation reported: truncated: true
means the public-role scan hit its cap and count is a lower bound, so a
rows.length < count pagination gate would stop early.
Parameters
opts
BinaryMarketFilter & object
Returns
Promise<CountResult>
listPastBinaryMarkets()
listPastBinaryMarkets(
opts?):Promise<BinaryMarket[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1246
Past binary markets (expiry ≤ now), most-recently-expired first,
paginated with limit + offset.
Parameters
opts?
Returns
Promise<BinaryMarket[]>
getBinaryMarket()
getBinaryMarket(
id):Promise<BinaryMarket|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1252
One binary market by bytes32 marketId, or null (also null if the id resolves to a spot market).
Parameters
id
string
Returns
Promise<BinaryMarket | null>
getBinaryMarketByAddress()
getBinaryMarketByAddress(
marketAddress):Promise<BinaryMarket|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1258
One binary market by its on-chain BinaryMarket ADDRESS (the Market PK is the bytes32 marketId, so an address-keyed caller must resolve through this). Newest first for recycled/rebound addresses; null if not yet indexed.
Parameters
marketAddress
string
Returns
Promise<BinaryMarket | null>
getMarketFees()
getMarketFees(
id):Promise<MarketFees|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1263
Fee config frozen into the market's pool at creation (origin venue attribution + rates in bpsTimes1k), or null without attribution.
Parameters
id
string
Returns
Promise<MarketFees | null>
listSpotMarkets()
listSpotMarkets(
opts?):Promise<SpotMarket[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1269
listMarkets pre-narrowed to spot markets. Pass a
SpotMarketFilter (+ limit) to narrow by base/quote symbol.
Parameters
opts?
SpotMarketFilter & object
Returns
Promise<SpotMarket[]>
getSpotMarket()
getSpotMarket(
id):Promise<SpotMarket|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1272
One spot market by pool address, or null (also null if not spot).
Parameters
id
string
Returns
Promise<SpotMarket | null>
getMarketStatusHistory()
getMarketStatusHistory(
marketId):Promise<MarketStatusUpdate[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1278
A market's status-transition history (Trading→Locked→Settling→Resolved…), oldest-first — the resolution/lock timeline for a market page.
Parameters
marketId
string
Returns
Promise<MarketStatusUpdate[]>
listPerpMarkets()
listPerpMarkets(
opts?):Promise<PerpMarket[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1284
listMarkets pre-narrowed to perp markets. Pass a
PerpMarketFilter (+ limit) to narrow by base/quote symbol.
Parameters
opts?
PerpMarketFilter & object
Returns
Promise<PerpMarket[]>
getPerpMarket()
getPerpMarket(
id):Promise<PerpMarket|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1290
One perp market by pool address, or null (also null if the id resolves to another market kind).
Parameters
id
string
Returns
Promise<PerpMarket | null>
getCandles()
getCandles(
poolAddress,intervalSeconds,opts?):Promise<Candle[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1302
OHLCV candles for one pool + interval, oldest first (chart-ready).
Details
intervalSeconds: Bucket size — one of the indexer's rollup intervals.opts.limit: Max buckets (default 500).opts.from: Only buckets at/after this unix-seconds timestamp.opts.to: Only buckets at/before this unix-seconds timestamp.
Parameters
poolAddress
string
intervalSeconds
number
opts?
limit?
number
from?
number
to?
number
Returns
Promise<Candle[]>
getMarketActivity()
getMarketActivity(
market,opts?):Promise<MarketActivity[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1335
One market's activity, newest first — trades interleaved with complete-set mints and merges, redemptions, oracle resolution and lifecycle transitions.
This is the market's transaction history. Every row names the transaction it
landed in, so a caller can follow any row to the chain. Narrow a row on its
kind (MarketActivity).
Use this for a market page's activity panel. It is the one-shot INDEXER
read, so it carries the history the panel needs on first paint, and it does
not update itself. For trades arriving with no round-trip, read
getLiveFills as well and merge on the trade rows' id, which is
TRADE: followed by the fill id — FIELD BY FIELD, preferring whichever
source has a value. Neither is a superset of the other: the tail leaves
taker/takerSide undefined on the fills it hydrates, and the indexer's
takerIsBid is null until its taker bridge lands. Preferring one source
wholesale drops what the other knew.
A spot or perp market returns TRADE rows only — the other kinds come from
binary-only entities, so asking for them there is not an error, just empty.
One round-trip. Page backwards with until, not an offset (see
MarketActivityOptions).
Parameters
market
string
The market's bytes32 marketId (case-insensitive). On spot and perp this is the pool address.
opts?
Returns
Promise<MarketActivity[]>
getTransactionActivity()
getTransactionActivity(
txHash,opts?):Promise<TransactionActivity>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1355
Everything the protocol did in ONE transaction — trades, complete-set mints and merges, redemptions, oracle resolution, lifecycle transitions, the orders it placed and the fees it paid (TransactionActivity).
The read behind a transaction detail view, and the counterpart to
getTradeContext: that starts from a trade and shows its transaction as
context, this starts from a transaction and shows every trade in it.
events is the same union getMarketActivity returns, with the same
row ids, so one component renders both — but in LOG order, earliest first,
because a transaction reads forwards.
A hash the indexer has nothing for returns empty collections and a null
blockNumber rather than throwing: an unknown hash and a transaction that
touched no protocol contract are both absence.
Parameters
txHash
string
Transaction hash (case-insensitive).
opts?
Returns
Promise<TransactionActivity>
getBlockActivity()
getBlockActivity(
blockNumber,opts?):Promise<BlockActivity>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1378
What the protocol traded in one block, grouped by market — the level above getTransactionActivity.
The block's own timestamp anchors every read, because no block column in the indexer schema is indexed. Resolving it is a chain read, and this client owns the transport, so it happens here: a caller never needs a second client. Reach for getViemClient only for chain work the SDK does not model.
A block with no markets activity — the common case, since only ~42% of
blocks carry any — returns an empty markets array rather than throwing.
Order rows carry no status: Order is mutable, so its status is
as-of-now and would show a state from the block's future. Use touch.
truncated reports a stream that came back full; page with opts.offset.
Parameters
blockNumber
bigint
Block to read.
opts?
Rows per stream and the offset to page from.
Returns
Promise<BlockActivity>
getLatestActiveBlock()
getLatestActiveBlock():
Promise<{blockNumber:bigint;timestamp:bigint; } |null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1388
The newest block the indexer has markets activity for, or null when it has none at all.
The entry point for a block view: the chain head runs ahead of the indexer, and most blocks carry no markets activity, so the head is usually a blank page. Pair with getBlockActivity.
Returns
Promise<{ blockNumber: bigint; timestamp: bigint; } | null>
getAdjacentActiveBlocks()
getAdjacentActiveBlocks(
blockNumber,opts?):Promise<{prev:bigint|null;next:bigint|null; }>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1403
The closest blocks with markets activity below and above one block.
The read behind a block view's prev/next: most blocks carry no markets activity, so stepping by n±1 lands on a blank page more often than not. Either side is null when no active block was found within the bounded scan.
Anchored the same way as getBlockActivity, and for the same reason resolves that anchor itself.
Parameters
blockNumber
bigint
The block being viewed; excluded from both answers.
opts?
Rows per stream per direction.
Returns
Promise<{ prev: bigint | null; next: bigint | null; }>
getFills()
getFills(
pool,opts?):Promise<FillRow[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1416
Recent fills on one pool, newest first. Bound the tape with since/until
in seconds, or with sinceBlock to resume from a processed block
(FillsOptions).
Parameters
pool
string
opts?
Returns
Promise<FillRow[]>
Throws
The pool or block bound is unusable.
Throws
The read did not complete.
getTradeContext()
getTradeContext(
id):Promise<TradeContext|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1436
ONE fill IN CONTEXT, by id — the trade, its market, both sides' orders resolved, the fees it paid, and the other fills its transaction produced (TradeContext).
getFill is the cheaper sibling: one query, the fill and its market, no surrounding context. Prefer it when a caller only renders the trade.
The read behind a trade detail view. getFills and
getMarketActivity are the list reads that produce the id; this is
the drill-down from one of their rows.
Returns null when no fill has this id — a stale or mistyped link, not a
failure. Two round-trips: the transaction's siblings and fees are anchored
on the fill's own timestamp, so the fill has to resolve first.
Parameters
id
string
Fill id, ${blockNumber}_${logIndex}.
Returns
Promise<TradeContext | null>
getUserFills()
getUserFills(
account,opts?):Promise<FillRow[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1453
Fills a user participated in (maker OR taker), newest first — the one-shot
indexer counterpart to getLiveUserFills. Optionally scope to one
market and/or pool, a since/until window, and a sinceBlock bound
(FillsScope). Use sinceBlock to resume from a processed block:
blocks can share a timestamp, so a seconds bound repeats or skips them.
On binary, scope by market rather than pool for one market's tape: a
pool is recycled by successive markets, so pool also returns the fills of
that pool's earlier lives. Both predicates run at the indexer, so limit
applies to the rows you asked for.
Parameters
account
string
opts?
Returns
Promise<FillRow[]>
Throws
The account, a scope value or a block bound is unusable.
Throws
The read did not complete.
getUserFillsPage()
getUserFillsPage(
account,options?):Promise<UserFillsPage>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1488
Read one historical fill page through this owner's indexer. Prefer this to offset paging when new fills can arrive between reads. Numeric timestamp, block number and log index define a total descending order. Self-trades appear once. Existing fill fields and account-side interpretation are unchanged.
The default limit is 50; valid limits are integers from 1 to 1000. A sentinel row establishes continuation without returning it. Null continuation means no further row was observed, not that indexing or historical coverage is complete.
Cursors bind account, chain, configured endpoint, normalized filters and sort. They do not authenticate the caller or identify a dataset generation. Continue only on an unchanged dataset. Discard cursors and cached pages after reindex, repair or cutover. A deployment-aware reset contract is required before migrating persistent frontend caches. Newer inserts belong to a fresh first-page read. Cancellation through the configured owner's signal preserves the caller's abort reason rather than converting it to an IndexerError.
Parameters
account
string
Wallet participating as maker or taker.
options?
Market/pool, inclusive time and source-block filters, bounded limit and cursor.
The cursor is scoped to the normalized filters, including sinceBlock.
Returns
Promise<UserFillsPage>
Existing fill rows and the next cursor, or null when this read has no next row.
Throws
InvalidInputError For invalid input or malformed/foreign cursors.
Throws
IndexerError When the read fails or returned position scalars are invalid.
Example
const first = await exchange.client.getUserFillsPage(account, { limit: 100 });
if (first.nextCursor !== null) {
const next = await exchange.client.getUserFillsPage(account, { limit: 100, cursor: first.nextCursor });
console.log(next.fills);
}
getFillsPage()
getFillsPage(
options):Promise<FillsPage>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1533
Every fill of one MARKET KIND in an inclusive block range, across every pool of that kind, oldest first — the read behind a published trade feed.
Takes no pool, unlike getFills: a feed indexes the whole venue and must not enumerate its pools. The block range is what bounds the read.
Use blocks, not since/until seconds, whenever successive reads must
tile the chain exactly. Several Somnia blocks can share a timestamp, so a
seconds window drops or repeats the fills in them at every seam. Both
bounds here are inclusive and (blockNumber, logIndex) is a total order,
so [a, b] then [b + 1, c] covers every fill once.
Pages default to 500 rows. The cursor names the last row returned and binds
the chain, endpoint, kind and both bounds, so a cursor from one range is
rejected by another. A full page always returns a cursor, so a range that
ends on a page boundary costs one empty final page. Drain a range until
nextCursor is null; a null
cursor means this read saw no further row IN THE RANGE, not that indexing
is complete — getLatestFillBlock is what reports how far the fill
data reaches.
Amounts stay raw strings, as everywhere on FillRow. Do not route a published feed through the human-unit market reads.
Parameters
options
Kind, inclusive block range, page size and continuation.
Returns
Promise<FillsPage>
Throws
A bound, the kind, the limit or the cursor is unusable.
Throws
The read did not complete, or returned unusable block positions.
Example
let cursor: string | undefined;
do {
const page = await exchange.client.getFillsPage({
marketType: "SPOT",
sinceBlock: 441_000_000n,
toBlock: 441_010_000n,
cursor,
});
console.log(page.fills.length);
cursor = page.nextCursor ?? undefined;
} while (cursor !== undefined);
getLatestFillBlock()
getLatestFillBlock(
marketType):Promise<LatestFillBlock|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1551
The newest block carrying an indexed fill of one market kind, with that block's timestamp — the head marker to poll before asking for a range.
Taken from the fill data rather than from the indexer's processed-block watermark, so the marker can never name a block getFillsPage cannot yet serve.
Returns null when no fill of that kind is indexed — a fresh deployment or
one still replaying, not a failure. getLatestActiveBlock is the
wider question: the newest block with ANY markets activity, fills included.
Parameters
marketType
Market kind to report on.
Returns
Promise<LatestFillBlock | null>
Throws
The market kind is unusable.
Throws
The read did not complete.
getFill()
getFill(
id):Promise<FillDetail|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1558
One fill by its id (${blockNumber}_${logIndex}) with both parties' order
linkage and the market it executed on — the single lookup behind a fill
detail view. Null when not indexed (a just-executed fill can lag a beat).
Parameters
id
string
Returns
Promise<FillDetail | null>
getOrderFills()
getOrderFills(
pool,orderId,opts?):Promise<OrderFillRow[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1569
Every fill one order participated in — either side, newest first.
(pool, orderId) names exactly one order forever (ids never reuse).
This bounded whole-history lookup accepts only limit; use getFills or
getUserFills with sinceBlock to resume a pool or account tape.
Parameters
pool
string
orderId
string | bigint
opts?
limit?
number
Returns
Promise<OrderFillRow[]>
Throws
The pool identifier or order id is unusable.
Throws
The read did not complete.
getOrder()
getOrder(
pool,orderId):Promise<OrderDetail|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1576
One order by (pool, orderId) — the indexer's view, including owner and
full lifecycle attribution (status, cancelReason, amend chain). Null when
not indexed; for chain-head truth use getOrderOnchain.
Parameters
pool
string
orderId
string | bigint
Returns
Promise<OrderDetail | null>
listMarketsByPool()
listMarketsByPool(
pool,opts?):Promise<Market[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1583
Every market a pool has hosted, newest first — one row for SPOT/PERP, the full recycle history for a BINARY pool. First row = the current market. The one-row shortcut is getMarketByPool.
Parameters
pool
string
opts?
limit?
number
Returns
Promise<Market[]>
getOpenOrders()
getOpenOrders(
owner,opts?):Promise<OpenOrder[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1597
owner's currently-OPEN orders, newest first. Pass OrdersOptions
(minus status — always "Open" here) to scope by pool/pools/market/
markets/side/userData/sinceBlock and page. Each row carries the placement's own
userData tag, so a caller can match a row to the order it sent.
NOTE: this lags the chain — for a trading loop prefer
getLiveUserOrders (or track the orderIds your own
placeOrder calls return). For non-open history use getOrders.
Parameters
owner
string
opts?
Omit<OrdersOptions, "status">
Returns
Promise<OpenOrder[]>
Throws
The owner, a scope, tag or block bound is unusable.
Throws
The read did not complete.
getOrders()
getOrders(
owner,opts?):Promise<OrderRow[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1611
owner's orders across ALL statuses (Open/Filled/Cancelled/Expired/Closed),
newest first — the order-history counterpart to getOpenOrders. Each
row carries its lifecycle status, fill progress and the placement's own
userData tag. Filter by status/side/pool/pools/market/
markets/userData/sinceBlock and page via OrdersOptions. sinceBlock
bounds the PLACEMENT block, so it does not report later changes to older
orders.
Parameters
owner
string
opts?
Returns
Promise<OrderRow[]>
Throws
The owner, a scope, tag or block bound is unusable.
Throws
The read did not complete.
listSweepableOrders()
listSweepableOrders(
opts?):Promise<SweepableOrder[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1632
Orders past expiry that are STILL RESTING, across the whole book — the work-list for a permissionless expired-order sweep. Not scoped to an account.
Works on every market kind; scope with pool and/or marketType. Each row
carries exactly what the sweep verbs need: orderId for
trader.cancelExpiredOrders, and isBid + price for
trader.sweepExpiredAtLevel.
This is not status: "Expired". That status is written when the chain
emits OrderExpired — i.e. once an order has ALREADY been removed. The sweepable
set is the opposite: status = "Open" and expireTimestampNs < now, orders the
book still holds because nobody has cleaned them up. They are NOT matched against
— the matcher skips an expired maker — but each costs a warm SLOAD per traversal
and holds a priority-index slot.
Longest-overdue first. GTC excludes itself because this SDK writes it as now + 50 years, not via any contract sentinel.
Parameters
opts?
pool?
string
marketType?
owner?
string
asOfSec?
number | bigint
limit?
number
offset?
number
Returns
Promise<SweepableOrder[]>
getOutcomeBalances()
getOutcomeBalances(
account,marketAddress):Promise<OutcomeBalances>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1646
Indexed YES/NO outcome-token balances of account in one binary market
("0" when unseen). Display-grade: to gate a write, read the tokens'
on-chain balances via getErc20Balance instead.
Parameters
account
string
marketAddress
string
Returns
Promise<OutcomeBalances>
getPortfolio()
getPortfolio(
account,opts?):Promise<Portfolio>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1654
A wallet's whole binary portfolio in one round-trip once the registry is warm
(a cold call resolves the market-type scope first): non-zero outcome
positions, open orders, and recent trades (each with market context).
Pass PortfolioOptions to page orders/trades or window trades. Trades default to the last seven days — the bound comes back as tradesSince; pass since to widen it.
Parameters
account
string
opts?
Returns
Promise<Portfolio>
getSpotPortfolio()
getSpotPortfolio(
account,opts?):Promise<SpotPortfolio>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1661
A wallet's spot activity: open orders, pending stop orders, and recent
trades. Token holdings are NOT here — spot balances are plain ERC-20 /
native balances; read them on-chain. Pass PortfolioOptions to page. Trades default to the last seven days — the bound comes back as tradesSince; pass since to widen it.
Parameters
account
string
opts?
Returns
Promise<SpotPortfolio>
getSpotStopOrders()
getSpotStopOrders(
account,opts?):Promise<SpotStopOrder[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1668
A wallet's spot stop orders — PENDING by default (list + cancel via
trader.cancelStopOrder). Pass status to see triggered/failed/cancelled
history, pool to scope to one market, limit to page.
Parameters
account
string
opts?
pool?
string
status?
limit?
number
Returns
Promise<SpotStopOrder[]>
getPerpPortfolio()
getPerpPortfolio(
account,opts?):Promise<PerpPortfolio>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1679
A wallet's perp activity as indexed: open perp orders + recent perp
trades. Positions/collateral live in the MarginBank — read them on-chain
with getPerpPosition / getMarginAccount. Pass
PortfolioOptions to page. Trades default to the last seven days — the bound comes back as tradesSince; pass since to widen it.
Parameters
account
string
opts?
Returns
Promise<PerpPortfolio>
listPerpStopOrders()
listPerpStopOrders(
opts?):Promise<PerpStopOrder[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1699
Perp take-profit / stop-loss orders, newest first — the read that makes TP/SL usable at all.
The PerpStopOrderRegistry keeps pending orders in private storage behind no enumeration getter, so there is no chain read that answers "what stops do I have". Creation and triggering both work; without this a trader cannot see, price or cancel what they created, which is why the feature shipped gated.
Every scope comes from the same call: { account } for a trader's working stops
(default status PENDING), { pool } with no account for a market's whole
pending book, and status for history. account is optional deliberately — a
market-wide view of what will fire is a legitimate monitoring read.
Read dropReason before calling a TRIGGER_FAILED order a failure: a reduce-only
drop means the stop was overtaken by events, which is ordinary; only
PlacementFailed is a rejection.
Parameters
opts?
account?
string
pool?
string
status?
limit?
number
offset?
number
Returns
Promise<PerpStopOrder[]>
getPerpStopOrder()
getPerpStopOrder(
ref):Promise<PerpStopOrderOnChain|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1724
One pending stop read straight from its registry — the chain tier listPerpStopOrders does not have.
The only way to read a LIMIT stop's limitPrice, its linked siblingOrderId
and its intent: no event carries them, so PerpStopOrder cannot.
Cannot enumerate — list ids there, then enrich each here.
null when the id is not live. Do not infer liveness from the terms: a
dead id keeps plausible values until its slot is recycled, so live is the
only truth.
Parameters
ref
Returns
Promise<PerpStopOrderOnChain | null>
Throws
InvalidInputError The order id is not a valid uint128 integer.
Throws
NotConfiguredError The owner has no chain WebSocket endpoint.
Throws
RpcError The registry read failed before it returned a contract result.
Throws
ContractRevertError The registry rejected the read.
getPerpStopOrders()
getPerpStopOrders(
refs):Promise<readonlyPerpStopOrderRead[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1758
Enrich known perp stop ids with one ordered chain batch.
Use listPerpStopOrders to discover ids. Each result belongs to the
input ref at the same index. absent means the registry confirmed that the
stop is not live. failed means only that member was unreadable.
The configured chain uses Multicall3 when available. Other chains use a
bounded point-read fallback. Both paths pin every result to one chain head.
A contract revert or RPC failure for a member is returned as failed.
Parameters
refs
readonly PerpStopOrderRef[]
Returns
Promise<readonly PerpStopOrderRead[]>
Throws
InvalidInputError An order id is not a canonical unsigned uint128 decimal.
Throws
NotConfiguredError The owner has no chain WebSocket endpoint.
Throws
RpcError The head could not be pinned or the batch result was malformed.
Throws
ContractRevertError The Multicall3 aggregate rejected the batch.
Example
const indexed = await client.listPerpStopOrders({ account: owner });
const refs = indexed.map((stop) => {
if (!isAddress(stop.registry)) throw new Error(`Invalid registry ${stop.registry}`);
return { registry: stop.registry, orderId: stop.orderIdRaw };
});
const reads = await client.getPerpStopOrders(refs);
for (const [index, read] of reads.entries()) {
const stop = indexed[index];
if (stop === undefined) throw new Error(`Missing indexed stop ${index}`);
if (read.status === "present") console.log(stop.id, read.order);
if (read.status === "absent") console.log(stop.id, "no longer live");
if (read.status === "failed") console.error(stop.id, read.error);
}
getPerpStopOrderSomiPayment()
getPerpStopOrderSomiPayment(
registry):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1764
SOMI a perp stop registry charges per pending order, in wei. Send exactly this with a create or it reverts; refunded on cancel, consumed on a fire.
Parameters
registry
`0x${string}`
Returns
Promise<bigint>
getUnclaimedPerpStopSomi()
getUnclaimedPerpStopSomi(
ref):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1772
SOMI a perp stop registry owes account, in wei, claimable with
trader.claimPerpStopSomi. Credited when a cancel's direct refund fails (a
contract owner with no payable receiver) OR when the registry is wound down,
which credits every owner — including EOAs.
Parameters
ref
registry
`0x${string}`
account
`0x${string}`
Returns
Promise<bigint>
listPerpOrderHistory()
listPerpOrderHistory(
account,opts?):Promise<PerpOrderHistoryRow[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1790
An account's FINISHED perp orders, most-recently-ended first — the history tab behind getPerpPortfolio's open-orders list.
getPerpPortfolio hard-filters status = "Open", so before this there was no
way to see a filled, cancelled or expired perp order at all.
Excludes working orders by default (status != "Open"); pass status to narrow
to particular outcomes. Ordered by when each order ENDED, not when it was
placed — a long-resting order that just filled belongs at the top of a history
view, not buried at its placement date.
Note Closed is terminal, not transitional: an IOC that partially filled
without resting stays Closed forever, so treating it as "still working" would
show a finished order as live.
Parameters
account
string
opts?
pool?
string
status?
orderBy?
"placed" | "ended"
limit?
number
offset?
number
Returns
Promise<PerpOrderHistoryRow[]>
getSyncStatus()
getSyncStatus(
chainId):Promise<IndexerSyncStatus|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1807
Read the indexer's own metadata without chain RPC. A missing chain row returns null. Use the concrete owner's getIndexerFreshness for an independent comparison.
Parameters
chainId
number
Returns
Promise<IndexerSyncStatus | null>
Throws
A query variable is invalid.
Throws
The metadata request failed.
waitForIndexedBlock()
waitForIndexedBlock(
chainId,block,opts?):Promise<IndexedBlockWait>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1836
Wait until the indexer has processed block on chainId, then resolve with
what the wait observed.
The step between a confirmed write and an indexer read of that write: every indexer-backed read answers from the processed height, so a read issued before the block is indexed correctly reports the row as absent. Resolving means a read issued afterwards sees what that block wrote.
Polls chain_metadata every pollMs (default 500) until timeoutMs
(default 30,000). Pass signal to abort; the caller's abort reason is
rethrown unchanged.
Example (Read your own write)
const receipt = await exchange.client.getViemClient().waitForTransactionReceipt({ hash });
await exchange.client.waitForIndexedBlock(exchange.client.config.chain.id, receipt.blockNumber);
const orders = await exchange.client.getOpenOrders(owner, { userData: 7n });
Parameters
chainId
number
block
number | bigint
opts?
Returns
Promise<IndexedBlockWait>
Throws
The block height, timeoutMs or pollMs is not a usable whole number.
Throws
The deadline passed with the indexer still behind the block.
Throws
A metadata read failed, or the indexer serves no row for this chain.
The complete union is SomniaMarketsClientWaitForIndexedBlockError.
getMarketByPool()
getMarketByPool(
pool):Promise<Market|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1846
Resolve a market by its pool address (one query; no live watch), or null. Binary markets are keyed by bytes32 marketId, so this is the by-pool lookup.
Parameters
pool
string
Returns
Promise<Market | null>
countOrders()
countOrders(
owner,opts?):Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1861
Server-side COUNT of owner's orders matching an OrdersOptions
filter — the total for an order-history page. Privileged _aggregate role
(server-only), with a bounded row-count fallback on the public role.
WITHOUT THAT HEADER THE RESULT IS A LOWER BOUND, returned as if exact: the
fallback scan stops at 10,000 rows and reports 10,000, and Order is far
past that in production. There is no bounded variant of this method yet —
countMarketsBounded is the shape to copy.
Parameters
owner
string
opts?
Returns
Promise<number>
Throws
The owner, a scope, tag or block bound is unusable.
Throws
The count did not complete.
countUserFills()
countUserFills(
account,opts?):Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1878
Server-side COUNT of the fills account participated in (maker OR taker),
optionally scoped by market and/or pool + a since/until window or
inclusive sinceBlock source-block bound (FillsScope) — a
history-page total.
WITHOUT THE PRIVILEGED _aggregate HEADER THE RESULT IS A LOWER BOUND,
returned as if exact: the fallback scan stops at 10,000 rows and reports
10,000, and Fill is the deepest counted table in production. There is no
bounded variant of this method yet — countMarketsBounded is the
shape to copy.
Parameters
account
string
opts?
Returns
Promise<number>
Throws
The account, a scope value or a block bound is unusable.
Throws
The count did not complete.
getRouterActions()
getRouterActions(
account,opts?):Promise<RouterActionRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1889
An account's RouterMinter action history (redeem / mint / merge), newest
first — optionally scoped to one market (or several via markets) and/or
kind, paginated (RouterActionsOptions).
Mint and merge move a position's cost basis, so scope this the same way you scope the fills you fold it against: an account-wide capped read drops the OLDEST rows, which are the ones that set the basis.
Parameters
account
string
opts?
Returns
Promise<RouterActionRecord[]>
getMarketResolution()
getMarketResolution(
marketId):Promise<{events:MarketResolutionEvent[];reference:MarketReferenceLink|null;closingAnswer:OracleAnswer|null;openingAnswer:OracleAnswer|null;oracleAnswer:OracleAnswer|null; }>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1899
Everything the indexer knows about how a market resolves: lifecycle events,
the oracle reference link, and the posted oracle answers. closingAnswer is
the market's own resolution answer (the CLOSING price for a reference-mode
up/down market); openingAnswer is the reference-question answer (the OPENING
price it resolves against, null for fixed-strike markets). Any piece may be
absent. oracleAnswer is a deprecated alias of closingAnswer.
Parameters
marketId
string
Returns
Promise<{ events: MarketResolutionEvent[]; reference: MarketReferenceLink | null; closingAnswer: OracleAnswer | null; openingAnswer: OracleAnswer | null; oracleAnswer: OracleAnswer | null; }>
getOpeningPrices()
getOpeningPrices(
marketIds):Promise<Record<string,string|null>>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1931
Batch opening (reference-question) prices for many markets in one pair of
round-trips — for list views. Map of lowercased marketId → raw oracle
numericValue (null when no reference answer yet). Format with the market's
oracle price scale.
Parameters
marketIds
string[]
Returns
Promise<Record<string, string | null>>
getResolutionPrices()
getResolutionPrices(
marketIds):Promise<Record<string,string|null>>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1939
Batch RESOLUTION (settlement) prices for many markets in one pair of
round-trips — the settlement counterpart to getOpeningPrices. Map
of lowercased marketId → raw oracle numericValue, null where unresolved.
Joins each market's OWN question, so fixed-strike markets are covered too.
Parameters
marketIds
string[]
Returns
Promise<Record<string, string | null>>
getOnchainResolutionPrice()
getOnchainResolutionPrice(
marketId):Promise<OnchainResolutionPrice|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1949
A market's RESOLUTION price read straight from CHAIN — the fallback for a
settled market whose answer the indexer never saw, because its oracle
adapter is not the one whose events the indexer ingests. Resolves the
market's bound adapter through the module, so it works for any adapter.
Null while the question is not final. Carries its own decimals (adapters
differ — do NOT assume a scale).
Parameters
marketId
string
Returns
Promise<OnchainResolutionPrice | null>
getBookTops()
getBookTops(
marketIds):Promise<Record<string,BookTop>>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1959
Batch top of book (best resting bid/ask + mid) for many markets in one round-trip — for list views that want a book-derived price without an N+1 per-pool fan-out. EVERY market kind: spot and perp pool addresses and binary market ids are all valid, and may be mixed in one call. Map of lowercased marketId → BookTop, whose prices are raw and in each market's own terms; empty-book markets are absent.
Parameters
marketIds
string[]
Returns
Promise<Record<string, BookTop>>
listProtocolFees()
listProtocolFees(
opts?):Promise<ProtocolFeeRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1966
Realized protocol-fee records, newest first — filter by recipient /
market / pool / payer, paginate. The per-fill stream behind
getMarketFees's running total.
Parameters
opts?
recipient?
string
market?
string
pool?
string
payer?
string
limit?
number
offset?
number
Returns
Promise<ProtocolFeeRecord[]>
listBuilderFees()
listBuilderFees(
opts?):Promise<BuilderFeeRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1979
Realized builder/routing-fee records, newest first — filter by builder /
market / payer, paginate.
Parameters
opts?
builder?
string
market?
string
payer?
string
limit?
number
offset?
number
Returns
Promise<BuilderFeeRecord[]>
listSettlementFees()
listSettlementFees(
opts?):Promise<SettlementFeeRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:1991
Realized settlement-fee records, newest first — filter by market /
recipient, paginate.
Parameters
opts?
market?
string
recipient?
string
limit?
number
offset?
number
Returns
Promise<SettlementFeeRecord[]>
listBuilderApprovals()
listBuilderApprovals(
opts?):Promise<BuilderApproval[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2003
Builder-approval directory, newest-updated first — filter by user and/or
builder, paginate. The directory complement to the on-chain point read
getBuilderApproval.
Parameters
opts?
user?
string
builder?
string
limit?
number
offset?
number
Returns
Promise<BuilderApproval[]>
getVaultPayoutFallbacks()
getVaultPayoutFallbacks(
owner,opts?):Promise<VaultPayoutFallback[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2015
An owner's vault-credit fallback history (append-only), newest first —
optionally scoped to one token, paginated. The live claimable balance is
the chain read getVaultBalance.
Parameters
owner
string
opts?
token?
string
limit?
number
offset?
number
Returns
Promise<VaultPayoutFallback[]>
getFundingPayments()
getFundingPayments(
account,opts?):Promise<FundingPayment[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2024
An account's funding-payment history, newest first — optionally scoped to
one pool, paginated.
Parameters
account
string
opts?
pool?
string
limit?
number
offset?
number
Returns
Promise<FundingPayment[]>
getMarginEvents()
getMarginEvents(
account,opts?):Promise<MarginEvent[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2033
An account's margin-account movement history (deposits/withdraws/locks), newest first — paginated.
Parameters
account
string
opts?
limit?
number
offset?
number
Returns
Promise<MarginEvent[]>
listLiquidations()
listLiquidations(
opts?):Promise<LiquidationEvent[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2051
Liquidation events, newest first — filter by account, pool and/or kind, paginate.
kind matters more than it looks: the rows are stages of one mechanism, so one
cascade produces many rows and an unfiltered limit is spent mostly on stages the
caller did not ask about. See LiquidationEvent.kind.
The sort is a TOTAL order — timestamp, then blockNumber, then the id primary
key — so the sequence is stable between requests. That fixes tie ordering only: these
are live rows, and an event indexed ahead of your offset still repeats a row while a
reorg that removes one still skips a row. Offset paging here is approximate, not
snapshot-consistent.
Parameters
opts?
Returns
Promise<LiquidationEvent[]>
Throws
IndexerError The indexed read did not complete. The complete union is SomniaMarketsClientListLiquidationsError.
getLiquidations()
getLiquidations(
opts?):Promise<LiquidationEvent[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2062
Liquidation events, newest first.
Parameters
opts?
Returns
Promise<LiquidationEvent[]>
Deprecated
Renamed to listLiquidations, per SDK-TYPE-006. Forwards verbatim.
Throws
IndexerError As SomniaMarketsClient.listLiquidations. The union is SomniaMarketsClientGetLiquidationsError.
listFundingRateHistory()
listFundingRateHistory(
pool,opts?):Promise<FundingRateUpdate[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2076
A perp pool's funding-rate history, newest first by default.
from/to are unix SECONDS and are what a chart should use — settlement is hourly
(24 rows per pool per day, and 288 across the retired 300s cadence still in indexed
history), so paging by offset to reach a date is both slow and fragile. Normalize each
row with its OWN fundingWindowSec.
Pass order: "asc" to make from a forward CURSOR. Under the default "desc" a page
always comes off the newest end, so from = last.timestamp + 1 re-reads the tail
instead of advancing.
Parameters
pool
string
opts?
limit?
number
offset?
number
from?
number | bigint
to?
number | bigint
order?
"desc" | "asc"
Returns
Promise<FundingRateUpdate[]>
listFundingRateCandles()
listFundingRateCandles(
pool,intervalSeconds,opts?):Promise<FundingRateCandle[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2098
A perp pool's funding-rate ROLLUPS at one resolution (3600 | 14400 | 86400), newest first — for ranges the raw series is too dense for.
Buckets can be ABSENT where no settlement's span reached them: zero-fill those grid
slots as { avgFundingRate8h: 0, coverage: 0 } and never carry the previous rate
forward. Past buckets also get REVISED when a catch-up settlement reaches backwards.
Pages NEWEST-first against a default limit of 500, so a month of hourly buckets (720)
silently returns its newest 500 — treat rows.length === limit as truncated.
Parameters
pool
string
intervalSeconds
number
opts?
limit?
number
offset?
number
from?
number | bigint
to?
number | bigint
Returns
Promise<FundingRateCandle[]>
listPerpFees()
listPerpFees(
opts?):Promise<PerpFeeRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2112
Realized perp fees / rebates / builder credits, newest first — the perps fee rail off
MarginBank, distinct from the binary/spot listBuilderFees.
insurancePortion is a component OF amount, not an addition to it: a fee total is
SUM(amount), an insurance inflow is SUM(insurancePortion), and adding the two
double-counts. amount is unsigned — isRebate carries the direction.
Parameters
opts?
account?
string
pool?
string
builder?
string
kind?
string
limit?
number
offset?
number
Returns
Promise<PerpFeeRecord[]>
listPerpOrderRejections()
listPerpOrderRejections(
opts?):Promise<PerpOrderRejection[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2133
Orders refused inside a BATCH placement, newest first.
placeOrders / placeOrdersFor only — the singular entry points revert, and a
revert discards its logs, so a singular placement leaves no row here. Nothing here
has an Order row either: a rejected request never rested and never filled. Map a
row back to what was sent with requestIndex.
reason is the decoded name and is null for a member this SDK version does not know;
reasonRaw always carries the index. The reason FILTER takes the index, so a
caller can select a reason this SDK cannot yet name.
Parameters
opts?
owner?
string
pool?
string
reason?
number
limit?
number
offset?
number
Returns
Promise<PerpOrderRejection[]>
getFundingRateHistory()
getFundingRateHistory(
pool,opts?):Promise<FundingRateUpdate[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2146
Lists funding-rate history through the compatibility alias.
Parameters
pool
string
opts?
limit?
number
offset?
number
from?
number | bigint
to?
number | bigint
Returns
Promise<FundingRateUpdate[]>
Deprecated
Use listFundingRateHistory instead. This alias forwards verbatim.
getOpenInterestHistory()
getOpenInterestHistory(
pool,opts?):Promise<OpenInterestSnapshot[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2152
A perp pool's open-interest history, newest first — paginated.
Parameters
pool
string
opts?
limit?
number
offset?
number
Returns
Promise<OpenInterestSnapshot[]>
listPerpPositions()
listPerpPositions(
account,opts?):Promise<IndexedPerpPosition[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2167
An account's perp positions across every pool, newest-updated first — ONE round-trip, replacing a chain read per market.
A snapshot as of each row's updatedAtBlock, NOT marked to market: unrealized
PnL, liquidation price and margin health all still need a chain read.
entryFundingIndex is not selected — the deployed Hasura schema does not carry
it yet — so anything funding-sensitive belongs on getPerpPosition.
Size-0 (fully closed) rows are excluded unless includeFlat — upserted rows
are never deleted, so closed positions linger forever. An empty array means the
indexer has no rows, not that the account is flat.
Parameters
account
string
opts?
pool?
string
includeFlat?
boolean
limit?
number
offset?
number
Returns
Promise<IndexedPerpPosition[]>
getBinaryOrderBook()
getBinaryOrderBook(
pool,opts?):Promise<BinaryOrderBook>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2194
Read a binary pool's resting book from the contract (getBookLevels,
both sides in one pipelined round-trip), 4-sided like the live variant.
Use when the tail isn't running or as a checksum; in a render/quote path
prefer getLiveBinaryOrderBook.
Details
opts.depth: Price levels per side (default 10).opts.decimals: Price scale decimals for the NO-side inversion (default 6).opts.blockNumber: Pin both sides to this block. Omitted: select one head. Successful empty books retain the pin. This is an exact chain snapshot.
Parameters
pool
`0x${string}`
opts?
Returns
Promise<BinaryOrderBook>
Throws
InvalidInputError If depth or the block pin is invalid.
Throws
NotConfiguredError If the owner has no chain endpoint.
Throws
RpcError If selecting the head or reading either side fails.
Throws
ContractRevertError If the contract rejects either read.
getSpotOrderBook()
getSpotOrderBook(
pool,opts?):Promise<SpotOrderBook>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2211
Read a spot OR perp pool's resting book from the contract (both ride the shared OrderBook base). Live variant: getLiveSpotOrderBook.
Details
opts.depth: Levels per side (default 12).opts.blockNumber: Pin both sides to this block. Omitted: select one head. Successful empty books retain the pin.
Parameters
pool
`0x${string}`
opts?
Returns
Promise<SpotOrderBook>
Throws
InvalidInputError If depth or the block pin is invalid.
Throws
NotConfiguredError If the owner has no chain endpoint.
Throws
RpcError If selecting the head or reading either side fails.
Throws
ContractRevertError If the contract rejects either read.
getOrderOnchain()
getOrderOnchain(
pool,orderId,opts?):Promise<OnchainOrder|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2256
One order's state at chain head, by (pool, orderId) — ids are unique per
pool. Reads your own writes: answers from the block a placement landed in,
while the indexed getOrders may still lag. null when the pool has
no ACTIVE order for that id (never assigned, filled, cancelled, expired-and-swept,
or replaced by an amend, which re-places under a NEW id; a reduceOrder keeps its
id and stays active) - the indexer is the surface that keeps history.
opts.blockNumber reads at the end of that block instead - historical order
state, for a consumer decoding OrderFilled from chain logs. That event carries
the fill's own fillPrice (which IS the maker's resting price), quantityFilled
and makerRemainingQuantity, so take those from the event; what it does not carry
is the maker's SIDE, and the fill removes the maker order in the same transaction,
so the last height holding it is fill.blockNumber - 1n.
That read is exact for the maker's identity - isBid, owner, userData,
expireTimestampNs, none of which any fill log carries - and BLOCK-LEVEL for BOTH
quantities: an earlier transaction in the fill's own block may have filled this
maker, or reduced it (reduceOrder decrements fullQuantity and
quantityRemaining together, under the same id), and no block read sees between
transactions.
Two edges answer plausibly rather than failing: a PARTIAL fill leaves the order
in place with a smaller quantityRemaining, so reading at the fill's own block
succeeds with different numbers; and an order placed and filled inside ONE block
is absent at blockNumber - 1n, so that read is null and the placement has to
come from the same block's OrderPlaced. A pinned read far behind head needs
archive state.
// A fill's side, for a maker this process never saw rest.
const maker = await client.getOrderOnchain(pool, makerOrderId, { blockNumber: fillBlock - 1n });
// `null` is an UNRESOLVED side, not a sell: an order placed and filled inside one
// block has no state one block earlier, and its side is in that block's OrderPlaced.
const takerBought = maker === null ? null : !maker.isBid;
Parameters
pool
`0x${string}`
orderId
bigint
opts?
Returns
Promise<OnchainOrder | null>
Throws
InvalidInputError If opts.blockNumber is negative.
Throws
NotConfiguredError If the owner has no chain endpoint.
Throws
RpcError If the read fails.
Throws
ContractRevertError If the contract rejects the read for any reason other than the id having no active order.
getBookTopsOnchain()
getBookTopsOnchain(
markets,opts?):Promise<BookTopsOnchain>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2278
Top of book for many markets, read from POOL STATE at ONE pinned block — the chain-sourced sibling of getBookTops.
Prefer this wherever a quote must not lag: a board, a selector, a mark for open positions. getBookTops stays the cheaper read (one indexed round-trip, no chain dependency) for an unbounded list that tolerates indexer lag.
Pass the market rows a view already holds — each supplies its own
poolAddress, so nothing is resolved twice. tops is keyed by lowercased
market id and omits empty-book markets, exactly as getBookTops
does, so the two are comparable key for key. Cost is two reads per market
where the chain declares no Multicall3; keep the set to what a view shows.
Parameters
markets
object[]
opts?
Returns
Promise<BookTopsOnchain>
Throws
InvalidInputError If opts.blockNumber is negative.
Throws
NotConfiguredError If the owner has no chain endpoint.
Throws
RpcError If the read fails.
Throws
ContractRevertError If a pool rejects the read.
getOwnOpenOrdersOnchain()
getOwnOpenOrdersOnchain(
pool,owner):Promise<bigint[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2289
An owner's open order ids at chain head. Any address may be asked about —
the pool's view reads msg.sender and this impersonates via the eth_call
sender, so no signer is involved. Indexed counterpart, with human units and
history: getOpenOrders.
Parameters
pool
`0x${string}`
owner
`0x${string}`
Returns
Promise<bigint[]>
getAllOpenOrdersOnchain()
getAllOpenOrdersOnchain(
pool,opts):Promise<{orders:OnchainOrder[];hasMore:boolean;nextCursor:bigint; }>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2308
One page of every open order on one side, at chain head — the per-order
detail the aggregated book reads (getBinaryOrderBook,
getSpotOrderBook) collapse into levels. The pool accepts this view
only from the zero address, so a configured signer is never forwarded. Loop
while hasMore, feeding nextCursor back as cursor; pin a block if pages
must be mutually consistent.
Details
opts.maxCount: Orders per page (default 100).opts.blockNumber: Read at that exact block instead of the current head, so every page of a multi-page snapshot sees one book. Sample a head withgetBlockNumberand pass it to every page.
Parameters
pool
`0x${string}`
opts
isBid
boolean
maxCount?
number
cursor?
bigint
blockNumber?
bigint
Returns
Promise<{ orders: OnchainOrder[]; hasMore: boolean; nextCursor: bigint; }>
Throws
InvalidInputError If opts.blockNumber is negative.
getPerpState()
getPerpState(
pool):Promise<PerpStateOnchain>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2318
A perp pool's live mark/index price, funding rate + cumulative index, and open interest in one pipelined fan-out — fresher than the indexed row (which only updates on funding settlements).
Parameters
pool
`0x${string}`
Returns
Promise<PerpStateOnchain>
getPerpFeedStatus()
getPerpFeedStatus(
pool):Promise<PerpFeedStatus>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2343
Is a perp pool's mark feed live, and how much open interest is riding on it — the pair a mark-feed monitor needs, with the index timestamp as best-effort corroboration.
Prefer this to getPerpState for MONITORING a feed. That read is
all-or-nothing and one of its legs is a bare IOracle.getPrice(), so a dead oracle
rejects the whole call and the mark verdict is lost in exactly the case it is wanted.
Here the verdict cannot be taken down by the oracle: tryGetMarkPrice reports
staleness rather than reverting, open interest consults no oracle, and only the index
timestamp — which arrives undefined instead — is allowed to fail.
Read getPerpState instead when you want the full pricing and funding picture and a dead oracle is a legitimate reason to fail the call.
Parameters
pool
`0x${string}`
Returns
Promise<PerpFeedStatus>
Throws
NotConfiguredError No WebSocket endpoint is configured — wsRpcUrl,
or a chain whose rpcUrls carry one. Raised when this read resolves its client,
before any request goes out.
Throws
RpcError A chain read did not complete — the block pin included.
Throws
ContractRevertError The pool rejected the mark or open-interest read.
A reverting INDEX read is NOT among these: it is swallowed by design and surfaces as
an absent indexUpdatedAt. The complete union is
SomniaMarketsClientGetPerpFeedStatusError.
getPerpFundingPremium()
getPerpFundingPremium(
pool):Promise<PerpFundingPremium>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2358
A perp pool's funding-premium state: what the next settlement will charge, the standing instantaneous sample, and the raw accumulator behind them.
Separate from getPerpState on purpose —
these getters arrived with Wave 28 and do not exist on an older pool implementation,
and getPerpState batches with allowFailure: false, so folding them in would let
one un-upgraded pool take a core read down.
Read timeWeightedPremium for a predicted funding rate, never lastObservedPremium
— the contract getter behind the latter kept its signature and changed its meaning.
Check armed before calling the figure an average.
Parameters
pool
`0x${string}`
Returns
Promise<PerpFundingPremium>
getPerpPosition()
getPerpPosition(
ref):Promise<PerpPosition>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2364
An account's position in one perp pool, from the MarginBank (signed size:
positive = long). ref.marginBank comes off the PerpMarket row.
Parameters
ref
Returns
Promise<PerpPosition>
getMarginAccount()
getMarginAccount(
marginBank,account):Promise<MarginAccount>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2373
An account's cross-margin state (free/locked collateral, equity,
withdrawable, active pools) from the MarginBank — now including the account
health (imReq/mmReq/cmReq) and marginStatus. The client samples the
chain head once and pins every component read to that block, so all fields
describe one chain state.
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<MarginAccount>
getAccountHealth()
getAccountHealth(
marginBank,account):Promise<AccountHealth>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2380
An account's cross-margin health alone (equity vs IM/MM/CM + the derived status) — a lighter read than getMarginAccount when only health matters. The health tuple and status are pinned to one sampled chain block.
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<AccountHealth>
getLiquidationPrice()
getLiquidationPrice(
ref):Promise<bigint|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2392
Estimated liquidation price for an account's position in one perp pool (raw
quote units per whole base), or null when flat. Solves equity == mmReq with
BOTH sides moving against the mark — see perpLiquidationPrice — over the
cross-margin equity/mmReq, so it is the price at which this pool's move alone
trips maintenance. Throws on a stale mark anywhere in the account.
This is where liquidation triggers. For the contract's own figure of where a position's equity is exhausted, see getBankruptcyPrice.
Parameters
ref
Returns
Promise<bigint | null>
getPerpLeverage()
getPerpLeverage(
ref):Promise<PerpLeverage>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2407
An account's realized leverage at one position and across the whole cross-margin account, plus every ceiling that bounds it — the market's IMF-implied max, the account's own cap, the protocol limit, and the credit-voucher confinement. Ratios are bps of 1x.
Derived, not read: the MarginBank exposes only leverage caps, never a measurement of a position.
The ceilings are returned as stored and do not compose by taking a minimum — see
PerpLeverage.voucherLeverageCapX. For whether a specific order passes,
use previewPerpOrderMargin.
Parameters
ref
Returns
Promise<PerpLeverage>
getPerpPositionAnalytics()
getPerpPositionAnalytics(
ref):Promise<PerpPositionAnalytics>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2423
One position, marked — unrealized PnL, accrued funding, notional, the three margin requirements it contributes, and its return on margin. Two reads, pinned to one block.
The split getAccountHealth cannot give you: that returns one equity figure for
the whole account, with every market's PnL and funding already summed and netted,
so a two-position trader cannot see which one carries the loss and cannot see
funding at all.
accruedFunding is owed — positive means the account pays. Returns
{ priceable: false } on a stale mark rather than throwing, because in a
positions table one dead feed must degrade one row, not the page.
Parameters
ref
Returns
Promise<PerpPositionAnalytics>
listPerpPositionAnalytics()
listPerpPositionAnalytics(
p):Promise<PerpPositionAnalytics[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2436
Every position the account holds, each marked — the positions-table read.
1 + 2n reads for n active markets, all pinned to ONE block, which is the
point of having it rather than looping the single read: unpinned, the rows come
from different heights and their equityContributions do not re-sum to any
equity the account ever had.
Scoped to the bank's own activePerpPools, so a closed position does not linger
the way it does on the indexed rows.
Parameters
p
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<PerpPositionAnalytics[]>
getMaxPerpOrderSize()
getMaxPerpOrderSize(
p):Promise<PerpMaxOrderSize>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2457
The largest order this account can place at price — what a Max button should
call. The inverse of previewPerpOrderMargin, and the protocol has no such view.
Does not re-derive the sizing rule: it binary-searches the forward one, so the two
cannot disagree. A hand-rolled equity / (price × imf) drops the adverse
mark-to-entry term, which is the usual reason a "max" order is rejected.
maxQuantity is aligned down to the pool's lot grid. Check placeable — a
size below the pool's minQuantity is a revert, not a small order. limitedBy
says which gate bound it. Market-wide maxOpenInterest and book depth are
deliberately not modelled.
Pass autoPull when the transaction sender will be the order owner. That is
the pool's whole gate for topping the account up from its wallet (T70), and with it
on, an account with an empty bank and a funded, approved wallet goes from a max of
0n to whatever the wallet funds. Leave it off for placeOrderFor, an operator
grant or the stop registry, where no pull happens.
Parameters
p
pool
`0x${string}`
marginBank
`0x${string}`
account
`0x${string}`
isBid
boolean
price
bigint
autoPull?
boolean
builderFeeBpsTimes1k?
bigint
Returns
Promise<PerpMaxOrderSize>
previewPerpClosePnl()
previewPerpClosePnl(
p):Promise<PerpClosePreview>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2480
What closing a position — all of it or part — would actually realise. Backs a close modal.
Two things it gets right that a hand-derived figure usually does not, both silent:
the close is aligned down to the lot grid first, so a "close all" on a position
that is not a lot multiple leaves a remainder open; and funding settles on the
whole position rather than the closed share, because settleTrade settles
before it touches the position.
netProceeds is the number to show — realizedPnl − fundingSettled − fee.
fundingSettled is positive when the account pays.
Parameters
p
pool
`0x${string}`
marginBank
`0x${string}`
account
`0x${string}`
quantity?
bigint
price?
bigint
asMaker?
boolean
Returns
Promise<PerpClosePreview>
previewPerpLiquidationPrice()
previewPerpLiquidationPrice(
p):Promise<PerpLiquidationPreview>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2499
Where a proposed order would leave the liquidation price if it filled in full at its limit price, alongside where it sits now — the projection an order form needs, which getLiquidationPrice cannot give for an order not yet placed.
Ports all four of MarginBank.settleTrade's cases (open / increase / reduce /
flip) and charges the fill's fee, so a reduce and an add move the answer in
opposite directions. Whether the order is ACCEPTED is
previewPerpOrderMargin's question, not this one.
Parameters
p
pool
`0x${string}`
marginBank
`0x${string}`
account
`0x${string}`
isBid
boolean
quantity
bigint
price
bigint
asMaker?
boolean
Returns
Promise<PerpLiquidationPreview>
getPerpSideHolders()
getPerpSideHolders(
ref,opts?):Promise<PerpSideHolders>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2531
Every account holding an open position on one side of one perp market, from the MarginBank's own per-(pool, side) holder array — the read that lets a liquidation keeper find its watch set from head state alone, no off-chain indexer.
Chain tier. Pages through the bank's bounded slice view (many holders per
round-trip, never one call per holder), with every page pinned to ONE block
— opts.blockNumber, or the head sampled once — so a holder entering or
leaving mid-walk can neither be missed nor double-counted. The result
carries asOfBlock; feed it into getBankruptcyPrice's
opts.blockNumber (and the other side's call) to keep a sweep on one
consistent snapshot — the other position/health reads answer at head only.
The indexed counterpart, listPerpPositions, answers the inverse question (one account's positions across pools) and lags head.
Details
opts.blockNumber: pin to this block instead of the current headopts.pageSize: holders per contract call (default 1000)
Parameters
ref
opts?
Returns
Promise<PerpSideHolders>
getBankruptcyPrice()
getBankruptcyPrice(
ref,opts?):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2552
The MarginBank's OWN bankruptcy price for an account's position in one perp pool (raw quote units per whole base) — the contract-computed price at which the position's allocated equity is exhausted. What a liquidation keeper prices a bankrupt position against.
A different quantity from getLiquidationPrice, not a better version of it: that is the SDK's client-side estimate of where liquidation triggers (use it for UI/monitoring); this is the contract's figure for where there is nothing left (use it for anything that settles or bids).
Reverts rather than returning a sentinel — a ContractRevertError
with errorName: "NoOpenPosition" when the account is flat in that pool
(branch on errorName, never message text).
Details
opts.blockNumber: read at this block instead of head. Pricing an enumerated holder? Pass the enumeration'sasOfBlock— at head, a holder that closed after the snapshot revertsNoOpenPosition.
Parameters
ref
opts?
Returns
Promise<bigint>
getPerpSystemConfig()
getPerpSystemConfig(
marginBank):Promise<PerpSystemConfig>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2567
How the perps stack is wired — the address book for every other contract in the
plane (collateral token, pool factory, liquidation engine, insurance fund, fee
recipient), plus the protocol-wide leverage ceiling and a fullyWired flag.
Read this first: the addresses here are what the other protocol-state reads should be pointed at, so nothing is hardcoded per chain, and they are the bank's own view — the addresses it will actually call.
liquidationEngine is the PROXY. An implementation address answers reads with
unset defaults (zero bidders, zero penalty), which looks like a configured-but-idle
engine rather than the wrong address.
Parameters
marginBank
`0x${string}`
Returns
Promise<PerpSystemConfig>
getInsuranceFundState()
getInsuranceFundState(
fund):Promise<InsuranceFundState>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2573
The InsuranceFund's per-tier balances and the total bad debt it can absorb.
Point it at insuranceFund from getPerpSystemConfig.
Parameters
fund
`0x${string}`
Returns
Promise<InsuranceFundState>
listPerpInsuranceFundEvents()
listPerpInsuranceFundEvents(
opts?):Promise<PerpInsuranceFundEvent[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2584
The InsuranceFund's tier ledger, newest first — how each tier reached the balance getInsuranceFundState reports. Indexer tier; the chain keeps no history.
Do not sum amount bare. It is populated on inflows, outflows and the internal
TierAllocated move alike, so a plain total is turnover rather than a balance — fold
it by kind. covered on a BadDebtAuthorised row restates the TierDebited rows
beside it, and TierCredited restates the fee plane's insurancePortion.
Parameters
opts?
kind?
string
tier?
number | bigint
account?
string
limit?
number
offset?
number
Returns
Promise<PerpInsuranceFundEvent[]>
getLiquidationEngineConfig()
getLiquidationEngineConfig(
engine):Promise<LiquidationEngineConfig>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2601
The LiquidationEngine's configured bounds — penalty, spread range, per-block
volume cap, registered backstop bidders. Not its history, which is indexed as
LiquidationEvent.
bidderCount === 0n is an operational signal: with no registered bidders the
takeover stage has nobody to take a position over, so the waterfall reaches ADL
sooner than the configuration implies.
Parameters
engine
`0x${string}`
Returns
Promise<LiquidationEngineConfig>
tryGetPerpAccountEquity()
tryGetPerpAccountEquity(
marginBank,account):Promise<bigint|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2610
An account's equity, or null when it could not be computed.
getAccountHealth propagates an oracle failure, which is exactly when a health sweep most needs an answer. Null means "not computable right now" — an unpriceable market in the account's set — never "zero equity".
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<bigint | null>
getPerpCollateralBasis()
getPerpCollateralBasis(
marginBank,account):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2619
Collateral BACKING an account: max(0, unlocked + locked), raw units.
Deliberately unlike equity — one storage pair, no market walk, no oracle, and it cannot revert. A solvency floor that survives a dead price feed; use equity when you need mark-to-market truth.
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<bigint>
listPerpPoolStatuses()
listPerpPoolStatuses(
p):Promise<PerpPoolStatus[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2642
Every perp market the factory has deployed, in deployment order, with the two
independent gates that decide whether it is tradeable: restricted
(close-only) and registered (activated on the MarginBank).
Do not build a market list from the factory's raw pool list — that is the deployment history and includes markets wound down to close-only, so listing it unfiltered presents dead markets as tradeable.
Chain-sourced, which makes it complete and available when the indexer is not: the indexer's perp set comes from a curated manifest, so a market deployed after that manifest was written is invisible there and present here.
You do not pass a MarginBank. It is a per-network singleton in practice, but each pool names its own and that is the bank its settlement path uses — so it is read per pool and returned on every row, ready for the getMarginAccount / getPerpPosition reads that follow.
Feature-detects the factory's one-call status view and falls back to a per-pool fan-out on a factory that predates it, returning the same shape either way.
Parameters
p
factory
`0x${string}`
Returns
Promise<PerpPoolStatus[]>
listTradeablePerpPools()
listTradeablePerpPools(
p):Promise<`0x${string}`[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2645
Just the tradeable perp pools, filtered from listPerpPoolStatuses.
Parameters
p
factory
`0x${string}`
Returns
Promise<`0x${string}`[]>
readPerpMarketFromChain()
readPerpMarketFromChain(
p):Promise<PerpMarket>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2661
One factory-deployed perp market as a native PerpMarket row, read entirely from the chain — for a market the indexer does not carry.
Chain tier. Reads the pool's book grid and margin factor, the base token's symbol and decimals, and the pool's stop registry from the factory. History-derived fields come back as documented placeholders, because no chain read can supply them — see UnifiedMarket.indexed for which ones and what they mean.
Gotchas
- Throws RpcError when a read cannot be completed, and ContractRevertError when the pool or token rejects one. The grid, the margin factor and the decimals have no safe fallback, so an unreadable pool fails rather than producing a mis-scaled market. Two reads degrade instead: a token exposing no
symbol()yieldsbaseSymbol: null, and a factory predatingIPerpPoolFactoryStopRegistryyieldsstopRegistry: null.
Parameters
p
status
collateralToken
`0x${string}`
collateralDecimals
number
collateralSymbol
string | null
factory
`0x${string}`
Returns
Promise<PerpMarket>
isPerpPoolRegistered()
isPerpPoolRegistered(
p):Promise<boolean>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2678
Whether the MarginBank has one perp pool registered — the activation gate on its own. Coming from the factory only proves a pool is authentic; registration is what makes it usable.
Not interchangeable with getPoolTier, which is itself gated on registration
and so returns 0 for an uncovered-but-registered market and an unregistered one
alike.
Parameters
p
marginBank
`0x${string}`
pool
`0x${string}`
Returns
Promise<boolean>
previewPerpOrderMargin()
previewPerpOrderMargin(
p):Promise<PerpOrderMarginPreview>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2727
What a perp order will lock and whether the pool will accept it, computed BEFORE sending — the read behind an order form's "margin required" row and submit gate.
Ports PerpPool._computeLockAmount plus the MarginBank gate it feeds, so the
number shown is the number actually reserved.
Why not a contract pre-check. quoteMeetsIMForOrder looks right and is not:
it runs with the order's base margin treated as already reserved, because on the
real path the lock has run first. Called cold it counts the order's margin
nowhere and returns true for almost any size. meetsIMForFill does charge base
margin but models neither the lock nor its adverse mark-to-entry reserve — the
term that rejects a naively-sized "max" order.
Reports two gates separately, because they fail for different reasons and
imply different fixes: hasCollateralForLock (the lock can be taken at all) vs
meetsInitialMargin (what remains still covers the requirement) — "deposit
more" vs "close something".
Every read is pinned to one block; a preview is a statement about that block, so re-quote near send time for anything close to the edge.
Pass autoPull when the transaction sender will be the order owner — the pool's
whole gate for topping the account up from its wallet (T70). With it on, both gates
describe the post-pull balance. Off, they describe the in-bank balance alone, which
is what an operator- or registry-routed placement actually faces.
topUpRequired is the total the pull REQUESTS, not one wallet's debit: a linked
child is funded by its own wallet first and its main for the residual, so show
ownWalletPull and mainWalletPull beside the margin figure and read
fundingPayer for whose wallet the second one is. Only mainWalletPull > 0n proves
another wallet actually moves.
Parameters
p
pool
`0x${string}`
marginBank
`0x${string}`
account
`0x${string}`
isBid
boolean
quantity
bigint
price
bigint
autoPull?
boolean
builderFeeBpsTimes1k?
bigint
Returns
Promise<PerpOrderMarginPreview>
meetsPerpImForFill()
meetsPerpImForFill(
p):Promise<boolean>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2746
The MarginBank's initial-margin probe for an order not yet locked — the closest single contract call to a pre-trade gate. Charges the increasing leg's base margin against free equity, but does not model the lock's adverse mark-to-entry reserve; previewPerpOrderMargin is the accurate gate.
additionalSize is the INCREASING quantity, not necessarily the whole order.
Parameters
p
marginBank
`0x${string}`
account
`0x${string}`
pool
`0x${string}`
additionalSize
bigint
price
bigint
Returns
Promise<boolean>
quoteMeetsPerpImForOrder()
quoteMeetsPerpImForOrder(
p):Promise<boolean>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2763
The MarginBank's placement-time initial-margin check, verbatim.
Not a pre-trade gate, despite the name — it treats the order's base margin as already reserved, so called cold it answers true for almost any size. Correct only for a caller that has already taken the lock, i.e. for mirroring the placement check itself. For "will my order be accepted", use previewPerpOrderMargin.
Parameters
p
marginBank
`0x${string}`
account
`0x${string}`
pool
`0x${string}`
additionalSize
bigint
price
bigint
Returns
Promise<boolean>
quotePerpOrderTopUp()
quotePerpOrderTopUp(
p):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2785
The MarginBank's auto-pull sizing, verbatim — how much placing an order would take from the owner's wallet.
For an order form use previewPerpOrderMargin with autoPull instead. It
derives lockAmount, feeHeadroom and increasingQuantity from the order, which
is the awkward part: they come from the POOL, not the bank, so calling this directly
means reproducing the same three numbers the pool would pass. This is the
cross-check on that port.
Returns 0n both when no pull is needed and in the three cases where a pull would
be wrong rather than unnecessary — a purely reducing order, an account already in
debt, and a voucher-blocked increase — so read it beside the unlocked balance.
Parameters
p
marginBank
`0x${string}`
pool
`0x${string}`
account
`0x${string}`
lockAmount
bigint
feeHeadroom
bigint
increasingQuantity
bigint
price
bigint
Returns
Promise<bigint>
getPerpLeverageImSurcharge()
getPerpLeverageImSurcharge(
marginBank,account):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2810
The EXTRA initial margin an account's own leverage settings demand, summed over every market where it BOTH holds a position AND has set a stricter-than-market cap.
This explains an InsufficientMarginForOrder that quotePerpOrderTopUp
cannot. The two measure different things: the quote funds one order against the
UNLOCKED balance, while the admission gate measures whole-account EQUITY — so an
order can be fully funded on its own market and still be refused because of an
override on a different one. Deposit this deliberately rather than expecting a
pull to cover it.
Reverts if a market that is both positioned and overridden is unpriceable; use tryGetPerpLeverageImSurcharge in a sweep.
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<bigint>
tryGetPerpLeverageImSurcharge()
tryGetPerpLeverageImSurcharge(
marginBank,account):Promise<bigint|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2824
getPerpLeverageImSurcharge without the revert — null when it could not
be computed.
null means "not computable right now", never "no surcharge". Substituting 0n
would under-state the requirement, which is the wrong direction to be wrong in.
Only a revert from the view itself becomes null. A read that never reached
the chain throws, and so does an address that does not declare the view.
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<bigint | null>
Throws
RpcError The chain read did not complete, or marginBank does not declare the view.
getPerpMaxLeverage()
getPerpMaxLeverage(
ref,opts?):Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2845
One account's own leverage cap for one perp pool, as the MarginBank stores it —
the cheap path to the number getPerpLeverage reports as
accountMaxLeverageX.
Chain tier, exactly one storage read. Unlike getPerpLeverage it does NOT walk the account, so a stale mark on some other market cannot take it down — the cap is a setting, not a measurement, and never needed a price. Use it for a per-position badge or a leverage dialog; use getPerpLeverage when the question is realized account-wide leverage.
0 means "no account cap set", never zero leverage — the market ceiling binds
then. Returned unchanged for the caller to compose.
Details
ref: the (bank, account, pool) tripleopts.blockNumber: read at this block instead of head. Combining the cap with an enumeration's or analytics row's figures? Pass that row'sasOfBlockso both describe one moment.
Parameters
ref
opts?
Returns
Promise<number>
getPerpLinkedWalletRegistry()
getPerpLinkedWalletRegistry(
marginBank):Promise<`0x${string}`|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2855
The registry the bank resolves wallet links through, or null while the
linked-wallet funding rail is DORMANT.
Read it from the bank rather than a deployment manifest: the bank decides which
registry is authoritative, and a registry nobody has armed is inert. null means
no child can draw on any main on this deployment.
Parameters
marginBank
`0x${string}`
Returns
Promise<`0x${string}` | null>
quotePerpFundingPayer()
quotePerpFundingPayer(
marginBank,account):Promise<PerpFundingPayer>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2865
Whether this account's next position-increasing order would spend a main's wallet, and whose.
A discriminated union, because the contract's single zero collapses three cases a
UI must not render alike: the rail is dormant, the wallet is unlinked, or the
wallet IS a main. Only unlinked is the user's to fix.
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<PerpFundingPayer>
getPerpMainFunding()
getPerpMainFunding(
marginBank,account):Promise<PerpMainFunding>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2875
Principal a main has funded into this account and not recovered, plus the payer recorded at funding time.
What a main funds can be borrowed, never withdrawn — withdraw frees at most
balance - principal. The payer is SNAPSHOTTED, so it is who gets repaid even if
the link has since changed.
Parameters
marginBank
`0x${string}`
account
`0x${string}`
Returns
Promise<PerpMainFunding>
getPerpWalletPullCapacity()
getPerpWalletPullCapacity(
marginBank,wallet):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2884
What a wallet could contribute to a pull right now — min(balance, allowance).
On a MAIN this is the ceiling on what its children can collectively draw, and the number to reduce to revoke the rail without unlinking (consent is the allowance). On a CHILD it is how much of its own money it burns before reaching its main's.
Parameters
marginBank
`0x${string}`
wallet
`0x${string}`
Returns
Promise<bigint>
getPerpWalletLinkage()
getPerpWalletLinkage(
registry,wallet):Promise<PerpWalletLinkage>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2894
A wallet's link group and its ADL-netting maturity.
Takes the REGISTRY address — resolve it with
getPerpLinkedWalletRegistry so a dormant deployment reads as dormant
rather than as an empty group. maturesAt gates ADL netting only: the funding
rail reads the raw graph, so a link can be fundable and not yet mature.
Parameters
registry
`0x${string}`
wallet
`0x${string}`
Returns
Promise<PerpWalletLinkage>
listPerpLinkedChildren()
listPerpLinkedChildren(
registry,main):Promise<readonly`0x${string}`[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2900
Every child of a main, excluding the main — the isolated buckets one treasury currently serves.
Parameters
registry
`0x${string}`
main
`0x${string}`
Returns
Promise<readonly `0x${string}`[]>
getPerpMaxLinkedChildren()
getPerpMaxLinkedChildren(
registry):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2906
How many children one main may hold. Owner-tunable, so read it before offering to link another wallet rather than hardcoding the cap.
Parameters
registry
`0x${string}`
Returns
Promise<bigint>
listPerpWalletLinkEvents()
listPerpWalletLinkEvents(
opts?):Promise<PerpWalletLinkEvent[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2917
The linked-wallet consent graph over time, newest first.
The only way to see a PENDING proposal — the registry exposes no getter for one,
so a Proposed row with no later row for the same pair is an offer still standing.
Consent is not authority: a Linked row grants no power over funds by itself. Ask
quotePerpFundingPayer whether an order would actually spend a main's wallet.
Parameters
opts?
main?
string
child?
string
kind?
string
limit?
number
offset?
number
Returns
Promise<PerpWalletLinkEvent[]>
listPerpMarginPulls()
listPerpMarginPulls(
opts?):Promise<PerpMarginPull[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2936
Margin pulled to fund placements, newest first — the POOL side of the rail, and the side that names an ORDER.
One placement can produce TWO rows: source: "OwnWallet" for what the owner's own
wallet covered, then source: "Main" for the residual drawn from their linked main.
amount is what that leg pulled, not the order's total requirement.
Never sum these with listPerpMainFundingEvents — one pull emits a row on each side for the same wei.
Parameters
opts?
account?
string
pool?
string
orderId?
string
source?
string
limit?
number
offset?
number
Returns
Promise<PerpMarginPull[]>
listPerpMainFundingEvents()
listPerpMainFundingEvents(
opts?):Promise<PerpMainFundingEvent[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2955
A main's claim against a child over time, newest first — the BANK side of the rail, carrying the running principal. The live claim is getPerpMainFunding.
amount is null on Settled and that is not missing data: the child's own losses
discharged part of the claim, so no cash moved while outstandingPrincipal still
fell.
Never sum these with listPerpMarginPulls — same wei, two sides.
Parameters
opts?
account?
string
payer?
string
kind?
string
limit?
number
offset?
number
Returns
Promise<PerpMainFundingEvent[]>
getPerpRiskParams()
getPerpRiskParams(
pool):Promise<PerpRiskParams>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2963
Parameters
pool
`0x${string}`
Returns
Promise<PerpRiskParams>
getPerpHealthSnapshot()
getPerpHealthSnapshot(
pool):Promise<PerpHealthSnapshot>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2976
A perp market's live health inputs in one call — mark price, projected cumulative funding, the effective (OI-scaled) IMF, and the maintenance / close-out thresholds. The contract exposes this precisely so a cross-margin health walk reads a market once instead of making five getter calls.
Returns a discriminated union: an unpriceable market (stale or zero mark)
arrives as { priceable: false } rather than an all-zero struct, so a
maintenanceMarginBps of 0 cannot be mistaken for "no maintenance
requirement". Narrow on priceable before reading any field.
Parameters
pool
`0x${string}`
Returns
Promise<PerpHealthSnapshot>
getEffectiveImfBps()
getEffectiveImfBps(
pool):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:2988
The initial-margin factor a perp market is charging right now, in bps — OI-scaled when dynamic IMF is enabled, otherwise the static base.
Sizing an order off initialMarginBps instead under-margins it whenever open
interest has pushed the curve above its floor, and the pool rejects an order
the client believed fit. Reverts if dynamic IMF is on and the index is stale.
getPerpHealthSnapshot returns this alongside the rest for one
round-trip.
Parameters
pool
`0x${string}`
Returns
Promise<bigint>
getVaultBalance()
getVaultBalance(
p):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3005
Claimable balance an owner can withdraw from a pool's internal ERC20Vault for
token, raw units — the value behind the append-only
getVaultPayoutFallbacks history.
Reads at chain head. Pass blockNumber to pin it, which is what an answer
combining this with other reads at one height needs: the balance is contract
state behind an append-only payout history, so no indexed entity reconstructs
it at a past height. A pinned read far behind head needs archive state.
const owed = await client.getVaultBalance({ vault: pool, owner, token: quote });
const owedAt = await client.getVaultBalance({ vault: pool, owner, token: quote, blockNumber: 1_234n });
Parameters
p
Returns
Promise<bigint>
getManualVaultMode()
getManualVaultMode(
p):Promise<boolean>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3012
Whether user has opted out of wallet auto-pull on this SpotPool, at chain
head — see trader.setManualVaultMode. True means their orders draw only on
pre-deposited vault balance and their payouts stay as vault credit.
Parameters
p
Returns
Promise<boolean>
getAutoPullRequirement()
getAutoPullRequirement(
p):Promise<AutoPullRequirement>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3020
What an order of this shape would consume from owner, and how far short
their vault balance falls (delta) — the pool's own worst-case funding
envelope. In auto-pull mode delta is what the wallet gets pulled for; under
manual vault mode it is what must be deposited first.
Parameters
p
Returns
Promise<AutoPullRequirement>
isOperatorAuthorized()
isOperatorAuthorized(
p):Promise<boolean>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3027
Whether owner authorized operator for selector on this SpotPool, at
chain head — resolved through the pool's OperatorPermissionsRegistry, so no
indexer lag.
Parameters
p
Returns
Promise<boolean>
isGloballyApproved()
isGloballyApproved(
p):Promise<boolean>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3037
Whether a GLOBAL operator grant is on record for this owner/operator/selector,
at chain head — the raw slot trader.setOperatorApprovalGlobal writes.
Independent of pool registration and of denials, so true here does not mean
the operator can act on a given pool. For that, use
isOperatorAuthorized.
Parameters
p
Returns
Promise<boolean>
isApprovedForPool()
isApprovedForPool(
p):Promise<boolean>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3046
Whether a PER-POOL operator grant is on record, at chain head — the read-back
for trader.setOperatorApprovalForPool.
Ignores any global grant and any denial. For the pool's resolved decision, use isOperatorAuthorized.
Parameters
p
Returns
Promise<boolean>
getOperatorPermissionsRegistry()
getOperatorPermissionsRegistry(
pool):Promise<`0x${string}`|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3070
The OperatorPermissionsRegistry this SpotPool gates operator calls through, at
chain head — or null when the pool is unwired and denies every operator call.
Discovery for a caller with no addresses.operatorPermissionsRegistry
configured: the grant writes and the two grant reads need that address and
otherwise throw NotConfiguredError, and no deployment manifest carries
the key yet. A configured address still wins where it is used — this read adds a
path, it does not redirect one.
The pool is the authority: its own gate consults this registry and no other, so a grant written elsewhere admits nobody here.
Failures. This read needs no address of its own, but it does need chain access,
and every chain client is resolved lazily on first use — so it throws
NotConfiguredError when neither wsRpcUrl nor the chain definition's own
WebSocket endpoint exists. It throws ContractRevertError when the pool
rejects the call, and RpcError when the read gets no answer — which is
also what an EOA or any non-pool address produces, because an empty return is
classified as a failed read rather than as a revert. null is an answer, never a
failure.
Parameters
pool
`0x${string}`
Returns
Promise<`0x${string}` | null>
getOwnLockedBalance()
getOwnLockedBalance(
p):Promise<LockedBalance>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3076
Base/quote owner has locked in this pool's resting orders. Pair with
getVaultBalance to account for everything the pool holds for them.
Parameters
p
pool
`0x${string}`
owner
`0x${string}`
Returns
Promise<LockedBalance>
getLockedTokenBreakdown()
getLockedTokenBreakdown(
pool):Promise<LockedTokenBreakdown>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3082
How the pool's reserves of each token split between resting orders and leftover — venue-health introspection, not a portfolio read.
Parameters
pool
`0x${string}`
Returns
Promise<LockedTokenBreakdown>
convertToQuoteAtPriceCeil()
convertToQuoteAtPriceCeil(
p):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3088
Base→quote at a price using the pool's OWN ceil rounding — for interpreting getLockedTokenBreakdown without reimplementing it.
Parameters
p
pool
`0x${string}`
baseQuantity
bigint
price
bigint
Returns
Promise<bigint>
getMarketOnchain()
getMarketOnchain(
marketId):Promise<MarketOnchain>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3101
A binary market's full wiring + state (tokens, pool + nonce, status, expiry, resolution, finalized, decimals) straight from chain — authoritative for write eligibility, and works before the indexer has seen the market.
BREAKING (0.13.0): takes the bytes32 marketId (resolved through the
BinaryMarketsModule), NOT the BinaryMarket contract address — pools are
recycled across successive markets in v2, so market identity is the module
id. Post-finalize, backing falls back to the settlement record's net
backing. Requires addresses.binaryModule in the config.
Parameters
marketId
`0x${string}`
Returns
Promise<MarketOnchain>
getPoolCreator()
getPoolCreator(
pool):Promise<`0x${string}`>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3109
A pool's creator — its first-deploy market creator, the only party that
can reuse it — straight from chain (BinaryMarketsModule.poolCreator).
Zero address for a pool the module never deployed. No signer needed;
requires addresses.binaryModule.
Parameters
pool
`0x${string}`
Returns
Promise<`0x${string}`>
getFreePools()
getFreePools(
creator,collateral):Promise<`0x${string}`[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3117
A creator's free (finalized + released, reusable) pools for collateral,
LIFO order (the LAST entry is popped first on the creator's next
createMarket), straight from chain (BinaryMarketsModule.getFreePools).
No signer needed; requires addresses.binaryModule.
Parameters
creator
`0x${string}`
collateral
`0x${string}`
Returns
Promise<`0x${string}`[]>
getPoolBindings()
getPoolBindings(
pool):Promise<PoolBindingRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3126
A pool's full pool→market binding history from the indexer, newest
(highest nonce) first — every market the pool has served. A row with
toBlock === null is the pool's CURRENT binding; closedBy says whether
a past binding ended by PoolReleased ("Released") or by the next
MarketCreated recycling the pool onward ("Rotated").
Parameters
pool
string
Returns
Promise<PoolBindingRecord[]>
getPool()
getPool(
address):Promise<IndexedPool|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3133
The indexer's per-pool aggregate (creator, collateral, current binding,
generation count) for a long-lived, recycled BinaryPool — null if the
indexer has never seen a MarketCreated on that address.
Parameters
address
string
Returns
Promise<IndexedPool | null>
getErc20Balance()
getErc20Balance(
token,account):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3139
ERC-20 balanceOf(account), raw units. For outcome positions use
getOutcomeBalance (ERC-6909), not this.
Parameters
token
`0x${string}`
account
`0x${string}`
Returns
Promise<bigint>
getErc20Metadata()
getErc20Metadata(
token):Promise<Erc20Metadata>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3145
ERC-20 symbol/name/decimals in one fan-out — label a token the
indexer hasn't denormalized.
Parameters
token
`0x${string}`
Returns
Promise<Erc20Metadata>
getErc20Allowance()
getErc20Allowance(
token,owner,spender):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3151
ERC-20 allowance(owner, spender), raw units — gate a write that pulls
ERC-20 collateral (outcome tokens use per-operator approval instead).
Parameters
token
`0x${string}`
owner
`0x${string}`
spender
`0x${string}`
Returns
Promise<bigint>
getOutcomeBalance()
getOutcomeBalance(
p):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3158
ERC-6909 balanceOf(account, id) on the outcome-token singleton, raw
units. p.outcomeToken is the singleton (from getMarketOnchain);
p.id is the market's yesId/noId.
Parameters
p
Returns
Promise<bigint>
getBalances()
getBalances(
tokens,account):Promise<bigint[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3168
Batch-read many balances for one account in a single fan-out. Each entry
is read as a plain ERC-20 balanceOf(account) when id is omitted, or as
an ERC-6909 outcome position balanceOf(account, id) on the singleton
token when id is set. Results are returned positionally, aligned to
tokens. The explorer uses this to read a portfolio's collateral +
outcome positions in one round-trip instead of N calls.
Parameters
tokens
readonly BalanceQuery[]
account
`0x${string}`
Returns
Promise<bigint[]>
getStopOrderSomiPayment()
getStopOrderSomiPayment(
registry):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3174
SOMI a SpotStopOrderRegistry charges per pending stop order (funds the trigger gas; refunded on cancel). Raw wei.
Parameters
registry
`0x${string}`
Returns
Promise<bigint>
getMaxBuilderFeeBpsTimes1k()
getMaxBuilderFeeBpsTimes1k(
pool):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3180
A pool's protocol-wide per-order builder-fee ceiling (pool bps×1000). Read-only — no signer — for the order form's routing-fee ceiling hint.
Parameters
pool
`0x${string}`
Returns
Promise<bigint>
getBuilderApproval()
getBuilderApproval(
ref):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3183
A user's raw per-builder approval cap on a pool (pool bps×1000; 0 = none).
Parameters
ref
Returns
Promise<bigint>
getEffectiveBuilderApproval()
getEffectiveBuilderApproval(
ref):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3190
The ENFORCED per-builder approval on a pool: the user's raw cap
clamped by the pool's protocol-wide ceiling — the limit a builderFeeBpsTimes1k
must not exceed. Drives the order form's "approve builder first" gate.
Parameters
ref
Returns
Promise<bigint>
getContractMeta()
getContractMeta(
address,opts?):Promise<ContractMeta>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3196
owner / EIP-1967 implementation / native balance for a deployed contract —
the /system dashboard diagnostics. proxy: true reads the impl slot.
Parameters
address
`0x${string}`
opts?
proxy?
boolean
Returns
Promise<ContractMeta>
getNativeBalance()
getNativeBalance(
address):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3199
Native (SOMI/STT) balance, raw wei.
Parameters
address
`0x${string}`
Returns
Promise<bigint>
getTransactionSummary()
getTransactionSummary(
hash):Promise<TransactionSummary|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3211
Chain-direct summary of one transaction — sender, gas spent, fee paid, status — for enriching an order/fill view with what its tx cost. Null for a malformed hash and for one the node reports as not found.
A read that did not complete throws, so "it never landed" stays distinct from "the node could not be reached".
Parameters
hash
string
Returns
Promise<TransactionSummary | null>
Throws
RpcError The chain read did not complete.
createNetworkTape()
createNetworkTape(
opts?):NetworkTape
Defined in: packages/sdk/src/somniaMarketsClient.ts:3220
The network-wide order-flow firehose: one topics-only chain-log
subscription that sees OrderPlaced/OrderFilled from EVERY pool (including
pools created later), no indexer on the hot path. Nothing connects until
the tape's first subscribe; the last unsubscribe closes the socket.
Each call returns an independent tape.
Parameters
opts?
Returns
getHeadBlock()
getHeadBlock():
Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3223
Latest block number as the RPC sees it.
Returns
Promise<number>
getSystemInfo()
getSystemInfo():
Promise<SystemInfo>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3235
Deployed protocol state (impl pointers, oracle, collateral) for ops
dashboards. Needs config.addresses.
A null field means the contract is not configured or not wired. A failed
read throws, so the snapshot never reports a zero the chain did not answer.
Returns
Promise<SystemInfo>
Throws
RpcError A chain read did not complete.
Throws
ContractRevertError A configured contract rejected its read (usually an ABI mismatch).
listOperators()
listOperators(
opts?):Promise<IndexedOperator[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3246
List operators, newest-first by id, paginated. Pass owner to scope to
one owner's operators (the indexed "my operators", no log scan), enabled
to filter by the kill switch, limit/offset to page. Indexer read.
Parameters
opts?
OperatorFilter & object
Returns
Promise<IndexedOperator[]>
countOperators()
countOperators(
opts?):Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3256
Server-side COUNT of operators matching a filter (for directory
pagination). Needs the privileged _aggregate role (server-only), like
countBinaryMarkets.
Without that header the total is bounded at 10,000 by the row-scan
fallback, and past it would be a lower bound reported as exact. Operator
is orders of magnitude below the cap, so no bounded variant exists.
Parameters
opts?
Returns
Promise<number>
getOperator()
getOperator(
operatorId):Promise<IndexedOperator|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3258
One operator by id, or null if never registered. Indexer read.
Parameters
operatorId
number
Returns
Promise<IndexedOperator | null>
listVenues()
listVenues(
opts?):Promise<IndexedVenue[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3263
List venues, creation-order, optionally scoped to one operator and/or market type and/or the venue-level creation flag. Paginated. Indexer read.
Parameters
opts?
operatorId?
number
marketType?
string
creationEnabled?
boolean
limit?
number
offset?
number
Returns
Promise<IndexedVenue[]>
countVenues()
countVenues(
opts?):Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3278
Server-side COUNT of venues matching a filter (for per-operator venue
pagination). Needs the privileged _aggregate role (server-only).
Without that header the total is bounded at 10,000 by the row-scan
fallback, like countOperators; Venue is far below the cap, so no
bounded variant exists.
Parameters
opts?
operatorId?
number
marketType?
string
Returns
Promise<number>
getVenue()
getVenue(
venueId):Promise<IndexedVenue|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3280
One venue by its opaque bytes32 id, or null. Indexer read.
Parameters
venueId
string
Returns
Promise<IndexedVenue | null>
encodeBinaryVenueFeeParams()
encodeBinaryVenueFeeParams(
vp):Promise<`0x${string}`>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3287
Build a BINARY_V1 venue's feeParams bytes from plain-bps rates via the
deployed BinaryMarketsModule's encodeVenueFeeParams — the on-chain
ground truth for the version tag + struct shape (used by the create/edit
venue forms). Needs config.addresses.binaryModule.
Parameters
vp
Returns
Promise<`0x${string}`>
getMaxVenueFeeBps()
getMaxVenueFeeBps():
Promise<number>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3292
The module's protocol-level ceiling on any single venue fee rate, in plain
bps (e.g. 1_000 = 10%). Needs config.addresses.binaryModule.
Returns
Promise<number>
listMarketCreators()
listMarketCreators(
opts?):Promise<IndexedMarketCreator[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3306
List MarketCreators, newest-first, paginated. Pass owner for "my
machinery", operatorId/venueId to scope. Each row carries its nested
series. Indexer read.
Parameters
opts?
MarketCreatorFilter & object
Returns
Promise<IndexedMarketCreator[]>
getMarketCreator()
getMarketCreator(
creator):Promise<IndexedMarketCreator|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3308
One MarketCreator by address (with its series), or null. Indexer read.
Parameters
creator
string
Returns
Promise<IndexedMarketCreator | null>
listOracleAdapters()
listOracleAdapters(
opts?):Promise<IndexedOracleAdapter[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3315
List oracle adapters, newest-first, paginated. Pass owner to scope,
approved to filter by the module-approval gate. Oracle v2: the one
approved adapter is the OracleHub — this directory tracks
AdapterApproved history. Indexer read.
Parameters
opts?
owner?
string
approved?
boolean
limit?
number
offset?
number
Returns
Promise<IndexedOracleAdapter[]>
getOracleAdapter()
getOracleAdapter(
adapter):Promise<IndexedOracleAdapter|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3322
One oracle adapter by address, or null. Indexer read.
Parameters
adapter
string
Returns
Promise<IndexedOracleAdapter | null>
listSeries()
listSeries(
opts?):Promise<IndexedSeries[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3324
List series, creation-order, optionally scoped to one creator. Indexer read.
Parameters
opts?
creator?
string
limit?
number
offset?
number
Returns
Promise<IndexedSeries[]>
listSeriesLatestMarkets()
listSeriesLatestMarkets(
opts?):Promise<SeriesLatestMarket[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3377
The most recent market of every series that has rolled at least once - one row per series, joined server-side. The read behind a "has this series stopped rolling" monitor. Paginated over series. Indexer read.
A series with no market yet has NO row; see SeriesLatestMarket.
Parameters
opts?
ListSeriesLatestMarketsOptions
Returns
Promise<SeriesLatestMarket[]>
Example
// Which of an owner's series have gone quiet. Page to exhaustion: the read
// is bounded per call, so a short page is the end and a full one is not.
const latest = new Map<string, bigint>();
for (let offset = 0; ; offset += 100) {
const page = await exchange.client.listSeriesLatestMarkets({ limit: 100, offset });
for (const row of page) latest.set(row.series, BigInt(row.createdAtTimestamp));
if (page.length < 100) break;
}
// A series with NO row has never rolled - that is "unanchored", NOT
// "stalled". Nothing indexed says when a first roll is due, so judging a
// missing row as late pages every newly registered series.
//
// RE-REGISTRATION needs the same treatment, and the indexer will not do it
// for you: Market->Series links are preserved, so `latest` still holds the
// PREVIOUS schedule's market after a restart. Ageing that row against the new
// schedule reports a deliberate restart as quiet. A series is re-registered
// when `updatedAtTimestamp` is later than `createdAtTimestamp`, and the row
// in hand belongs to the old generation when it predates that restart - so
// treat it as unanchored too, exactly as the probe's own sweep does.
const seconds = (v: string | null) => (v == null ? Number.NaN : Number(v));
for (const s of await exchange.client.listSeries()) {
const rolledAt = latest.get(s.id);
if (rolledAt === undefined) continue;
const restartedAt = seconds(s.updatedAtTimestamp);
const registeredAt = seconds(s.createdAtTimestamp);
const restarted = Number.isFinite(restartedAt) && (!Number.isFinite(registeredAt) || restartedAt > registeredAt);
if (restarted && Number(rolledAt) <= restartedAt) continue;
const lateBy = BigInt(Math.floor(Date.now() / 1000)) - rolledAt;
if (lateBy > BigInt(s.intervalSec) * 2n) console.log("quiet:", s.id, lateBy);
}
Throws
InvalidInputError opts.limit is not an integer from 1 to
1000, or opts.offset is not a non-negative safe integer. Checked before
the request: NaN and Infinity are ordinary number values that would
serialize to null and lift the page bound entirely.
Throws
IndexerError The indexer request failed or returned an unusable response. The union is SomniaMarketsClientListSeriesLatestMarketsError.
getSeries()
getSeries(
creator,seriesId):Promise<IndexedSeries|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3384
One series by its composite key (creator, seriesId) — seriesId is
per-creator. The row is the CURRENT spec (registerSeries overwrites in
place). Null when never registered.
Parameters
creator
string
seriesId
number
Returns
Promise<IndexedSeries | null>
getSchedulingCost()
getSchedulingCost(
def):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3400
The hub's MARGINAL scheduling cost for def — 0 when an identical
template definition is already scheduled (the call would dedup), the full
oracle submission cost otherwise. Chain read; needs
config.addresses.oracleHub.
Parameters
def
Returns
Promise<bigint>
earmarkedOf()
earmarkedOf(
operatorId):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3405
Native LOCKED for an operator's outstanding markets (wei; never
withdrawable). Chain read; needs config.addresses.oracleHub.
Parameters
operatorId
number
Returns
Promise<bigint>
creditOf()
creditOf(
operatorId):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3410
An operator's accrued WITHDRAWABLE surplus credit on the hub (wei). Chain
read; needs config.addresses.oracleHub.
Parameters
operatorId
number
Returns
Promise<bigint>
outstandingOf()
outstandingOf(
operatorId):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3415
Count of an operator's bound-but-unresolved markets. Chain read; needs
config.addresses.oracleHub.
Parameters
operatorId
number
Returns
Promise<bigint>
withdrawableOf()
withdrawableOf(
operatorId):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3420
Wei an operator's owner may withdraw right now (== creditOf). Chain read;
needs config.addresses.oracleHub.
Parameters
operatorId
number
Returns
Promise<bigint>
payerCreditOf()
payerCreditOf(
payer):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3427
A1: the withdrawable surplus credited to a reserve-PAYER (an open-venue
creator, or the autonomous MarketCreator on its rolls) rather than the
operator; drawn by that account via createOracleHubAdmin().withdrawMyCredit.
Chain read; needs config.addresses.oracleHub.
Parameters
payer
`0x${string}`
Returns
Promise<bigint>
payerOf()
payerOf(
marketId):Promise<`0x${string}`>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3432
A1: the reserve-payer recorded for a market at onBind (surplus recipient);
zero-address once settled + swept. Chain read; needs config.addresses.oracleHub.
Parameters
marketId
`0x${string}`
Returns
Promise<`0x${string}`>
resolveReserve()
resolveReserve():
Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3437
The hub's resolveReserve() — the per-market reserve attached+locked at
onBind (wei). Chain read; needs config.addresses.oracleHub.
Returns
Promise<bigint>
quoteCreateMarketValue()
quoteCreateMarketValue(
def):Promise<bigint>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3444
THE §8e create-market value quote: getSchedulingCost(def) + resolveReserve() (the reserve is attached to the create). Attach exactly
this to scheduleAndCreateMarket (excess refunds). Chain read; needs
config.addresses.oracleHub.
Parameters
def
Returns
Promise<bigint>
getOracleQuestion()
getOracleQuestion(
oracleQuestionId):Promise<OracleQuestionRecord|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3449
One hub-scheduled oracle question (dedup key, scheduler, bind count) by its oracleQuestionId, or null. Indexer read.
Parameters
oracleQuestionId
string
Returns
Promise<OracleQuestionRecord | null>
listOracleQuestions()
listOracleQuestions(
opts?):Promise<OracleQuestionRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3454
Hub-scheduled questions, newest first — filter by scheduler /
questionKey, paginate. Indexer read.
Parameters
opts?
scheduler?
string
questionKey?
string
limit?
number
offset?
number
Returns
Promise<OracleQuestionRecord[]>
getOperatorHubAccount()
getOperatorHubAccount(
operatorId):Promise<OperatorHubAccountRecord|null>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3464
One operator's hub account (earmarked / credit / outstanding) by operatorId, or null. Indexer read.
Parameters
operatorId
string | number
Returns
Promise<OperatorHubAccountRecord | null>
listOperatorHubAccounts()
listOperatorHubAccounts(
opts?):Promise<OperatorHubAccountRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3469
Operator hub-account records, most-recently-updated first, paginated. Indexer read.
Parameters
opts?
limit?
number
offset?
number
Returns
Promise<OperatorHubAccountRecord[]>
listOracleBinds()
listOracleBinds(
opts?):Promise<OracleBindRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3475
Bind records (operator attribution → exact metered resolve charge +
subsidy per market, §8e), newest first — filter by operatorId /
oracleQuestionId / resolved, paginate. Indexer read.
Parameters
opts?
operatorId?
number
oracleQuestionId?
string
resolved?
boolean
limit?
number
offset?
number
Returns
Promise<OracleBindRecord[]>
listOracleCallbacks()
listOracleCallbacks(
opts?):Promise<OracleCallbackRecord[]>
Defined in: packages/sdk/src/somniaMarketsClient.ts:3487
Resolution-callback conservation records (CallbackAccounted), newest
first, paginated (a callback drains across many questions, so no
per-question filter). Indexer read.
Parameters
opts?
limit?
number
offset?
number
Returns
Promise<OracleCallbackRecord[]>
createTrader()
createTrader(
traderConfig):Trader
Defined in: packages/sdk/src/somniaMarketsClient.ts:3513
Build a Trader bound to a signer and this client's chain, store,
and socket. With a privateKey/local account the trader signs locally
(fixed fees, locally-tracked nonce — zero pre-send RPCs) and confirms in
one round-trip via realtime_sendRawTransaction; with a browser
walletClient it sends through the wallet and confirms off the newHeads
subscription. Every write resolves only once mined, with its receipt. With
an executor the trader sends through it instead — see
SomniaMarketsClient.createExecutor.
- Throws SignerRequiredError - none of
executor,privateKey,accountorwalletClient(with an account) is set. - Throws InvalidInputError -
privateKeyis not a valid secp256k1 key, orexecutorsends on a chain other than this client's. - Throws NotConfiguredError - this client has no chain transport
(no
wsRpcUrland a chain without a WebSocket endpoint) and nopublicClientwas passed to send through.
The complete union is SomniaMarketsClientCreateTraderError.
Parameters
traderConfig
Returns
createExecutor()
createExecutor(
spec):Executor
Defined in: packages/sdk/src/somniaMarketsClient.ts:3571
Build one of the built-in executors, bound to this engine's chain, socket,
fee envelope and nonce lane. The spec names only who acts — a private key
or local account, a wallet client, a Somnia session seed, a safe with
the executor that sends its outer transaction, or a smart account from
@somnia-chain/accounts-sdk. Hand the result to
createTrader({ executor }), or compose it (a safe's inner), or place it
in a SomniaMarketsAccount for the exchange to trade through.
Gotchas
- A safe's
innermust be authorized on the safe: an owner of a threshold-1 safe in"owner"mode, an enabled module in"module"mode. See ExecutorSpec. - A smart account's
innerfollows the same rule when nothing signs (nosigner, nothrough): its actor must be a direct owner of a threshold-1 account. Asigneror athroughchain of parent accounts switches to a real signature, which the accounts SDK nests to any depth. See ExecutorSpec. - A nested Safe can be the owner or enabled module when
inner.actorhas that authorization. Module mode does not require threshold one. The SDK does not check the owner set or threshold. Other authorization schemes need a custom Executor. Failed Safe calls may revert or return a receipt withfailure; Trader writes throw either failure. - Before sending, a safe executor checks that
safeand any requiredmultiSendhave code. Missing code raises InvalidInputError; otherwise a call could succeed without executing. Successful checks are cached. Single calls do not use or check MultiSend. - Throws InvalidInputError - a
privateKeyorsessionSeedthat is not a valid 32-byte key, a wallet spec with no account to act as, a safe or smart-account spec whoseinnersends on another chain, or a smart-account spec on a chain the accounts SDK has no deployment for. - Throws NotConfiguredError - a key, account, wallet or session
spec on a client with no chain transport (no
wsRpcUrland a chain without a WebSocket endpoint); a safe or smart-account spec needs none of its own.
The complete union is SomniaMarketsClientCreateExecutorError.
Example (A safe driven by a session key)
const session = client.createExecutor({ sessionSeed });
const safe = client.createExecutor({ safe: SAFE, inner: session, multiSend: MULTISEND });
const trader = client.createTrader({ executor: safe });
await trader.placeOrder(params); // approval + order in ONE safe transaction
Example (A factory smart account driven by a session key)
const session = client.createExecutor({ sessionSeed });
const account = client.createExecutor({ smartAccount: ACCOUNT, inner: session });
const trader = client.createTrader({ executor: account });
await trader.placeOrder(params); // approval + order in ONE account transaction, nothing signs
Parameters
spec
Returns
createOperatorAdmin()
createOperatorAdmin(
config):OperatorAdmin
Defined in: packages/sdk/src/somniaMarketsClient.ts:3578
Build an OperatorAdmin bound to a signer — registers/updates operators and creates/updates venues on MarketsCore. Same signer doctrine as createTrader (privateKey/local account, or a browser walletClient).
Parameters
config
Returns
createOracleHubAdmin()
createOracleHubAdmin(
config):OracleHubAdmin
Defined in: packages/sdk/src/somniaMarketsClient.ts:3589
Build an OracleHubAdmin bound to a signer — the OracleHub surface
(Oracle v2 §8e): quote reads (quoteCreateMarketValue = the §8e create
value = scheduling cost + resolveReserve), the credit-only withdraw
(owner-gated — draws accrued surplus credit only), and the protocol-admin
writes (fundHub, gas + drain params, enableReactivity/migrateSubscription —
precompile, testnet/mainnet only). Same signer doctrine as
createOperatorAdmin. Needs config.addresses.oracleHub.
Parameters
config
Returns
createGovernanceAdmin()
createGovernanceAdmin(
config):GovernanceAdmin
Defined in: packages/sdk/src/somniaMarketsClient.ts:3597
Build a GovernanceAdmin bound to a signer — the protocol-admin-only
surface that approves oracle adapters on the module (setAdapterApproved;
in Oracle v2 the ONE approved adapter is the OracleHub — deploy wiring +
emergency revoke). Gate its UI on GovernanceAdmin.isModuleOwner.
Parameters
config
Returns
createMarketCreatorAdmin()
createMarketCreatorAdmin(
config):MarketCreatorAdmin
Defined in: packages/sdk/src/somniaMarketsClient.ts:3604
Build a MarketCreatorAdmin bound to a signer — stamps MarketCreators (+ policies) from the factory, registers rolling series under them, funds them, and triggers rolls. Same signer doctrine as createOperatorAdmin.