# Somnia Markets Documentation > Somnia Markets is a decentralized information and trading protocol on the Somnia network: spot pairs, binary information markets, and perps on one fully on-chain order-book engine. Guides for the TypeScript SDK and for SDK-less integration straight against the smart contracts (order placement, materializing the order book from events, market making), plus the full TypeDoc API reference. --- # /docs # Somnia Markets Somnia Markets is a decentralized information and trading protocol on [Somnia](https://somnia.network): one fully on-chain central limit order-book engine runs every market family — **spot** pairs, **binary** information markets, and **perps** — alongside a realtime on-chain index-price feed. Everything is on-chain and permissionless: order matching, escrow, settlement, market creation (per-venue), and resolution. The APIs below are conveniences over the same public contracts — nothing they do is privileged. **Spot markets** are plain base/quote order books (e.g. SOMI/USDC), each pool pushing a smoothed on-chain mark price straight from its own book. **Binary markets** are the information leg: a YES/NO question — such as an asset above a strike at expiry — whose outcome shares trade on the book at prices that *are* probabilities, so each book doubles as a live on-chain forecast. Shares are ERC-6909 positions backed 1:1 by collateral: a complete set (1 YES + 1 NO) always mints from and merges back to exactly one collateral unit, the winning side redeems 1:1 at resolution, and resolution itself is driven on-chain by the Prophecy oracle through Somnia's reactivity — no operator in the loop. Each market carries an on-chain kind tag (`marketType()`); future kinds (multi-outcome, dual-book) extend the same protocol. **Perps** are linear, collateral-settled perpetuals — cross-margin via the MarginBank, on-chain funding and liquidations — live on testnet. ## Ways to integrate **The TypeScript SDK — `@somnia-chain/markets-sdk`.** The fastest path for apps and bots in a JS runtime: realtime order books, trades, candles, and positions streamed with zero polling, plus a typed trader for placing orders, managing margin, and minting/redeeming outcome shares. Start with [The SDK](../packages/sdk/README.md), then [The exchange API](../packages/sdk/docs/EXCHANGE.md); the per-family guides — [Spot markets](../packages/sdk/docs/SPOT.md), [Binary markets](../packages/sdk/docs/BINARY.md), [Perps](../packages/sdk/docs/PERPS.md) — cover what differs per kind, and [Architecture](../packages/sdk/docs/ARCHITECTURE.md) explains how it works under the hood. **Raw smart contracts — no SDK.** Any language, any runtime, nothing but an RPC node and the ABIs: discover markets, place orders, and materialize a live local order book straight from contract events. [Raw Smart-Contract Integration](./RawIntegration.md) is the end-to-end guide; [Market Making](./MarketMakingTips.md) covers what is venue-specific for quoting operations — book encoding, escrow semantics, event caveats, market lifecycle. ## Going deeper - The [System page](/system) is the live deployment view: every protocol contract with its address, owner, and implementation, plus indexer health. - The API reference in the sidebar is generated from the SDK source (TypeDoc). - These docs are also served machine-readable at [`/llms.txt`](/llms.txt) and [`/llms-full.txt`](/llms-full.txt). --- # /docs/typescript # @somnia-chain/markets-sdk The TypeScript SDK for building on **Somnia Markets** — read live market data and place trades on the on-chain order book from your own app. - **Realtime data, no wallet required.** Order books, trades, candles, and a user's positions and open orders stream into your UI the moment they happen on-chain — no polling loops to write or manage. - **Trading with a signer.** Place and cancel orders, mint and redeem outcome shares, and more, through a typed trader bound to your wallet. - **Works anywhere, with first-class React.** Use plain async functions in any environment, or drop in the hooks for components that update themselves. ## Install ```sh pnpm add @somnia-chain/markets-sdk viem # npm / yarn / bun equivalents work too ``` `viem` is a peer dependency. `react` is an optional peer — only needed for the `@somnia-chain/markets-sdk/react` entry. > Versions up to 0.19.0 were published to GitHub Packages under the private > `@somnia-chain` scope; from 0.20.0 the package is public on npm — no > registry configuration or token needed. ## Create an exchange `new SomniaMarkets(config)` is the single entry point — the exchange owns everything: symbols, market data, watches, and writes. No global setup, no hidden singleton; each exchange is isolated. ```ts import { SomniaMarkets, SOMNIA_MAINNET_ADDRESSES } from "@somnia-chain/markets-sdk"; import { somniaMainnet } from "@somnia-chain/markets-sdk/chains"; // every Somnia network, incl. Shannon/Elwood/Hideki/local const exchange = new SomniaMarkets({ indexerUrl: "https://prd.smk.somnia.host/v1/graphql", // the production indexer chain: somniaMainnet, wsRpcUrl: "wss://api.infra.mainnet.somnia.network/ws", addresses: SOMNIA_MAINNET_ADDRESSES, // baked-in per-chain constants (SOMNIA_TESTNET_ADDRESSES for testnet) privateKey, // optional — needed for createOrder & friends }); await exchange.loadMarkets(); const book = await exchange.watchOrderBook("BTC-95000-31DEC26/USDC#YES"); // live, zero RTT const order = await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 10, 0.62); ``` For testnet, swap all four: `https://dev.smk.somnia.host/v1/graphql`, `somniaShannon`, `wss://api.infra.testnet.somnia.network/ws`, and `SOMNIA_TESTNET_ADDRESSES`. The raw engine tier — bigint-exact, address-keyed — is reached _through_ the exchange (`exchange.client`, `exchange.trader`), never constructed separately. The WebSocket opens lazily on first chain I/O, so an indexer-only exchange (e.g. server-side GraphQL reads) never opens one. Nothing is shared between instances: a bot per chain, per-request servers, parallel tests — just construct another. Two exchanges never share watch state or sockets. New to the SDK? The **[documentation map](https://prd.smk.somnia.host/docs/typescript)** groups every page by need: two tutorials that end with a cancelled order on testnet, goal-shaped how-to guides, reference tables for configuration, symbols, units, and errors, and explanations of the design. The area guides, in reading order: - **[The exchange API](https://prd.smk.somnia.host/docs/typescript/exchange)** — the `SomniaMarkets` class, the SDK's primary surface: symbols (`SOMI/USDC`, `BTC-95000-31DEC26/USDC#YES`), `fetch*`/`watch*`/`createOrder`, human-unit structs. Exchange-bot muscle memory (ccxt included) transfers directly — start here. - **[Spot markets](https://prd.smk.somnia.host/docs/typescript/spot-markets)** — base/quote books: ticks and lots, native-base escrow, market orders, and stop orders. - **[Binary markets](https://prd.smk.somnia.host/docs/typescript/binary)** — YES/NO information markets: probability prices, the four sides, mint/burn/redeem, and a maker loop. - **[Perps](https://prd.smk.somnia.host/docs/typescript/perps)** — live on testnet: cross-margin via the MarginBank, funding, positions, and how perps slot into the `marketType` union. - **[Price feeds](https://prd.smk.somnia.host/docs/typescript/prices)** — realtime BTC/ETH index prices from the on-chain EMA oracle: `watchPrice`/`getLivePrice`, one-shot history + candles, and the React hooks. - **[SomniaLend](https://prd.smk.somnia.host/docs/typescript/lend)** — the third-party money market wrapped as `client.lend`: supply idle collateral, borrow working capital, reserve rates as APYs. - **[Chains](https://prd.smk.somnia.host/docs/typescript/chains)** — every Somnia network as a viem `Chain` (mainnet, Shannon, Elwood, Hideki, local anvil) from `@somnia-chain/markets-sdk/chains`, plus `getSomniaChain(id)`. - **[Bridge](https://prd.smk.somnia.host/docs/typescript/bridge)** — moving tokens between Somnia networks over the Hyperlane warp routes: the token/network enums, the per-network registry, and `createBridgeTransfer` → the unsigned transactions that do it. - **[Native RPC](https://prd.smk.somnia.host/docs/typescript/native)** — the `somnia_*` namespace wrapped as ordinary calls: the native ledger block, chain statistics, protocol parameters, reactivity subscription reads, and **session transactions** (the node holds the key, tracks the nonce, signs, and returns the receipt). - **[Reactivity](https://prd.smk.somnia.host/docs/typescript/reactivity)** — Somnia's event-driven primitive via `@somnia-chain/markets-sdk/reactivity` (a pointer at the upstream `@somnia-chain/reactivity` package): events pushed _with_ the state that goes with them, into TypeScript (`watch`) or into a Solidity handler (`subscribe`). - **[The engine (advanced)](https://prd.smk.somnia.host/docs/typescript/engine)** — the raw tier behind the exchange (`exchange.client` / `exchange.trader`): bigint-exact reads, ref-counted watches, React hook wiring, raw writes. - **[Architecture guide](https://prd.smk.somnia.host/docs/typescript/architecture)** — diagrams of the whole machine: the watch seam, event routing, the local order book, the reconnect lifecycle, and the one-round-trip write path. ### Three ways to read | How | What it is | Returns | | ------------------------------------------ | ---------------------------------------------------------------------- | ------------------- | | `client.list*` / `client.get*` | **One-shot** read (indexer GraphQL or on-chain) | a `Promise` | | `client.getLive*` + `client.subscribeLive` | **Synchronous** read off the live store (within a `watchMarket` scope) | a value, now | | `use*` hooks (`/react`) | React bindings over the live store (auto-watching) | re-render on change | So `client.getFills` fetches once; `client.getLiveFills` reads the live tape; `useLiveFills` re-renders a component as it updates. In React, provide the client once with `` (from `@somnia-chain/markets-sdk/react`) and the hooks read it from context. Markets come from one discriminated union — `Market = SpotMarket | PerpMarket | BinaryMarket`, keyed on `marketType` — via `client.listMarkets` / `client.getMarket`. Binary-only callers can use `client.listBinaryMarkets` / `client.getBinaryMarket`, the same query pre-narrowed to `BinaryMarket`. (Note: _binary_, not _clob_ — a spot market is an order book too, so "CLOB" was never the right label for the binary surface.) Money crosses the API as raw integers (bigint on writes, decimal strings from the indexer) scaled by token decimals. Convert at the edges with `fromHuman` (input) and `toHuman` / `toHumanString` (display); for binary prices, `probabilityToPrice` / `priceToProbability` map a YES price ↔ a 0–1 probability. ## What's included - **Entry point** — `new SomniaMarkets(config)` → the exchange (symbols, `fetch*`/`watch*`/`createOrder`, human-unit structs). Its engine tier — `exchange.client` (`SomniaMarketsClient`, bigint-exact reads + watches) and `exchange.trader` (raw writes) — is reached through it; `ClientConfig` - **React** — `SomniaMarketsProvider`, `useSomniaMarketsClient`, and the hooks `useWatchMarket`, `useWatchUser`, `useLiveStatus`, `useIsTailing`, `useLiveFills`, `useLiveUserFills`, `useLiveMarketByPool`, `useLiveMarketByAddress`, `useLiveUserOrders`, `useLiveBinaryOrderBook`, `useLiveSpotOrderBook`, … — the pool-keyed data hooks **watch automatically** while mounted; the indexer, price, funding, and lend hooks are listed in the API reference - **Client reads** — `client.listMarkets`/`getMarket` (the `Market` union), `listBinaryMarkets`/`getBinaryMarket`, `getCandles`, `getBinaryOrderBook`, `getOpenOrders`, `getPortfolio`, `getSyncStatus`, `getMarketOnchain`, `getSystemInfo`, … (indexer reads **throw** on failure — an empty result always means "no rows", never "request failed") - **Order state at chain head** — `getOrderOnchain(pool, orderId)`, `getOwnOpenOrdersOnchain(pool, owner)`, `getAllOpenOrdersOnchain(pool, { isBid })` answer from the pool contract, so an order is readable the moment its block lands. Use these to read your own writes; use the indexed `getOpenOrders` / `getOrders` for history — the chain surface only knows what is open **now**. `getOrderOnchain(pool, orderId, { blockNumber })` reads at the end of a past block instead, which is how a log consumer recovers the side and owner of a maker order the fill already removed; the fill's own numbers stay with the event, and an old block needs an archive node - **Live watches (no React)** — `client.watchMarket(pool)` / `watchMarkets({ discover })` / `watchUser(account)` → ref-counted handles; `getWatchStatus`, `subscribeLive`, `getLiveStatus`, `getLiveMarkets`, `getLiveMarketByPool`/`…ByAddress`, `getLiveFills`, `getLiveUserFills`, `getLiveUserOrders`, and the locally materialized resting books `getLiveBinaryOrderBook` (binary, 4-sided) / `getLiveSpotOrderBook` — synchronous, zero round-trips, scoped to what you watch. Every market kind streams; a discovery watch picks up new markets from the creation events (the MarketCreator's rolling series AND direct `BinaryMarketsModule.createMarket` markets); binary status/resolution stays current from chain events. - **Trading** — `client.createTrader(...)` → `placeOrder`, `cancelOrder`, `approveBuilder` (opt a routing/builder frontend in for per-order builder fees), `placeSpotOrder`, `placeSpotStopOrder`, `mintSet`, `burnSet`, `redeem`, `faucet`, `resolve`, `voidMarket`. Each write **awaits its receipt** and resolves to `{ hash, receipt }` (`placeOrder` adds `orderId` + `fills`). With a `privateKey`/local `account` the SDK signs locally with **fixed fees** and a locally-tracked nonce, and sends via Somnia's `realtime_sendRawTransaction` — send + confirm in **one round-trip**, zero fee/nonce/gas estimation RPCs. In the browser, pass a `walletClient` (confirm rides the newHeads subscription). - **Contract ABIs** — the minimal ABI data the SDK itself encodes and decodes with, exported so a caller that builds a transaction or reads a receipt by hand uses the SAME signatures: the order-placement writes (`binaryPoolWriteAbi`, `spotPoolWriteAbi`, `perpPoolWriteAbi`, `orderBookBatchWriteAbi`), the funding writes (`erc20WriteAbi`, `erc20VaultWriteAbi`, `marginBankWriteAbi`), operator delegation (`operatorRegistryWriteAbi`), the spot stop-order lifecycle (`spotStopRegistryWriteAbi` + `spotStopRegistryEventsAbi` — created, triggered, cancelled, inert-cancelled), the shared order-book events (`orderBookEventsAbi`), and the binary module / settlement / ERC-6909 / OracleHub ABIs. Hand-copying a signature instead is how one drifts in silence - **Operator delegation** — `client.getOperatorPermissionsRegistry(pool)` names the registry a SpotPool actually gates operator calls through (`null` when the pool is unwired), so a caller can discover the address instead of configuring `addresses.operatorPermissionsRegistry`. Read a grant back with `client.isApprovedForPool` / `isGloballyApproved` (the raw slots) or `client.isOperatorAuthorized` (the pool's resolved answer) - **Types & helpers** — `Market`/`SpotMarket`/`BinaryMarket` (+ `isSpotMarket`/ `isBinaryMarket`), `LiveFill`, `LiveOrder`, `BinarySide`, `TailStatus`, `kindOf`, `fillKind`, `fromHuman`/`toHuman`, `DECIMALS`, … - **Chains** (`@somnia-chain/markets-sdk/chains`) — `somniaMainnet` (5031), `somniaShannon` (Shannon, 50312), `somniaElwood` (50313), `hidekiTestnet` (50383, 10 ms blocks) and `somniaLocal` (anvil, 31337) as viem `Chain`s, plus `somniaChains` / `getSomniaChain(id)` / `isSomniaChainId`. Nothing here imports chains from `viem/chains` any more - **Bridge** (same `/chains` entry) — the Hyperlane warp routes between Somnia networks as live-verified data (`BridgeToken`, `ChainId`, `SOMNIA_BRIDGE`, `getBridgeToken`, `getBridgeNetwork`, …) plus `createBridgeTransfer(...)` → the ordered, tagged **unsigned transactions** (`approve` then `bridge`) that move a balance. The registry and planner are pure (no RPC, no signer); `sendBridgeStep` is the one opt-in sender. ⚠️ dev/test bridge — not for real funds - **Native RPC** (`@somnia-chain/markets-sdk/native`) — `createNative(client)` wraps the node's `somnia_*` namespace, exactly the twelve methods in the [public JSON-RPC reference](https://docs.somnia.network/developer/json-rpc-api): `getBlock` (the native ledger block), `getStatistics`, `listPrivilegedReceipts`, `getNodePublicKeys`, the reactivity subscription reads, and `sendSessionTransaction` — plus `sessionAddress(seed)` / `sessionPrivateKey(seed)`, derived locally with no round-trip. Takes any EIP-1193 client, needs nothing else from the SDK - **Reactivity** (`@somnia-chain/markets-sdk/reactivity`) — a pointer at [`@somnia-chain/reactivity`](https://www.npmjs.com/package/@somnia-chain/reactivity) (optional peer dep, re-exported verbatim — no second copy of it here): `createReactivity(exchange.client)` → `watch` (a `somnia_watch` socket subscription that delivers each event _together with_ `eth_call` results from the same block), `subscribe` / `subscribeRaw` / `unsubscribe` (Solidity handler subscriptions via the precompile) and `scheduleSubscriptionAt{Timestamp,Block,Epoch}`, plus `unwrap()` to turn upstream's `Error`-returns into throws Every method, hook, and type is listed in the **API reference**. ## Using a query library (TanStack Query, SWR, …) The SDK deliberately ships no cache-library wrapper. Two rules cover the whole surface: - **Live hooks need no cache.** The `useLive*` hooks read a push-fed store that is already a shared singleton — ref-counted watches and deduped hydration mean ten components on one pool cost one subscription. Wrapping them in a query cache would cache a value that is already live; don't. - **Async reads go in YOUR query library**, with an `exchange.client` method as the `queryFn` and the SDK's exported key factory as the `queryKey`. Every client read is a plain promise, which is already the ideal `queryFn`, and the key factories (`marketsKey`, `portfolioKey`, `candlesKey`, `syncStatusKey`, `marketOnchainKey`, …) are plain functions from the root entry — no query library is imported, so they work with any of them. (Client reads take no per-request `AbortSignal` — cancellation is client-scoped via `ClientConfig.signal`; pass your query library's `signal` to any fetching your `queryFn` does itself.) ```tsx import { useQuery } from "@tanstack/react-query"; import { candlesKey } from "@somnia-chain/markets-sdk"; const { data: candles } = useQuery({ queryKey: candlesKey(pool, 60, { limit: 500 }), queryFn: () => client.getCandles(pool, 60, { limit: 500 }), refetchInterval: 15_000, }); ``` After a write, invalidate by the same factory — `queryClient.invalidateQueries({ queryKey: portfolioKey(account) })` — or everything SDK-shaped at once with the `["somnia-markets"]` prefix (`QUERY_KEY_SCOPE`). Hand-written key strings drift; the factories are the one canonical spelling per read. Outside a query library, `useIndexerQuery(fn, deps)` remains the built-in option: it re-runs on dep changes, keeps `data`/`loading`/`error`, and aborts a superseded request via the `AbortSignal` it passes to `fn`. ## How the live feed works You get instant updates without running your own indexer — scoped to exactly the markets you watch. Opening a watch loads a consistent snapshot of that scope (the one and only indexer touch), then keeps it current by streaming its on-chain events over a WebSocket — so trades, orders, prices, and the resting order book itself update the moment they're final on-chain. There is no polling anywhere: the WebSocket is the only realtime transport, and if it drops the watches heal themselves by reconnecting with backoff and backfilling the missed blocks straight from chain. ## Debugging The SDK is silent by default. To see what a client is doing — every trader call, the sign/broadcast pipeline, live-tail hydration and block application — pass a `debug` sink in the config. Events are structured data (`DebugEvent`: log lines plus span start/end pairs with ids, explicit `parentId` links, durations, and errors), so the sink owns all filtering and formatting. The toggle mechanism belongs to your app, not the SDK: The bundled `consoleDebugSink()` renders the stream as an indented span tree (reconstructed from `parentId`, so it stays correct under concurrency): ```text [sdk] ▶ trader.placeOrder { params: { pool: "0x…", side: "BUY_YES" } } [sdk] ▶ trade.execute { functionName: "placeBinaryOrder", … } [sdk] liveTail applying logs { received: 3, … } [sdk] ▶ trade.signCall [sdk] ◀ trade.signCall 2.1ms [sdk] · trade.execute { hash: "0x…" } [sdk] ◀ trade.execute 38.2ms [sdk] ◀ trader.placeOrder 41.0ms ``` ```ts import { consoleDebugSink } from "@somnia-chain/markets-sdk"; // Browser (explorer dev) — flip on from devtools with // localStorage.setItem("sdk-debug", "1") and reload: const exchange = new SomniaMarkets({ ...config, debug: localStorage.getItem("sdk-debug") ? consoleDebugSink() : undefined, }); // Node bot — JSON lines behind an env var: const exchange = new SomniaMarkets({ ...config, debug: process.env.SDK_DEBUG ? (e) => console.log(JSON.stringify(e, (_, v) => (typeof v === "bigint" ? v.toString() : v))) : undefined, }); ``` In tests, `debugCollector()` captures the stream with typed filters: ```ts import { debugCollector } from "@somnia-chain/markets-sdk"; const c = debugCollector(); const exchange = new SomniaMarkets({ ...config, debug: c.sink }); await exchange.trader.placeOrder(params); expect(c.starts("trade.execute")).toHaveLength(1); ``` Span events map 1:1 onto OpenTelemetry (`name` ↔ span name, `data` ↔ attributes, `error` ↔ status, `parentId` ↔ context link), so a real tracer is just a sink that keeps a `Map` — `phase: "start"` calls `tracer.startSpan(...)` (linking `parentId` via OTel context) and `phase: "end"` calls `span.end()`. The OTel dependency lives entirely in your app; the SDK stays dependency-free. ## Book provenance and live-tail integrity Book reads expose `blockNumber` so consumers can identify the data they hold. A native chain read pins both sides to one block. Supply `blockNumber` in the read options, or let the SDK select one head. Empty chain books retain that pin. Unified `fetchOrderBook` accepts `{ limit, blockNumber }` and preserves the pin in YES and NO views. A caller-built book can omit provenance. Live books expose a per-scope materialization watermark. It is the snapshot seam or highest applied event block for that scope. It is not the observed chain head. It does not prove that all events in that block arrived, or that an indexed seed equals chain state. The displayed live book also filters expiry using the local wall clock. Use a pinned chain read when an exact as-of chain snapshot is required. Historical and streaming unified trades expose their source `blockNumber` and `logIndex`, including NO views. Historical native fill rows retain decimal block strings. These fields are optional on `FillRow` and `UnifiedTrade` for compatibility with caller-built values. SDK reads populate them from the source. If a caller-built row omits either field, its unified trade keeps that field `undefined`; the SDK does not substitute block zero or log zero. A later log delivery checks any intervening range with chunked RPC log reads. Recovered events apply before the triggering later events. Head-only activity makes no default recovery reads. An empty probe is a quiet range; only a nonempty successful recovery increments `getLiveStatus().healedGaps`. Background failures are contained and visible in `getLiveStatus().failure`, with a semantic SDK error. The tail retains its range and retries with bounded reconnect backoff. It does not apply later batches across a failed recovery. This detects bounded block gaps. Adjacent delivered blocks can conceal a partially missing block. Missing terminal activity has no default trigger if no later log arrives. The SDK does not claim a gapless transport protocol. Optional owner `reconciliation` accepts a positive bigint `blockInterval` and integer `depth` from 1 to 100. It is off by default. At each eligible checkpoint, it recovers logs through a fixed target and compares native top levels against both chain sides pinned to that target. It filters local expiry using the target's chain timestamp. Head work coalesces while one comparison runs. Each checkpoint costs chunked log reads, a block header, and two contract reads per watched pool. `lastDivergence` retains the pool, block, depth, and differing raw levels even after a later match. Read failures remain distinct from empty or matching books. Reconciliation never replaces the event-derived order history with a top-N ladder. It does not repair historical seed rows. Owner cleanup stops pending work. The following example compares provenance labels. `config` selects the local or deployed environment, and `pool` is a pool in that environment. Choose a block that exists on that chain for the pinned read. The two labels describe different read contracts; equal labels alone do not prove equal books. ```ts const owner = new SomniaMarkets({ ...config, reconciliation: { blockInterval: 100n, depth: 10 }, }); try { const watch = await owner.client.watchMarket(pool); const live = owner.client.getLiveSpotOrderBook(pool); const pinned = await owner.client.getSpotOrderBook(pool, { blockNumber: 123n }); console.log({ delivered: live.blockNumber, pinned: pinned.blockNumber }); console.log(owner.client.getLiveStatus()); watch.stop(); } finally { await owner.close(); } ``` --- # /docs/typescript/docs # Somnia Markets SDK documentation This page is the map of the `@somnia-chain/markets-sdk` documentation. The pages are grouped by what you need right now: to learn, to finish a task, to look something up, or to understand a design. Every TypeScript example has a compile-checked counterpart that uses the public package entrypoints and real dependency types. The tutorials were run on the testnet. ## Start here Two lessons take a newcomer from an empty directory to a cancelled order on the Somnia testnet. Follow them in order. Each one takes about 15 minutes. 1. [Stream a live order book](./tutorials/stream-a-live-order-book.md). No wallet needed. Install the SDK, load the markets, read a book, and watch it change. 2. [Place and cancel your first order](./tutorials/place-and-cancel-your-first-order.md). Fund a testnet key, rest a limit order, see it in your open orders, and cancel it. ## Do a task Goal-shaped guides for a developer who already knows what they want. - [Configure the SDK for testnet, mainnet, or a local chain](./how-to/configure-for-a-network.md) - [Get testnet funds](./how-to/get-testnet-funds.md) - [Run a quoting loop](./how-to/run-a-quoting-loop.md): place, amend, and cancel orders from a bot - [Detect when an order fills](./how-to/detect-fills.md) - [Sign with a browser wallet](./how-to/sign-with-a-browser-wallet.md) - [Use the React hooks](./how-to/use-the-react-hooks.md) - [Handle errors and reverts](./how-to/handle-errors.md) - [Debug what the SDK is doing](./how-to/debug-the-sdk.md) ## Look something up Neutral descriptions of the machinery. Facts, defaults, and constraints, without instruction. - [Configuration](./reference/configuration.md): every field of `SomniaMarketsConfig`, with defaults - [Networks and endpoints](./reference/networks-and-endpoints.md): chain ids, RPC and indexer URLs, address constants - [Symbols](./reference/symbols.md): the symbol grammar and how raw references resolve - [Units and scales](./reference/units-and-scales.md): raw versus human values, decimals, basis points, ray, timestamps - [Read tiers](./reference/read-tiers.md): which methods read the live store, the chain, or the indexer - [Errors](./reference/errors.md): the SDK error classes and the contract error names they decode - The API reference, generated from the source, lists every method, hook, and type. On the docs site it sits in the sidebar under "TypeScript SDK". ## Understand the design Discussion for reading away from the keyboard. - [About the exchange instance](./explanation/about-the-exchange-instance.md): why one object owns the sockets, the store, and the signer - [About symbols and human units](./explanation/about-symbols-and-human-units.md): why the exchange API speaks in symbols and decimal numbers, and what that costs - [Architecture](./ARCHITECTURE.md): the watch seam, event routing, the local order book, reconnects, and the write path ## Area guides One guide per market family or module. Each one covers reading, trading, and background for its area. - [The exchange API](./EXCHANGE.md), [Spot markets](./SPOT.md), [Binary markets](./BINARY.md), [Perps](./PERPS.md) - [Price feeds](./PRICES.md), [SomniaLend](./LEND.md) - [Chains](./CHAINS.md), [Bridge](./BRIDGE.md), [Chains walkthrough](./CHAINS_WALKTHROUGH.md) - [Native RPC](./NATIVE.md), [Reactivity](./REACTIVITY.md) - [The engine](./ENGINE.md): the raw client behind the exchange --- # /docs/typescript/exchange # The exchange API The `SomniaMarkets` class is the SDK's primary surface: markets keyed by symbols, `fetch*`/`watch*`/`createOrder` verbs, human-unit structs — the idioms every exchange bot already speaks (if you've driven a venue through ccxt, nothing here will surprise you, down to the field names). Under the hood it runs on the native engine (scoped watches, local books, one-round-trip writes), so the `watch*` channels are zero-round-trip and `createOrder` confirms in a single round-trip. ```ts import { SomniaMarkets } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets({ indexerUrl, chain, wsRpcUrl, privateKey }); // one per chain await exchange.loadMarkets(); const symbol = "BTC-95000-31DEC26/USDC#YES"; const book = await exchange.watchOrderBook(symbol, 10); // live, zero RTT const order = await exchange.createOrder(symbol, "limit", "buy", 10, 0.62); // … later: await exchange.cancelOrder(order.id, symbol); ``` The raw engine stays available at `exchange.client` — bigint-exact, address-keyed — for anything the exchange verbs don't cover; see [the engine guide](./ENGINE.md). ## Symbols A **symbol names a market**; a **tradable symbol** names something you place orders on. For spot they coincide; for outcome markets each outcome is its own tradable: | Kind | Market symbol | Tradables | | -------------------- | ------------------------ | ------------------------ | | Spot | `SOMI/USDC` | `SOMI/USDC` | | Binary | `BTC-95000-31DEC26/USDC` | `…#YES`, `…#NO` | | Perp | `BTC/USDSO:USDSO` | `BTC/USDSO:USDSO` | | Categorical _(soon)_ | `US-ELECTION-28/USDC` | `…#TRUMP`, `…#NEWSOM`, … | Binary symbols are synthesized as `ASSET-STRIKE-DDMONYY/QUOTE` (quote = the collateral's ERC-20 symbol), with an `-HHMM` expiry component for intraday series markets (`ETH-171780-03JUL26-0930/TUSDC`); any residual collision gets a deterministic 4-hex market-id tiebreaker on the base side of the slash. Everything before `#` follows standard exchange symbol conventions; `#OUTCOME` is our extension (binary markets need one). **Any raw ref works wherever a symbol does** — a pool address, market id, or BinaryMarket address resolves to the same tradable (outcome markets default to `#YES`). Numbers are **human units in the tradable's own terms**: a `#NO` price of 0.38 _is_ the NO probability — the YES-terms complement, raw integers, and escrow math are all internal. Raw payloads ride on every struct's `info`. ## Verbs | Method | Backed by | Notes | | ---------------------------------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `loadMarkets()` / `fetchMarkets()` | indexer (+ one-time `symbol()` reads) | builds the symbol registry | | `fetchOrderBook(symbol, limit?)` | chain | head-fresh one-shot | | `fetchTrades(symbol, since?, limit?)` | indexer | public tape | | `fetchOHLCV(symbol, "5m", since?, limit?)` | indexer | `1m 5m 15m 1h 4h 1d` | | `fetchOpenOrders(symbol?, limit?)` | indexer | authenticated; `limit` is per venue (default 200) | | `fetchMyTrades(symbol?, since?, limit?)` | indexer | authenticated; scoped + windowed at the query, newest-first across venues | | `fetchBalance()` | chain | wallet balances by currency code (incl. binary YES/NO ERC-6909 holdings, keyed by tradable symbol) | | `fetchStatus()` | local | watch/socket health | | `watchOrderBook(symbol, limit?)` | **local store** | zero RTT, current to last block | | `watchTrades(symbol)` · `watchOrders(symbol)` · `watchMyTrades(symbol)` | **local store** | streaming | | `createOrder(symbol, type, side, amount, price?, params?)` | chain write | 1-RTT confirm, fills decoded | | `cancelOrder(id, symbol)` | chain write | | | `mintSet` / `burnSet` / `redeem` `(symbol, amount)` | chain write | outcome markets only | | `fetchFundingRate(symbol)` | chain | perps: mark/index + funding rate | | `fetchPositions(symbols?)` | chain | perps: open MarginBank positions | | `depositMargin` / `withdrawMargin` `(symbol, amount)` | chain write | perps: cross-margin collateral | | `watchPrice(asset)` · `fetchPrice(asset)` | price feed | index price (EMA oracle) — see [Price feeds](./PRICES.md) | | `fetchPriceOHLCV(asset, "1m")` | price feed | index candles: `1m`/`1h`/`1d` | | `fetchTicker(symbol)` | indexer; best-effort chain read on perps | last, 24h change and volume; perps add mark/index/funding/open interest when `getPerpState` succeeds and degrade to candle data when that chain read fails | | `fetchOrders(symbol?, since?, limit?, { offset? })` | indexer | authenticated; order history as one offset-paged set | | `getOrderHistoryPage({ ref?, status?, limit?, offset? })` | indexer | authenticated; preferred indexed-history name; partial raw-row page with immutable identity and continuation | | `getOrdersPage({ ref?, status?, limit?, offset? })` | indexer | compatibility name for `getOrderHistoryPage` | | `fetchPortfolioAnalytics(timeframe, params?)` | indexer | authenticated; PnL, equity and holdings series | | `createStopOrder(symbol, type, side, amount, triggerPrice, price?, params?)` | chain write | spot only; see [Spot markets](./SPOT.md) | | `fetchOpenStopOrders(symbol?)` · `cancelStopOrder(id, symbol)` | indexer · chain write | spot stop orders | | `fetchFundingRateHistory(symbol, since?, limit?)` | indexer | perps: funding-rate history | | `setSigner({ privateKey \| account \| walletClient })` | local | bind or replace the signer after construction | | `priceToPrecision(ref, price)` · `amountToPrecision(ref, amount)` | local | snap a value down onto the market's tick or lot grid | | `market(ref)` | local | resolve any handle to its tradable | | `close()` | local | release all watches, channels, and sockets; a Node script exits on its own afterwards | Still reserved: `watchPositions`, `setLeverage` (the raw `trader.setPerpLeverage` exists for the latter). ### Paginated order identity `getOrderHistoryPage` reads one bounded page for the configured account. Use it when the caller must retain the chain, account, market, pool, and order id together. `getOrdersPage` remains available as a compatibility name. The default limit is 100 and the default offset is 0. A `status` filter runs in the indexer. A `ref` also scopes the query to its pool, then verifies each raw market id so a recycled binary pool cannot cross market lifetimes. `rowsRead` counts raw indexer rows. `nextOffset` advances after a full raw page, even when outcome filtering removes every display order or every identity is unresolved. The `unresolved` list keeps rows whose immutable market id is absent or inconsistent in the loaded registry. A null binary side remains on the YES book. A NO scope excludes that row. Every result has `coverage: "partial"` and `source: "indexer-offset"`. These are indexed mutable records. They are not an immutable lifecycle log or a current Open Orders snapshot. The indexer orders rows by placement time without a frozen revision or a unique tie-break. Concurrent inserts or status changes can make pages skip or repeat rows. A short page does not prove complete account state. The `status` option filters indexed history. `status: "Open"` cannot establish completeness, removals, continuity, or action freshness. Use a separately supported current-state flow when the caller needs the SDK's current open-order view. Each flow retains its documented freshness limits. ```ts let offset = 0; while (true) { const page = await exchange.getOrderHistoryPage({ limit: 100, offset }); for (const order of page.orders) console.log(order.identity, order.status); if (page.nextOffset === null) break; offset = page.nextOffset; } ``` ### The `watch*` idiom Each `await` resolves when the channel next changes; the first call resolves immediately after the (ref-counted) market watch hydrates: ```ts while (running) { const book = await exchange.watchOrderBook(symbol, 5); // resolves per change requote(book.bids[0], book.asks[0]); } ``` **"Did my resting order fill?"** — watch your orders and look for the status flip: ```ts const orders = await exchange.watchOrders(symbol); // resolves per change const mine = orders.find((o) => o.id === orderId); if (mine?.status === "closed") … // filled ``` ### `createOrder` params - `type: "limit" | "market"` — market orders compute a crossing limit from the best opposite level ± `params.slippage` (default 1% on this surface; the engine's `quoteBinaryStake` / `quoteBinarySell` helpers default to 3% with a 10-tick floor) and send IOC; they throw `InvalidInputError` if the opposite side is empty. When the chain rejects an order you get a `ContractRevertError` whose `errorName` is the contract's own error — see [ENGINE.md § Errors](./ENGINE.md#errors--branch-on-the-type-never-the-message). - `params.timeInForce: "GTC" | "IOC" | "FOK" | "PO"` (or `postOnly: true`) — maps to the on-chain order types. - `params.builder` / `params.builderFeeBpsTimes1k` — attribute the order to a routing/builder frontend and pay it a per-order fee (pool bps×1000 unit). Requires a prior one-time `exchange.trader.approveBuilder({ pool, builder, maxFeeBpsTimes1k })` opt-in on the pool, else a non-zero fee reverts (`BuilderFeeExceedsCap` on binary, `BuilderNotApproved` on spot, `BuilderFeeExceedsApproval` on perp). Works on binary, spot and perp — but the approval is stored per pool, so opt in on each pool you attribute orders on. - The returned order: `status: "open"` (rested), `"closed"` (fully filled in the same round-trip — `filled`/`remaining` say how much), or `"canceled"` (IOC remainder). `info` carries the receipt + raw fills. ## Structs One set of shapes throughout: markets `{ id, symbol, type, base, quote, active, precision, limits, outcomes?, info }`; books as `[price, amount]` pairs, best first; orders `{ id, symbol, type?, side, price, amount, filled, remaining, status, timestamp, info }` (`type` is absent on orders read back from the indexer — the pools do not emit it); trades `{ id, symbol, price, amount, cost, side?, timestamp, info }`; balances `{ [code]: { free, used, total } }` (escrowed funds live in the pools, so wallet `free === total`); OHLCV rows `[ms, open, high, low, close, baseVolume]`. ## How each market kind maps - **Spot** — symbol is the tradable; `side` is base-buy/base-sell; done. - **Binary** — two tradables per market. The engine keeps one YES-terms book; the resolver presents each outcome's own view (prices, sides, candles all outcome-relative). `mintSet`/`burnSet`/`redeem` operate at market level. - **Perps** — `type: "swap"`, settle = quote (linear, collateral-settled); `createOrder` unchanged (margin locks from your MarginBank balance — `depositMargin` first); `fetchPositions`/`fetchFundingRate` read the MarginBank/pool live. - **Categorical / multi-outcome** _(teed up)_ — N tradables on one pool (outcome index = the order's `userData`, exactly as binary uses 0/1 today); same verbs, and cross-book complete-set fills will surface in `watchMyTrades` with a shared match id in `info`. The design intent: **the verbs never change again** — every future market kind is new data (a `type`, an `outcomes[]` list), not new API. --- # /docs/typescript/binary # Binary markets A binary market is an order book over a YES/NO question ("Will BTC be above $95k at expiry?"). Each market deploys a `BinaryMarket` contract (lifecycle, resolution) and a `BinaryPool` (the CLOB + escrow) with a YES and a NO outcome token backed 1:1 by collateral. This guide covers reading and trading them; the shared client mechanics (watches, read tiers, signers) are in [the engine guide](./ENGINE.md). ## The mental model - **Prices are YES probabilities.** Every price in the API is the YES price in raw collateral units per whole outcome token — `620000` with 6-decimal collateral means 0.62, i.e. a 62% implied probability. Convert with `probabilityToPrice` / `priceToProbability`, and `fromHuman` / `toHuman` at the UI edges. The NO side is always the complement: a NO at 0.38 _is_ a YES at 0.62 — the pool keeps ONE book in YES terms. - **Four sides, one book.** `BinarySide` is `BUY_YES | SELL_YES | BUY_NO | SELL_NO`. Buys escrow collateral; sells escrow the outcome token you're selling. Opposite-side orders can match by _minting_ a fresh YES+NO pair from collateral (two buyers) or _burning_ one back to collateral (two sellers) — the `BinaryFillKind` on a fill tells you which. - **Lifecycle.** `Listed → Trading → Locked → Settling → Resolved | Voided → Finalized` (`BinaryMarketStatus`; `Finalized` once the settlement snapshot is swept and the pool released). Trading is only possible in `Trading`; after resolution the winning token redeems 1:1 for collateral, net of the venue's one-time settlement fee if it configured one. A voided market pays BOTH sides instead, from the payout vector it stored at void time, never fee'd — so redeeming one names the leg (see Complete sets and settlement). - **Markets roll themselves.** Each cadence (1m / 5m / 15m / 1h / 4h / 24h) is a _series_ that a `MarketCreator` contract advances autonomously — at every wall-clock boundary it clones the next `BinaryMarket` + `BinaryPool` and schedules the oracle question. Series markets are **reference-mode**: there is no fixed strike (the event's `strike` is always 0) — a market resolves YES iff its own oracle answer is at/above the previous boundary's _reference_ answer. Markets can also be created directly via `BinaryMarketsModule.createMarket` under an operator's venue (these can be bucket-mode, with a real strike). Discovery is event-driven either way: an all-markets watch with `discover` picks each new market up from the creation events (see below). You don't need to create markets — you watch, trade, and redeem them. ## The series, and how a market is born `MarketCreator` runs the whole protocol off **one** Somnia reactivity `Schedule` subscription (the precompile at `0x0100`). When it fires, a single callback drains that boundary's whole batch of due series in a **gas-bounded loop** — rolling series until the gas envelope runs low — then re-arms the `Schedule` sub for the next-earliest pending boundary. A batch too large for one callback (the 00:00-UTC collision, where every cadence lands at once) saves a resume index and arms a sub for the **next block** to finish the spill. Exactly one subscription is ever live. (Historical note: an earlier one-series-per-hop `RollNext` reentrancy chain was tried and removed — on live Somnia the self-emitted event wasn't re-queued after a heavy roll, so it stalled after one hop. The gas-bounded loop with next-block spill replaced it.) Each roll emits, from the `MarketCreator`: ``` MarketCreated( bytes32 marketId, address market, address pool, uint256 yesId, uint256 noId, address collateral, string asset, uint256 strike, // always 0 — series markets are reference-mode (no fixed strike) uint64 tradingStart, uint64 expiry, uint256 oracleQuestionId, string question, uint64 intervalSec // series cadence: 60 / 300 / 900 / 3600 / 14400 / 86400 ) ``` Every market — series-rolled or not — ALSO fires the `BinaryMarketsModule`'s own 20-field `MarketCreated`, the only creation event carrying the `(operatorId, venueId)` origin attribution. A discovery watch (`watchMarkets({ discover: true })`) listens to both, so module-created markets that never pass through a `MarketCreator` join the watch live too. - **Read cadence from `intervalSec`, and treat it as approximate.** A series' first market is a _bootstrap partial_ (trigger time → the next aligned boundary), so its window is shorter than the cadence. On the SDK's `BinaryMarket` type the cadence surfaces as `intervalSec?: string | null` (`null` when a market predates the field). For a `MarketCreator`-rolled market the indexer patches the exact cadence from `MarketCreator.MarketCreated.intervalSec`, so the field joins by equality. Module-created markets, and rows indexed before that patch existed, still carry the window-derived `expiry − tradingStart`, which a late roll shortens to 898s or 899s on a 15m series. `BinaryMarketFilter.intervalSec` bands the value (± `CADENCE_TOLERANCE_SEC`) and `snapToCadence` groups by the same rule, so both kinds of row match; use those rather than comparing the raw field. **Resolution is a separate loop.** When a market expires, the `ProphecyOracle` posts an `AnswerPosted(uint256 questionId, uint8 outcomeIdx, string outcomeLabel, int256 numericValue, bool voided, VoidReason reason, uint256[] receiptIds)`; the `ProphecyOracleAdapter`'s event subscription catches it and routes to `BinaryMarketsModule`, which resolves the market (or voids it). The SDK sees this as a `Resolved` / `Voided` lifecycle event on the `BinaryMarket` — gate redemption on that, per the rule below. ## Reading Watch the market, then read the live store — synchronous, zero round-trips, current to the last block: ```ts const watch = await client.watchMarket(market.poolAddress); const book = client.getLiveBinaryOrderBook(market.poolAddress, { depth: 11 }); // { yesBids, yesAsks, noBids, noAsks } — NO sides derived as 1 − yesPrice const tape = client.getLiveFills(market.poolAddress, { limit: 40 }); const live = client.getLiveMarketByPool(market.poolAddress); // status, lastPrice, volumes ``` In React the hooks watch automatically: `useLiveBinaryOrderBook(pool)`, `useLiveFills(pool)`, `useLiveMarketByPool(pool)`, `useLiveUserOrders(pool, account)`. Discovery and history come from the indexer tier: `listLiveBinaryMarkets()` / `listPastBinaryMarkets({ limit, offset })` for the market lists, `getCandles(pool, interval)` for charts, `getPortfolio(account)` (trades default to the last seven days — `tradesSince` echoes the bound; pass `since` to widen) for a wallet's positions + orders + trades in one round-trip. `listLiveBinaryMarkets()` with no argument returns every live market; pass a filter to narrow (all fields optional, applied server-side): ```ts await client.listLiveBinaryMarkets(); // all live markets await client.listLiveBinaryMarkets({ operatorId: 1 }); // one operator's live board await client.listLiveBinaryMarkets({ venueId: "0x5bc0…", asset: "BTC", intervalSec: 900 }); await client.listLiveBinaryMarkets({ status: "Trading" }); // active only ``` (`operatorId` is the uint32 operator id; `venueId` is the venue's opaque bytes32 hex id — enumerate the pairs in play with `listBinaryVenueIds()`.) For the underlying-asset universe and board size, use `listBinaryAssets()` (the distinct assets with markets, e.g. `["BTC","ETH"]`) and `countBinaryMarkets({ operatorId?, venueId?, asset?, status? })` (the total behind a filtered board, for pagination headers). Each row carries `marketAddress`, `poolAddress`, `operatorId`, and `venueId`, so a multi-venue UI can group the live board by origin without any contract-level call — market discovery is the indexer's job, not the MarketCreator's. One correctness rule: **gate writes on live or on-chain status, never indexer status** — `getLiveMarketByPool(...).status` (chain events) or `getMarketOnchain(marketAddress)` are authoritative; the indexed status lags. ### History + attribution (indexer) Beyond the live board and portfolio, the indexer serves the fee, resolution, router, and vault-credit history the live tail doesn't materialize — all one-shot reads: ```ts // How a market resolves: lifecycle events + the oracle reference link + the // posted numeric oracle answer (joined by oracleQuestionId), in one round-trip. const { events, reference, oracleAnswer } = await client.getMarketResolution(marketId); // Router-level collateral flow for a wallet (redeem / mint / merge complete set), // attributed to the TRUE end user even through the native/Permit2 periphery. const actions = await client.getRouterActions(account, { market, limit: 50 }); // The per-fill fee streams behind getMarketFees' running total (all filter by // `payer` — the order owner who funded the fee — plus recipient/market/pool). const protoFees = await client.listProtocolFees({ market, payer }); const bldFees = await client.listBuilderFees({ builder }); const settleFees = await client.listSettlementFees({ market }); // Builder-approval directory (the indexed complement to the on-chain point read // getBuilderApproval) — every user→builder cap, filterable by user or builder. const approvals = await client.listBuilderApprovals({ user }); ``` **Vault credits.** A payout that can't be delivered to the wallet is credited to the owner's `ERC20Vault` balance instead. That history is append-only — `client.getVaultPayoutFallbacks(owner, { token })` lists the credit log — but the vault's own credit/debit is silent (no event), so the **live claimable balance is a chain read**: `client.getVaultBalance({ vault, owner, token })` (`ERC20Vault.getWithdrawableBalance`). Withdraw with `trader.withdrawVault({ vault, token, amount })`. ## Trading ```ts const trader = client.createTrader({ privateKey }); // Node — or { walletClient } in the browser // Rest a limit order: buy 10 YES at 0.62. const { orderId, fills, receipt } = await trader.placeOrder({ pool: market.poolAddress, side: "BUY_YES", price: probabilityToPrice(0.62), // raw collateral units per whole token quantity: fromHuman(10), // raw outcome-token units }); if (fills.length) console.log("crossed immediately:", fills); else console.log("resting as order", orderId); await trader.cancelOrder({ pool: market.poolAddress, orderId }); ``` Every write **awaits its receipt** — there is no bare hash to babysit, and `placeOrder` resolves with the decoded `orderId` + `fills` from the same round-trip. The escrow token (collateral for buys, YES/NO for sells) is approved automatically on first use; pass `autoApprove: false` to manage approvals yourself. - **Market orders** are `orderType: ORDER_TYPE.MARKET` (an IOC) placed at a crossing price — cross the best opposite level ± slippage so it sweeps and the remainder cancels. `ORDER_TYPE` also has `FILL_OR_KILL` and `POST_ONLY`. - **Sides and prices:** all four `BinarySide`s take the YES-terms price. A `BUY_NO` at YES-price 0.62 escrows `quantity × (1 − 0.62)` collateral. - Token wiring resolves from the pool contract automatically (cached); pass `outcomeToken`/`yesId`/`noId`/`collateral` explicitly to skip even that one-time read. ### Stake-sized market orders ("bet $50 on Up") A stake-first UI usually asks for a **collateral stake**, not a share quantity. `quoteBinaryStake` is the inverse of `quoteBinaryOrder`: it walks the live asks cheapest-first, sizing the largest quantity whose escrow at the worst level touched stays within the stake — so the quoted shares and payout match what actually fills, not a top-of-book estimate. The protective limit is padded with a slippage cushion (default 3%, min 10 ticks) so the IOC still crosses a moving book, aligned to the pool's on-chain tick grid, and the quantity is lot-aligned with escrow re-fit under the stake — off-grid prices and non-lot quantities are the pool's two rejection reasons, handled for you: ```ts const quote = await client.quoteBinaryStake({ pool: market.poolAddress, side: "BUY_YES", // Up; "BUY_NO" for Down stake: fromHuman(50), // raw collateral — the max loss }); if (quote) { await trader.placeOrder({ pool: market.poolAddress, side: quote.side, price: quote.yesPrice, // protective limit, YES terms quantity: quote.quantity, // shares = payout if this side wins orderType: ORDER_TYPE.MARKET, }); } ``` `null` means nothing is fillable (empty book, or a stake too small for one lot) — disable the control rather than sending a doomed order. Unwind a position with the sell-side sibling, which cushions a floor below the best bid the same way: ```ts const sell = await client.quoteBinarySell({ pool: market.poolAddress, side: "SELL_YES", quantity: position.balance, // lot-aligned down automatically }); if (sell) { await trader.placeOrder({ pool: market.poolAddress, side: sell.side, price: sell.yesPrice, quantity: sell.quantity, orderType: ORDER_TYPE.MARKET, }); } ``` Unlike the buy side, a sell's `quantity` is your position, not a book-sized fit — on a thin book the IOC fills what rests within the cushion and cancels the rest. Compare `sell.fillableQuantity` (with `sell.estProceeds`, the collateral it would raise) against `sell.quantity` and warn before submitting when the unwind would be partial. Both quotes read the live book (needs an active watch) plus the pool's tick/lot grid via one cached `eth_call` (`getBinaryBookParams`). The pure kernels — `quoteBinaryStakeOverBook` / `quoteBinarySellOverBook` / `slippageForCrossing` — are exported for callers that already hold a book. ### Builder / routing fees (optional) A frontend that routes orders can attach itself to each order and charge a per-order fee — but only after the trader has opted it in on that pool: ```ts await trader.approveBuilder({ pool, builder, maxFeeBpsTimes1k: 5_000n }); // allow up to 5 bps; 0 revokes await trader.placeOrder({ pool, side: "BUY_YES", price, quantity, builder, // the routing/builder frontend builderFeeBpsTimes1k: 5_000n, // per-order fee, pool bps×1000 unit }); ``` A non-zero `builderFeeBpsTimes1k` without a prior approval reverts `BuilderFeeExceedsCap` on a BinaryPool (`BuilderNotApproved` on a SpotPool, `BuilderFeeExceedsApproval` on a PerpPool). The enforced ceiling is the trader's approval clamped by the pool's protocol-wide cap — read it with `trader.getEffectiveBuilderApproval({ pool, user, builder })` (the pool-wide cap alone is `trader.getMaxBuilderFeeBpsTimes1k(pool)`). On the exchange surface the same rides `createOrder`'s `params.builder` / `params.builderFeeBpsTimes1k`, on binary, spot and perp alike — each pool holds its own approval, so opt in once per pool. ### Complete sets and settlement ```ts await trader.mintSet({ pool, amount }); // collateral → equal YES + NO await trader.burnSet({ pool, amount }); // YES + NO → collateral back await trader.redeem({ market: marketAddress, amount }); // winning token → collateral (post-resolution) // A VOIDED market has no winner — both legs pay — so name the leg yourself. // One entry per leg claims both in a single transaction: await trader.redeemMany({ entries: [ { marketId, outcomeIdx: 0, amount: yesAmount }, { marketId, outcomeIdx: 1, amount: noAmount }, ], }); ``` `mintSet`/`burnSet` are how you take (or unwind) a both-sides position without touching the book; `redeem` pays out after resolution (it looks up the winning outcome on-chain if you don't pass it). That lookup is **resolution-only**: a voided market has no winning outcome, so `redeem` throws unless you pass `outcomeIdx` — it will not guess a leg for you, because on a void both legs are redeemable and only you know which you hold. An unresolved market also throws; the SDK reads the payout vector only after confirming resolution. If the venue configured a settlement fee, the pool skims it ONCE from the whole winning backing at the first winning redeem (`SettlementFeeCharged`) and every winner redeems for `1 − fee` — voided markets refund both sides with no fee. Demo-stack extras: `faucet()` mints the test collateral; `resolve`/`voidMarket` drive the FakeOracle. #### Unified exchange redemption The exchange wrapper takes display units rather than raw token amounts. On a resolved market it selects the indexed winner: ```ts await exchange.redeem(symbol, winningAmount); ``` A voided market has no single winner. Pass the leg you hold and call once for each leg you want to redeem: ```ts await exchange.redeem(symbol, yesAmount, { outcomeIdx: 0 }); ``` The SDK rejects a malformed or impossible final payout vector. Only an absent vector on a legacy market uses the compatibility fallback. ### A maker loop, end to end ```ts const watch = await client.watchMarket(pool); const trader = client.createTrader({ privateKey }); client.subscribeLive(async () => { const book = client.getLiveBinaryOrderBook(pool, { depth: 1 }); // zero RTT const mine = client.getLiveUserOrders(pool, me, { limit: 50 }).filter((o) => o.status === "Open"); // zero RTT // decide → place/cancel; each write resolves after its receipt arrives }); ``` The live store is the only state a quoting loop needs: the book, your working orders, and fills all update the moment the chain emits them. --- # /docs/typescript/spot-markets # Spot markets A spot market is a plain base/quote order book on a `SpotPool` (e.g. SOMI/USDC) — same OrderBook core as the binary pools, so the live machinery is identical; only the semantics differ. This guide covers reading and trading spot; the shared client mechanics (watches, read tiers, signers) are in [the engine guide](./ENGINE.md). ## The mental model - **Prices are quote-per-base.** Raw quote units per whole base token, scaled by the market's own `quoteDecimals`/`baseDecimals` (spot markets are NOT assumed 6dp — read the decimals off the `SpotMarket` row). - **Two sides.** `isBid: true` buys base (escrows quote); `false` sells base (escrows base — or sends native SOMI as `msg.value` when `baseIsNative`). ERC-20 approval checks use `requiredAmount`, which is the pool's worst-case reserve including fee headroom. A native sell sends `delta`, which subtracts the owner's current vault balance from that reserve. Sending only the bare quantity can revert with `InvalidMsgValue` on a fee-bearing pool. - **Book constraints.** Orders must respect the pool's `tickSize`, `lotSize`, and `minQuantity` (all on the `SpotMarket` row, kept live by the watch). - **Mark price.** Pools publish a smoothed `markPrice` (streamed live via `MarkPriceUpdated`) — it's what stop orders trigger on, distinct from `lastPrice` (last fill). ## Reading Discover markets first (indexer tier) — `listSpotMarkets` returns the board and `getSpotMarket` resolves one by id; both yield the `SpotMarket` rows the live reads key off: ```ts const markets = await client.listSpotMarkets({ limit: 50 }); // SpotMarket[]; filterable (base/quote/…) const spot = await client.getSpotMarket(id); // SpotMarket | null ``` ```ts const watch = await client.watchMarket(spot.poolAddress); const book = client.getLiveSpotOrderBook(spot.poolAddress, { depth: 11 }); // { bids, asks }, best first const tape = client.getLiveFills(spot.poolAddress, { limit: 40 }); const live = client.getLiveMarketByPool(spot.poolAddress); // markPrice, tick/lot, stats ``` React: `useLiveSpotOrderBook(pool)`, `useLiveFills(pool)`, `useLiveMarketByPool(pool)` — all auto-watch while mounted. History and wallet views come from the indexer tier: `getCandles(pool, interval)`, `getSpotPortfolio(account)` (open orders + pending stops + the last seven days of trades by default — `tradesSince` says which; pass `since` to widen), and `getSpotStopOrders(account, { pool })`. Holdings are plain balances — read them on-chain with `getErc20Balance` / `getNativeBalance`, not from the indexer. ## Trading ```ts const trader = client.createTrader({ privateKey }); // Rest a limit bid: buy 5 base at 1.25 quote. const { orderId, fills } = await trader.placeSpotOrder({ pool: spot.poolAddress, isBid: true, price: parseUnits("1.25", spot.quoteDecimals), quantity: parseUnits("5", spot.baseDecimals), quoteToken: spot.quoteToken, baseToken: spot.baseToken, baseIsNative: spot.baseIsNative, }); await trader.cancelOrder({ pool: spot.poolAddress, orderId }); // same core as binary ``` ### Per-order fields: expiry, attribution, self-match, user data `placeSpotOrder` takes these per-order fields as optional inputs. Each one has an SDK default that keeps today's behaviour, so an existing call is unaffected: ```ts await trader.placeSpotOrder({ ...order, expireTimestampNs: BigInt(Date.now() + 86_400_000) * 1_000_000n, // default: ~50y (GTC) builder: "0xYourFrontend", // default: the zero address (no attribution) builderFeeBpsTimes1k: 25_000n, // default: 0 selfMatchingOption: SELF_MATCHING_OPTION.CANCEL_MAKER, // default: CANCEL_TAKER userData: 7n, // default: 0 — an opaque tag, never interpreted }); ``` `placeSpotOrders`, `placeOrder` (binary), `placePerpOrder`, `amendOrder` and `amendOrders` take the same `selfMatchingOption`, and the batch verbs take it per request. **Self-match.** A pool matches your incoming order against your own resting order, and `selfMatchingOption` says which side loses. `CANCEL_TAKER` (0) drops the rest of the incoming order and leaves the resting one on the book; `CANCEL_MAKER` (1) cancels the whole resting order and lets the incoming one continue. **The 0 is the SDK's default, not the pool's** — the pool reads the value out of every order request and has no default of its own, so a raw integration must pass it. Reach for `CANCEL_MAKER` when the new quote matters more than the old one, such as re-pricing a ladder into your own resting rungs; keep `CANCEL_TAKER` when a self-cross means you made a mistake and want the order rejected. In a batch a `CANCEL_TAKER` self-match is one of the benign non-placements: the rung reports `outcomes[i].success === false` rather than taking the batch down. **The ceiling.** A non-zero `builderFeeBpsTimes1k` must stay within `trader.getMaxBuilderFeeBpsTimes1k(pool)`. Read that cap rather than assuming it: it is owner-updatable on a SpotPool, and while it is 0 the pool rejects builder codes outright, so the rail is off on that venue. **The approval.** A non-zero fee also needs a prior `trader.approveBuilder({ pool, builder, maxFeeBpsTimes1k })`. Spot pools implement the same builder calls as binary ones, but **the approval is stored per pool** — approving a builder on one pool grants nothing on another, and an unapproved placement reverts `BuilderNotApproved`. > **A past expiry reverts.** A placement whose `expireTimestampNs` is already > behind the chain clock fails with `OrderAlreadyExpired`. Earlier protocol > versions accepted it silently — the pool skipped the placement and returned no > order id, so the transaction still succeeded — but it now rejects outright. > The batch verb differs: `placeSpotOrders` rejects the offending request on its > own rather than taking the whole batch down, so there you check > `outcomes[i].success` — an already-expired expiry is one of the benign > non-placements it reports. > **Expiry does not refund by itself.** When a spot order lapses its escrow > stays locked in the pool until someone sweeps it — > `trader.cancelExpiredOrders({ pool, orderIds })` reclaims it, and is callable > by anyone, not only the owner. Set an expiry deliberately. Escrow is approved automatically (quote on buys, base on non-native sells; native-base sells pay via `msg.value` instead). A **market order** is `orderType: ORDER_TYPE.MARKET` with a crossing price — take the live book's best opposite level ± slippage, tick-aligned, so it sweeps and the remainder cancels: ```ts const best = client.getLiveSpotOrderBook(pool, { depth: 1 }); // zero RTT, last-block fresh const crossing = (best.asks[0].price * 10100n) / 10000n; // +1% slippage bound ``` ### Amending a quote set Re-pricing a ladder one order at a time costs two transactions per rung and leaves the book briefly one-sided. `amendOrders` cancels each old order and places its replacement in a single transaction: ```ts const { newOrderIds } = await trader.amendOrders({ pool: spot.poolAddress, amendments: [ { oldOrderId: bid1, newOrder: { isBid: true, price: newBid1, quantity: qty } }, { oldOrderId: bid2, newOrder: { isBid: true, price: newBid2, quantity: qty }, alwaysPlace: true }, ], }); ``` It is **all-or-nothing** — any bad request reverts the whole batch, so the book never sees a partial re-quote. `newOrderIds` is index-aligned with `amendments`. `alwaysPlace` handles the race where the order you meant to amend already filled or was cancelled. False (the default) reverts `AmendOldOrderGone`; true skips the cancel leg and places the replacement anyway. It never tolerates an ownership failure — a live order owned by someone else still reverts. For ONE order, use `amendOrder` rather than a one-element batch: ```ts const { newOrderId } = await trader.amendOrder({ pool: spot.poolAddress, oldOrderId: bid1, newOrder: { isBid: true, price: newBid1, quantity: qty }, }); ``` The difference is the error you get back. The singular raises the replacement's own landing-time reason — `PostOnlyWouldCross`, `FillOrKillNotFillable` and friends — where the batch wraps it as `AmendReplacementRejected(requestIndex, reason)`. With one order that index tells you nothing you did not already know, and you have to unwrap it to find the reason. Everything else matches: same `alwaysPlace` race rule, same lost queue priority, same non-payable funding constraint. Amend re-inserts at the back of the price-time queue. To shrink an order **without** losing queue priority, use `reduceOrder` instead. Three things to know before re-laddering with it: - **Replacements are not shielded from each other.** Cancelling all the old orders first protects a replacement from the order it replaces — but not from the _other_ replacements in the same batch. If a new bid crosses a new ask, `CANCEL_TAKER` (the SDK's default when you omit `selfMatchingOption`) rejects it, and because amend is all-or-nothing the whole re-ladder reverts. Keep the new set uncrossed, or set `selfMatchingOption` per replacement. - **The revert names the rung.** A rejected replacement reverts `AmendReplacementRejected(requestIndex, reason)` — `requestIndex` is the position in your `amendments` array and `reason` is the pool's `uint8` rejection code (the SDK does not export a name table for it). That is the signal to branch on; `AmendOldOrderGone` is a different, earlier failure from the cancel leg. - **Approve the escrow first.** Unlike `placeSpotOrder`, `amendOrders` does not auto-approve. On an auto-pull pool the cancel leg returns the freed tokens to your wallet and the place leg pulls them back, which needs an allowance — so a trader whose _first_ call is `amendOrders` hits `ERC20InsufficientAllowance`. Place once (or approve manually) before amending. **Not for BinaryPools** — amend places, and binary pools reject generic placement with `UseBinaryPlacement`. Spot and perp only. Note that error is what you hit on a _live_ binary market; a locked one reverts `TradingNotActive` and a malformed replacement reverts on validation first, so don't branch on `UseBinaryPlacement` alone to detect the wrong pool kind. ### Batches — place a ladder, pull a ladder Market making means many orders at once. `placeSpotOrders`, `cancelOrders` and `reduceOrders` each do a whole ladder in ONE transaction instead of a loop of sends: ```ts // Place a three-rung sell ladder. const placed = await trader.placeSpotOrders({ pool: spot.poolAddress, quoteToken: spot.quoteToken, baseToken: spot.baseToken, orders: [1.01, 1.02, 1.03].map((p) => ({ isBid: false, price: parseUnits(String(p), spot.quoteDecimals), quantity: parseUnits("1", spot.baseDecimals), })), }); // outcomes is index-aligned with `orders`; a rung that did not place is // success:false (e.g. a PostOnly that would have crossed), NOT an error. const ids = placed.outcomes.flatMap((o) => (o.success ? [o.orderId!] : [])); // Pull what is left. Best-effort: an id that filled meanwhile is skipped, so // the other rungs still come off the book. const pulled = await trader.cancelOrders({ pool: spot.poolAddress, orderIds: ids }); const skipped = pulled.outcomes.filter((o) => !o.cancelled).map((o) => o.orderId); ``` Three things to know before using them: - **They are non-payable.** Unlike `placeSpotOrder`, a batch sends no `msg.value`, so a **native-base sell** funds from the pool's vault balance — pre-deposit native to the vault first. ERC-20 auto-pull works normally, and the batch approves each escrow token once for the whole batch's total. - **`placeSpotOrders` is spot-only.** Binary pools reject generic placement with `UseBinaryPlacement` (the YES/NO kind must be explicit) — use `placeOrder` there. `cancelOrders` and `reduceOrders` are inherited from the shared order book, so they work on binary pools too. - **Cancel is best-effort, reduce is atomic.** A stale id in `cancelOrders` is skipped; a single invalid reduction in `reduceOrders` reverts the whole batch. A cancel `false` says the id emitted no event — it does not say _why_, so a benign fill race and a wrong id look the same. - **Every per-order field is per rung.** `orderType`, `expireTimestampNs`, `selfMatchingOption`, `userData`, `builder` and `builderFeeBpsTimes1k` are read off each request, so a ladder can attribute one rung to a builder and leave the next unattributed. A rung that omits a field gets the same default the single verb applies. - **Tag rungs with `userData` if exact attribution matters.** Outcomes are matched to requests on every field the `OrderPlaced` event echoes (side, price, quantity, userData, expiry). Two byte-identical adjacent rungs with different outcomes are indistinguishable from logs — the earlier index gets the credit; a distinct `userData` per rung removes the ambiguity. ### Stop orders Spot pools with a `stopRegistry` support stop-loss / take-profit orders that rest OFF the book and fire when the **mark price** crosses the trigger: ```ts await trader.placeSpotStopOrder({ registry: spot.stopRegistry, pool: spot.poolAddress, isBid: false, // sell when the market drops… quantity: parseUnits("5", spot.baseDecimals), triggerPrice: parseUnits("1.10", spot.quoteDecimals), triggerOperator: 1, // 1 = LTE (mark ≤ trigger), 0 = GTE stopOrderType: 1, // 1 = MARKET at trigger, 0 = LIMIT (needs limitPrice) quoteToken: spot.quoteToken, baseToken: spot.baseToken, baseIsNative: spot.baseIsNative, }); await trader.cancelStopOrder({ registry: spot.stopRegistry, orderId }); ``` Under the hood the first stop order per account performs a one-time operator approval (so the registry may place the triggered order for you), funds the trigger gas with a small SOMI payment (`msg.value`, refunded on cancel), and ensures the pool can pull the escrow at trigger time — including pre-loading the pool vault for native-base sells. The SDK handles all of it; list pending stops with `getSpotStopOrders(account, { pool })` and stream their market context via the watch. --- # /docs/typescript/perps # Perpetuals Perps are live on testnet: `BTC/USDSO:USDSO` and `ETH/USDSO:USDSO`, backed by PerpPool CLOBs riding the same shared OrderBook core as spot and binary. ## The shape `Market` is a three-way discriminated union — `SpotMarket | PerpMarket | BinaryMarket`, keyed on `marketType` (guards: `isSpotMarket` / `isPerpMarket` / `isBinaryMarket`). A `PerpMarket` is a plain base/quote book plus perp state: `marginBank`, `initialMarginBps`, `fundingRate`, `cumulativeFundingPerUnit`, `indexPrice`, `openInterest`, `fundingWindowSec`, `fundingIntervalSec`. > **`fundingRate` is per CALCULATION WINDOW** (`fundingWindowSec`, 28800s / 8h on every > live pool) — not per settlement interval and not annualized. Each settlement accrues > `rate / n` where `n = fundingWindowSec / fundingIntervalSec`: **8** on every live pool > (3600s settlement). It has been **96** at a 300s cadence, and the same value means a 12x > different per-interval accrual across that boundary — which still reaches anyone reading > indexed history, so read `n` off each row rather than assuming it. Normalize with the > helpers > (`fundingRate8h`, `fundingRate1h`, `fundingRatePerInterval`, `annualizedFundingRate`), > never with a hardcoded denominator. > > `openInterest` replaced `longOpenInterest` + `shortOpenInterest`: the contract keeps ONE > counter because the short side is provably equal in a matched CLOB. The removed pair was > `null` on every row — the subscription feeding it was dead. - **Watches and live reads are unchanged.** Perp pools emit the same order events, so `watchMarket(pool)`, `getLiveSpotOrderBook`-style depth, `getLiveFills`, `getLiveUserOrders`, and the React hooks just work. Funding (`FundingUpdated`) and open interest (`OpenInterestUpdated`) stream into the perp market row live. - **Margin, not escrow.** Collateral (USDso) lives cross-margin in the MarginBank: `trader.depositMargin` / `withdrawMargin` move it; `trader.placePerpOrder` (or plain `createOrder` on a perp symbol) locks margin from that balance — no per-order token approval. - **Re-quoting a ladder? Amend it atomically.** `trader.amendOrders` cancels N orders and places their replacements in one transaction (see SPOT.md for the full semantics). On a perp pool it needs no token fields at all — margin comes from the MarginBank, so there is no escrow to approve. - **Builder attribution.** `placePerpOrder` takes optional `builder` / `builderFeeBpsTimes1k` (alongside its existing `expireTimestampNs`), both defaulting to no attribution. A non-zero fee needs a prior `trader.approveBuilder({ pool, builder, maxFeeBpsTimes1k })` and must stay within `trader.getMaxBuilderFeeBpsTimes1k(pool)` — read it rather than assuming it, since it is owner-updatable on a PerpPool and the rail is off while it is 0. Perp pools implement the same builder calls as binary ones, but **the approval is per pool**: approving a builder on one pool grants nothing on another, and an unapproved placement reverts `BuilderFeeExceedsApproval` (a PerpPool has no separate "not approved" check — an absent approval is simply a zero cap). - **Positions are on-chain reads**, not indexed rows: `client.getPerpPosition({ marginBank, account, pool })` and `client.getMarginAccount(marginBank, account)` — or the unified `exchange.fetchPositions()`. Live pricing/funding comes from `client.getPerpState(pool)` / `exchange.fetchFundingRate(symbol)`. - **MONITORING a mark feed is a different read.** `client.getPerpFeedStatus(pool)` answers whether the mark is live and how much open interest rides on it. `getPerpState` batches with `allowFailure: false` and one of its legs is a bare `IOracle.getPrice()`, so a dead or rotated oracle rejects the whole read — losing the verdict in the one case it matters most. `getPerpFeedStatus` keeps the mark verdict and open interest as a pair no oracle can revert, and degrades the index timestamp to `undefined` instead. Use `getPerpState` when you want the full pricing and funding picture and a dead oracle should fail the call. - **…except when you want them all at once.** `client.listPerpPositions(account)` returns every pool's position in ONE indexer round-trip instead of a chain read per market — the right read for a positions _table_. It is a snapshot as of each row's `updatedAtBlock` and is **not marked to market**: unrealized PnL, liquidation price and margin health still need the chain reads above. Two things the shape will not let you get wrong, both documented on the type: `size` is **signed** (the entity stores magnitude and direction separately; they are folded back together here so a short can't read as a long), and the entry funding index is **absent by design** — it is not on the schema production serves, so it waits on the next reindex — and anything funding-sensitive belongs on `getPerpPosition`. Fully-closed positions are excluded unless you pass `includeFlat` — upserted rows are never deleted, so they linger at size 0 forever. - **Margin health is a chain read too.** `getMarginAccount` now also returns the requirements + status (`imReq` / `mmReq` / `cmReq` / `marginStatus`, from `MarginBank.getAccountHealth` + `getMarginStatus`); `client.getAccountHealth(marginBank, account)` is the lighter standalone read when only health matters, and `client.getLiquidationPrice({ marginBank, pool, account })` estimates the mark at which this pool's move alone would trip maintenance (null when flat). `MarginStatus` / `MARGIN_STATUS` / `AccountHealth` are exported; `exchange.fetchPositions()` now fills `UnifiedPosition.liquidationPrice`. - **Liquidation price: both sides of the inequality move with the mark.** Liquidation begins where `equity == mmReq`, and `mmReq` is recomputed on the _current_ mark (`ceil(|size| × mark × mmBps / (oneBase × 10000))`), so it shrinks under a falling long and grows under a rising short. Solving `equity(p) == mmReq(p)` therefore carries a `10000 ∓ mmBps` factor: ```text long p = mark − (equity − mmReq) × oneBase × 10000 / (|size| × (10000 − mmBps)) short p = mark + (equity − mmReq) × oneBase × 10000 / (|size| × (10000 + mmBps)) ``` `perpLiquidationPrice(...)` is that solve, exported as a pure function — no client, no block — so you can re-run it against a live store or a hypothetical. Both `getLiquidationPrice` and `previewPerpLiquidationPrice` go through it, which is why they cannot disagree on identical inputs. It is a **single-market** solve: other markets' contributions are held at the value baked into `equity`/`mmReq`, so a correlated move across several markets liquidates sooner. - **Where would an order put my liquidation price?** `client.previewPerpLiquidationPrice({ pool, marginBank, account, isBid, quantity, price, asMaker? })` answers that for an order not yet placed, returning `currentLiquidationPrice` beside `projectedLiquidationPrice` so a form can show the move. It ports all four of `MarginBank.settleTrade`'s cases — open, increase (floored VWAP entry), reduce/close (realized PnL at the fill price, entry untouched), and flip (old side closed, remainder re-opened) — and charges the fill's fee, defaulting to the taker rate. A reduce moves the price _away_ from the mark and an add moves it _closer_, so the four cases are not interchangeable. Note what it deliberately does **not** do: it applies the whole quantity rather than splitting it against `getReducingCapacity` (that split governs the collateral _lock_, not the position), and it does not judge whether the order would be accepted — that is `previewPerpOrderMargin`'s job. An unpriceable market returns `{ priceable: false }` rather than reverting, so an order form can still render. - **How much can I actually place?** `client.getMaxPerpOrderSize({ pool, marginBank, account, isBid, price })` — what a **Max** button should call. The inverse of `previewPerpOrderMargin`, which the protocol does not offer. It does not re-derive the sizing rule; it **binary-searches the forward one**, so the two cannot disagree. That matters because a max computed by a second, subtly different rule reverts on placement — and the term such a rule most often drops is the adverse mark-to-entry reserve, which on a 10%-above-mark bid cuts the affordable size by roughly two thirds. `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` names the binding gate — `"collateral"`, `"initialMargin"`, `"maxPositionSize"` or `"voucherBlocked"`. Market-wide `maxOpenInterest` is deliberately not modelled: it is enforced at fill against a total every other trader moves, so no client-side number can be right about it for long. Nor is book depth — this is a placement limit, not a liquidity one. Nor are the two non-margin gates that reject the whole order rather than shrinking it: a close-only market (`PerpPool.isRestricted()`) and isolated-margin confinement. **Pass `autoPull: true` when the transaction sender will be the order owner.** The pool tops the in-bank balance up from the owner's wallet before it locks (`_onOrderPlaced` → `MarginBank.quoteOrderTopUp` → `depositFor`), so an account with an empty bank and a funded, approved wallet goes from a max of `0n` to whatever the wallet funds. `msg.sender == order.owner` is the pool's entire gate, and only the caller knows who will send — hence opt-in. Leave it off for `placeOrderFor`, an operator grant or the stop registry, where no pull happens. With it on, `topUpRequired` is the wallet spend to show beside the size, and `limitedBy` gains `"walletBalance"` / `"walletAllowance"` — different shortfalls with different fixes, so don't collapse them. `"restricted"` and `"isolated"` name the two gates that reject the whole order rather than resizing it. **A linked child is funded by two wallets, and both count.** The pool spends the owner's own wallet first and takes the residual from the main it is linked to, so `autoPull` reads `MarginBank.quoteFundingPayer` and adds the main's `quoteWalletCapacity` as a second leg. That matters most for the account the rail exists for: an isolated sub-account is meant to hold nothing, and sized off its own wallet alone it reads as unable to place anything at all. `fundingPayer` names the main **eligible** to fund a shortfall, or is `null` when the account funds itself — unlinked, a main itself, or the rail dormant on this deployment. Eligibility is not a debit: it resolves for every linked account, including an order needing no top-up and one whose own wallet covers the whole pull. `ownWalletPull` and `mainWalletPull` split `topUpRequired` between the two wallets in the order the pool spends them, and **only `mainWalletPull > 0n` proves a second wallet actually moves** — that is the figure to show before the trader signs. Read `topUpRequired` as the total REQUESTED, not one wallet's spend. Showing it as the child's debit over-states it by exactly the main's leg. `limitedBy` gains `"mainWallet"`, reported ahead of the two `wallet*` values whenever a main is in play: at a main-funded ceiling the child's own capacity is fully consumed, so `"walletBalance"` would also be literally true and would send a trader to fund a sub-account that is empty by design. It names the **preferred** remedy, not the only one — the two capacities add, so raising the child's balance or allowance lifts the ceiling just as well. **A partial pull is not a rejection on this path.** The unlinked pool asks for a fixed `topUpRequired` and the token reverts if the wallet is short. Both linked legs are `min(...)`-sized and neither can revert, so the pool pulls what it can and the margin gates judge the result — and `topUpRequired` includes the fee headroom, which is a reserve rather than part of the lock. So capacities that cover the lock but not the headroom fund an order the chain accepts, and `walletCoversTopUp` is informational there rather than a gate: read a `false` as "the position may be born close to its own initial margin", not as "this will be rejected". One case withholds the main's leg entirely. `MarginBank.depositForFromMain` allows one payer at a time, so while the child still owes a **prior** payer the pull reverts `PriorFundingPayerOutstanding` — reachable in one ordinary sequence: funded by main A, unlink, re-link to main B. `mainFundingBlocked` reports it and `limitedBy` says `"mainFundingBlocked"`; the fix is neither wallet but `trader.repayPerpMainFunding` against the old claim. It costs one extra read for an unlinked account and four for a linked one. The main's capacity arrives as a single `min(balance, allowance)`, which is all the bank exposes for another wallet, so a main-side shortfall does not say which of the two bound; read the main's token balance and allowance directly if you need that. Note the max is the top of the **contiguous** placeable region. Auto-pull makes the initial-margin gate non-monotone in quantity — it reduces to `(equity − unlocked) + feeHeadroom ≥ imRequirement`, whose only size-dependent term grows — so an account whose existing positions sit below their own initial margin can be rejected at a middling size and accepted at a much larger one. `previewPerpOrderMargin` reports that faithfully; the max deliberately does not offer sizes out of the disconnected region, because a slider has to be placeable at every value below its maximum. - **What do I get if I close?** `client.previewPerpClosePnl({ pool, marginBank, account, quantity?, price?, asMaker? })` — backs a close modal. Omit `quantity` for the whole position; `price` defaults to the mark, which is the right estimate for a market close. Two things it gets right that a hand-derived figure usually does not, and **both are silent** — the close succeeds, the number shown was just wrong: 1. **The size is aligned down to the lot grid first.** "Close all" on a position that is not a lot multiple leaves a remainder open. A modal reporting the position as flat is wrong, and it reads as a bug in the close button. 2. **Funding settles on the whole position, not the closed share.** `settleTrade` calls `_settleFundingWithValues` _before_ it touches the position, and that uses the full `pos.size`. So a 10% close settles 100% of the accrued funding; pro-rating it — the intuitive move — under-states the cash impact by the other 90%. `netProceeds` is the number to show: `realizedPnl − fundingSettled − fee`, with `fundingSettled` positive when the account pays. `realizedPnl` **floors** toward −∞ (`_realizedPnlForClose`), which is the opposite of the truncation unrealized PnL uses — the same inputs give `-1` here and `0` from `getPerpPositionAnalytics`, and both are correct. `placeable` is the pool minimum and nothing else. A close is only purely reducing up to `_reducingCapacity` — `|size|` minus what is already resting on the reducing side — so closing out while a reduce order is down leaves an increasing remainder that locks collateral and must clear `meetsIMForOrder`. Read `previewPerpOrderMargin` beside this one on an account with resting orders. `fee` is the pool's own maker/taker rate; a builder fee attached at placement is charged on the same notional and lands on top. - **What is this position actually doing?** `client.getPerpPositionAnalytics({ marginBank, pool, account })` for one, `client.listPerpPositionAnalytics({ marginBank, account })` for a positions table. Two reads for one position, `1 + 2n` for the table, all pinned to one block. This is the split `getAccountHealth` cannot give you: it returns **one** equity figure for the whole account, with every market's PnL and funding already summed and netted together, so a two-position trader cannot see which position carries the loss and cannot see funding at all. Back apart: | Field | Means | | ------------------------------------------------------------ | --------------------------------------------------------------------------------------- | | `unrealizedPnl` | `(mark − entry) × size / oneBase` — price only, **excludes** funding | | `accruedFunding` | funding **owed** since entry; **positive means you pay** | | `equityContribution` | `unrealizedPnl − accruedFunding` — what this position adds to equity | | `notional` | `\|size\| × mark / oneBase` | | `initialMarginRequirement` | "position margin" — the only per-position margin the protocol defines | | `maintenanceMarginRequirement` / `closeOutMarginRequirement` | the liquidation and takeover thresholds' shares | | `returnOnMarginBps` | `equityContribution` over the initial requirement, **net of funding**; `null` when flat | A direct port of `MarginBank._computePositionMetrics` and `_marketHealthFromSnapshot`, which is what lets the rows re-sum to the bank's own equity to the wei — a test pins that. **The two roundings differ and are not interchangeable**: unrealized PnL truncates toward zero, while funding ceils toward +∞ so a payer never underpays. For a negative quotient that is the opposite of rounding the magnitude up. `accruedFunding` uses the pool's _projected_ cumulative index, so it includes intervals no one has settled yet — settlement is permissionless and lazy, and measuring against the settled index under-reports what the account already owes. An unpriceable market comes back as `{ priceable: false }` rather than throwing, so one dead feed costs one row rather than the page. `initialMarginRequirement` uses the market's IMF only: an account leverage setting raises the bar for a _new_ order but never appears in health, so use `previewPerpOrderMargin` for the order-gating figure. The pure core is exported as `perpPositionAnalytics(...)` — no client, no block. - **How levered am I?** `client.getPerpLeverage({ marginBank, pool, account })`. **The protocol has no leverage view to call** — `getMaxLeverage` / `getMaxLeverageLimit` / `getVoucherLeverageCap` are all _cap configuration_ and none of them measures a position — so this derives it from mark notional over equity, and returns every denominator rather than picking one: | Field | Means | | ---------------------- | ------------------------------------------------------------------------------------------------------- | | `positionLeverageBps` | this position's notional over account equity | | `accountLeverageBps` | **Σ** notional over account equity — the figure that governs risk under cross margin | | `marketMaxLeverageBps` | `10000² / effectiveImfBps` — the most this market will open at, at _live_ OI-scaled IMF | | `accountMaxLeverageX` | the account's own per-market cap, `0` when unset (what `setPerpLeverage` writes, finally readable) | | `protocolMaxLeverageX` | the ceiling that clamps it | | `creditFloor` | the account's credit-voucher floor; `0n` on an ordinary account, and the switch that arms the two below | | `voucherLeverageCapX` | what a voucher account is confined to when it **increases**; `0` is a block, not "uncapped" | | `voucherMarketAllowed` | whether this market is on the voucher allowlist | The ceilings are **not** collapsed into one number, and they do not compose by taking a minimum. A voucher cap _replaces_ an unset or looser `accountMaxLeverageX` before `protocolMaxLeverageX` clamps the result, and it applies only to a position increase — `MarginBank._meetsIM` gates the whole voucher branch on `additionalSize > 0`, so a voucher holder can always close out or place a stop, even on a market since removed from the allowlist. The load-bearing half is that a voucher turns an _unset_ account cap into an enforced one: `accountMaxLeverageX === 0` means "no cap" on an ordinary account and "confined to `voucherLeverageCapX`" on a voucher one. For whether a _specific_ order passes, use `previewPerpOrderMargin`, which applies all of it and reports `voucherBlocked`. Every ratio is **bps of 1x** (`10_000` = 1.00x, `200_000` = 20x), matching the protocol's own unit for every margin figure. Position and account leverage are `null` on non-positive equity — an account with no equity left is insolvent, not infinitely levered; read `marginStatus` for that. `accountNotional` costs two extra reads per _other_ active market (the MarginBank exposes no aggregate, and `imReq` can't be inverted because each market applies its own IMF), so a single-market account pays nothing extra. - **Liquidation-keeper reads — who holds, and what a bankrupt position is worth.** The MarginBank keeps a per-(pool, side) holder array, so a keeper can find every open position from head state alone — no off-chain indexer: ```ts const { holders, asOfBlock } = await client.getPerpSideHolders({ marginBank, pool, isLong: true }); const prices = await Promise.all( // Priced at the SNAPSHOT's block — at head, a holder that closed since // the enumeration would revert NoOpenPosition and reject the sweep. holders.map((h) => client.getBankruptcyPrice({ marginBank, account: h, pool }, { blockNumber: asOfBlock })), ); ``` `getPerpSideHolders` pages through the bank's bounded slice view (many holders per round-trip) with every page pinned to ONE block; feed `asOfBlock` into `getBankruptcyPrice`'s `blockNumber` option (and into the other side's call) to keep a sweep on one consistent snapshot. The other position/health reads answer at head only. `getBankruptcyPrice` is the **contract's own figure** — the price at which the position's allocated share of the account's equity is exhausted — and it is a different quantity from `getLiquidationPrice`, not a better version of it: `getLiquidationPrice` is the SDK's client-side estimate of where liquidation _triggers_ (use it for UI and monitoring), while `getBankruptcyPrice` is what the contract computes a bankrupt position to be worth (use it for anything that settles or bids — a keeper pays against this number, and a client-side estimate can drift from contract rounding). It reverts rather than returning a sentinel: `ContractRevertError` with `errorName: "NoOpenPosition"` when the account is flat in that pool (branch on `errorName`, never message text). - **Protocol state — is the stack wired and solvent.** The plane below any one account or market, mirroring what the protocol repo's `perps:state` / `perps:health` ops tasks read: ```ts const cfg = await client.getPerpSystemConfig(marginBank); // the address book const fund = await client.getInsuranceFundState(cfg.insuranceFund); const eng = await client.getLiquidationEngineConfig(cfg.liquidationEngine); ``` `getPerpSystemConfig` is the entry point: every other contract in the plane is reachable from it, so nothing is hardcoded per chain, and it carries `fullyWired` — a single flag for "some part of this stack is half-configured", which is the state where liquidation and settlement degrade silently rather than reverting. Point the other two at the addresses it returns. `liquidationEngine` is the **proxy**: an implementation address answers with unset defaults (zero bidders, zero penalty), which reads as a configured-but-idle engine rather than the wrong address. `bidderCount === 0n` is itself operational — with no registered backstop bidders the takeover stage has nobody to take a position over, so the waterfall reaches ADL sooner than the configuration implies. For account-level health when a feed may be down: `tryGetPerpAccountEquity` returns `null` rather than reverting (null is "not computable", never "zero"), and `getPerpCollateralBasis` is a solvency floor that reads one storage pair and cannot revert at all. - **Take-profit / stop-loss listing.** `client.listPerpStopOrders({ account?, pool?, status? })`. 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, but without this a trader cannot see, price or cancel what they created. It is indexed, and there is no chain fallback. One call covers every scope: `{ 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: `ReduceOnly*` means the stop was overtaken by events (position already closed, flipped, or below the minimum), which is ordinary; only `PlacementFailed` is a rejection. SOMI is consumed on every fire either way. - **The registry may be holding SOMI for you.** Placing a perp stop pre-pays the trigger gas in SOMI. Cancelling refunds it by direct transfer — but when that transfer _fails_, the registry credits an unclaimed balance instead and emits `SomiRefundFailed`. That is the ordinary outcome for a contract owner with no payable receiver (most multisigs and smart accounts). A registry wind-down credits the same balance to **every** owner, EOAs included. ```ts const owed = await client.getUnclaimedPerpStopSomi({ registry: perp.stopRegistry, account }); if (owed > 0n) await trader.claimPerpStopSomi({ registry: perp.stopRegistry }); ``` Read before claiming — `claimSomi` reverts `NothingToClaim` on a zero balance, and the payout is a plain native transfer to the caller, so an owner that still cannot receive native reverts `WithdrawalFailed` and the balance stays put. Do not assume an EOA is owed nothing: the wind-down path reaches them too. Note the trigger path is the opposite of a refund — SOMI is consumed on every fire and never returned. - **Batching writes that have to be atomic.** One SDK write is one transaction, which is wrong for a flow that is only safe as one — an order with TP/SL attached (sent separately, the order can fill and sit with no stop on it), approve + deposit, withdraw + forward to the wallet. `trader.buildPlacePerpStopOrder`, `buildCancelPerpStopOrder(s)`, `buildDepositMargin` and `buildWithdrawMargin` take the same parameters as their sending twins and return the unsigned call (`{ to, data, value, description }`) for you to pack into one UserOp / Safe batch / multicall. Two gotchas. Approvals come back rather than going out — `operatorApproval` on a stop, `approval` on a deposit — and must execute **before** the call they enable; the perp stop's grant especially, because without it the trigger reverts and the prepaid SOMI is spent having placed nothing. And no ids come back, because you hold the receipt: read them with `decodePerpStopOrderIds(receipt.logs, registry)`. - **Where the registry address comes from.** Every stop write — `placePerpStopOrder`, `cancelPerpStopOrder`, `cancelPerpStopOrders` — takes the per-pool `PerpStopOrderRegistry` as a required `registry` argument. Read it off the market row: `stopRegistry` on `PerpMarket`, and on the market context attached to perp portfolio orders and fills. `null` there means the pool has no registry deployed, so TP/SL is unavailable on it — not that the address is elsewhere. - **One call for a market header.** `exchange.fetchTicker(symbol)` on a perp now returns `markPrice`, `indexPrice`, `fundingRate`, `fundingTimestamp` and `openInterest` alongside the 24h high/low/volume it already computed from candles. Those five are chain state, not candle-derived, so before this a header needed a second read the consumer had to know to make. They are `undefined` on spot and binary, and no chain round-trip is spent on a non-perp. `fundingRate` is on the **same per-8h axis** as `fetchFundingRate` and `fetchFundingRateHistory` — deliberately, because a header on one basis beside a chart on another is a wrong number that looks right. It is not the per-settlement amount. For one settlement's charge, divide by `n = fundingWindowSec / fundingIntervalSec` (8 on every live pool) — and for a HISTORICAL row that caught up over several intervals, multiply that by the row's `intervalsAccrued`, since one settlement can charge more than one interval's worth. Both figures ride on `info.perp`. `markPrice` is omitted rather than reported as 0 when the feed is stale. - **Previewing an order before you send it.** `client.previewPerpOrderMargin({ pool, marginBank, account, isBid, quantity, price })` returns what the pool will actually lock and whether it will accept the order — the read behind an order form's "margin required" row and its submit gate. Do **not** reach for `quoteMeetsIMForOrder`: it runs with the order's base margin treated as already reserved (true on the real path, where `lockCollateral` runs first), so called cold it counts the order's margin nowhere and returns `true` for almost any size. `meetsPerpImForFill` does charge base margin, but neither models the lock's **adverse mark-to-entry reserve** — a buy above mark (or sell below) opens underwater by that gap and the pool reserves it on top of initial margin. That term is the usual reason a `notional × IMF`-sized "max" order gets rejected. Two gates are reported separately because they fail for different reasons and imply different fixes: `hasCollateralForLock` (can the lock be taken at all) versus `meetsInitialMargin` (does what remains still cover the requirement) — "deposit more" versus "close something". Only the _increasing_ leg locks. An order that nets against an existing position locks nothing up to `effectiveReducingCapacity`, which resting opposite-side orders have already partly spoken for. **Pass `autoPull: true` when the sender will be the order owner**, and both gates describe the balance the pool will have topped up to from the wallet rather than the one already in the bank. `topUpRequired` is then the wallet spend to show beside the margin figure, and `wallet` carries the balance and MarginBank allowance it was measured against. `feeHeadroom` appears either way: it is not charged and not part of `lockAmount`, only an auto-pull addend that keeps a fresh max-leverage position out of `MarginCall` at birth. A `topUpRequired` of `0n` means three different things — no pull needed, or one of the pool's declines: a purely reducing order, an account already in debt, or a voucher-blocked increase. Read it beside `unlockedCollateral`, not on its own. Every read is pinned to one block, so the result is a statement about that block; the adverse-gap term moves with the mark, so re-quote near send time for anything close to the edge. - **Market discovery is a chain read, and "deployed" is not "tradeable."** `client.listPerpPoolStatuses({ factory })` enumerates the `PerpPoolFactory` and returns every market with the **two independent gates** that decide tradeability — they fail for unrelated reasons and both must pass: 1. `restricted` — the market is close-only. Position-increasing orders revert `MarketRestricted`; closes, reduces and cancels still work. These stay listed on purpose (holders must still exit), and it is reversible. 2. `registered` — the MarginBank has activated the pool. Coming from the factory only proves a pool is _authentic_; `addPerpPool` is what makes it usable. An unregistered pool rejects every quote view and settlement callback while reading as an ordinary market from the factory. (`getPoolTier` is **not** a substitute — it is itself gated on registration.) `tradeable` folds both together, and `listTradeablePerpPools` filters to it. 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. Do **not** build a market list from the factory's raw pool list: it is the deployment history, so listing it unfiltered presents wound-down markets as tradeable. Testnet today has 10 pools, four of them restricted `SBTC*` arena markets. This is also more complete than the indexer, whose perp set comes from a curated manifest — a market deployed after that manifest was written is invisible there and present here. - **Per-market risk parameters are a chain read.** `client.getPerpRiskParams(pool)` returns the pool's frozen config — initial / **maintenance** / close-out margin in bps, the OI and position caps, and the maker/taker rates. `maintenanceMarginBps` is exposed nowhere else (the indexed market row carries only `initialMarginBps`), and without it a client can show the real liquidation price of an open position but not the **projected** one for an order it hasn't placed. This read never reverts, so maintenance margin stays available when the mark feed is down — exactly when you most want to explain a liquidation. - **Initial margin is not a constant.** `initialMarginBps` is only the FLOOR of the curve: with dynamic IMF enabled the pool scales it with open interest, and `client.getEffectiveImfBps(pool)` is the rate actually charged. Sizing an order off the static base under-margins it whenever OI has pushed the curve up, and the pool rejects an order the client believed fit. Maintenance margin deliberately does **not** scale — a liquidation threshold must not move under a position because the market's OI grew. - **One call for a health walk.** `client.getPerpHealthSnapshot(pool)` returns `oneBase`, mark, projected cumulative funding, the effective IMF and both thresholds together; the contract added it so a cross-margin walk reads a market once instead of five times. It returns a discriminated union — an unpriceable market arrives as `{ priceable: false }` rather than an all-zero struct, because a `maintenanceMarginBps` of `0` reads as "can never be liquidated". Narrow on `priceable` before touching a field. ## Linked wallets (isolated margin) Isolated margin on perps is one wallet per position. The MarginBank is cross-margin, so a single account's collateral backs every position it holds; the only way to give one position its own collateral bucket is to open it from its own wallet. `setIsolated` does not do this — it is single-market confinement, which caps how many markets one account may touch and changes no margin math. One wallet per position used to mean one treasury operation per position. The linked-wallet rail removes that. A wallet links to a **main** wallet, and from then on the child's position-increasing orders draw their margin shortfall from the main's wallet. One funded main serves every child linked to it. Two layers, and they answer different questions: - `LinkedWalletRegistry` is the **consent** graph. It records who is linked to whom and grants no authority over funds. - `MarginBank` is the **money** layer, and it is armed separately. Until the bank holds a registry address the rail is dormant and no child can draw on any main, whatever the registry says. ### Linking a sub-account A link takes a two-sided handshake and **both wallets sign**. The main offers, the child accepts, and no wallet can act for the other: ```ts // The MAIN offers. Its own deposit leaves the standing allowance the rail spends. await main.trader.depositMargin({ marginBank, amount: fromHuman(1000, 18) }); await main.trader.proposePerpWalletLink({ marginBank, child: childAddress }); // The CHILD accepts, with its own signer and its own transaction. await child.trader.acceptPerpWalletLink({ marginBank, main: mainAddress }); // The child's own placement now pulls the shortfall from the main's wallet. await child.trader.placePerpOrder({ pool, isBid: true, price, quantity }); ``` Pass `registry`, `marginBank` or `pool` to any of the four consent writes. Only `registry` skips a chain read: the bank names the registry it treats as authoritative, so the SDK reads it from the bank rather than a manifest, and a bank holding none throws `NotConfiguredError` rather than sending consent nowhere. That read is never cached, because the bank's owner can rotate the registry. ### How the funding actually happens There is no funding call, and this is the part that surprises people. The main supplies USDso and an ERC-20 allowance to the **MarginBank**, and then sends nothing. `PerpPool` performs the pull inside the child's own order placement: - The child's own wallet pays first, sized by `min(balance, allowance)`. - The main's wallet pays the residual, sized the same way. - The pool's entire gate is `msg.sender == order.owner`. An order routed through `placeOrderFor`, an operator grant, a router or the stop registry pulls **nothing**, from either wallet. So the child must send its own orders, and it needs native SOMI for gas. Revoking the main's allowance stops the funding without touching the link. Funding does not wait for link maturity: the rail reads the raw graph, and `maturesAt` gates ADL netting only. What a main funds is a **claim, not a gift**. The bank records the funded principal against the child, and the child's `withdraw` frees at most `balance - principal` — so a compromised child key can trade the money and lose it, but cannot take it out. The child's own money is the junior tranche: a loss eats it first, and a child that genuinely lost the principal owes nothing. ### Getting the money back Read the outstanding claim with `client.getPerpMainFunding(marginBank, account)`. Two routes send it home, and they differ only in who signs: | Write | Signer | Use it when | | ------------------------------------------------- | --------- | ------------------------------------------- | | `trader.repayPerpMainFunding({ amount })` | the child | the child is finished and returns the money | | `trader.recallPerpMainFunding({ child, amount })` | the payer | the main pulls its capital back | Both pay the payer the bank snapshotted at funding time, not whoever is linked now, so an unlink or a re-link in between cannot misroute the money. Both **clamp** the amount to `min(amount, outstanding, present balance)`, so over-asking is safe and only a clamp that reaches zero reverts. Both recover principal and never winnings. `trader.unlinkPerpWallet({ counterparty })` dissolves the link from either end. It settles no money, so clear the claim first if the intent is to part cleanly. `PerpsUnlinkGuard` vetoes it while the leaver holds open positions and is at `PartialLiquidation` or worse; a healthy or flat wallet can always leave. ### Batching the two steps that need it Two steps have an ordering dependency inside one transaction, and each has a build-only twin for it: - `trader.buildAcceptPerpWalletLink` — accept, then open the isolated position, in one signature. - `trader.buildRepayPerpMainFunding` — repay, then withdraw the remainder. The withdrawal's own gate reads the claim the repayment clears, so it has to follow. The other four writes are standalone administrative calls and have no twin. ### Which read answers which question The six chain reads are live contract STATE — a value as of a block, which no log can reconstruct. The history is the opposite: the contracts expose no getter for any of it, so the events in the chain's logs are the only record, and the indexer is what makes them queryable. | Question | Read | Tier | | --------------------------------------------------- | ------------------------------------------------------ | ------- | | Is the rail on at all on this deployment? | `client.getPerpLinkedWalletRegistry(marginBank)` | chain | | Is a main eligible to fund this account, and which? | `client.quotePerpFundingPayer(marginBank, account)` | chain | | What is outstanding, and to whom? | `client.getPerpMainFunding(marginBank, account)` | chain | | What can a wallet actually contribute right now? | `client.getPerpWalletPullCapacity(marginBank, wallet)` | chain | | Who is in my group, and when did it mature? | `client.getPerpWalletLinkage(registry, wallet)` | chain | | Which children does this main have? | `client.listPerpLinkedChildren(registry, main)` | chain | | How many children may one main hold? | `client.getPerpMaxLinkedChildren(registry)` | chain | | How did it get to this state? | the three `list*` ledgers below | indexer | **Eligibility is not a prediction.** `quotePerpFundingPayer` takes no order and no sender, so it cannot say whether a given order will debit the main. Four things stop an eligible main from paying anything: the order needs no top-up, the child's own wallet covers the whole pull, the order is routed by someone other than its owner, or the main has no spendable capacity. Size the order with `client.previewPerpOrderMargin({ autoPull: true })` and read its `mainWalletPull` for the amount that would actually move. `quotePerpFundingPayer` returns a discriminated union rather than an address, because the contract's single zero collapses three situations a UI must not render alike. Narrow on `funded` first: ```ts const payer = await client.quotePerpFundingPayer(marginBank, account); if (payer.funded) { // A main is ELIGIBLE to cover what this account's own wallet cannot. Whether any // given order debits it is `previewPerpOrderMargin({ autoPull: true }).mainWalletPull`. console.log("eligible payer", payer.payer); } else if (payer.reason === "unlinked") { // The one case the user can fix, by linking. } else if (payer.reason === "dormant") { // The rail is off for everyone here. Linking would not help. } else { // "isMain" — linked, but funding flows main->child only. } ``` `getPerpMainFunding` reports the claim and the payer **snapshotted at funding time**, which is not necessarily whoever is linked now. When the two disagree, the snapshot is who gets repaid. It also carries `withdrawableFromPrincipal`, which is always `0n` — a field rather than prose because "why can I not withdraw my balance" is the commonest question this surface has to answer. ### Finding an incoming proposal The registry keeps pending proposals in a hashed map with **no getter**. So a child cannot discover from any chain read that a main has offered it a link, and `client.listPerpWalletLinkEvents` is the only evidence such an offer exists. That list yields **candidates, not accepts that will succeed**. `acceptLink` applies five live-state guards, and each is a current-state rather than an ever-happened question: 1. An offer stands only while the pair's newest row is the `Proposed` itself. Mind the direction: an unlink clears the pending proposal in **both** directions, so an `Unlinked` naming this wallet as the main can retire an offer it holds as the child. 2. The child must be free right now (`AlreadyLinked`). Accepting one main leaves the losing mains' proposals in storage, dead only while that link stands. 3. The main must not itself be a child right now (`CallerIsChild`). 4. The accepting wallet must not itself be a main (`CallerIsMain`). 5. The main must be under its child cap (`MaxChildrenReached`). All five are **derivable in principle** from a complete `Linked` / `Unlinked` replay — except the cap, whose value is owner-tunable and whose `MaxChildrenUpdated` event is deliberately not subscribed. In practice a paginated page of rows is not a complete replay, which is the real reason not to decide an accept off this list. So confirm on chain. `client.getPerpWalletLinkage(registry, wallet)` settles guards 2, 3 and 4 — read it on both parties, since `main` being non-zero means the wallet is already in a group. It does **not** carry the cap: that is `client.getPerpMaxLinkedChildren(registry)` against `client.listPerpLinkedChildren(registry, main)`. ### The two funding ledgers, which must not be summed Every proposal, link, pull, settle and return is indexed, because the chain keeps no history of any of it: ```ts const links = await client.listPerpWalletLinkEvents({ child: account }); // Proposed | ProposalCancelled | Linked | Unlinked const pulls = await client.listPerpMarginPulls({ account, source: "Main" }); // the POOL side — names the order const claims = await client.listPerpMainFundingEvents({ account }); // the BANK side — carries the running claim ``` **A MAIN-funded leg emits a row on each side for the same wei.** Adding `listPerpMarginPulls` to `listPerpMainFundingEvents` therefore double-counts every main-funded transfer. Read one or the other, never both as one total, and pick by the question: the pool side names the **order**, the bank side carries the **claim**. The overlap is exactly the main legs, and no more. An own-wallet pull has no bank-side twin: the bank's `DepositedFor` is deliberately not subscribed, because `PerpMarginPull(source: "OwnWallet")` already carries the same amount plus the order id. So `PerpMainFundingEvent` is the main legs only, while `PerpMarginPull` is both. One placement can produce two `PerpMarginPull` rows — an `OwnWallet` leg and a `Main` leg, in that order — because the child's own wallet contributes what it can before the main is touched. Filter on `source: "Main"` to see only what a main actually paid for. On `PerpMainFundingEvent`, a `Settled` row moved no cash: it records the child's losses discharging part of the claim, so its `amount` is `null` while `outstandingPrincipal` still drops. Fold by `kind` rather than summing `amount`. ## History (indexer) The CURRENT position/margin is the chain read above; the **append-only history** the chain doesn't expose is indexed (perp account plane), all one-shot indexer reads: ```ts const funding = await client.getFundingPayments(account, { pool, limit: 50 }); // signed funding paid/received const margin = await client.getMarginEvents(account, { limit: 50 }); // deposit/withdraw/lock/unlock const liqs = await client.listLiquidations({ account, pool }); // liquidation events const rates = await client.listFundingRateHistory(pool, { from, to }); // per-pool funding-rate series const candles = await client.listFundingRateCandles(pool, 3600, { from, to }); // 1h/4h/1d rollups for charting const oi = await client.getOpenInterestHistory(pool); // per-pool open-interest series ``` `listFundingRateHistory` / `getOpenInterestHistory` are the append-only counterparts to the overwrite-only `fundingRate` / `openInterest` fields on the perp `Market` row (which only carry the latest value). `getFundingRateHistory` is the deprecated alias of the first; it forwards verbatim. Liquidation history is served by the `LiquidationEngine` subscription, which is live — the contract is deployed and indexed from block 436,735,800. There is no `MarginBank`-sourced fallback: `MarginBank.Liquidated` was deleted from the protocol, so the rows that claim used to describe cannot exist. Per-position detail comes from `LiquidationEngine.PositionLiquidated`, and the waterfall's other outcomes (ADL, takeover, close-out, the residual and declined-coverage markers) arrive as sibling rows sharing a `txHash` — read `kind` to tell them apart, and read the TSDoc on `badDebt` / `insuranceCovered` / `deficit` / `coverageDeclined` before aggregating any of them, because only the flows are summable. ### Reading a liquidation's stage `AccountLiquidated` rows carry `stageReached`. It tells you how far down the waterfall a liquidation went. The number needs a mapping, because the protocol enum is 0-indexed with six members while the published waterfall numbers its stages 1 to 6: | `stageReached` | Enum member | Published stage | | -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | 0 | `OrderCancellation` | before stage 3 — cancelling the account's resting orders alone restored health | | 1 | `CLOBPartial` | stage 3 | | 2 | `BidderTakeover` | stage 4 | | 3 | `InsuranceFund` | stage 5 | | 4 | `ADL` | stage 6 | | 5 | `Deferred` | not a stage — stage 3 hit its per-block rate limit, and stages 4 to 6 were not consulted. Ships dormant, so it does not appear yet | Published stages 1 (Healthy) and 2 (Margin Call) are account states, not actions. The engine cannot reach them, so no value maps to them. Two rules govern the number, and neither is visible in the value itself. **It names the deepest stage that acted, not the deepest stage consulted.** A stage that ran and moved nothing does not promote it. So a `BidderTakeover` (2) row sitting beside a `BadDebtAbsorbed` row is consistent. It means the insurance fund was asked and paid nothing. `BadDebtAbsorbed` fires on the request, not on the payment, so read `insuranceCovered` on that row to see whether the fund actually paid. A market the fund does not cover produces exactly this shape: the loss falls through as `ResidualBadDebt`. **`CLOBPartial` (1) is a fall-through marker.** It means stages 4 to 6 were consulted and none of them acted. It does not prove stage 3 filled anything. Against an empty book you get `CLOBPartial` with a `positionsProcessed` of 0, which means the account's orders were cancelled and no position was closed. Read `positionsProcessed` with it: ```ts const rows = await client.getLiquidations({ account }); const summary = rows.find((r) => r.kind === "AccountLiquidated"); // A real CLOB partial fill, not an empty-book no-op. const clobFilled = summary?.stageReached === 1 && Number(summary.positionsProcessed) > 0; ``` `counterparty` on a `BadDebtAbsorbed` row names the fund the engine asked. The address is recorded even when `insuranceCovered` is 0, so it does not mean the fund paid either. `marginStatusAfter` needs the same care. A flat account that still owes bad debt reports `CloseOut` (3) so the debt stays visible to monitoring. That is a terminal state, not an account that is still liquidatable. A `ResidualBadDebt` row in the same transaction identifies it. If you query the indexer's GraphQL directly rather than through the SDK, note that its own field descriptions still carry the older wording for `kind`, `counterparty` and `stageReached`. Correcting them changes the served schema and so needs a reindex; it is tracked separately. This section is the current reference. ## Watch from chain (event ABIs) Indexer history is one-shot and the chain reads are point-in-time. To see a perp event as it lands, decode the log yourself. The SDK publishes the event ABIs so your decoder uses the same signatures the SDK and the indexer use: | ABI | Contract | Scope | Carries | | ---------------------------- | ----------------- | -------------------- | ------------------------------------------------------------------------------------- | | `perpPoolEventsAbi` | PerpPool | one per market | funding rate, open interest, the maker pre-fill reason tags | | `marginBankEventsAbi` | MarginBank | singleton, all pools | positions, collateral flow, funding settlement, fees, the liquidation settlement legs | | `liquidationEngineEventsAbi` | LiquidationEngine | singleton, all pools | the liquidation waterfall stages and their costs | Both singletons serve every pool and every account, so a subscription is one stream. The pool and the account are indexed topics, not the log source. Get the addresses from the market row and the system config: ```ts import { getAbiItem } from "viem"; import { liquidationEngineEventsAbi, marginBankEventsAbi } from "@somnia-chain/markets-sdk"; const market = await client.getPerpMarket(perpMarketId); const { liquidationEngine } = await client.getPerpSystemConfig(market!.marginBank); const viem = client.getViemClient(); // shares the SDK's WebSocket // Per-wallet funding settlement. `payment` is signed: positive is what the // account PAYS. const unwatchFunding = viem.watchEvent({ address: market!.marginBank, event: getAbiItem({ abi: marginBankEventsAbi, name: "FundingSettled" }), args: { account }, onLogs: (logs) => { for (const log of logs) console.log(log.args.perpPool, log.args.payment); }, }); // Every liquidation on the venue. `PositionLiquidated` is pool-scoped, so filter // by pool here if you only want one market. const unwatchLiquidations = viem.watchEvent({ address: liquidationEngine, event: getAbiItem({ abi: liquidationEngineEventsAbi, name: "PositionLiquidated" }), onLogs: (logs) => { for (const log of logs) console.log(log.args.account, log.args.sizeDelta, log.args.markPrice); }, }); ``` Three things to know before you build on this. **The waterfall is split across both singletons.** LiquidationEngine emits the stages and their costs. MarginBank emits the settlement legs of the same liquidation — `AutoDeleveraged`, `PositionTransferred`, `CloseOutMarginSettled` and `BadDebtAbsorbed`. Subscribe both, or you see half of each event. **Account-level events carry no pool.** `AccountLiquidated`, `ResidualBadDebt`, `AdlPriceCapacityExhausted` and their siblings describe the account, not one market. A per-pool liquidation filter therefore drops them. Filter by pool only on the per-position events. **Not every field is summable.** `BadDebtAbsorbed` reports `badDebt` (the full negative balance, before coverage) beside `covered` (the wei the insurance fund moved). `ResidualBadDebt` reports the uncovered remainder of the same hole. Adding them counts one loss twice. The same applies to `collateralTransferred` on `PositionTransferred` and `amount` on `CloseOutMarginSettled`: both are flows between accounts, not losses. The signatures are pinned by topic0 against the compiled artifacts in `test/perpEventsAbi.test.ts`. A wrong signature is a different topic0, which means `watchEvent` filters on something no contract emits and your handler never fires, with no error to see. Use the published ABI rather than a copy. Note the SDK's own live tail does not subscribe either singleton yet, so `client.watchMarket(pool)` gives you funding-RATE updates (`FundingUpdated` on the pool) but not funding settlement, positions or liquidations. Those are the raw watch above until the tail covers them. ## Quick start ```ts const exchange = new SomniaMarkets({ chain, wsRpcUrl, indexerUrl, privateKey }); await exchange.loadMarkets(); await exchange.depositMargin("BTC/USDSO:USDSO", 1_000); // USDso → MarginBank await exchange.createOrder("BTC/USDSO:USDSO", "limit", "buy", 0.001, 62_000); const [pos] = await exchange.fetchPositions(); // long/short + uPnL const { fundingRate, markPrice } = await exchange.fetchFundingRate("BTC/USDSO:USDSO"); ``` ## One-shot reads (no watch) For a plain fetch without a live tail: ```ts const perps = await client.listPerpMarkets({ baseSymbol: "WBTC", limit: 20 }); const one = await client.getPerpMarket(perps[0].id); // null if not a perp const port = await client.getPerpPortfolio(account, { ordersLimit: 50, tradesLimit: 50, since }); const hist = await client.listPerpOrderHistory(account, { limit: 100 }); // FINISHED orders const state = await client.getPerpState(one!.poolAddress); // mark/index/funding/OI ``` `listPerpMarkets` takes a `PerpMarketFilter` (`baseSymbol` / `quoteSymbol`, all server-side); `getPerpPortfolio` takes the shared `PortfolioOptions` (`ordersLimit` / `tradesLimit` / `since`). Trades default to the **last seven days** — the result's `tradesSince` is the bound that was applied; pass `since` to widen it. Positions + collateral stay on-chain (`getPerpPosition` / `getMarginAccount`), not indexed rows. `getPerpPortfolio` returns **open** orders only, so `listPerpOrderHistory` is the other half — finished orders, most-recently-ended first. It excludes working orders by default and sorts by when each order _ended_ rather than when it was placed, so a long-resting order that just filled lands at the top of a history view instead of buried at its placement date. Pass `status` to narrow to particular outcomes. Sort axis is selectable — `orderBy: "ended"` (default) or `"placed"`. Watch `Closed`: it is terminal, not transitional. Every pool places an order as `Closed` and a following `OrderRested` promotes it to `Open`, so an IOC that partially filled without resting stays `Closed` forever — reading it as "still working" shows a finished order as live. ## Writing forward-compatible code ```ts const m = client.getLiveMarketByPool(pool); switch (m?.marketType) { case "BINARY": /* YES/NO book */ break; case "SPOT": /* base/quote book */ break; case "PERP": /* base/quote book + funding/positions */ break; } ``` Key on `marketType` (not on field presence), use the type guards, and read decimals off the market row rather than assuming. --- # /docs/typescript/lend # Lend — SomniaLend through the SDK SomniaLend is a third-party money market on Somnia mainnet and testnet (an Aave v3.0 fork — [docs.somnialend.finance](https://docs.somnialend.finance/)). The SDK wraps its deployed contracts behind the `client.lend` namespace, so trading capital can earn while idle: supply USDso between sessions, post it as collateral, borrow working capital against it. It lives on the master client as the `lend` namespace. Because SomniaLend is third-party, its addresses are not in the deployments manifests — wire them in config, with the published deployments available as constants: ```ts import { SOMNIA_MAINNET_LEND } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets({ ...config, addresses: { ...addresses, lend: SOMNIA_MAINNET_LEND }, }); const lend = exchange.client.lend; ``` `SOMNIA_MAINNET_LEND` (chain 5031) and `SOMNIA_TESTNET_LEND` (chain 50312) carry the two published deployments (Pool, PoolAddressesProvider, UiPoolDataProviderV3, WrappedTokenGatewayV3), verified against the on-chain contracts. Set one as `addresses.lend` and reach the surface through `client.lend`; that is the only entry point, so a lend read always rides the client's own chain transport. Everything else you need without the client comes from the root entry (`@somnia-chain/markets-sdk`): the types, both deployment constants, the ray-math helpers (`lendRayRateToApy`, `rayMul`, …) and the verified minimal ABIs. Targeting a different deployment means a **different client** — the addresses and the chain travel together, so `new SomniaMarkets({ chain, wsRpcUrl, addresses: { lend } })`. (A `createLend(client, addresses)` factory used to be exported; it took a whole client to use two of its members, and let one chain's addresses be grafted onto another chain's socket, which type-checked and silently read nothing.) ## Reads Two calls cover the whole surface — both are chain reads over the client's WebSocket, current to head, no indexer involvement (`useLendReserves` and `useLendAccount` in `@somnia-chain/markets-sdk/react` wrap them for components): ```ts const reserves = await lend.listReserves(); // every listed asset const account = await lend.getAccount(me); // health factor + positions ``` `listReserves` is one aggregated `eth_call` (UiPoolDataProviderV3): per reserve you get the config (LTV / liquidation threshold / caps / flags), live rates and indexes, available liquidity, total debt, and the oracle price. `getAccount` joins the Pool's risk aggregate (health factor, borrowing power) with every non-empty supplied/borrowed position. Units, in the SDK-wide convention (bigint raw units everywhere): - **Rates and indexes are ray (1e27).** Convert a rate for display with `lendRayRateToApy(r.liquidityRateRay)` — the per-second-compounded APY fraction Aave UIs show. - **`healthFactor` is a wad (1e18).** Below `1e18` the position is liquidatable; a debt-free account reports `maxUint256`. - **`*Base` aggregates** (`totalCollateralBase`, `availableBorrowsBase`, reserve prices) are denominated in the oracle base currency — USD with 8 decimals on this deployment (`baseCurrencyDecimals` rides along). - **`borrowCap` / `supplyCap` are whole tokens** (Aave convention), not raw units; `0` means uncapped. - Balances (`aTokenBalance`, `variableDebt`, `totalSupplied`, …) are raw underlying units, accrued to the read's timestamp with Aave's own interest math (linear for supply, compounded for debt) — they match what the Pool would settle, not the last stored checkpoint. ## Writes ```ts const lender = lend.createLender({ privateKey }); // or account / walletClient await lender.supply(usdso, 1_000n * 10n ** 18n); // auto-approves the Pool await lender.borrow(usdce, 500n * 10n ** 6n); // variable rate only await lender.repay(usdce, maxUint256); // maxUint256 = full debt await lender.withdraw(usdso, maxUint256); // maxUint256 = full balance await lender.setUseAsCollateral(usdso, true); ``` Same doctrine as the trader: writes resolve once mined (with the receipt), gas is a fixed generous ceiling, fees are the client's fixed EIP-1559 config, and ERC-20 pulls auto-approve `maxUint256` once per (token, spender) with an in-memory grant cache (`approve: false` opts out per call; `clearApprovalCache()` resets). Borrowing is variable-rate only — stable borrowing isn't surfaced. Native SOMI has gateway-routed siblings so you never touch WSOMI yourself: `supplyNative` / `withdrawNative` / `borrowNative` / `repayNative`. Two of them need a one-time grant the SDK also handles automatically: `withdrawNative` approves the gateway to pull your aWSOMI, and `borrowNative` delegates borrowing power on the WSOMI variable-debt token (`approveDelegation`). `repayNative` doesn't take `maxUint256` — overpay slightly instead; the gateway refunds the excess. ## Risk notes - A borrow that would push the health factor below 1 reverts; watch `getAccount(me).healthFactor` and size against `availableBorrowsBase`. - Liquidation pays the liquidator `liquidationBonusBps` out of your collateral — keep headroom, especially against WSOMI's price. - Reserve flags matter: `isFrozen` blocks new supplies/borrows, `isPaused` blocks everything; check them before sizing. - The SDK talks to SomniaLend's contracts as deployed — protocol risk (upgrades, oracle, listing params) is SomniaLend's admin surface, not this SDK's. See their [risks page](https://docs.somnialend.finance/risks). --- # /docs/typescript/prices # Price feeds A realtime index price for an asset (BTC, ETH) from the **on-chain EMA price oracle** — streamed the same way the order books are: hydrate a snapshot to get roughly up to speed, then tail live. It's a _read-only_ feed (an index price, not a tradable market), so there are no orders here — just `watch`/`fetch`. The shared client mechanics (read tiers, the reactive store, React wiring) are in [the engine guide](./ENGINE.md); how the number itself is produced — venue sourcing, weighted median, quantization, validator consensus, the EMA mark — is [Methodology](#methodology) at the bottom of this page. ## The mental model - **A separate service.** Prices come from a standalone EMA price-feed indexer (Hasura GraphQL), _not_ the markets indexer — its own endpoint, its own WebSocket. So price watches are independent of `watchMarket`: their own store, their own `subscribePrices` signal, their own health. - **One endpoint, every asset.** A single endpoint (`config.priceFeed`) serves every tracked asset (`"BTC"`, `"ETH"`, …); callers select an asset by symbol (case-insensitive). Discover what's tracked with `listPriceFeeds()`. With no `priceFeed` configured, the price methods throw with guidance. - **Snapshot, then live tail.** A watch first pulls an HTTP snapshot (current price + recent ticks), then a Hasura subscription streams updates. Unlike the order-book tail there's no seam to stitch — a price subscription is a full-state stream, so a reconnect just re-delivers current state (handled with backoff internally). - **Human numbers + exact raw.** Every price is a 1e18-scaled integer on the wire; the structs carry a display `number` (`price`, `ema`) _and_ the exact 1e18 string in `raw` — never round-trip money through the `number`. Timestamps are unix **seconds** (`blockTimestamp` is chain time, monotonic — use it as a series x-axis; `observedAt` is the oracle's own source time and can drift). ## Configuration ```ts import { SomniaMarkets, SOMNIA_TESTNET_PRICE_FEED } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets({ indexerUrl, chain, wsRpcUrl, priceFeed: SOMNIA_TESTNET_PRICE_FEED, // { url } — the deployed dev feed, all assets // or your own: priceFeed: { url: "https://…/v1/graphql" } }); ``` `priceFeed` is `{ url, wsUrl? }`; `wsUrl` is derived from `url` (`http→ws`, `https→wss`) when omitted. Live subscriptions use the global `WebSocket` (browsers, Node ≥ 21). ## Reading — live ```ts const watch = await client.watchPrice("BTC"); // snapshot + subscribe; ref-counted const now = client.getLivePrice("BTC"); // LivePrice | null — { price, ema, blockTimestamp, raw, … } const tape = client.getLivePriceTicks("BTC", { limit: 120 }); // recent ticks, newest first const info = client.getLivePriceFeedInfo("BTC"); // decimals, symbol, description, latest const state = client.getPriceStatus("BTC"); // "unwatched" | "hydrating" | "live" | "error" watch.stop(); // release (the last release tears the socket down) ``` **Batch variants** take/return arrays and are the ergonomic choice for a multi-asset ticker — one watch, one read: ```ts const handle = await client.watchPrices(["BTC", "ETH", "SOL"]); // snapshot + subscribe all; ref-counted const rows = client.getLivePrices(["BTC", "ETH", "SOL"]); // (LivePrice | null)[], index-aligned const status = client.getPriceStatus("BTC"); // "live" after snapshot/subscription setup handle.stop(); // release all in one call ``` Reads are synchronous, zero-round-trip, and current to the last pushed tick; subscribe to changes with `client.subscribePrices(listener)` (independent of the order-book `subscribeLive`). In React the hooks auto-watch while mounted: ```tsx import { useLivePrice, useLivePriceTicks, useWatchPrice } from "@somnia-chain/markets-sdk/react"; function Ticker() { const price = useLivePrice("BTC"); // updates the moment a tick lands const status = useWatchPrice("BTC"); // "hydrating" | "live" | "error" — render off this const ticks = useLivePriceTicks("BTC", 120); // for a sparkline if (status === "error") return price feed stopped; return {price ? `$${price.price.toLocaleString()}` : "…"}; } ``` ### The `"error"` state The status is `"error"` when the price-feed server rejected or terminated the asset's subscription. This happens on a validation failure after a schema change, or on a permission denial. The subscription will not heal by itself, so stop the watch and start a new one. Reads keep answering in this state. They return the last values they held, which have stopped updating. A view that renders a price without checking the status therefore shows a frozen price as a live one. Each rejection is also emitted as a `warn` event on the client's debug channel with the server payload. ## Reading — one-shot No watch, one HTTP round-trip each — for history, charts, or a server render: ```ts const info = await client.fetchPriceFeedInfo("BTC"); // metadata + current price const price = await client.fetchPrice("BTC"); // LivePrice | null const history = await client.fetchPriceHistory("BTC", { limit: 500, from, to }); // ticks, newest first const candles = await client.fetchPriceCandles("BTC", "M1", { from, to }); // OHLC, oldest first ``` Candle resolutions are `"M1"` / `"H1"` / `"D1"` (60s / 3600s / 86400s). `count` on a candle is the number of oracle updates in the bucket (update density), **not** trade volume. Like every indexer read these **throw** on request failure — an empty result means "no rows", never "request failed". ## From the exchange The unified [`SomniaMarkets`](./EXCHANGE.md) surface exposes prices by asset (these don't need `loadMarkets` — a price feed isn't a symbol-keyed market): ```ts const px = await exchange.fetchPrice("BTC"); // { symbol, price, ema, timestamp, … } | null for await (const _ of forever) { const tick = await exchange.watchPrice("BTC"); // resolves on each new tick } const ohlcv = await exchange.fetchPriceOHLCV("BTC", "1m"); // [ms, o, h, l, c, count][] — "1m"/"1h"/"1d" ``` The native `LivePrice` (raw strings + block metadata) rides on each struct's `info`. ## Methodology Everything above is the read surface. This section is how the number itself is produced: exactly what is measured, what is discarded, how it is aggregated, how it is encoded, and what a consumer is guaranteed when it reads a cell. Every constant is the value in the shipped code (`impl v9`). **One-line version.** A weighted median across seven venue mids, quantized to nine significant figures, medianed again across three independent validators, packed with its own provenance into one 256-bit storage word — every second, paid for by the contract itself. | | | | -------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | Cadence | 1 s | | Scale | 18 decimals | | Sources | 7 centralised exchanges, top-of-book mid | | On-chain aggregation | 3-validator subcommittee, 2-of-3 threshold | | Networks | Somnia mainnet (5031) `0x1998C88D54a240b8C671493f27f58eC416b81D7F` · testnet (50312) `0x7ccAE31E45693475be1e4BAa2360D6997eB2D32B` | ```mermaid flowchart TB V["7 venues
top-of-book mid"] --> G["4 freshness gates
+ per-symbol quorum floor"] G --> M["weighted median
over the fresh set"] M --> Q["quantize
30-bit mantissa + 5-bit exponent"] Q --> B["48-bit slot per symbol
packed blob"] B --> C["3 validators submit
independently"] C --> M2["second median
per symbol, on-chain"] M2 --> E["EMA mark
alpha = 0.125"] E --> S["one 256-bit cell
spot + mark + provenance"] S --> R["consumer read
pull, never reverts"] ``` --- ### 01 — Source: seven venue mids, streamed A Go process — the **price-oracle agent** — connects to seven centralised exchanges through a pruned fork of `ccxt`. It does not fetch on demand. One goroutine per venue runs continuously, writing the latest quote for every tracked pair into an in-memory store; a price request is a read of that store, so it answers in about a millisecond with zero network I/O on the request path. The quantity collected is the **top-of-book mid**, `(bid + ask) / 2`, spot markets only. Four venues stream over WebSocket; three fall back to bulk REST polling on a 1-second ticker. | Venue | Weight | Transport | Why | | ------- | ------ | --------- | ---------------------------------------------------------- | | binance | 3 | ws stream | | | okx | 2 | ws stream | | | bybit | 2 | rest poll | `wss` endpoint geoblocked from the runners' datacentre IPs | | kucoin | 1 | ws stream | | | kraken | 1 | ws stream | | | gateio | 1 | rest poll | stream unimplemented in the fork | | mexc | 1 | rest poll | stream connects, never delivers | Total weight **11**. Weights are static configuration — **not** measured volume or depth. They are placeholders intended to be tuned against real per-venue liquidity. Measured source freshness: 70–220 ms on the streaming venues, 225 ms–3.3 s on REST. > `internal/exchange/ccxt.go`, `oracle.json` · 61 tracked pairs · > `POLL_INTERVAL` 1 s · `PER_CALL_TIMEOUT` 8 s · reconnect backoff doubles to > 30 s, jittered ### 02 — Admission: four gates, then a quorum floor Staleness is the first and strictest gate. A quote that sat in the cache longer than three seconds is not aggregated — it is not even reported as a number. | Gate | When | Rule | Effect | | ----------- | ----------- | ------------------------------------------------------------------- | ------------------------------------ | | Book sanity | ingest | both sides present, `bid > 0`, `ask > 0`, not crossed (`ask ≥ bid`) | quote discarded, never cached | | Spread | ingest | `(ask − bid) / mid ≤ 0.02` | quote discarded, never cached | | Dwell | aggregation | `now − UpdatedAt > STALE_AFTER (3 s)` | exclude, `excludedReason: "stale"` | | Never seen | aggregation | configured exchange has never returned this pair | exclude, `excludedReason: "no-cell"` | The first two run in `midPrices` as each venue's ticker batch is reduced to a mid, so a bad book never reaches the store at all — there is no exclusion reason for it, and a venue that only ever produces bad books is indistinguishable from one that has never returned the pair. `"stale"` and `"no-cell"` are the only two exclusion reasons that exist. - **The spread bound is loose on purpose.** Liquid USDT pairs run around 1 bp, so 2% only catches a book wide enough to be a manipulation surface. - **Dwell is measured on the agent's own ingest clock** (`now − UpdatedAt`), not the exchange's timestamp, so it is immune to venue clock skew. The comparison is strictly greater: exactly 3.000 s still counts. **Then a per-symbol quorum floor.** With fewer than `minSources` fresh venues the agent refuses to publish. The default floor is **3**, with a per-token override table (`SOMI/USDC: 1`, because it does not list on three of these venues). Below the floor the symbol's slot is written as **all zeroes** — not a small number, not a stale number, nothing. > `internal/store/store.go:136,198` · `internal/server/handlers.go:98–112, 406–437` · `maxMidSpreadFrac = 0.02` · `STALE_AFTER = 3s` ### 03 — Aggregation: a weighted median, not an average Sort the fresh quotes by price. Walk the weights. The first price whose cumulative weight crosses half the total is the index. One venue can be the whole answer. All seven venues fresh, total weight 11, half is 5.5: | Venue | Price | Weight | Cumulative | | ----------- | -------------- | ------ | -------------------------- | | kraken | 107,373.90 | 1 | 1 | | mexc | 107,374.05 | 1 | 2 | | okx | 107,374.18 | 2 | 4 | | **binance** | **107,374.21** | **3** | **7** ← first to cross 5.5 | | bybit | 107,374.44 | 2 | 9 | | kucoin | 107,374.60 | 1 | 10 | | gateio | 107,375.02 | 1 | 11 | The index is **107,374.21**. Drop `binance` (stale) and the total falls to 8, half is 4, and `bybit` at 107,374.44 becomes the index — a 23-cent step with no bad data anywhere. There is **no outlier or deviation rejection anywhere in the agent**. Robustness comes entirely from the choice of median over mean. ### 04 — Quantization: nine significant figures in six bytes The float becomes an 18-decimal integer, then is re-encoded as a 30-bit mantissa and a 5-bit exponent. Everything past the ninth digit was never real. Two lossy steps, in order: 1. **Scale-up.** The price is a `float64` the whole way through the agent, so multiplying by `10^18` in a `big.Float` pinned at a 53-bit mantissa re-rounds rather than shifting exactly. This is why BTC arrives on-chain looking like `63420.750000000000327680` — that tail is `float64` residue, not market data. 2. **Wire encoding.** Pick the smallest exponent whose mantissa still fits 30 bits, rounding half up. One symbol's wire slot is exactly 48 bits and exactly full: | Field | Bits | Range | Example — BTC at 107,374.21 | | ------------- | ---- | -------------- | ----------------------------------------- | | `mantissa` | 30 | `0 … 2^30 − 1` | `107374210` | | `exp` | 5 | `0 … 31` | `15`, so the value is `107374210 × 10^15` | | `sourceAgeMs` | 13 | `0 … 8191` | `120` | ### 05 — Transport: the packed blob The contract calls `getPricesSlots(string[],uint8)` and gets back a single `bytes` value of **exactly** `6 × nActive` bytes — no ABI element padding at all. The symbol at active position `p` lives at bytes `[6p, 6p+6)`, big-endian. Slots straddle 32-byte word boundaries by design. - 30 active symbols → blob length must equal **180 bytes**, exactly. - A **whole-zero slot** means "this validator did not price this symbol". - A **nonzero slot with a zero mantissa** is malformed and is dropped the same way. - **Any other length drops the validator entirely** — a stale cell, never a wrong price. ### 06 — Consensus: three validators, then a second median Nobody trusts one agent. A subcommittee of three runs the same code in three sandboxes against three separate caches, and the contract medians them again. Each elected subcommittee member detects the request, runs the agent in its own Docker sandbox, and submits its own blob on-chain. Because the agent answers from a continuously-updated cache, the three answers are legitimately different — which is why the platform finalises on **Threshold** consensus (2-of-3), not Majority, which would require identical result hashes. | Live parameter | Value | Consequence | | ------------------ | ------------- | --------------------------------------------------------------- | | `subcommitteeSize` | 3 | three independent agent runs per tick | | `threshold` | 2 | two contributors is the ordinary steady state; one is reachable | | `consensusType` | 1 (Threshold) | non-identical results are expected, not a fault | | `timeout` | 15 s | must exceed 10 s — the runner cancels at `deadline − 10s` | | `decimals` | 18 | the scale the agent is asked to pre-apply | **Four gates on the response, before a single cell moves.** | Rejection | Reason code | Why | | ---------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | not in the inflight ring | `not-inflight` | ring lookup and consume, so a duplicate callback is idempotent | | `status ≠ Success` | `AgentRequestFailed` | no cells written | | `block.timestamp − kickedAt > 3 s` | `stale-response` | the platform's timeout upkeep can deliver a quorum-met partial as `Success` hours late; ingesting it would sawtooth the feed and poison the EMA | | `symbolsVersion` moved | `symbols-version-mismatch` | responses carry no symbol identity, only array position — if the symbol list changed since the kick, position `i` may be a different asset | Any symbol-list mutation invalidates every inflight request; the next tick refills everything within one interval. **The second median — per validator, per symbol.** For each symbol the fill loop does one `calldataload` per validator, gates it, and medians the survivors. The gate is **per-validator**, which is the whole point: one garbage validator drops out instead of shifting the median. | Symbol | Validator A | Validator B | Validator C | Cell written | | ------------- | ----------- | ------------ | ----------- | ---------------------------------- | | BTC/USDC | 107,374.18 | 107,374.21 | 107,374.30 | 107,374.21 · vc 3 | | ETH/USDC | 3,142.07 | slot = 0 | 3,142.11 | 3,142.11 · vc 2 | | SOL/USDC | slot = 0 | mantissa = 0 | 184.62 | 184.62 · vc 1 | | FARTCOIN/USDC | slot = 0 | slot = 0 | slot = 0 | untouched — omitted from the batch | Insertion sort, then `values[n / 2]` — the **upper** middle on even counts, which at the ordinary 2-of-3 threshold means the higher of the two prices. On a 2-validator tick the median is not a blend; it is a pick. `vc` is `validatorCount`, the surviving contributor count, saturating at 7, with 0 meaning _unknown_ — never "none". ### 07 — Mark price: the same number, smoothed Mark is **not a different data source**. It is an EMA over the spot series, computed from the previous cell, and it costs no extra storage. Each tick the mark moves `emaAlpha = 0.125e18` — one eighth — of the way from the previous mark toward the new spot. At the 1 s cadence that is a smoothing horizon of τ ≈ 8 s. **Response to a genuine move.** After `n` ticks the fraction of a step captured is `1 − 0.875^n`. The conventional time constant τ is where that crosses 63%, and it lands exactly where `interval / alpha` predicts — 8 ticks: | Ticks | 1 | 2 | 4 | 6 | 8 (= τ) | 16 | 24 | | -------- | ----- | ----- | ----- | ----- | ------- | ----- | ----- | | Captured | 12.5% | 23.4% | 41.4% | 55.1% | 65.6% | 88.2% | 95.9% | **Alpha is per tick, not per second.** τ ≈ 8 s here, but τ ≈ 80 s in the DEX's oracles — same `emaAlpha = 0.125e18`, copied from their production values, but their cadence is 10 s. Rescale alpha if the cadence changes and the smoothing horizon should stay put. `emaAlpha = 1e18` disables smoothing entirely — mark becomes spot. ### 08 — Storage: everything in one slot Spot, mark, timestamp, source age and provenance share a single 256-bit word. One cold `SSTORE` per symbol per tick, one `SLOAD` to read all of it. | Field | Bits | Encoding, and what 0 means | | ------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `price` | 86 | spot median at 18 dp. Ceiling ≈ 77 M per unit. | | `quality` | 14 | packed sub-fields, below | | `mark` | 86 | EMA mark; always between the previous mark and this spot | | _reserved_ | 14 | | | `updatedAtMs` | 42 | `block.timestamp × 1000` — second-granular, shared by every symbol written in the same tick. A `maxAgeMs` bound below the tick cadence is not meaningful. Good to year 2109. | | `sourceAgeMs` | 14 | a delta below `updatedAtMs`, not an absolute stamp — capped at 16.383 s. The top value is the sentinel and reads back as `0 = unknown`, never "current", so a real age clamps one below it. | The 14-bit `quality` field expands to: | Sub-field | Bits | Meaning | | -------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `validatorCount` | 3 | contributors to the median, saturating at 7. `0 = unknown` (a cell written before the field shipped), never "none" — a written cell always had ≥ 1. | | `medianControlCount` | 3 | reserved. Always reads `0`. No room on the wire. Do not branch on it. | | `flags` | 2 | bit 0 `FLAG_MARK_RESYNCED`; bit 1 `FLAG_DEVIATION` reserved and never set. | | _reserved_ | 6 | | Removing a symbol deletes its cell. **Indices are append-only and never reused**, so an on-chain consumer can resolve index → symbol once off `SymbolAdded` and read by index forever — one `SLOAD` cheaper than the string-keyed path, with no risk that a removal elsewhere silently shifts the mapping. > `contracts/feed/lib/PriceCell.sol` · `lib/FeedHealth.sol` · > `lib/ActiveIndexSet.sol` ### 09 — Consumption: pull, and decide staleness yourself Reads never revert. Staleness is the caller's decision, always — the feed will not decide on your behalf what is too old. | Interface | Keyed by | Gives you | | --------------------- | ---------------- | ---------------------------------------------------- | | `IPriceFeed` | symbol string | spot, cell age, source age, tracked-symbol registry | | `IMarkPriceFeed` | symbol string | EMA mark (separate so `IPriceFeed`'s id never moved) | | `IIndexedPriceFeed` | stable `uint256` | the same data, one `SLOAD` cheaper | | `IQualifiedPriceFeed` | either | quorum, flags, feed liveness, and the safe reads | **Off-chain: one batched event, and history.** Each tick emits a single `PricesUpdated(requestId, updatedAtMs, indices[], prices[], marks[], sourceUpdatedAtsMs[], resyncedBits)` — one event for the whole batch, carrying only stable indices. An Envio + Hasura stack indexes it into `Feed` (latest per symbol, a Chainlink-ish `latestRoundData` analogue), `PricePoint` (the per-tick firehose), `Candle` (OHLC at M1 / H1 / D1) and `Symbol` (the index → pair registry). That GraphQL surface is what the price methods above read. > **GraphQL is for humans, not for settlement.** Testnet only, and observability > only. It lags the chain, can be resynced, and is not part of the support > contract. Never settle, liquidate, or price anything off it. **End-to-end latency.** | Leg | Time | | ---------------------------------------------------- | ----------- | | 1 — exchange → agent | ~0.1 s (ws) | | 2 + 4 + 5 — cache dwell + kick→response + cell write | ~0.8 s | | 6 — wait for your next read | 0–~1 s | Measured on testnet over 150 consecutive BTC/USDC ticks: cell cadence median 1 s (max 2 s), kick→cell median ~0.8 s ≈ 7 blocks at ~116 ms. A consumer acts on a price 1–2 s old; at the instant of the cell write it is ~0.9 s. The dominant and most actionable leg is kick→cell. REST-only venues are the other lever — they inflate leg 1 and can leave source age unmeasurable entirely. --- ### Sources Contracts and scheduler: - `smart-contracts/contracts/feed/PriceFeedScheduler.sol` - `smart-contracts/contracts/feed/lib/PriceCell.sol` - `smart-contracts/contracts/feed/lib/SlotResponse.sol` - `smart-contracts/contracts/feed/lib/FeedHealth.sol` - `smart-contracts/docs/price-feed-scheduler.md`, `price-feed-latency.md`, `price-feed-design-decisions.md` - `smart-contracts/script/config/feed-testnet-development.json` - `docs/price-feed-integration.md` - `price-feed/indexer/schema.graphql` Agent: - `somnia-agents/agents/price-oracle/internal/store/store.go` - `somnia-agents/agents/price-oracle/internal/server/handlers.go` - `somnia-agents/agents/price-oracle/internal/exchange/ccxt.go` - `somnia-agents/agents/price-oracle/oracle.json`, `agent.json` ## Delivery state and acquisition errors The price service is separate from the main indexer. Its results do not carry main-indexer watermarks. `hydrated` means the HTTP snapshot completed. `streaming` requires valid initial results from both the current-price and tick subscriptions. Empty arrays confirm delivery without creating a price. A connection acknowledgement alone does not establish streaming. `stale` means known delivery loss. It does not infer an expected oracle tick frequency. The asset retains its last values while reconnecting, and both streams must deliver again before `streaming` returns. `error` means hydration failed or a subscription was rejected. Each asset reports its own state, so a healthy sibling cannot conceal a stale one. Existing `getPriceStatus` and `useWatchPrice` keep `unwatched | hydrating | live | error`. The legacy `live` state means snapshot/subscription setup succeeded; it does not confirm operation delivery. A disconnect does not change that legacy state. Opt into `client.getPriceHealth(asset)` or `client.listPriceHealth()` for the precise states above. They share the existing price watches and `subscribePrices` notifications. No extra socket opens. Automatic hooks continue reporting acquisition failures through the debug/console warning channel. Use `useWatchMarketResult`, `useWatchUserResult`, or `useWatchPriceResult` for typed inline acquisition UI. Effects ignore superseded failures and release handles acquired after unmount. --- # /docs/typescript/chains # Chains Every Somnia network as a viem `Chain`, from one import — so nothing has to hand-roll a `defineChain({...})` or reach for `viem/chains` again. ```ts import { somniaShannon } from "@somnia-chain/markets-sdk/chains"; ``` `chain` is a required field of every exchange/client config (it signs writes and sizes viem's waiting heuristics), and `wsRpcUrl` is the transport the live tail runs on — both come straight off these objects. Moving tokens _between_ these networks is the [bridge](./BRIDGE.md) — same module, same import. ## The networks | Export | Chain id | Native | Blocks | Multicall3 | Explorer | | --------------- | -------- | ------ | --------- | ---------- | -------------------------------------------------------------------------- | | `somniaMainnet` | `5031` | SOMI | 100 ms | ✅ | [explorer.somnia.network](https://explorer.somnia.network) | | `somniaShannon` | `50312` | STT | 100 ms | ✅ | [shannon-explorer.somnia.network](https://shannon-explorer.somnia.network) | | `somniaElwood` | `50313` | STT | 100 ms | — | — | | `hidekiTestnet` | `50383` | STT | **10 ms** | ✅ | — | | `somniaLocal` | `31337` | STT | — | — | — | - **Shannon** (`somniaShannon`) is the public testnet and the default target for development. `https://dream-rpc.somnia.network` is an alias for the same network and is listed as a secondary endpoint. - **Elwood** is the testnet's regenesis: its own cluster, DNS zone and genesis, otherwise identical to Shannon. - **Hideki** is the low-latency Tokyo network — ~100 blocks/s. If you are measuring latency, measure here. - **`somniaLocal`** is the anvil stack (`demo-clob.sh up`, `DEPLOY_ENV=local`). It deliberately presents as _Somnia_/_STT_ rather than _Foundry_/_Ether_: the agent-facing docs read the chain name and native symbol out of this object, and a local stack should still read as Somnia there. Every definition carries **both** transports — `rpcUrls.default.http` and `rpcUrls.default.webSocket` — so an exchange can be built from the chain alone: ```ts import { SomniaMarkets } from "@somnia-chain/markets-sdk"; import { hidekiTestnet as chain } from "@somnia-chain/markets-sdk/chains"; const exchange = new SomniaMarkets({ chain, wsRpcUrl: chain.rpcUrls.default.webSocket[0], indexerUrl: "/v1/graphql", }); ``` ## Absences are deliberate Elwood and the local chain carry **no `contracts.multicall3`** and no `blockExplorers` — nothing is deployed there to point at. That is not an oversight to be filled in with the canonical `0xcA11bde05977b3631167028862bE2a173976CA11`: viem routes batched reads at whatever address it finds, so a Multicall3 entry with no code behind it turns every batched read into a failure. An absent field just makes viem fall back to individual `eth_call`s. Mainnet, Shannon and Hideki each have their **own** Multicall3 deployment at _different_ addresses (`0x5e44…5a11`, `0x841b…4223` and `0x540B…D131`) — don't copy one to another. Hideki's (deployed 2026-08-10 by the bridge infra) is the canonical runtime bytes at a **non-canonical** address: the presigned "Nick's method" deployment can never land on Somnia chains — contract creation costs ~4,928 gas per deployed byte here, far over that transaction's fixed 500k limit — and its nonce-0 deployer has already been burned on these networks, so `0xcA11bde0…` is unreachable for good. The values here — ids, cadence, Multicall3 addresses — were verified against the live networks (`eth_chainId`, block-timestamp deltas over 10k blocks, and a real `getBlockNumber()` call on each Multicall3 candidate), not copied from a chain list. ## Resolving a chain id you were handed Deployment manifests (and `NEXT_PUBLIC_CHAIN_ID`-style env) carry a plain `number`. `getSomniaChain` bridges that to a `Chain`, returning `null` when the id isn't one of ours: ```ts import { getSomniaChain, defineChain } from "@somnia-chain/markets-sdk/chains"; const chain = getSomniaChain(deployment.chainId) ?? defineChain({ id: deployment.chainId, name: "Somnia", nativeCurrency: { name: "STT", symbol: "STT", decimals: 18 }, rpcUrls: { default: { http: [rpcUrl] } }, }); ``` `somniaChains` is the same table, keyed by id — iterate it to build a network switcher. `isSomniaChainId(id)` is the type guard that narrows a `number` to `ChainId`, enough to index it without a cast. When the id flows the other way — your code names the network — **`ChainId`** is the constant to reach for: `ChainId.somniaShannon` is `50312`, keyed by the same export names as the definitions (`ChainId.somniaShannon === somniaShannon.id` by construction). ## Extending one `defineChain` and the `Chain` type are re-exported here, so overriding an endpoint (a private node, a fork) needs no second import: ```ts import { defineChain, somniaShannon } from "@somnia-chain/markets-sdk/chains"; const forked = defineChain({ ...somniaShannon, id: 31_337, name: "Somnia Testnet (forked)", rpcUrls: { default: { http: ["http://127.0.0.1:8545"], webSocket: ["ws://127.0.0.1:8545"] } }, }); ``` ## Relationship to `viem/chains` viem ships two of these networks as `somnia` and `somniaTestnet`; our `somniaMainnet` and `somniaShannon` carry the same content under the names the runbooks use (a test asserts field-for-field parity), and the module adds the three networks viem cannot ship — Elwood, Hideki and the local stack are ours, on our cadence. One import covers every target, and a new network lands when we bring it up rather than when viem next cuts a release. Each definition lives in its own file under `src/chains/definitions/`, written the way viem writes its own, so the two stay diffable. `src/chains/bridge/` sits alongside them with the warp-route registry — see the [bridge guide](./BRIDGE.md). --- # /docs/typescript/bridge # Bridge Moving tokens between Somnia networks. A specialised chain is only useful if value can reach it — Hideki is a ~10 ms-block network built for traders, and this is how balances get there from the general-purpose testnet. ```ts import { BridgeToken, ChainId, createBridgeTransfer, sendBridgeStep } from "@somnia-chain/markets-sdk/chains"; ``` It lives in the [chains](./CHAINS.md) module because that is what it is: verified static addresses, alongside the chain definitions and their Multicall3 entries. The registry and `createBridgeTransfer` are **pure** — no RPC, no client, no signer: `createBridgeTransfer` returns transaction data and you send it. `sendBridgeStep` is the one opt-in sender. > ⚠️ **This is a dev/test bridge.** One validator, a threshold-1 ISM, EOA owners — > one key is the entire bridge. `SOMNIA_BRIDGE.status` is `"dev-test"` and it means > it: **do not put real funds behind it.** ## What's live One lane, five routes — [full deployment record](https://github.com/somnia-chain/hyperlane-bridge-infra/blob/main/docs/deployments/somnia-testnet-hideki-testnet.md): | Token | Somnia Testnet (50312) | Hideki Testnet (50383) | Decimals | | ------- | ---------------------- | ---------------------- | -------- | | `STT` | native | native | 18 | | `USDso` | collateral | synthetic | 18 | | `WBTC` | collateral | synthetic | **8** | | `WETH` | collateral | synthetic | 18 | | `HBTT` | collateral | synthetic | 18 | Mainnet, Elwood and the local chain are **not** bridged — `getBridgeNetwork` returns `null` for them, and `createBridgeTransfer` throws rather than inventing a route. Bridging is also **not transitive**: a chain has to be a member of the token's own route. ## The enumerations ```ts BridgeToken.WBTC; // "WBTC" — the bridge's own enum ChainId.hidekiTestnet; // 50383 — from the chains module: the chain id IS the value ``` Both are `const` objects with a matching type, not TS `enum`s — the pattern the rest of this SDK uses. You get `BridgeToken.WBTC` for the value and `BridgeToken` for the type, plain literals still assign, and nothing non-erasable is emitted. Networks are named by **`ChainId`**, which lives with the [chain definitions](./CHAINS.md) rather than here — every Somnia network has a chain id; only some are bridged. Its keys are the definition export names, so `ChainId.hidekiTestnet === hidekiTestnet.id` by construction, and the id is the value because that is what wallets, manifests and viem speak — on this bridge the Hyperlane **domain id equals the chain id**, so one number identifies a network everywhere. ## Bridging ```ts const plan = createBridgeTransfer({ token: BridgeToken.WBTC, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: 100_000_000n, // 1 WBTC — 8 decimals, not 18 recipient: account.address, }); if (plan.approveStep) await sendBridgeStep(client, plan.approveStep, { account }); const receipt = await sendBridgeStep(client, plan.bridgeStep, { account }); ``` Two fields are the whole plan: **`bridgeStep`** — the `transferRemote` call, always present — and **`approveStep`**, the ERC-20 approval a collateral route needs first, simply **absent** on native and synthetic routes. Branching on `plan.approveStep` narrows it, so no `!` is ever needed; its role is the field name, and `description` is the human label. **`sendBridgeStep(client, step, { account })`** is the sender: it signs locally (fixed fees, fixed gas ceiling, never estimated) and broadcasts via Somnia's `realtime_sendRawTransaction`, which blocks server-side and returns the **receipt in the same call** — send + confirm in one round-trip, so the approve-then-bridge ordering above is safe by construction. It throws on a reverted receipt, and on a node without the method (anvil, stock geth) it falls back to `eth_sendRawTransaction` + a receipt wait. It needs a **local** signer (viem `privateKeyToAccount`, a session account); with a browser wallet, spread the step into `walletClient.sendTransaction({ ...plan.bridgeStep, account })` instead — extensions don't sign raw transactions. One consequence of fixed ceilings worth knowing: Somnia's mempool admits a transaction only when the balance covers `gas × maxFeePerGas` (0.6 STT at the defaults) on top of its `value`, even though unused gas is never charged — fund small accounts for the envelope, not the expected fee. Each transaction is `{ chainId, to, data, value, description }` — everything you must send, nothing you must fill in. No `gas`, no `nonce`, no fees: those belong to the signer, and a builder guessing gas for a contract on another chain would be inventing numbers. `value` **is** ours, because it is protocol-semantic: | Route model | `value` | Approval | | ------------ | ---------------------------------------------- | ------------------------------------ | | `native` | **the amount** — the coin rides in `msg.value` | none | | `collateral` | `0n` | ERC-20 `approve` to the router | | `synthetic` | `0n` | none — the router burns your balance | Amounts are **bigint base units of the origin side's decimals**. Read them from `plan.origin.decimals` rather than assuming 18 — WBTC is 8 on both sides. **Browser wallets and JSON boundaries.** A viem wallet client takes a step as-is — including one on `custom(window.ethereum)`. For the raw `eth_sendTransaction` path, or to move a server-built plan across a JSON boundary (a step's `value` is a `bigint`, and `JSON.stringify` throws on bigints), `toEip1193Transaction(step, { from? })` returns the hex-quantified, JSON-safe request object — typed as viem's own `RpcTransactionRequest`. It deliberately drops `chainId`: an EIP-1193 wallet signs on its **active** chain, so switch with `wallet_switchEthereumChain` first. The [walkthrough](./CHAINS_WALKTHROUGH.md) shows both paths end to end. ## Two failure modes worth preflighting **Native-route liquidity.** An `STT` transfer is native on both sides, so delivery is paid out of the _destination router's own balance_ rather than by minting. If that balance is short, `process()` reverts and the transfer sits in escrow until someone refunds the router — not lost, but stuck. The destination side's `requiresDestinationLiquidity` flags it; check the balance yourself before offering the transfer: ```ts if (plan.destination.requiresDestinationLiquidity) { const liquidity = await destinationClient.getBalance({ address: plan.destination.router }); if (liquidity < plan.amount) throw new Error("destination router is short — transfer would stall"); } ``` At the last verification the Somnia-side router held **0 STT** and Hideki's held 100, so a _first_ Hideki → Somnia transfer stalls until seeded. Seeding is a plain native transfer to the router. **The relayer is a liveness dependency.** No InterchainGasPaymaster is deployed, so `quoteGasPayment` is 0 on every router and the relayer pays delivery gas unmetered (`SOMNIA_BRIDGE.relayerPaysDestinationGas`). A sender attaches nothing for delivery — but if the relayer runs dry, transfers keep being accepted on the origin and stop being delivered. Should a gas quote ever be introduced, read it and pass it as `gasPayment`; it lands in `bridgeStep.value`. Delivery is asynchronous either way: `transferRemote` escrows and dispatches, and the far side is credited seconds later (median ~4s per leg since the relayer's 2026-08 latency work; 5–10s before it). The transaction you send does not wait for it. ## Looking things up ```ts getBridgeToken(BridgeToken.USDso, ChainId.hidekiTestnet); // one side of one route, or null listBridgeTokens(ChainId.somniaShannon); // everything bridgeable from a network getBridgeNetwork(ChainId.somniaShannon); // mailbox / ISM / hooks, or null listBridgeNetworks(); // the bridged networks getBridgeRoute(BridgeToken.WBTC, 50312, 50383); // the lane, either order, or null getBridgeRouter(BridgeToken.STT, ChainId.somniaShannon); // just the router address SOMNIA_BRIDGE; // the lane: routes, trust model, docs ``` Lookups return `null` on a miss (the `get*` contract: a `get*` read answers with `null` for a real absence); `createBridgeTransfer` **throws**, because an unsupported triple is a programming error and its message names what would work. `warpRouterAbi` is exported too, for reading a router directly — `quoteGasPayment`, `routers`, `destinationGas`, `token`. ## How the values got here Every address, decimal and model in the registry was read off the **live chains**, not transcribed: all ten routers have code, are owned by one account, are wired to their chain's mailbox and ISM, and are mutually enrolled in both directions; the collateral routers' `token()` matches the canonical ERC-20; the synthetics' `decimals()` match; `quoteGasPayment` is exactly 0 everywhere. The `transferRemote` encoding was _simulated_ with `eth_call` — `value = amount` on the native route returns a real message id, while dropping the value, skipping the approval, or naming an unenrolled destination each revert. `test/bridge.test.ts` pins the calldata offline. `test/bridge.e2e.test.ts` re-runs the whole verification against both chains on demand — nothing signed, nothing sent: ```sh SOMNIA_E2E_BRIDGE=1 pnpm test ``` A note on one client-side trap the registry exists to avoid: a **native** router answers `token()` with the _zero address_ rather than reverting, so code that probes `token()` to decide "collateral or native" silently gets `0x0…0`. Use `plan.origin.model` / `BridgeTokenDetails.model` instead. ## Adding a token or a lane Both are data. `hyperlane-bridge-infra` is the source of truth — a new route there becomes a new entry in `src/chains/bridge/registry.ts`, and the types already carry it: `destinations` is a list, `SOMNIA_BRIDGE.routes` is a list, and every lookup is a filter. Adding a route needs no agent restart and no new core contracts; the validator and relayer are token-agnostic. --- # /docs/typescript/chains-walkthrough # Chains walkthrough A hands-on tour of `@somnia-chain/markets-sdk/chains`, end to end: pick a network, stand up clients, send a transaction, bridge STT both ways, fund a Hideki session account from a Shannon wallet, and run the live test suite that proves all of it against the real networks. The reference guides are [CHAINS.md](./CHAINS.md) (the network definitions) and [BRIDGE.md](./BRIDGE.md) (the warp-route registry and its trust model) — this page is the "follow along in a terminal" version. **You need:** Node + pnpm, `viem` (a peer dependency of the SDK), and an account holding STT on the networks you target. Shannon STT comes from the Somnia testnet faucet or a funded team key; Hideki has no public faucet — use a funded key. Everything below runs on the two bridged testnets and costs fractions of a (test) token. ```ts import { somniaShannon, hidekiTestnet } from "@somnia-chain/markets-sdk/chains"; ``` The module is **pure data + pure functions** — importing it performs no RPC. The networks it ships: | Export | Chain id | Blocks | Bridged | | --------------- | -------- | --------- | ------- | | `somniaMainnet` | `5031` | 100 ms | — | | `somniaShannon` | `50312` | 100 ms | ✅ | | `somniaElwood` | `50313` | 100 ms | — | | `hidekiTestnet` | `50383` | **10 ms** | ✅ | | `somniaLocal` | `31337` | — | — | This walkthrough sticks to the two bridged testnets: **Shannon** (`50312`, the general-purpose testnet) and **Hideki** (`50383`, the low-latency Tokyo network). ## 1. Create a client for different chains Every definition is a complete viem `Chain` — endpoints (HTTP _and_ WebSocket), block cadence, and Multicall3 where one actually exists. So a client is one call, and `http()` with no URL already means "the chain's default endpoint": ```ts import { createPublicClient, http, webSocket } from "viem"; import { somniaShannon, hidekiTestnet } from "@somnia-chain/markets-sdk/chains"; const shannon = createPublicClient({ chain: somniaShannon, transport: http() }); const hideki = createPublicClient({ chain: hidekiTestnet, transport: http() }); await shannon.getChainId(); // 50312 await hideki.getChainId(); // 50383 // The live tail and anything latency-sensitive should ride the WebSocket: const hidekiWs = createPublicClient({ chain: hidekiTestnet, transport: webSocket(), // hidekiTestnet.rpcUrls.default.webSocket[0] }); ``` When the chain id arrives as a plain `number` (a deployment manifest, a `NEXT_PUBLIC_CHAIN_ID` env), resolve it instead of switching on magic numbers: ```ts import { getSomniaChain, isSomniaChainId, somniaChains } from "@somnia-chain/markets-sdk/chains"; const chain = getSomniaChain(Number(process.env.CHAIN_ID)); // Chain | null if (!chain) throw new Error("not a Somnia network"); // somniaChains is the same table keyed by id — iterate it for a network switcher. // isSomniaChainId(id) narrows a number so somniaChains[id] indexes without a cast. ``` Two behaviors to know, both deliberate (details in [CHAINS.md](./CHAINS.md)): - **Every bridged network batches, at its own address.** Shannon, Hideki and mainnet each carry a `contracts.multicall3` — three _different_ addresses (Hideki's arrived 2026-08-10, at a non-canonical address, because the canonical `0xcA11bde0…` deployment can never land on Somnia chains). Elwood and the local chain have none, and viem silently falls back to individual `eth_call`s there. Don't "fix" an absence by pasting the canonical multicall address into an extended definition — there is no code at it, and viem would route every batched read into a failure. - **`blockTime` drives viem's waiting heuristics.** Hideki's `10` means `waitForTransactionReceipt` polls fast enough to return in tens of milliseconds; a hand-rolled `defineChain` without it would wait seconds. ## 2. Post a transaction A wallet client from a private key, a send, a receipt — the only chains-module-specific part is that the `Chain` object is the one import: ```ts import { createWalletClient, http, parseEther } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { somniaShannon } from "@somnia-chain/markets-sdk/chains"; const account = privateKeyToAccount(process.env.SOMNIA_TESTNET_PK as `0x${string}`); const wallet = createWalletClient({ account, chain: somniaShannon, transport: http() }); const hash = await wallet.sendTransaction({ to: "0x0000000000000000000000000000000000000001", value: parseEther("0.001"), }); const receipt = await shannon.waitForTransactionReceipt({ hash }); receipt.status; // "success" ``` The same code targets Hideki by swapping the chain and the key. Gas, nonce and fees are viem's job — the chain definitions carry everything viem needs to estimate them correctly per network. ## 3. Bridge STT both ways The bridge is the same import: a Hyperlane warp lane between Shannon and Hideki carrying `STT`, `USDso`, `WBTC`, `WETH`, `HBTT`. [`createBridgeTransfer`](./BRIDGE.md#bridging) is pure — it returns the unsigned transactions; you sign and send them. > ⚠️ It is a **dev/test** bridge — one validator, threshold-1 ISM. Testnet > value only. Shannon → Hideki, delivered and verified: ```ts import { BridgeToken, ChainId, createBridgeTransfer, sendBridgeStep } from "@somnia-chain/markets-sdk/chains"; import { parseEther } from "viem"; const amount = parseEther("0.05"); const plan = createBridgeTransfer({ token: BridgeToken.STT, from: ChainId.somniaShannon, // 50312 — the values ARE chain ids to: ChainId.hidekiTestnet, // 50383 amount, recipient: account.address, }); // STT is native on both sides → no approval, the amount rides in msg.value. // A collateral route (USDso/WBTC/WETH/HBTT leaving Shannon) needs an ERC-20 // approval first — plan.approveStep is present exactly when that's the case. // // sendBridgeStep signs locally (fixed fees, no estimation) and broadcasts via // Somnia's realtime_sendRawTransaction: the node blocks until the transaction // is executed and answers with the RECEIPT — send + confirm in one round-trip, // so each line below resolves confirmed. (No wallet client needed: the public // client is the wire, the account is the signer.) if (plan.approveStep) await sendBridgeStep(shannon, plan.approveStep, { account }); const receipt = await sendBridgeStep(shannon, plan.bridgeStep, { account }); receipt.status; // "success" — a reverted receipt throws instead ``` That receipt only proves **escrow + dispatch** on the origin. Delivery is asynchronous — the relayer credits the far side seconds later (median ~4 s per leg since the relayer's 2026-08 latency work). Watch the destination: ```ts async function waitForDelivery(client, address, floor, timeoutMs = 180_000) { const deadline = Date.now() + timeoutMs; while (Date.now() < deadline) { const balance = await client.getBalance({ address }); // ERC-20 routes: readContract balanceOf if (balance >= floor) return balance; await new Promise((r) => setTimeout(r, 2_000)); } throw new Error("not delivered — is the relayer alive? is the destination router funded?"); } const before = await hideki.getBalance({ address: account.address }); // ... send the plan (previous snippet) ... await waitForDelivery(hideki, account.address, before + amount); ``` The reverse direction is the same call with `from`/`to` swapped and a Hideki-funded wallet — but preflight it, because **native-route delivery pays out of the destination router's own balance**: ```ts const back = createBridgeTransfer({ token: BridgeToken.STT, from: ChainId.hidekiTestnet, to: ChainId.somniaShannon, amount, recipient: account.address, }); if (back.destination.requiresDestinationLiquidity) { const liquidity = await shannon.getBalance({ address: back.destination.router }); if (liquidity < back.amount) { // Underfunded ≠ lost: the transfer would sit in escrow until the router is // seeded. Seeding is a plain native transfer to the router address — and // note the symmetry: every transfer OUT of a chain escrows on that chain's // router, which is exactly the balance a later reverse transfer draws on. throw new Error(`Shannon STT router holds ${liquidity} wei — seed it first`); } } ``` At the last live run the Shannon-side router held **0 STT**, so a first Hideki → Shannon transfer stalls until the router is seeded (or until an equal amount has been bridged Shannon → Hideki, which self-seeds it). Hideki's router held 100 STT. Mind the units: amounts are **bigint base units of the origin side's decimals** — read `plan.origin.decimals`, don't assume 18 (WBTC is 8 on both sides). Lookups (`getBridgeToken`, `getBridgeRoute`, …) return `null` on a miss; `createBridgeTransfer` **throws** on an unsupported triple, naming what would work. ### Signing in the user's browser Everything so far signed with a private key in Node. In a dapp the key lives in the user's wallet extension, and the order reverses: **connect first** — the sender (and usually the recipient) is the wallet's address, which you only know once it answers — _then_ build the plan, _then_ let the user confirm each step. Two distinct moments, worth keeping apart: 1. **The transaction is created** by `createBridgeTransfer` — a pure function that returns unsigned calldata. No RPC happens, nothing is sent, and there is nothing secret in the result. 2. **The transaction is signed** when a step is handed to the wallet — one prompt per step — and only then does anything reach the chain. The whole flow, self-contained: ```ts import { createPublicClient, createWalletClient, custom, http, parseEther } from "viem"; import { BridgeToken, ChainId, createBridgeTransfer, somniaShannon } from "@somnia-chain/markets-sdk/chains"; // 1. Connect — this is where the user's address comes from. const browser = createWalletClient({ chain: somniaShannon, transport: custom(window.ethereum) }); const [account] = await browser.requestAddresses(); // 2. Create the transaction(s): pure, unsigned, not yet sent anywhere. const plan = createBridgeTransfer({ token: BridgeToken.STT, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: parseEther("0.05"), recipient: account, // the user's own address on the destination chain }); // 3. Sign + send — one wallet prompt per transaction; the wallet fills // gas/nonce/fees. The approval must land before the bridge call spends it. // (The realtime path from §3 doesn't apply here: realtime_sendRawTransaction // needs a locally-held key, and an extension won't sign raw transactions — // the wallet's own eth_sendTransaction is the browser's send path.) const shannon = createPublicClient({ chain: somniaShannon, transport: http() }); if (plan.approveStep) { const hash = await browser.sendTransaction({ ...plan.approveStep, account }); await shannon.waitForTransactionReceipt({ hash }); } const hash = await browser.sendTransaction({ ...plan.bridgeStep, account }); await shannon.waitForTransactionReceipt({ hash }); ``` Because step 2 is pure it can also run **server-side** (an API route, a server action): the browser sends the connected address up, the server builds the plan and returns the transactions. A `BridgeStep` doesn't cross that boundary as-is — its `value` is a `bigint`, and `JSON.stringify` throws on bigints — `toEip1193Transaction` is the JSON representation: the exact object `eth_sendTransaction` takes, every quantity hex-encoded. ```ts // On the server — build the plan for the address the browser sent: import { ChainId, createBridgeTransfer, toEip1193Transaction } from "@somnia-chain/markets-sdk/chains"; const plan = createBridgeTransfer({ token: BridgeToken.STT, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: parseEther("0.05"), recipient: userAddress, }); return Response.json({ chainId: plan.bridgeStep.chainId, // the ORIGIN chain the wallet must be on approve: plan.approveStep && toEip1193Transaction(plan.approveStep, { from: userAddress }), bridge: toEip1193Transaction(plan.bridgeStep, { from: userAddress }), }); // bridge: {"from":"0x…","to":"0xB043…aB35","data":"0x81b4e8b4…","value":"0xb1a2bc2ec50000"} ``` ```ts // In the browser — no SDK import needed, the transactions are ready-made requests: import { numberToHex } from "viem"; const { chainId, approve, bridge } = await (await fetch("/api/bridge-plan")).json(); // ⚠️ eth_sendTransaction has NO chain field — an EIP-1193 wallet signs on its // ACTIVE chain. Switch to the origin chain first, or the transfer goes out on // whatever network the wallet happens to be on: await window.ethereum.request({ method: "wallet_switchEthereumChain", params: [{ chainId: numberToHex(chainId) }], }); if (approve) { // wait for this hash (public client / wallet UI) before submitting the bridge call await window.ethereum.request({ method: "eth_sendTransaction", params: [approve] }); } const hash = await window.ethereum.request({ method: "eth_sendTransaction", params: [bridge] }); ``` `toEip1193Transaction` deliberately drops `chainId` (see the warning above) and the `kind` / `description` tags (UI metadata — some wallets reject unknown keys), and pins `from` only when you pass it. Gas, nonce and fees stay with the wallet, same as everywhere else in this module. ## 4. Worked example: a Hideki session funded from Shannon Everything above, composed into the flow a trading UI actually runs: the user's wallet lives on Shannon, a disposable **session account** trades on Hideki, and the bridge is what moves gas and working capital between them. (Session accounts come from the [native module](./NATIVE.md) — a 32-byte seed the node can sign for, whose derivation is public, so the address is computable locally before any RPC. **The seed is a private key in another shape: store it like one.**) ```ts import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; import { sessionAddress, sessionPrivateKey } from "@somnia-chain/markets-sdk/native"; const seed = generatePrivateKey(); // any 32 random bytes, persisted like a secret const session = privateKeyToAccount(sessionPrivateKey(seed)); session.address === sessionAddress(seed); // true — the node derives the same address // The user's wallet signs on Shannon; the session signs on Hideki. const userAccount = privateKeyToAccount(process.env.SOMNIA_TESTNET_PK as `0x${string}`); const userWallet = createWalletClient({ account: userAccount, chain: somniaShannon, transport: http() }); const sessionWallet = createWalletClient({ account: session, chain: hidekiTestnet, transport: http() }); ``` **Fund it.** Two transfers out of the user's Shannon wallet: STT so the session can pay Hideki gas, and HBTT as working capital. HBTT is Hyperlane's open test token — anyone can `mint(address,uint256)` on Shannon, which is what makes this walkthrough self-service: ```ts import { parseAbi, parseEther, erc20Abi } from "viem"; const mintAbi = parseAbi(["function mint(address to, uint256 amount)"]); const hbtt = getBridgeToken(BridgeToken.HBTT, ChainId.somniaShannon)!; // Working capital exists first as the canonical ERC-20 on its home chain. await userWallet.writeContract({ address: hbtt.address!, abi: mintAbi, functionName: "mint", args: [userAccount.address, parseEther("10")], }); // Gas money: STT to the session (native route — §3, recipient swapped). // 1 STT, not a sliver: Somnia's mempool admits a transaction only when the // balance covers the full fee envelope (10M gas ceiling × 60 gwei = 0.6 STT), // even though unused gas is never charged. const gas = createBridgeTransfer({ token: BridgeToken.STT, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: parseEther("1"), recipient: session.address, }); // Working capital: HBTT to the session (collateral route — approve, then bridge). const capital = createBridgeTransfer({ token: BridgeToken.HBTT, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: parseEther("10"), recipient: session.address, }); // Each sendBridgeStep resolves once its transaction is CONFIRMED (§3), so the // approve-before-bridge ordering holds by construction. await sendBridgeStep(shannon, gas.bridgeStep, { account: userAccount }); // STT: native, no approval if (capital.approveStep) await sendBridgeStep(shannon, capital.approveStep, { account: userAccount }); await sendBridgeStep(shannon, capital.bridgeStep, { account: userAccount }); ``` Watch both deliveries land on Hideki — the STT with `getBalance` as in §3, the HBTT by polling the synthetic's `balanceOf` (delivery _mints_, so no destination liquidity is involved; remember the synthetic token **is** its router address): ```ts const hbttHideki = getBridgeToken(BridgeToken.HBTT, ChainId.hidekiTestnet)!; await hideki.readContract({ address: hbttHideki.address!, abi: erc20Abi, functionName: "balanceOf", args: [session.address], }); // 10000000000000000000n once the relayer delivers ``` **Spend as the session.** On Hideki it is just an account with a key — the bridged STT pays its gas, the synthetic HBTT is a plain ERC-20: ```ts await sessionWallet.writeContract({ address: hbttHideki.address!, abi: erc20Abi, functionName: "transfer", args: [friend, parseEther("4")], }); ``` **Send what's left home.** Synthetic → collateral needs **no approval** — the router burns the session's balance, and the Shannon router releases the collateral it escrowed on the way out: ```ts const home = createBridgeTransfer({ token: BridgeToken.HBTT, from: ChainId.hidekiTestnet, to: ChainId.somniaShannon, amount: parseEther("6"), recipient: userAccount.address, }); home.approveStep; // undefined — the bridge call alone, signed by the session await sendBridgeStep(hideki, home.bridgeStep, { account: session }); // Poll the canonical HBTT on Shannon for userAccount — it comes back +6. ``` The runnable version of this exact flow (delivery polling, shortfall-only minting, delta assertions) is the session round-trip test in `test/chains.live.e2e.test.ts` — see the next section. ## 5. Run the live test suites Two opt-in suites under `packages/sdk/test/` prove everything above against the real networks. Both skip silently unless their env var is set, so plain `pnpm test` / CI never touch the network. **Read-only** — verifies the registry against the live deployment and simulates the planner's calldata via `eth_call` state overrides. No key, no funds, nothing signed: ```sh cd packages/sdk SOMNIA_E2E_BRIDGE=1 pnpm test test/bridge.e2e.test.ts ``` **Live + signed** — `test/chains.live.e2e.test.ts` checks every chain definition against its endpoints (HTTP + WS chain ids, Multicall3, block cadence, explorer), then **spends**: it bridges ~0.05 STT in each direction with real keys, waits for the relayer to deliver, signs + revokes a real collateral-route approval, and runs the §4 session round-trip for real — derives a session, bridges STT and 10 freshly-minted HBTT to it, pays 4 HBTT to another Hideki wallet as the session, and bridges the remaining 6 home. Needs a funded key per network: ```sh cd packages/sdk SOMNIA_E2E_CHAINS_LIVE=1 \ SOMNIA_TESTNET_PK= \ HIDEKI_TESTNET_PK= \ pnpm test test/chains.live.e2e.test.ts ``` Keys are accepted with or without the `0x` prefix and are read from the environment only — never hardcode them. Budget ≥3 STT on Shannon and ≥1 STT on Hideki. Per run: the two accounts trade ~0.1 STT of bridged value (plus gas), 1 STT of gas money parks with the session account on Hideki (the seed is deterministic, so reruns reuse it), the Hideki account gains 4 HBTT, and the Shannon account nets +6 of the 10 HBTT it mints. If a delivery toward Shannon times out, check the STT router's balance on Shannon — a drained router is the expected failure mode, not a bug in the suite. ## 6. Where to go next - [CHAINS.md](./CHAINS.md) — the definitions in full: why absences are deliberate, parity with `viem/chains`, extending a definition with `defineChain`. - [BRIDGE.md](./BRIDGE.md) — route models (native/collateral/synthetic), the relayer as a liveness dependency, how every registry value was verified. - Generated API reference: `pnpm docs` in `packages/sdk` writes it to `docs/api/` (gitignored). - The deployment record behind the registry: [hyperlane-bridge-infra](https://github.com/somnia-chain/hyperlane-bridge-infra/blob/main/docs/deployments/somnia-testnet-hideki-testnet.md). --- # /docs/typescript/native # Native RPC Somnia's node serves a `somnia_*` namespace alongside the usual `eth_*`. It exposes things the Ethereum-compatible surface has no field for — the native ledger block, chain statistics, reactivity subscription reads — plus **session transactions**, where the node holds the key, tracks the nonce, signs, retries, and hands back the receipt, so a client can transact with no signer at all. This module wraps exactly the twelve methods in the [public JSON-RPC reference](https://docs.somnia.network/developer/json-rpc-api) (as ten TypeScript methods: the by-hash and by-number block and receipt reads, and the two `isReady` variants, fold together), and nothing else — see [Not wrapped](#not-wrapped). ```ts import { createPublicClient, http } from "viem"; import { somniaShannon } from "@somnia-chain/markets-sdk/chains"; import { createNative } from "@somnia-chain/markets-sdk/native"; const client = createPublicClient({ chain: somniaShannon, transport: http() }); const native = createNative(client); const block = await native.getBlock("latest"); console.log(block?.consensusBlock.proposerAddress, block?.executionBlock.executionGasUsed); ``` `createNative` takes anything with an EIP-1193 `.request` — a viem client, the markets client's (`createNative(exchange.client.getViemClient())`), or an injected wallet provider. It needs nothing else from the SDK. ## Why a wrapper Because these endpoints are easy to call wrong, and the node's reply when you do is a bare `-32602 invalid parameters` that tells you nothing. Two shapes surprise everyone, both confirmed against a live node: | You'd write | The node wants | | --------------------------------------- | ----------------------------------------------------------- | | `params: [1]` | `params: ["0x1"]` — block numbers are hex **strings** | | `params: [[1, 2]]` for subscription ids | `params: ["0x1", "0x2"]` — the ids **are** the params array | And what comes back is the node's C++ member names verbatim, with no case conversion — so blocks are `snake_case` (`consensus_block.block_number`) while statistics are `camelCase` (`numSuccessfulTransactions`), purely because that is how the two structs happen to be written. Quantities are hex strings. This module takes `bigint`s and tags, hex-encodes them correctly, and decodes the replies into one consistent camelCase surface with `bigint` quantities. Receipts go through viem's own `formatTransactionReceipt`, so a session receipt is the same `TransactionReceipt` the rest of your code already handles. The untouched wire shapes are exported as `Rpc*` types if you want them. ### Read the node's message, not viem's Somnia reports mempool rejections as JSON-RPC **`-32000`**, with the useful text in `message` and a `MempoolStatusCode` byte in `data`. viem maps `-32000` to its `InvalidInputRpcError`, whose display text is the generic **"Missing or invalid parameters."** So the obvious thing to log claims your parameters are wrong when the real problem is an unfunded account: ``` error.message "Missing or invalid parameters. Double check you have provided…" error.details "account does not exist" ← what the node actually said ``` `getSomniaRpcError` recovers it, and decodes the status byte: ```ts import { getSomniaRpcError, SomniaMempoolStatus } from "@somnia-chain/markets-sdk/native"; try { await native.sendSessionTransaction({ seed, gas: 21_000n, to, value }); } catch (error) { const rpc = getSomniaRpcError(error); console.error(rpc?.message); // "account does not exist" if (rpc?.mempoolStatus === SomniaMempoolStatus.nonceTooSmall) retryWithFreshNonce(); } ``` Branch on `mempoolStatus` rather than matching message text — `nonceTooSmall` is retryable, `insufficientBalance` needs funding, and `accountDoesNotExist` means the _sender_ has never existed, which is a third fix. The codes come from `MempoolStatusCode` in the node source, so the set is complete rather than the three we happened to trip over. **Nothing needs bypassing.** viem preserves the original: `BaseError`'s constructor inherits `details` from a `BaseError` cause, so the node's text propagates up the whole wrapper chain from the `RpcRequestError` that set it, and the raw `{ code, message, data }` object is still the innermost `cause`. `getSomniaRpcError` walks to it structurally — no `instanceof` against viem's classes, so it also works on an error from a plain `fetch`-based requester that never went through viem. This cost real time during live testing: a correctly-encoded session send read as a parameter error until the raw HTTP body showed `account does not exist`. ## Reads ```ts await native.isReady(); // false while syncing await native.getBlock("latest"); // tag, number, or 32-byte hash await native.getStatistics(blockNumber - 100n, "latest"); // aggregate activity await native.listPrivilegedReceipts("latest"); // protocol-issued txs (usually none) await native.listReactivitySubscriptionIds(owner); // → bigint[] await native.getReactivitySubscription(1n); // → one, or null await native.listReactivitySubscriptions([1n, 2n]); // → many, one round-trip await native.getNodePublicKeys(); // address + 2 keys + 2 proofs ``` `getBlock` and `listPrivilegedReceipts` accept a tag (`"latest"`, `"earliest"`, `"pending"`, `"safe"`, `"finalized"`), a block number, **or** a 32-byte hash — a 32-byte hex value dispatches to the by-hash RPC, anything shorter is a number. A **ledger block** is not the Ethereum block: it pairs the consensus half (proposer, timing, the data-chain blocks it commits) with the execution half (gas, receipts hash, state snapshot). Note `consensusBlock.timestamp` is unix **milliseconds** — Somnia blocks are ~100 ms apart, so seconds would be useless. `getNodePublicKeys` returns all five fields the node publishes: the address, the secp256k1 and BLS public keys, and the two proofs that bind them together (a BLS proof of possession and a proof of address). The proofs are what make the rest meaningful, so they are not dropped. ## Session transactions A session is a **32-byte seed**. The node turns it into a key pair, assigns the nonce, signs, submits, retries transient failures, and returns the receipt — one call instead of sign + send + poll. Useful when a client shouldn't hold a key at all: load generators, bots, game backends. ```ts import { createNative, sessionAddress } from "@somnia-chain/markets-sdk/native"; const seed = "0x…"; // 32 bytes, and a SECRET — see below // Where to send funds. Derived locally: no RPC, no node involved. const from = sessionAddress(seed); const receipt = await native.sendSessionTransaction({ seed, gas: 21_000n, // enough ONLY if `to` already exists — see gas, below to: recipient, value: parseEther("0.1"), }); console.log(receipt.status, receipt.transactionHash); ``` Five things to know before using it: - **The seed is a private key in another shape.** The derivation is public and deterministic — `sessionPrivateKey(seed)` computes the very key the node uses. Anyone who learns a seed can drain its account without touching the node. Guard it as a key. A failed call does not hand it back: `sendSessionTransaction` and `getSessionAddress` throw an `RpcError` instead of viem's error, whose message would print the request body — seed included. When the node answered, `cause` is its own `{ code, message, data? }` and `getSomniaRpcError` reads it as before; when the transport failed first, `cause` is `{ name, message, status? }` with the request text kept and the seed blanked out. - **Pre-fund the account.** Use `sessionAddress(seed)`; an unfunded session cannot pay gas. `native.getSessionAddress(seed)` asks the node the same question if you want confirmation (the two are asserted equal by the live test suite). Note the node rejects a send from an account that has never existed with `account does not exist` (mempool code `0x02`), not with an out-of-gas. - **Paying a brand-new address costs ~30× the Ethereum figure.** Somnia has to bring the account into existence, and `21_000` is not enough: the transaction **reverts with `status: "reverted"` having consumed the entire limit**, and the recipient is not credited. Measured on Hideki, first payment to a fresh address: | gas limit | outcome | gasUsed | | ---------- | -------------------------------- | ------------------- | | `21_000n` | reverted, recipient not credited | 21,000 (all of it) | | `100_000n` | reverted, recipient not credited | 100,000 (all of it) | | `700_000n` | success | 421,000 | `eth_estimateGas` quotes ~631,500 for such a transfer. A second payment to the same address costs the ordinary 21,000. Since the node does not estimate for you, budget by whether the recipient already exists — and treat a `reverted` receipt whose `gasUsed` equals the limit as "the limit was the problem". - **The nonce space is shared** with `eth_sendRawTransaction` from the same address. Sending both ways at once corrupts the sequence — pick one per account. - **It blocks until the receipt exists.** The node retries with backoff, so a call can take a while; give the transport a generous timeout. There is no fire-and-forget variant. Omit `to` to deploy a contract, with `data` as the init code. The send goes out with transport retries **disabled** (`retryCount: 0`). viem retries a failed request three times by default, and the node's failures (a node-side ceiling, a full mempool) look retryable — so a default retry could submit the same transfer again under a fresh nonce. One attempt; the node already retries internally where that is safe. A missing receipt **throws** rather than resolving to `null`: a receipt is the whole contract of the call. Sessions live in the serving node's memory: they are not shared between nodes, and are rebuilt from the seed after a restart. Nothing is persisted, and the derived key is never written to disk. ### Deriving locally ```ts sessionAddress(seed); // the address, offline sessionPrivateKey(seed); // the key itself — sign locally instead of trusting the node ``` The algorithm is `keccak256(seed ‖ uint64_le(i))` for `i = 0, 1, 2, …`, taking the first candidate inside `[1, n-1]`. In practice `i = 0` always wins: a keccak output falls outside the curve order with probability under 2^-128. This is pinned against the node for four different seeds in `test/native.e2e.test.ts` — if Somnia ever changed its derivation, every funded session address would move, and that test is what would catch it. ## Not wrapped The wrapped set is the [public JSON-RPC reference](https://docs.somnia.network/developer/json-rpc-api). A node build serves more than that, but an undocumented endpoint is not part of the contract — it can change shape or vanish between node versions, and one of them is outright hazardous. All of them stay reachable via `native.request(...)`, which is the point: stepping off the documented surface should be a decision, not an accident. **`somnia_getStorageDatabaseEntries` — undocumented and dangerous.** Its handler loops over the caller's key list with no cap on the number of keys and no bound on the size of each value returned, so one request can make a node dump unbounded data. **A 256-key request took the public Shannon testnet down on 2026-07-31** (discovered by this SDK's own live testing). It is also not what the name suggests to an Ethereum developer: keys are node-internal `StorageKeyType` discriminants — one byte, or one byte plus a 32-byte body, where byte 0 must be a member of that enum — not contract storage slots. For those, `eth_getStorageAt` is the method you want. A malformed key is an **error**, not a miss. **`somnia_getProtocolParameters` — undocumented.** The key set is node-version dependent and its values are plain JSON numbers rather than hex quantities, so wrapping it would mean publishing a shape that cannot be kept stable. Reach it with `native.request("somnia_getProtocolParameters", ["latest"])` if you need it; that is how the account-creation gas figure below was read. **Operator-only** (`kProtected` on the node) — a public endpoint answers `{ code: -1, message: "unauthorized" }`, which `isUnauthorized(error)` recognises **by message**, not by code. That matters: `-1` is the node's default error code, shared with `invalid range`, `could not load statistics` and `Block does not exist` (all confirmed live), so keying on the code would report a bad block range as an auth failure. The methods: `somnia_connectToPeer`, `somnia_dumpMemory`, `somnia_createTransactionLog`, `somnia_byteStringBenchmark`. If you _are_ the operator, reach them with `native.request("somnia_dumpMemory")`. **Validator plumbing** — `somnia_submitBatchedTransaction` and `somnia_submitMerkleBatchSignature` carry smash-encoded consensus structs a JS caller can't construct. Not exposed. **`realtime_sendRawTransaction`** is Somnia-specific too, but it is already the SDK's write path: a local-signer write sends through it and gets its receipt in one round-trip (see the [engine guide](./ENGINE.md)). No need to call it yourself. ## Nodes that don't have these Every method here is node-version dependent, and a stock geth or a local anvil has none of them. Degrade instead of breaking: ```ts import { isMethodNotFound } from "@somnia-chain/markets-sdk/native"; const stats = await native.getStatistics("earliest", "latest").catch((e) => { if (isMethodNotFound(e)) return null; // not a Somnia node — hide the panel throw e; }); ``` Everything else throws: a failed read never resolves to `null`. `null` appears in exactly two places, both genuine by-id misses — an unknown block and an unknown subscription id. `isReady()` returns a boolean. `isReady({ withErrorCode: true })` calls the node's error-code variant, which **throws** on a not-ready node instead of returning `false` (that is the point of the variant — a health check keys on the error), so it never returns `false`. ## Where these come from The method list is `somnia/api/handlers/somnia_api_handlers.h` in [somnia-chain/somnia2](https://github.com/somnia-chain/somnia2), and session transactions are specified in its `docs/session_transactions.md`. Both were read — and then every endpoint was called against a live Shannon node, because the wire and the C++ types disagree in ways that matter (the field-name inconsistency above, and `token()`-style traps like a params array that is not what the signature suggests). `test/native.test.ts` pins the encodings offline against captured payloads; `test/native.e2e.test.ts` re-checks them against a real node: ```sh SOMNIA_E2E_NATIVE=1 pnpm test ``` --- # /docs/typescript/reactivity # Reactivity Somnia pushes events to you **with the state that goes with them**. That is the whole idea: on any other EVM chain, reacting to an event is "see the log, then fetch the state" — two round trips, racing the next block. Here the notification carries the log _and_ the results of a fixed set of `eth_call`s executed at that same block. This module is a **pointer, not a port**. The implementation is [`@somnia-chain/reactivity`](https://github.com/somnia-chain/reactivity) — the upstream repo owns the protocol, the Solidity side (`SomniaEventHandler`, in `@somnia-chain/reactivity-contracts`) and the client. `@somnia-chain/markets-sdk/reactivity` re-exports that package verbatim and adds only the glue a markets consumer needs, so there is no second copy of the ABIs or the validation rules to drift out of step. ```ts import { createReactivity, unwrap } from "@somnia-chain/markets-sdk/reactivity"; ``` ## Install `@somnia-chain/reactivity` is an **optional peer dependency** — exactly like `react` is for the `/react` entry. Only callers of this subpath install it: ```sh pnpm add @somnia-chain/reactivity ``` Both `@somnia-chain/reactivity` and `@somnia-chain/markets-sdk` (from 0.20.0) are on the public npm registry; no `.npmrc` scope configuration is needed. ## What this entry adds | Export | Why it isn't upstream | | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createReactivity(client, { wallet? })` | builds the reactivity client from the markets client's viem client: reads and receipt waits reuse it; `watch` opens its own WebSocket from `chain.rpcUrls.default.webSocket[0]` | | `unwrap(result)` | upstream _returns_ `Error` objects; this SDK throws instead, so a failure stops the caller | | `SOMNIA_REACTIVITY_PRECOMPILE_ADDRESS` | not exposed by upstream's published build | | `DEFAULT_SUBSCRIPTION_OPTIONS` | the protocol's own `SomniaExtensions.DEFAULT_*` values: upstream ships them at runtime but omits them from its `.d.ts`, so they can't be re-exported with types (a test pins ours against upstream's) | | `isLocalPrecompileUnavailable(chainId)` | already lives in this package; the check to run before any Solidity subscription | Everything else — `Reactivity` / `SDK`, `SomniaReactivityPrecompileABI`, `SomniaEventHandlerABI` and every type — is upstream's, re-exported. A test asserts the re-exported classes are upstream's own identity, so this can never quietly become a fork. ## Two flavours - **WebSocket reactivity** (`watch`) — a TypeScript subscription over the socket (`somnia_watch`). Each matched log arrives with your `eth_call` results from the same block. Nothing on-chain, nothing to pay for, gone when you disconnect. - **Solidity reactivity** (`subscribe`) — a subscription registered _on-chain_ against the reactivity precompile, which makes validators call your handler contract's `onEvent(address,bytes32[],bytes)` when a matching log lands. Callbacks are paid out of the subscription owner's native balance (which must hold at least 32 SOMI/STT). This protocol already runs on the second one: `ProphecyOracleAdapter` is a Solidity handler the precompile pings on `AnswerPosted`, and MarketCreator rolls are scheduled subscriptions — which is what `enableReactivity` / `setReactivityGasParams` on the admin surfaces are configuring. This module is the same primitive pointed at _your_ contracts. ## Watching (TypeScript) `createReactivity` hands upstream the markets client's public client for reads and receipt waits; `watch` itself opens a second WebSocket to the same chain (see the note below): ```ts import { SomniaMarkets } from "@somnia-chain/markets-sdk"; import { createReactivity, unwrap } from "@somnia-chain/markets-sdk/reactivity"; import { somniaShannon } from "@somnia-chain/markets-sdk/chains"; const exchange = new SomniaMarkets({ chain: somniaShannon, wsRpcUrl, indexerUrl }); const reactivity = createReactivity(exchange.client); // Every Transfer on the collateral token, with the sender's new balance read // at the very same block — one notification, no follow-up call. const watch = unwrap( await reactivity.watch({ eventContractSources: [collateral], topicOverrides: [transferTopic], ethCalls: [{ to: collateral, data: balanceOfCalldata }], onData: (n: ReactivityNotification) => console.log(n.result.simulationResults), }), ); await watch.unsubscribe(); ``` > **Use a chain definition from [`/chains`](./CHAINS.md).** Upstream's `watch` > opens its own socket with viem's `webSocket()` _without a URL_, so the endpoint > comes from `chain.rpcUrls.default.webSocket[0]`. viem's own `somniaTestnet` has > no WebSocket entry, so `watch` fails on it; every definition in > `@somnia-chain/markets-sdk/chains` carries one. Notes that matter in practice: - **Every filter is optional, and omitting one means "everything".** A bare `{ ethCalls: [], onData }` tails every event on the chain. - **`ethCalls` is the point.** Batch several reads into one call against Multicall3 where you can — the notification is only as fast as the calls it carries. `simulationResults` comes back in the order subscribed. - **`context`** splices event-sourced values into the `ethCalls` calldata (`topic1`…`topic4`, `data`, `address`), so one subscription can read state _about the thing that just happened_ rather than a fixed address. - **`onlyPushChanges`** suppresses notifications whose call results match the previous ones — a cheap way to watch for a _state_ change rather than an event. - **The payload is at `notification.result`** — `{ address, topics, data, simulationResults }`. Upstream's README and type docs say `notification.params.result`, one level deeper; that is stale, because viem's WebSocket transport unwraps the JSON-RPC envelope before calling `onData`. Type the callback with `ReactivityNotification` (upstream types it `any`) — the shape is asserted against a live node in `test/reactivity.e2e.test.ts`, which runs with `SOMNIA_E2E_WS` set. This is a different tool from `client.watchMarket`: the markets tail materializes the order book from indexed protocol events, while `watch` is a general-purpose log+state subscription for anything on the chain. ## Subscribing (Solidity) Deploy a handler extending `SomniaEventHandler` (from `@somnia-chain/reactivity-contracts`), then register it. The signer becomes the subscription **owner** and its balance funds every callback: ```ts import { createReactivity, unwrap, DEFAULT_SUBSCRIPTION_OPTIONS } from "@somnia-chain/markets-sdk/reactivity"; const reactivity = createReactivity(exchange.client, { wallet: walletClient }); const hash = unwrap( await reactivity.subscribe({ handlerContractAddress: handler, filter: { emitter: collateral, eventTopics: [transferTopic] }, options: DEFAULT_SUBSCRIPTION_OPTIONS, }), ); ``` Upstream validates the precompile's preconditions before spending gas — a non-zero handler, well-formed `bytes32` topics, at least one narrowing filter (a match-everything subscription is rejected), `0 < gasLimit <= 200_000_000`, `maxFeePerGas >= priorityFeePerGas + 6 gwei` (or `0` to skip that check), and the owner holding ≥ 32 SOMI/STT. Note that writes need a **wallet client**: pass one to `createReactivity`, or upstream's write silently resolves to `null`. Cancel with `unsubscribe(subscriptionId)` (owner only), read one back with `getSubscriptionInfo(subscriptionId)`, and use `subscribeRaw` when you need the precompile's full struct including the protocol-reserved fields. ## Scheduling — cron, blocks, epochs The precompile emits its own system events (`Schedule`, `BlockTick`, `EpochTick`), so "call me later" is just a subscription to one of them with the tick as a topic filter: ```ts await reactivity.scheduleSubscriptionAtTimestamp({ timestampMs: Date.now() + 60_000, handlerContractAddress, options }); await reactivity.scheduleSubscriptionAtBlock({ blockNumber: head + 100n, handlerContractAddress, options }); await reactivity.scheduleSubscriptionAtEpoch({ epochNumber: 7n, handlerContractAddress, options }); ``` `scheduleSubscriptionAtBlock` with **no** `blockNumber` leaves the block topic a wildcard — a callback on _every_ block. Timestamps are unix **milliseconds** and must be at least a second out; a block must be past the head. ## Errors Upstream methods resolve to `T | Error` instead of throwing. Two ways to live with that, both fine: ```ts // 1. this SDK's contract — throw (recommended) const hash = unwrap(await reactivity.subscribe({ ... })); // 2. upstream's own idiom — check const result = await reactivity.subscribe({ ... }); if (result instanceof Error) throw result; ``` ## Local development The precompile does not exist on anvil or hardhat — check `isLocalPrecompileUnavailable(chainId)` before offering Solidity subscriptions in a UI, and note that it has no bytecode on _any_ chain, so `eth_getCode` can't probe for it. `somnia_watch` is a node feature too: a plain anvil node doesn't serve it. Test reactivity against Shannon (or Elwood/Hideki). --- # /docs/typescript/engine # The engine (advanced) This guide tours the **engine tier** — the raw `SomniaMarketsClient`: bigint-exact, address-keyed. It is not a second entry point: you reach it through the exchange — ```ts const exchange = new SomniaMarkets({ indexerUrl, chain, wsRpcUrl }); const client = exchange.client; // the engine: exact raw-unit reads + watches const trader = exchange.trader; // the raw write tier (needs a signer) ``` Most applications stay on **[the exchange API](./EXCHANGE.md)** itself; the engine is the tier for exact escrow math, custom reads, and anything the exchange verbs don't cover. Both surfaces share one config, one socket, one watch/store. **Multi-chain deployments are multiple exchanges**: one per chain. For market-kind specifics, see the [binary markets](./BINARY.md) and [spot](./SPOT.md) guides. ## The three read tiers Every read on the client belongs to one of three tiers. The `getLive*` prefix marks the first; for the other two the method's API reference names its source (`getMarket`, `getFills`, `getOpenOrders` are indexer reads; `getMarginAccount`, `getPerpState` are chain reads). The method name tells you which — and the tier tells you the freshness and the cost: | Tier | Methods look like | Backed by | Cost & freshness | | -------------- | --------------------------------------------- | ------------------------------------------------ | ------------------------------------------- | | **Live store** | `getLive*` (synchronous) | in-memory materialization of **watched markets** | zero round-trips, current to the last block | | **Chain** | `get*Onchain`, `getBinaryOrderBook`, balances | `eth_call` over the socket | one round-trip, current to head | | **Indexer** | `list*`, `getCandles`, `getPortfolio`, … | GraphQL (HTTP) | one round-trip, lags the chain slightly | Rule of thumb: **anything that gates an action reads the live store or the chain; the indexer is for history and aggregates.** Indexer reads throw on request failure — an empty result always means "no rows", never "it broke". ## Errors — branch on the type, never the message Every failure the SDK raises is a typed class exported from the barrel, all extending `SomniaMarketsError`. Catch the family, or branch on the member: ```ts import { ContractRevertError, IndexerError, NotConfiguredError } from "@somnia-chain/markets-sdk"; try { await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 25, 0.62); } catch (e) { if (e instanceof ContractRevertError) { // The chain rejected it. `errorName` is the contract's OWN error. if (e.errorName === "ExpiredOrderMustBeCancelled") await cancelFirst(); else if (e.errorName === "InsufficientBalance") await topUp(); else throw e; } else if (e instanceof IndexerError) { retryLater(); // the read didn't complete — never "no rows" } else if (e instanceof NotConfiguredError) { throw new Error(`missing config: ${e.what}`); // a deploy/config bug, not runtime } else throw e; } ``` | Class | Means | Your move | | --------------------- | ----------------------------------------------------------------------- | ----------------------- | | `InvalidInputError` | Bad argument, unknown symbol, wrong market kind (thrown before any I/O) | Fix the call | | `NotConfiguredError` | A needed address/URL was never passed (`what` names it) | Fix the config | | `SignerRequiredError` | The method writes; this client has no signer | Construct with a signer | | `IndexerError` | An indexer read did not complete | Retry / degrade | | `RpcError` | A node request did not complete | Retry / switch RPC | | `ContractRevertError` | The chain rejected the call — `errorName` + `args` | Branch on `errorName` | Three things worth knowing: - **Revert names come from the contracts.** The SDK bundles every custom error the protocol declares and decodes revert data against it, so a failed write reports `MarketNotSettled` rather than hex. When the data matches nothing known you still get a `ContractRevertError`, with the raw `reason`/`data` preserved. - **A mined-but-reverted transaction throws.** You don't need to check `receipt.status` yourself; the SDK replays the call to recover the reason first. - **`cause` is always chained.** The original viem/fetch error is there for logs. - **Never match on `error.message`** — messages are not a stable API. Branch on the class and its fields (`errorName`, `what`, `operation`). ## Watches — scoped, ref-counted live data Nothing is streamed by default. You open a **watch** on what you care about, and the client becomes a local indexer of exactly that scope: ```ts const watch = await client.watchMarket(pool); // one market: book, fills, orders, status const book = client.getLiveBinaryOrderBook(pool); // synchronous, zero round-trips, last-block fresh // ... trade against it ... watch.stop(); // release (ref-counted, brief linger) ``` - [`watchMarket(pool)`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#watchmarket) — hydrates a consistent snapshot of that market (its row, recent fills, full resting book) and streams its events from the chain WebSocket. Resolves once reads are live. This is the right default: cost scales with what you watch, not with the protocol. - [`watchMarkets({ discover? })`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#watchmarkets) — everything the indexer knows, for list views and multi-market bots; `discover: true` also watches the creation events (the `MarketCreator` factory AND `BinaryMarketsModule.createMarket`) so newly created markets — rolling-series or module-created — join live. - [`watchUser(user)`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#watchuser) — hydrates one account's order/fill _history_ (live events are attributed to every account automatically within watched markets). - [`getWatchStatus(pool)`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getwatchstatus) — `"unwatched" | "hydrating" | "live"`; this is how you distinguish "the book is empty" from "I'm not watching this pool". Watches are **ref-counted**: two watchers of the same pool share one snapshot and one subscription, and a released scope lingers ~30s before teardown so quick re-watches don't re-snapshot. If the socket drops, watches heal themselves — resubscribe with backoff, then backfill the missed blocks straight from chain (the indexer is only ever touched to hydrate a _new_ scope). While a market is watched, these answer synchronously with zero round-trips: [`getLiveBinaryOrderBook`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getlivebinaryorderbook) / [`getLiveSpotOrderBook`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getlivespotorderbook) (the resting book — **the one to render or quote against**), [`getLiveFills`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getlivefills) (tape), [`getLiveUserFills`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getliveuserfills) / [`getLiveUserOrders`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getliveuserorders) (one account's activity), [`getLiveMarkets`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getlivemarkets) / [`getLiveMarketByPool`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getlivemarketbypool) / [`getLiveMarketByAddress`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getlivemarketbyaddress) (market rows with live status + stats), and [`getLiveStatus`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getlivestatus) (global health). Reactivity without React: [`subscribeLive`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#subscribelive) fires after every batch of changes — re-read whatever you need inside the callback: ```ts const watch = await client.watchMarket(pool); client.subscribeLive(() => { const { yesBids, yesAsks } = client.getLiveBinaryOrderBook(pool, { depth: 5 }); requote(yesBids, yesAsks); // runs within ms of the on-chain event }); ``` ## React Provide the client once; the hooks read it from context and **watch automatically** — rendering a market's book is what subscribes to it, and unmounting releases it: ```tsx import { SomniaMarketsProvider, useLiveBinaryOrderBook, useLiveFills, useWatchUser, } from "@somnia-chain/markets-sdk/react"; function App({ children }) { return {children}; } function Terminal({ pool, account }: { pool: string; account?: string }) { useWatchUser(account); // hydrate the user's history once const book = useLiveBinaryOrderBook(pool, 11); // auto-watches `pool` while mounted const tape = useLiveFills(pool, 40); // shares the same watch (ref-counted) // ... } ``` The live-store hooks: `useLiveBinaryOrderBook`, `useLiveBinaryOrderBookByMarket`, `useLiveSpotOrderBook`, `useLiveFills`, `useLiveUserFills`, `useLiveUserOrders`, `useLiveFundingUpdates`, `useLiveMarketByPool`, `useLiveMarketByAddress`, `useLiveMarkets`, `useLiveStatus`, `useIsTailing`, plus the explicit `useWatchMarket` / `useWatchUser` and `useSomniaMarketsClient`. The price (`useWatchPrice`, `useLivePrice`, `useLivePriceTicks`, `useLivePriceFeedInfo`), funding (`useFundingRateSeries`), lend (`useLendReserves`, `useLendAccount`) and directory (`useMarketCreators`, `useOracleAdapters`) hooks are listed in the API reference. Every pool-keyed data hook holds a ref-counted watch on its pool while mounted; `useWatchMarket` also returns the pool's `WatchStatus` for loading UI. For the **indexer** tier (history + directories, not the live store) there is a generic engine hook — `useIndexerQuery(fn, deps)` runs `fn(client)` on mount and whenever `deps` change, tracks `{ data, loading, error, refetch }`, and discards stale responses: ```tsx const { data: markets } = useIndexerQuery((c) => c.listBinaryMarkets({ limit: 20 }), []); ``` Concrete wrappers over the common reads: `usePortfolio`, `useMarkets`, `useCandles`, `useMarketFees`, `useOperators`. Separately, `useLiveMarkets` is the zero-round-trip live-store view of every watched market (pair it with a discovery watch), not an indexer fetch. ## Chain reads — head-fresh, no watch required One `eth_call` round-trip over the client's socket (concurrent calls pipeline): - [`getMarketOnchain`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getmarketonchain) — a BinaryMarket's full wiring + state. **Authoritative for write eligibility** (status, resolution), and works before the indexer has ever seen the market. - [`getBinaryOrderBook`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getbinaryorderbook) / [`getSpotOrderBook`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getspotorderbook) — the book from the contract; the one-shot fallback (or checksum) for the live variants. - [`getErc20Balance`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#geterc20balance) / [`getNativeBalance`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getnativebalance) — raw balances (use these, not indexer balances, to gate a write). - `getBalances(tokens, account)` — batch multi-token balance read (one round-trip for a whole wallet); `getOutcomeBalance({ outcomeToken, account, id })` — a single ERC-6909 outcome-id balance (the on-chain point read behind the indexer's `getOutcomeBalances`). - `getErc20Metadata(token)` / `getErc20Allowance(token, owner, spender)` — token name/symbol/decimals and a spender allowance (gate an `approve` on it). - `getContractMeta(address, { proxy })` — contract/proxy introspection; and `getMaxVenueFeeBps()` — the protocol's hard fee-rate cap (bps). - Perp margin health — `getMarginAccount` (now including `imReq`/`mmReq`/`cmReq`/ `marginStatus`), `getAccountHealth`, and `getLiquidationPrice` (all `MarginBank` reads); see [perps](./PERPS.md). - `getVaultBalance({ vault, owner, token })` — the LIVE claimable balance behind the append-only `getVaultPayoutFallbacks` credit log (vault credits emit no event, so the current balance must be read from chain). - [`getHeadBlock`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getheadblock), [`getStopOrderSomiPayment`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getstopordersomipayment), [`getSystemInfo`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getsysteminfo). ## Indexer reads — history and aggregates One GraphQL round-trip; these are the only methods that touch the indexer (besides a watch's initial snapshot): - Markets: [`listMarkets`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#listmarkets), [`getMarket`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getmarket), and the binary-narrowed [`listBinaryMarkets`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#listbinarymarkets) / [`listLiveBinaryMarkets`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#listlivebinarymarkets) / [`listPastBinaryMarkets`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#listpastbinarymarkets) / [`getBinaryMarket`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getbinarymarket). - History: [`getCandles`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getcandles) (OHLCV, chart-ready), [`getFills`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getfills), and the account-scoped `getOrders(owner, opts)` (an owner's order history → `OrderRow[]`), `getUserFills(account, { market })` (an account's fills → `FillRow[]`; scope by `market` rather than `pool` on binary, where one pool is recycled across successive markets), and `getMarketStatusHistory(marketId)` (a market's lifecycle transitions). - Single-entity detail (the explorer's order/fill pages run on exactly these): [`getOrder`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getorder)`(pool, orderId)` — one order with owner + full lifecycle attribution (`OrderDetail`; ids never reuse, so the pair is a permanent name), [`getFill`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getfill)`(id)` — one fill by its `${block}_${logIndex}` id with both parties' order linkage (`FillDetail`), and [`getOrderFills`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getorderfills)`(pool, orderId)` — every fill one order participated in, either side. All three embed a `MarketRef` (symbols + decimals + routing identity) so a detail view renders from one read. - ONE transaction in full: [`getTransactionActivity`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#gettransactionactivity). The same event union as `getMarketActivity`, selected by transaction hash and ordered forwards, plus the orders placed, the fees paid and the markets touched. Empty for a hash that touched no protocol contract. - ONE trade IN CONTEXT: [`getTradeContext`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#gettradecontext). `getFill` above names one fill and its market in a single query; this adds the surrounding context — both orders resolved, the fees its transaction charged, and that transaction's other fills — for a second round-trip. Returns `null` for an unknown id. Use it behind a trade detail page that shows the counterparties; use `getFill` when rendering the trade alone. - One market's whole transaction history: [`getMarketActivity`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getmarketactivity). It reads what `getFills` reads and four more streams — complete-set mints and merges, redemptions, oracle resolution, lifecycle transitions — and returns them interleaved by time as one discriminated union, in one round-trip. Use it for a market page's activity panel; use `getFills` when only trades matter. Every row names its transaction hash. A spot or perp market yields `TRADE` rows only, because the other four streams read binary-only entities. - Wallet views: [`getPortfolio`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getportfolio) (binary positions + orders + trades in one round-trip), [`getSpotPortfolio`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getspotportfolio), [`getSpotStopOrders`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getspotstoporders), [`getOpenOrders`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getopenorders), [`getOutcomeBalances`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getoutcomebalances). - Control plane: [`listOperators`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#listoperators) / [`getOperator`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getoperator) / [`listVenues`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#listvenues) / [`getVenue`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getvenue) — the indexed MarketsCore operator/venue directory (venue ids are opaque bytes32; decode a BINARY_V1 venue's fee bytes with `decodeBinaryVenueFeeParams`). - Fee / resolution / router history (binary): `getMarketResolution`, `getRouterActions`, `listProtocolFees` / `listBuilderFees` / `listSettlementFees` (per-fill streams behind `getMarketFees`, filterable by `payer`), `listBuilderApprovals`, `getVaultPayoutFallbacks` — see [binary markets](./BINARY.md). - Perp account plane: `getFundingPayments`, `getMarginEvents`, `listLiquidations`, `listFundingRateHistory`, `listFundingRateCandles`, `getOpenInterestHistory` — the append-only history the chain doesn't expose; see [perps](./PERPS.md). - Lookups + totals: `getMarketByPool` (resolve a market by pool address) and `listMarketsByPool(pool)` (every market the pool has HOSTED, newest first — a binary pool is recycled across successive markets, so this is its full history; also `getSeries(creator, seriesId)` for one rolling series' current spec, the single-row sibling of `listSeries`), `countOrders` / `countUserFills` (history-page totals), and the board totals `countMarkets` / `countBinaryMarkets` / `countVenues` / `countOperators` (each takes the same filter as its `list*` sibling — use for pagination headers). `CANDLE_INTERVALS` is the exported bucket list `getCandles` accepts. - Ops: [`getSyncStatus`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getsyncstatus) — how far behind the indexer itself is. Two of these have faster live twins a trading loop should prefer: `getOpenOrders` → `getLiveUserOrders`, `getFills` → `getLiveFills`. ## The network tape — every order on the network, live ```ts const tape = client.createNetworkTape(); const stop = tape.subscribe(() => { render(tape.bids, tape.fills, tape.asks, tape.getStatus()); }); // … stop() closes the socket when the last listener unsubscribes. ``` [`createNetworkTape`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#createnetworktape) returns a [`NetworkTape`](https://prd.smk.somnia.host/docs/typescript/api/index/classes/NetworkTape) — a network-WIDE order-flow firehose: one topics-only chain-log subscription that sees `OrderPlaced` / `OrderFilled` from **every** pool (including pools created after it starts), no indexer on the hot path. It is not the live tail: no books, no snapshots — three newest-first ring buffers (`bids` / `fills` / `asks`) plus a session `(pool, orderId) → owner` map that attributes fills (takers always resolve — their placement follows the fill in the same tx; makers resolve when quoted while the tape ran, else `null`). Rows carry RAW units; join to `listMarkets` for symbols/decimals. Nothing connects until the first `subscribe`, and reconnect/stall handling (Somnia's silently-dying WS subs) is built in. For enriching a tape row's transaction, [`getTransactionSummary`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#gettransactionsummary)`(hash)` is the chain-direct companion: sender, gas used/limit, effective gas price, fee paid, status. It resolves to null for a malformed hash and for a transaction the node reports as not found. A read that does not complete throws `RpcError`, so an outage stays distinct from a transaction that never landed. ## Writes — `createTrader` ```ts const trader = client.createTrader({ privateKey }); // or { walletClient } in the browser const { orderId, fills } = await trader.placeOrder({ pool, side: "BUY_YES", price, quantity }); ``` [`createTrader`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#createtrader) binds a signer to this client's chain, fees, and socket and returns a [`Trader`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/Trader). The trader is **independent of the watches** — a pool's escrow tokens resolve from the pool contract itself (one cached read) when you don't pass them. With a local key the SDK signs locally with fixed fees and a fixed gas ceiling. Before each local send, it reconciles the pending nonce and serializes nonce consumption, signing, and broadcast acceptance. Some orders also need prerequisite funding reads or an approval transaction. `realtime_sendRawTransaction` returns the mined receipt; every write resolves only once mined, with that receipt (and, for orders, the decoded `orderId` + `fills`). Market-kind specifics: [binary markets](./BINARY.md#trading), [spot](./SPOT.md#trading). For the MarketsCore control plane there is a second, low-frequency write tier: `client.createOperatorAdmin({ privateKey })` returns an `OperatorAdmin` with `registerOperator`, `updateOperator`, `createVenue` (venues are typed by a `bytes4` market-type id — `MARKET_TYPE_BINARY_V1` — and get a contract-generated `bytes32` venue id back), `updateVenue`, `setVenueEnabled`, and the two-step operator-ownership transfer. Build a BINARY_V1 venue's fee bytes with `client.encodeBinaryVenueFeeParams({...})`. ## Escape hatch [`getViemClient()`](https://prd.smk.somnia.host/docs/typescript/api/index/interfaces/SomniaMarketsClient#getviemclient) returns the underlying viem WebSocket client for any read the SDK doesn't cover — your own contracts, or plain calls like `getBalance` / `getCode` / `waitForTransactionReceipt`. Same socket, same pipelining: a client of your own would open a second connection, and one-socket-per-client is deliberate here. **It is undecorated, and that is the point.** Every read reachable from the client interface goes through a _wrapped_ viem client whose `readContract` / `call` rethrow as [typed SDK errors](https://prd.smk.somnia.host/docs/typescript/api/index/classes/ContractRevertError) — a revert arrives decoded, as its Solidity name. The client this method hands you does **not** do that: reads keep viem's own error contract, so `e instanceof ContractFunctionRevertedError` and the rest of your existing viem error handling still work. Pick accordingly. For a _protocol_ contract, prefer the SDK's own methods — the decoding is the value, and on a contract the SDK doesn't bundle the decoder can only report `errorName: undefined` anyway. For anything else, this is the door. --- Next: [binary markets](./BINARY.md), [spot](./SPOT.md), [perps](./PERPS.md), and the [architecture guide](./ARCHITECTURE.md) for how the machine works inside. --- # /docs/typescript/architecture # Architecture The SDK connects a configured `SomniaMarkets` owner to the main indexer, chain RPC, and a separate price-feed service. This page explains where live state comes from and which resources each capability uses. Market watches hydrate indexed snapshots and then apply chain events locally. This keeps repeated store reads synchronous, while startup, recovery, historical reads, and price feeds still have network costs. Watches limit materialization work to the scopes the application uses. - [System overview](#system-overview) - [The client](#the-client) - [Watches: the snapshot seam + chain materialization](#watches) - [Event routing and the reducer](#event-routing-and-the-reducer) - [The local order book](#the-local-order-book) - [Connection lifecycle](#connection-lifecycle) - [The write path](#the-write-path) - [Choosing a read](#choosing-a-read) ## System overview The exchange owns its `SomniaMarketsClient`. The main Envio/Hasura indexer supplies historical reads and market/user snapshots over HTTP GraphQL. The engine's lazy chain WebSocket carries its chain reads, log/head subscriptions, backfills, and sends. Price feeds use a separate Hasura service over HTTP and one Hasura socket per watched asset key. Their `PriceStore` is separate from the market `MaterializerStore`. A subscribed network tape owns another chain socket. These capabilities do not share one universal realtime connection. ```mermaid flowchart LR subgraph app["Your app"] hooks["React hooks
useLiveFills, useLiveBinaryOrderBook, …"] node["Node / server code
bots, scripts, RSC"] end subgraph client["the engine (exchange.client)"] direction TB query["query.ts
one-shot indexer reads
listMarkets · getCandles · getPortfolio ·
getFills · getMarketResolution · getRouterActions ·
listProtocolFees · getFundingPayments · …"] reads["reads.ts / system.ts
one-shot chain reads
getBinaryOrderBook · getMarketOnchain ·
getAccountHealth · getLiquidationPrice ·
getVaultBalance · getErc20Balance · …"] subgraph live["live watches"] tail["liveTail.ts
watch registry + ingestion
ref-counted scopes · subscribe ·
backfill · seam"] reducer["reducer.ts
event → state
mirror of the indexer handlers"] store["store.ts
MaterializerStore
markets · orders · fills ·
book levels · status
versioned, memoized selectors"] end prices["priceFeed/
HTTP reads + asset watches
separate PriceStore"] tape["networkTape.ts
caller-owned activity tape
separate chain socket"] trader["trade.ts
writes
sign local · fixed fees ·
realtime send"] end subgraph backends["Backends"] indexer["Envio / Hasura indexer
HTTP GraphQL
history · aggregates ·
cold-start snapshot"] feed["Price-feed Hasura
HTTP + per-asset WebSockets"] chain["Somnia chain
engine WebSocket + separate tape sockets
eth_subscribe logs+heads ·
eth_call · getLogs ·
realtime_sendRawTransaction"] end hooks -- "useSyncExternalStore" --> store node -- "getLive* (sync)" --> store node -- "await client.*" --> query node -- "await client.*" --> reads node -- "createTrader(…)" --> trader query -- "POST /v1/graphql" --> indexer prices -- "hydrate/fetch HTTP + subscriptions" --> feed hooks -- "price selectors" --> prices tape -- "own logs + heads subscription" --> chain tail -- "cold scope hydration
(again after teardown)" --> indexer tail -- "watchEvent · watchBlocks ·
getLogs (seam backfill)" --> chain reads -- "eth_call (pipelined)" --> chain trader -- "realtime_sendRawTransaction
(send + receipt, 1 RTT)" --> chain tail --> reducer --> store ``` Key properties: - **Scoped.** Live materialization is opt-in per market via ref-counted watches. Cost — snapshot size, subscription filter width, event volume, reducer work — scales with what you watch, not with the protocol. Multi-chain is multiple clients, one per chain. - **Isolation.** Each exchange owns its configuration and stores. Price-feed state and failures are separate from market state. - **Shared engine chain transport.** Engine subscriptions, reads, backfills, and sends use its memoized chain transport. Parallel requests can overlap, but dependent reads, pagination, and cache misses still affect cost. Price watches and network tapes have separate sockets. - **Indexer startup dependency.** A new market or user scope needs indexed data to hydrate. After a successful market seam, chain events update that scope and chain backfill repairs reconnect gaps. A scope that was torn down needs hydration again. One-shot history and derived reads can continue to request the indexer while watches run. ## The client ```mermaid flowchart TB cc["new SomniaMarkets(config)"] --> ex["SomniaMarkets (exchange)"] -- ".client" --> pc["SomniaMarketsClient (engine)"] pc --> l1["live watches
watchMarket · watchMarkets · watchUser ·
getWatchStatus · stopLive · subscribeLive
getLiveStatus · getLiveMarkets · getLiveMarketByPool/ByAddress
getLiveFills · getLiveUserFills · getLiveUserOrders
getLiveBinaryOrderBook · getLiveSpotOrderBook"] pc --> l2["indexer reads (Promise, throw on failure)
listMarkets · getMarket · listBinaryMarkets · getBinaryMarket
getCandles · getFills · getMarketActivity · getOpenOrders · getOutcomeBalances
getPortfolio · getSpotPortfolio · getSpotStopOrders · getSyncStatus"] pc --> l3["chain reads (Promise)
getBinaryOrderBook · getSpotOrderBook · getMarketOnchain
getErc20Balance · getNativeBalance · getHeadBlock
getStopOrderSomiPayment · getSystemInfo"] pc --> l5["price feeds
fetchPrice · fetchPriceHistory · watchPrice
separate HTTP, Hasura sockets, and PriceStore"] pc --> l4["writes
createTrader({privateKey | account | walletClient})
→ placeOrder · cancelOrder · placeSpotOrder ·
placeSpotStopOrder · mintSet · burnSet · redeem · …"] ``` The socket opens lazily on first chain I/O, so an indexer-only client (e.g. server-side GraphQL reads) never opens the engine chain socket. Construction still requires `indexerUrl`, including for applications that only invoke chain reads. An individual chain read does not thereby make an indexer request. ## Watches A market watch materializes its scope locally: it hydrates a consistent snapshot of that scope from Envio up to block X, then materializes X+1.. directly from chain logs. Scopes are ref-counted (two watchers of one pool share everything) and torn down after a short linger when the last handle stops. The seam is gap-free and double-count-free: ```mermaid sequenceDiagram autonumber participant App participant Tail as LiveTail (watch registry) participant Idx as Indexer (GraphQL) participant WS as Chain WebSocket participant Store as MaterializerStore App->>Tail: watchMarket(pool) Tail->>WS: eth_subscribe logs (+ pool) · newHeads Note over Tail,WS: the scope's logs BUFFER from this instant —
nothing past the head can be missed Tail->>Idx: scope snapshot (HTTP GraphQL) Note over Idx: the market row · recent fills ·
its full resting order set ·
chain_metadata.latest_processed_block = X Idx-->>Tail: rows consistent to block X Tail->>Store: mergeSnapshot (other scopes untouched) Tail->>WS: widen subscription (+ the market's
BinaryMarket address, now known) Tail->>WS: eth_getLogs [X+1 … head] for the scope WS-->>Tail: backfill logs Tail->>Store: decode → reduce → commit Tail->>Tail: replay the scope's buffered logs
(deduped by (block, logIndex)) Tail-->>App: watchMarket resolves — reads are live loop live — every block WS-->>Tail: pushed logs + head Tail->>Store: decode → reduce → commit (one notify per batch) Store-->>App: subscribers re-read (hooks re-render) end ``` `watchMarkets({ discover })` is the same seam with scope = every market (plus the creation-event sources — the MarketCreator factory AND the BinaryMarketsModule — when discovering); `watchUser(user)` is snapshot-only (the account's past orders/fills — it opens no subscription of its own, and updates only from markets this client watches). Logs for a scope that is mid-hydration buffer in an inbox while other scopes keep applying live — one scope's seam never stalls another. Why this is safe on Somnia specifically: blocks have **instant BFT finality** — a delivered log is final, so there is no reorg handling. The dedupe set keyed by `(blockNumber, logIndex)` makes the buffer/backfill overlap harmless. Somnia logs carry no timestamp, so the `newHeads` stream doubles as the timestamp source (block number → timestamp map, pruned as the head advances). ## Event routing and the reducer One combined ABI (`liveEventsAbi`) decodes every watched log; the reducer routes by **event name + source address** and mutates the store exactly the way the Envio handlers mutate Postgres (`reducer.ts` mirrors `indexer/src/handlers/orderbook.ts` — keep them in lockstep): ```mermaid flowchart TB log["raw log from WS / backfill"] --> dec{"decodeEventLog
(liveEventsAbi)"} dec -- "source = a pool
(spot OR binary — byte-identical events)" --> ob["OrderBook events"] dec -- "source = a SpotPool" --> spot["spot-only events"] dec -- "source = MarketCreator /
BinaryMarketsModule" --> fac["MarketCreated"] dec -- "source = a BinaryMarket" --> bm["lifecycle events"] ob --> op["OrderPlaced → upsert order
(binary: side from isBid+userData, born Open;
spot: no side, born Closed)"] ob --> orst["OrderRested → rested=true
(spot: Closed → Open)"] ob --> ofill["OrderFilled → write LiveFill ·
patch maker order · bump market stats
(lastPrice, volumes, tradeCount)"] ob --> oc["OrderCancelled / OrderExpired /
OrderCancelledSelfMatch /
OrderReduced → patch order"] ob --> bk["SetMinted / SetBurned / Redeemed /
SettlementFeeCharged → market backing"] spot --> mp["MarkPriceUpdated → market.markPrice"] spot --> bp["OrderBookParametersUpdated →
tickSize · lotSize · minQuantity"] fac --> nm["build BinaryMarket row →
indexMarket → GROW the watch set →
catch-up getLogs for the creation range"] bm --> st["StatusChanged → status enum"] bm --> res["Resolved → status + winningOutcome"] bm --> vd["Voided → voided + status"] ``` Two ordering subtleties the reducer encodes: - **`OrderFilled` fires before the taker's `OrderPlaced`** in the same tx, so the taker is unknown at fill time. The fill stores `takerOrder_id` / `makerOrder_id` foreign keys; read-time selectors back-join owner + side from the order map (hydrated by the snapshot's open orders and live events). - **`MarketCreated` grows the discovery watch live.** Two creation events are watched. The `MarketCreator` factory rolls each series autonomously (a Somnia reactivity `Schedule` sub drains the due boundary's series in a gas-bounded loop, spilling to the next block when a batch is too large), emitting its 13-field `MarketCreated(marketId, market, pool, yesId, noId, collateral, asset, strike, tradingStart, expiry, oracleQuestionId, question, intervalSec)` — the trailing `intervalSec` is the series cadence (60 / 300 / 900 / 3600 / 14400 / 86400). The `BinaryMarketsModule` emits its own 20-field `MarketCreated` for EVERY market (rolled or created directly via `createMarket`) — the only creation event carrying the `(operatorId, venueId)` origin attribution — so module-created markets that never pass through a `MarketCreator` are discovered too. When an all-markets watch with `discover` is active, the tail re-subscribes with the new pool + market addresses and sweeps the creation range with a one-shot `getLogs`, so a market created seconds ago is fully tailed — the indexer is never asked again. ## The local order book The store _is_ the book. Every resting order is tracked through its lifecycle, so depth is an in-memory aggregation. Reading a hydrated book costs **zero round-trips** and reflects the events applied to that scope. Disconnection or recovery can leave it behind the head: ```mermaid flowchart LR subgraph store["MaterializerStore.orders"] o1["order: Open + rested
price 620000 · qty 50"] o2["order: Open + rested
price 620000 · qty 25"] o3["order: Open + rested
price 610000 · qty 10"] o4["order: Filled / Cancelled /
not rested → ignored"] end store --> agg["bookLevels(pool, depth)
group by (isBid, price) · sum qty ·
sort best-first · slice depth"] agg --> spotbook["getLiveSpotOrderBook
{ bids, asks }"] agg --> yes["YES-terms levels"] yes --> inv["toBinaryBook( )
NO side = 1 − yesPrice
(quantities carry over)"] inv --> binbook["getLiveBinaryOrderBook
{ yesBids, yesAsks, noBids, noAsks }"] ``` This matches the on-chain `getBookLevels` exactly because binary pools keep a _single_ book in YES terms — a NO order is expressed as `isBid`/`userData` with a YES-terms price, which is also how orders arrive in `OrderPlaced` events. The one-shot chain reads (`getBinaryOrderBook`/`getSpotOrderBook`) remain available as a separate source for callers that need a fresh node read. Stake and sell quotes also read a cached chain tick/lot grid and can resolve a missing pool through the main indexer; see [Read tiers](reference/read-tiers.md). Completeness note: live-witnessed orders are always present; orders that rested _before_ the watch opened come from the scope snapshot's open-order set — and because snapshots are per-scope, that set is the market's whole resting book, not a global cap's share of it. ## Connection lifecycle The following state machine describes market live-tail subscriptions. It does not describe price feeds or network tapes. Main-indexer hydration uses HTTP. The live tail relies on pushed chain logs and heads, with chain backfill for recovery. The live tail checks stalled heads every 15 seconds. After a stall it can request the chain head and reconnect if the subscription missed progress or the probe fails. A subscribed network tape checks for stalls every 5 seconds and has its own chain socket and recovery. These timers add background work; the SDK does not guarantee zero polling. ```mermaid stateDiagram-v2 [*] --> idle idle --> hydrating: first watchMarket / watchMarkets hydrating --> live: scope snapshot + backfill + replay OK hydrating --> reconnect_wait: snapshot / backfill failed live --> hydrating: new watch opens (its scope only —
existing scopes keep streaming) live --> reconnect_wait: WS error or stalled-head probe detects failure reconnect_wait --> live: resubscribe + getLogs
[lastBlock+1 … head] — CHAIN ONLY,
the indexer is not consulted note right of reconnect_wait exponential backoff 500ms → 1s → 2s → 4s → 8s (cap) reset to 500ms once live end note live --> idle: last watch released
(after a ~30s linger) live --> live: blocks stream in ``` Reconnects never re-snapshot: the store already holds state to block L, so the seam is simply `getLogs [L+1, head]` deduped against what's processed — chain truth heals chain gaps. This recovery path does not request the main indexer. A new or fully released scope still needs hydration, and one-shot indexer reads remain independent. Price watches first hydrate over the price-feed HTTP endpoint, then open a Hasura socket per asset key. They keep a separate store and connection status. A rejected subscription sets `getPriceStatus(asset)` to `error` and retains stale price values; it does not fail market watches. Price scopes also linger for about 30 seconds after the last handle stops. `exchange.close()` releases its watches and channels and stops the client's market and price live machinery. One-shot fetches remain usable. A network tape returned by `createNetworkTape` is caller-owned. Release each subscription with its returned unsubscribe function; the last release closes the tape socket. Its lifecycle is separate from the exchange watches. ## The write path Two signer modes, one rule: **gas is not estimated and receipts are not polled.** ```mermaid sequenceDiagram autonumber participant Bot as Caller participant T as Trader (trade.ts) participant WS as Chain WebSocket rect rgb(235, 245, 235) Note over Bot,WS: LOCAL SIGNER (privateKey / account) — the fast path Bot->>T: placeOrder({pool, side, price, quantity}) Note over T: resolve funding requirements
uncached ERC-20 approvals may read + send;
native spot sells read the current vault shortfall Note over T: reconcile pending nonce;
serialize nonce consumption, signing,
and broadcast acceptance;
use fixed fees + fixed gas ceiling T->>WS: realtime_sendRawTransaction(signedTx) Note over WS: node executes, blocks server-side
until the receipt exists WS-->>T: receipt WITH logs Note over T: decode OrderPlaced → orderId
decode OrderFilled → fills[] T-->>Bot: { hash, receipt, orderId, fills } end rect rgb(240, 240, 250) Note over Bot,WS: BROWSER SIGNER (injected walletClient) Bot->>T: placeOrder(…) T->>WS: eth_sendTransaction (wallet signs, fixed fees pinned) WS-->>T: tx hash T->>WS: getTransactionReceipt (immediate check) Note over T,WS: on miss: eth_subscribe newHeads —
re-check on each pushed head, first hit wins.
No poll, no timeout — socket errors reject. WS-->>T: receipt T-->>Bot: { hash, receipt, orderId, fills } end ``` An uncached (token, spender) pair does one `allowance` read. A short allowance causes one `approve(maxUint256)` transaction and then enters the cache. An existing effectively unlimited allowance also enters the cache. A finite allowance remains uncached because an order can consume it. The next order then reads the pool requirement and allowance again. Before each local write, viem reconciles the node's pending nonce with its in-memory offset. The trader serializes local nonce consumption, signing, and broadcast acceptance. One failed write therefore cannot invalidate a concurrent write's nonce reservation. A signer or broadcast failure resets the manager only after every earlier local write has reached a terminal send result. Measured on Somnia testnet with the `sdk-e2e` write suite (`E2E_WRITE=1`, which writes a gitignored `latency-report.md`): `placeOrder` confirm p50 ≈ **503ms**, within ~25ms of the raw transport floor. ### Spot funding preconditions The approval cache records only effectively unlimited allowances. A finite allowance is never cached, so the next order reads it again after the current order may have consumed it. Spot orders ask the pool for its exact fee-aware funding requirement when an approval check is needed. A native-base sell does that read every time so it can send only the current vault shortfall. ## Choosing a read Read selection depends on both the source and its startup state. [Read tiers](reference/read-tiers.md) contains the canonical Engine inventory, request costs, and method-specific exceptions. | You want | Use | Source and freshness | | --------------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | A book for frequent rendering | `getLiveBinaryOrderBook` / `getLiveSpotOrderBook` / hooks | Main-indexer hydration, then applied chain events. Synchronous after startup; inspect watch status during recovery. | | Live trade tape or user orders | `getLive*` / hooks | Market store. User hydration adds history; updates cover watched markets only. | | Market state from the node | `getMarketOnchain` | Chain RPC at the block served by the node. | | Candles, portfolios, historical fills, or market activity | `getCandles` / `getPortfolio` / `getFills` / `getMarketActivity` | Main indexer; delay is variable. | | A market list without watches | `listMarkets` / `listBinaryMarkets` | Main indexer; indexed rows can lag discovery. | | Raw balances or wiring | `getErc20Balance` / `getSystemInfo` | Chain RPC; composite reads may make multiple calls. | | Oracle price history or streaming prices | `fetchPriceHistory` / `watchPrice` / price hooks | Separate price-feed Hasura service and PriceStore; values can be stale during errors or disconnection. | Derived reads can combine sources. For example, Exchange `fetchTicker` uses cached market metadata, indexed candles, and best-effort perp chain state. Its timestamp is response time. Engine `getOpenPositionsWithPnL` and `getClaimable` use indexed inputs, so neither guarantees current chain state. Choose an action's inputs with these limits in mind. React's `useIndexerQuery` invokes a caller-supplied callback on mount, owner/dependency changes, and `refetch`. It does not poll or automatically refresh on live events. The callback chooses the source; the hook does not certify freshness. It passes an abort signal and ignores superseded results, while request cancellation depends on the callback forwarding the signal. --- # /docs/typescript/release-notes # Release notes ## 0.30.0 ### Minor Changes - Three new client reads answer block-scoped questions: `getBlockActivity` returns what one block traded grouped by market, `getLatestActiveBlock` names the newest block with markets activity, and `getAdjacentActiveBlocks` names the closest such block on either side. All three anchor on the indexed timestamp columns rather than a block column, none of which the indexer schema indexes. `getTransactionActivity` takes an optional `anchor` (the transaction's block and timestamp). Supplying it skips the `Order.placedTxHash` probe, which is not index-served and ran past the gateway timeout — so a transaction that produced no event, meaning one that only placed or cancelled orders, could not be read at all. - New `SOMNIA_MAINNET_PRICE_FEED` constant. It is the mainnet price feed, `https://price-feed.prd.oracle.somnia.host/v1/graphql`, pinned to the `USDC` quote. The SDK previously exported one price feed, `SOMNIA_TESTNET_PRICE_FEED`. A mainnet consumer had to write the endpoint by hand. The two feeds are separate deployments. Each one indexes the `PriceFeedScheduler` on its own chain. Use the feed that matches the chain the client runs on. The mainnet feed carries fewer symbols than the testnet feed. Code written for the testnet asset list can therefore fail on mainnet. Read the feed catalog to learn which bases exist. A base the feed does not carry returns no rows. It does not raise an error. Existing callers keep their behaviour. `SOMNIA_TESTNET_PRICE_FEED` is unchanged and remains correct for a testnet client. - Publish the perp event ABIs, so a consumer can decode perp logs from chain. `perpPoolEventsAbi` is now root-exported, and `marginBankEventsAbi` and `liquidationEngineEventsAbi` are new (18 and 13 events). Before this, `perpPoolWriteAbi` and `marginBankWriteAbi` exported no events and there was no MarginBank or LiquidationEngine event ABI at all, so funding settlement, positions, collateral flow and the liquidation waterfall were undecodable without a hand-copied ABI. Every signature is pinned by topic0 against the compiled artifacts. `docs/PERPS.md` has a new "Watch from chain" section. - Add `client.getPerpFundingPremium(pool)`, which reads the premium the next funding settlement will charge. Use `timeWeightedPremium` to project a funding rate. Do not use `lastObservedPremium` for that: the contract getter behind it kept its signature and changed its meaning, and it is now only the standing instantaneous sample. Check `armed` before calling the figure a time-weighted average, because a market that has not settled since the upgrade is still charging a point sample. This read is deliberately separate from `getPerpState`, whose batch would fail as a whole against a pool too old to serve these getters. Correct the funding documentation for the reworked premium and catch-up horizon. `FundingRateUpdate.intervalsAccrued` is no longer `min(intervalsSettled, n)`. A settlement now charges at most one interval, however long the gap, and the excess is forgiven. Compare `intervalsAccrued` against `intervalsSettled` to see whether anything was forgiven; `intervalsSettled` alone does not tell you. `intervalsPerWindow` is the per-interval divisor only. On a historical row that caught up over several intervals, one settlement's charge is `fundingRate * intervalsAccrued / n` rather than `fundingRate / n`. The premium driving the rate is the time-weighted impact-price premium, not a book midpoint, so `emaPremium` can be non-zero on a one-sided book. - Read the three perp ledgers the reindex made available: `listPerpInsuranceFundEvents` (the InsuranceFund's tier ledger behind `getInsuranceFundState`), `listPerpWalletLinkEvents` / `listPerpMarginPulls` / `listPerpMainFundingEvents` (the linked-wallet rail's consent graph and both funding sides), and `listPerpOrderRejections` (orders refused inside a batch placement). Two aggregation hazards are documented on the types: the insurance ledger's `amount` must be folded by `kind` rather than summed, and the two funding sides record the same wei — summing them double-counts every transfer. - `listPerpStopOrders` now returns `siblingOrderId` (the live OCO partner), `intent` and `cancelReason`, so a stops table no longer needs a chain read per row to show pairing or intent. `cancelReason` separates the three routes to `CANCELLED`, which refund differently: `"Owner"` returns the SOMI in the same transaction, while `"LinkedFill"` and `"Inert"` only credit `unclaimedSomi` for `claimSomi()`. - ### BREAKING — the portfolio trades legs default to the last seven days `getSpotPortfolio`, `getPerpPortfolio` and `getPortfolio` now apply `since = now − 7 days` to their trades leg unless the caller passes `since`. A caller that passed no `since` and expected the whole history gets the last week. Each result gains a required `tradesSince` (unix seconds): the bound that was applied, so a UI can label the list and a caller can page further back. **Migration.** To keep the previous unbounded read, pass `since: 0` (or the earliest time you need). Hand-built `Portfolio` / `SpotPortfolio` / `PerpPortfolio` values (fixtures, adapters) need a `tradesSince` field. A UI that renders `trades` should read `tradesSince` and say so when the list is empty — "no trades since " is true where "no trades yet" is not. Why a window: the type scope below is fast when a wallet's fills are dense in the requested type and slow when they are sparse — a spot market-maker asking for its binary fills walks every fill it has rejecting each. Measured on the development indexer for such a wallet: 24.8 s unbounded, 208 ms with a seven-day bound. A window is the only shape that is fast for every wallet without a schema change. Treat it as the SDK's standing position on wallet-scoped trade history, not as a stopgap: the composite indexes that would let it be dropped are a separate ticket, and removing a default later would be a second breaking change. ### Fixed — type- and pool-scoped reads no longer filter through the `market` relationship Every read that scoped `Fill`, `Order` or `StopOrder` by market type or by pool did so with `market: { marketType: { _eq } }` or `market: { poolAddress: { _eq } }`. Hasura compiles a relationship predicate to a correlated `EXISTS` on `Market` per candidate row, which stops Postgres using the `maker` / `taker` / `owner` indexes. Measured on the development indexer for one wallet's fills at `limit: 50`: `stream timeout` with the predicate, 102 ms without it. Three such reads every five seconds per open wallet page saturated the shared one-vCPU database and stalled ingestion on both indexer slots. These reads now scope on the direct, indexed columns instead: `pool` on `Fill`, `market_id` on `Order` and `StopOrder`. A market type resolves to its set of pools — `_in` for SPOT and PERP, whose `Market.id` is the pool address; `_nin` over spot ∪ perp for BINARY, whose pools are recycled across thousands of markets. A spot or perp pool is its own market id — a direct `_eq`, no query. A single **binary** pool keeps the `market: { poolAddress }` relationship form: a recycled pool has hosted ~2,000 markets, so an `_in` of its ids would be the worse shape, and every Order read that takes a pool also carries `owner`, which bounds that one EXISTS to the wallet's rows — no worse than before. Pool and type compose in one place (`marketScope`). The two type sets are memoized per indexer URL for a minute, so the extra hop is paid once, not once per poll. Affected: `getSpotPortfolio`, `getPerpPortfolio`, `getPortfolio`, `getOpenOrders`, `getOrders`, `countOrders`, `getSpotStopOrders`, `listPerpStopOrders`, `listPerpOrderHistory`, `listSweepableOrders`. Rows returned are unchanged for every read except the three portfolio trades legs, where the new default window applies. `getSpotStopOrders` in particular keeps returning every pending stop a wallet holds, spot or perp, as it did. - BREAKING for constructors — `PortfolioAnalytics` gains a required `holdings` series: what the traded book is worth over time The result's `equity` field is cumulative window PnL. It starts at zero, it is signed, and it is not the account's value. Consumers read the name and plotted it as a level, so a losing window drew a spot wallet below zero. `holdings` is the level that name promised. Each sample sums `qty × mark` over the open positions, on the same grid as `equity`, so a chart can draw both against one x axis: ```ts const p = await exchange.fetchPortfolioAnalytics("7d"); p.holdings.at(-1); // what the traded book is worth now p.equity.at(-1); // what it gained over the window ``` The first point is the carried-in book valued at the window start, not zero. The series sums signed position value. Every book the fold keeps today is long-only, so today the value cannot go below zero — but do not lock a chart axis to that, because a signed book marks negative and the perp plane is committed to joining this fold. The marks are the caller's and are not validated, so a negative price carries through as it already does for the PnL figures. A position the sample cannot price is left OUT of the value rather than valued at zero, and `HoldingsPoint.unpricedMarkets` counts what was left out. A market with no candle sample and no last price has no mark, and standing a zero in its place would drop a held position out of the level with nothing to say it had. Check the count before presenting a sample as the whole book. **Migration.** Reading the result needs no change: every existing field keeps its name, its meaning and its value. Anything that CONSTRUCTS a `PortfolioAnalytics` — a hand-written response fixture, a test mock, an adapter building the object for an HTTP layer — must add `holdings: HoldingsPoint[]` or it stops compiling. `HoldingsPoint` is exported from the package root. An adapter that forwards both series also serves roughly twice the series payload. The series measures the TRADED BOOK, not the wallet. A token that arrived without a fill — bridged in, transferred in, minted — is not in the book, so it is not in this value. Idle quote balance is not a position, so it is not included either. Funding events refine the capital base only, so a deposit inside the window does not step the curve. Read balances from the chain when you need what the wallet itself is worth. - BREAKING: `redeem` no longer guesses a leg before resolution, and unified leg selection now uses an options object `trader.redeem({ market, amount })` previously derived the winning leg as the argmax of the market's payout vector. A void pays BOTH legs, so that argmax was meaningless: it returned leg 0 on the uniform `[D/2, D/2]` vector, and the higher-priced leg on a `CLOB_SNAPSHOT` `[p, D−p]` one. A holder of only the NO leg got a confusing `InsufficientBalance` revert. A holder of both legs — what one `mintSet` call produces — redeemed YES, received half, and never attempted NO, with no error and a successful transaction. The collateral was stranded, not destroyed: it stays claimable from `BinarySettlement` with an explicit leg. The auto-lookup is now resolution-only. It checks the market's terminal state before reading the immutable payout vector. On a voided market `redeem` throws `InvalidInputError` naming both legs and pointing at `redeemMany`; on an unresolved market it asks the caller to wait for settlement. Resolved markets are unchanged: `[D,0]` still resolves to YES and `[0,D]` to NO. `exchange.redeem(ref, amount)` gains an optional trailing `RedeemOptions` bag, so a NO-holder can claim through the unified API instead of hitting a dead end. Existing two-argument calls behave as before. Migration: replace `exchange.redeem(ref, amount, outcomeIdx)` with `exchange.redeem(ref, amount, { outcomeIdx })`. If the market may be voided, pass the leg you hold. To claim both legs, use `redeemMany` with one entry per leg — they settle in one transaction. - Restore concurrent market-discovery coordination and stable user-fill pagination after their review withdrawal. Paginated fill reads include configured indexer headers, and indexer response-body cancellation preserves the caller's reason. This restoration supersedes the earlier withdrawal note. Dataset-reset coordination remains required for persisted fill cursors. - Add bounded user-fill pages with stable numeric continuation. Cursors preserve account and filter scope while newer fills arrive. Existing reads remain unchanged. Reindex, repair and endpoint cutover still require callers to discard cached pages and cursors. - Reject partially present void payout vectors, floor each raw payout leg from its stored numerator, and verify omitted unified redemption legs against on-chain terminal state. ### Patch Changes - Approval documentation now distinguishes cached unlimited allowances from finite allowances that each order must check again. - Traders from one configured client now coordinate local sends for each account. A failed signer cannot reset a nonce that another trader is still broadcasting. - Share concurrent initial market discovery within each exchange. Explicit registry reloads run in order, including after a failed read, so an older discovery cannot overwrite newer market metadata. - Withdraw the unreleased stable user-fill pagination API and concurrent market-discovery coordination pending maintainer review. This withdrawal supersedes the queued release notes announcing those additions; existing offset-based fill reads and the previous discovery behavior remain available. - Documentation: a documentation map plus tutorials, how-to guides, reference pages, and explanations organised by reader need. Two tutorials take a newcomer from an empty directory to a cancelled order on the Shannon testnet. Eight how-to guides cover network configuration, testnet funds, a quoting loop, fill detection, browser-wallet signing, the React hooks, error handling, and debugging. Six reference pages list configuration fields and defaults, networks and endpoints, the symbol grammar, units and scales, read tiers, and the error classes with the contract error names they decode. Every TypeScript example has a compile-checked public-import counterpart, and the tutorials were executed against the testnet. Corrections to the existing guides, verified against the source: the reactivity guide no longer claims the package is on GitHub Packages; the binary guide's cadence list, lifecycle (`Finalized`), `intervalSec` provenance, and builder-fee revert names are corrected; the exchange guide's verb table gains the ten verbs it omitted and notes that `close()` leaves the WebSocket open; the engine guide's API links now target the docs site; `isTailing()` is no longer presented as the price-feed status; the bridge guide names `sendBridgeStep` as its one sender; and the two `errors` TSDoc examples now match the real signatures of `createOrder` and `cancelExpiredOrders`. - Forward configured indexer headers to paginated user fill reads and preserve the caller's cancellation reason when an indexer response body is interrupted. - `/native`: a rejected `sendSessionTransaction` or `getSessionAddress` no longer carries the session seed in its error. viem builds a request failure's `message` and `cause` from the request body, so a mempool rejection or a transport error used to print the seed — a private key in another shape — in every log line that showed `error.message`. Both calls now throw `RpcError`. When the node answered, `cause` is its own `{ code, message, data? }` and `getSomniaRpcError` / `mempoolStatus` keep working on it; when the transport failed first, `cause` is `{ name, message, status? }` with the seed blanked out of the request text. `isMethodNotFound` also stops matching the node's genuine `account does not exist` and `Block does not exist` failures, which the documented degrade-to-`null` idiom used to swallow. - A live-tailed client no longer re-fetches every block it has already been handed. The tail took its chain head from viem's `watchBlocks`, which answers a pushed `newHeads` frame by issuing an `eth_getBlockByNumber` for the very block the frame already carried - nothing new, at double the per-block RPC cost. It now reads the height and timestamp straight off the pushed frame over the same socket. A frame is read only when both the height and the timestamp arrive as hex quantities; if either is missing, is not hex, or is the empty quantity `"0x"`, the frame is skipped whole rather than half-read. A skipped frame still counts as proof the stream is alive, so the heads watchdog behaves as before and the next head restores the timestamp. - Operational failures are no longer converted into success, zero, or a caller error at seven sites. Admin writes through `OperatorAdmin`, `GovernanceAdmin`, `MarketCreatorAdmin`, `OracleHubAdmin` and the lend `Lender` now throw `ContractRevertError` on a mined-but-reverted receipt (with the contract's error name when a replay at the receipt's block recovers it) instead of resolving as if confirmed, or misreporting the revert as `RpcError("no event")`. `SomniaMarkets.fetchBalance` throws when a balance read fails instead of reporting `0` or omitting the key. `getBinaryPositionPnL` falls back to `lastPrice` only when no chain client is configured, not when the book read fails. `cachedErc20Decimals` (and every read built on it) returns the fallback only for a token without `decimals()`, not on an RPC failure. `createStopOrder` surfaces a failed mark read as the indexer's error instead of `InvalidInputError("pass triggerDirection")`. `depositVaultNative` no longer broadcasts when its preflight read failed. The receipt wait used by external-signer and fallback confirms rejects after three consecutive receipt-read failures instead of pending forever; "receipt not found yet" still waits. - Decode three perps reverts that previously surfaced as opaque hex — `InvalidFundingCapDivergenceMargin`, `InvalidPremiumImpactNotional` and `InvalidLinkedWalletRegistry`, all added by the 2026-08-31 testnet upgrade. - `createOrder` and `createStopOrder` never send a larger quantity than requested. Quantities are truncated to the base token precision before applying the lot-size floor. `amountToPrecision` now truncates the decimal text instead of its binary floating-point expansion. Exact inputs such as `1.2` therefore remain exact for a `0.1` lot size. Local writes now serialize nonce consumption, signing, and broadcast acceptance. A signer or broadcast failure can reset nonce tracking without invalidating another in-flight write. - Live-tailed clients now receive binary settlement finalization. The SDK declared `MarketFinalized` with a stale trailing argument, so its topic0 did not match the emitted event and `liveTail` discarded every settlement finalize — leaving `netBacking` null for the settled lifetime of every binary market. Indexer-backed reads were never affected. - ### Fixed — a hydrated fill now names its taker A watch scope hydrated from a snapshot reported no taker on any of its fills. `taker`, `takerSide` and `kind` were missing from the snapshot's fill selection set and hardcoded `undefined` when the rows were parsed, on a comment claiming the indexer does not carry them. It does: they are real columns, stamped by the indexer's `PendingTakerFill` bridge once the taker's placement event lands. On a market-scoped watch this was permanent, not a live-tail race. The client-side back-join recovers taker fields from the local order map, but that scope hydrates resting orders only — and a taker order that filled completely is `Filled`, never `Open`, so it never enters the map to be joined against. Every market order and every IOC was affected, and a freshly loaded binary trade tape showed no taker side on any row it hydrated. `taker`, `takerSide` and `kind` now come through from the indexer, so: - A binary fill reports its taker's address, its four-way `BUY_YES`/`SELL_YES`/ `BUY_NO`/`SELL_NO` taker side, and its `DIRECT_YES`/`DIRECT_NO`/`MINT_A_PAIR`/ `BURN_A_PAIR` kind — the vocabulary `takerIsBid` cannot express, being one boolean covering two sides at a time and carrying no kind at all. - A spot or perp fill reports its taker. `takerSide` and `kind` stay undefined there, which is correct rather than a regression: outcome side is a binary-only concept and every spot and perp adapter leaves it unset. - A row the bridge has not stamped yet still reads `undefined`, and the existing back-join still fills in whatever is missing when the rows are selected. No type changed: the live-fill shape already declared all three as optional, and the user-scoped path already resolved them through the back-join. This closes the SDK half deferred by the binary trade tape's taker-colour fix. - Native-base spot sells now send the pool's exact vault shortfall as `msg.value`. This includes fee headroom and prevents `InvalidMsgValue` reverts on fee-bearing pools. Spot approval checks now use the pool's worst-case reserve. An allowance that covers only the principal is increased before the pull. Binary buy commitments now use the collateral token's exact scale. They also include the builder-fee headroom that the pool locks. - ### Fixed — a voided market now values against the payout vector it actually stored `estPayoutFor`, `computePositionPnL` and `computeBinaryPnl` returned a hardcoded half for every voided binary market. A void pays whatever payout vector the market stored. Under the `UNIFORM` void policy that vector is `[D/2, D/2]`, so the half was right. Under `CLOB_SNAPSHOT` a void that captures a two-sided close stores `[p, D−p]` at the closing YES price, and there the half was wrong on both legs: at a 0.80 close the YES leg was understated by 37.5% and the NO leg overstated by 150%. `estPayoutFor` quoted a claim settlement would not pay. All three now read `payoutNumerators` / `payoutDenominator`, which the indexer already carries and the market selection set already requested: - `estPayoutFor` returns `amount × payoutNumerators[outcomeIdx] / payoutDenominator` on a void. A void is never fee-charged, so no settlement fee applies on that branch. - `computePositionPnL` and `computeBinaryPnl` mark each leg from the same vector. `computePositionPnL` derives the NO leg by subtraction, as it already does while trading, so both legs still sum to exactly one collateral unit. - `ClaimableInput` accepts optional `payoutNumerators` and `payoutDenominator`, and `PortfolioMarket` carries them, so `getClaimable` and `getOpenPositionsWithPnL` value a void from the vector too. The payout comes from the vector and never from `voidPolicy`. A `CLOB_SNAPSHOT` market stores the uniform vector on every fallback — no capture-capable pool, a reverting `closingPrice()`, a one-sided or empty book, any overflow guard — so reading the policy instead of the vector would misreport exactly those markets. When a legacy voided market has no stored vector, all three keep returning the half, unchanged from previous behaviour. A present but invalid vector now raises `InvalidInputError` instead of silently turning corrupt indexer data into a plausible payout. The vector arrives from the indexer rather than the chain, so it is validated before use — as a whole vector, not one leg at a time. It must have both legs, both parseable and positive, a positive denominator, and a sum equal to that denominator. This is the shape `BinaryMarket` writes for a void: uniform or `[p, D−p]`, with `p` clamped to `[1, D−1]`. Rejecting any other present vector keeps corrupt data distinct from the legacy no-vector fallback. - Clarify voided-market rounding: `computePositionPnL` calculates each leg as `floor(oneCollateral * payoutNumerators[outcomeIdx] / payoutDenominator)`. It does not derive the voided NO mark by subtraction. Independent rounding can leave the two marks below one collateral unit in total. This supersedes the earlier queued payout-vector note's claim that the voided marks always sum to exactly one collateral unit; the implementation already follows settlement's independent rounding. ## 0.29.0 ### Minor Changes - ### Added — a market's whole history, one transaction, and one trade The tape and the fills list were the only ways in. A market page could show trades and nothing else; a transaction or a single fill had no read at all. - **`getMarketActivity(market, opts)` — one market's whole transaction history.** The mints, merges, redemptions, oracle resolutions and lifecycle transitions a market accumulates were all indexed and reachable only one entity at a time, in five different shapes. This returns them interleaved by time as one discriminated union on `kind` (`MarketActivity`), newest first, in a single round-trip. Every row carries its `txHash`, so a caller can follow any row to the chain. Select the streams with `kinds`, page backwards with `until`, and pass `pool` to let the fill read use its `(pool, timestamp)` index. A spot or perp market returns `TRADE` rows only — the other four streams read binary-only entities, so asking for them there is empty rather than an error. Pair it with `getLiveFills` for zero-latency trades: a trade's id is `TRADE:` followed by the fill id on both paths, so the two merge on `id` — but merge 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. Cache identity comes from the new `marketActivityKey`. **Known limit:** `until` has one-second resolution and is inclusive, so the boundary second is re-read between pages and a second holding `limit` or more rows cannot be paged past. A composite `(timestamp, blockNumber, logIndex)` cursor is the fix; it needs `logIndex` on the three non-fill streams, which this release adds to the indexer schema but which reaches a deployment only after a reindex. - **`getTransactionActivity(txHash)` — everything the protocol did in one transaction.** The transaction-scoped counterpart: the same `MarketActivity` union with the same row ids, but selected by transaction and returned in LOG order, plus the orders the transaction placed, the fees it paid and the market rows its events touched. One oracle callback settles every market on a question, so this is how a caller sees that a single transaction resolved four markets at once. A hash the indexer has nothing for returns empty collections and a null `blockNumber` rather than throwing — including a transaction that only rested a limit order, which emits no event and is anchored on the order table instead. New public types `TransactionActivity`, `TransactionActivityOptions` and `TransactionOrder`, and the `transactionActivityKey` cache key. - **`getTradeContext(id)` — one trade in full, for a trade detail view.** Returns the fill (with its block position), the market it executed in, BOTH sides' orders, the protocol and builder fees its transaction charged, and the other fills that transaction produced — enough to answer why a trade priced where it did. `null` for an unknown id, which is a stale link rather than a failure. New public types `TradeContext` and `FillOrder`, and the `tradeContextKey` cache key. Both transaction-scoped reads used to scan `Fill` to select by hash. The indexer schema now carries `@index` on `Fill.txHash`, so that scan goes away once a reindex has run. - ### Added — single-entity detail reads, a transaction summary, and the network tape The indexer surface was list-shaped throughout: orders, fills and markets could be enumerated, but nothing addressed ONE of them. An explorer drilling into a row had no read to call. - **`getOrder(pool, orderId)`, `getFill(id)`, `getOrderFills(pool, orderId)`** — the three reads a detail view runs on. Order ids never repeat (a monotonic per-pool counter), so `(pool, orderId)` names one order permanently; a fill is named by its `${blockNumber}_${logIndex}` id. All three embed a `MarketRef` (symbols, decimals, routing identity) so a page renders from one read instead of a second lookup per row. `null` for an unindexed id — a just-executed fill can lag by a beat, which is a stale link rather than a failure. The embedded market is `marketRef`, not `market`: `FillRow.market` is already the bytes32 marketId string, and GraphQL will not select a relationship alongside an alias of the same name. - **`listMarketsByPool(pool)`** — every market a pool has hosted, newest first. A binary pool is recycled across successive markets, so this is its full history rather than the one market `getMarketByPool` resolves. Plus **`getSeries(creator, seriesId)`**, the single-row sibling of `listSeries`. - **`getTransactionSummary(hash)`** — sender, gas used and limit, effective gas price, fee paid, status. Chain-direct rather than indexed, so it answers for any hash the node still has; `null` for an unknown one, never a throw. - **`createNetworkTape()`** — a network-wide order-flow firehose. One topics-only chain-log subscription sees `OrderPlaced` / `OrderFilled` from every pool, including pools created after it starts, with no indexer on the hot path. Not the live tail: no books and no snapshots, just three newest-first ring buffers (`bids` / `fills` / `asks`) plus a session `(pool, orderId) → owner` map that attributes fills. Takers always resolve; makers resolve when they were quoted while the tape ran. Rows carry RAW units — join to `listMarkets` for symbols and decimals. Nothing connects until the first `subscribe`, and reconnect plus stall detection for Somnia's silently-dying subscriptions is built in. The indexer also materializes the Market→Series edge from `MarketCreator.SeriesRolled` (`Market.series` / `Market.seriesKey`), replacing a heuristic join on asset + venue + cadence. That reaches a deployment only after a reindex, and the SDK does not read the field yet. - ### Added — read a pool's operator permissions registry from your own call `spotPoolOperatorRegistryReadAbi` is now exported from the package root. It is the ABI fragment for `getOperatorPermissionsRegistry()`, the view that tells you WHICH `OperatorPermissionsRegistry` a SpotPool consults when it gates `placeOrderFor`, `cancelOrderFor` and `reduceOrderFor`. `client.getOperatorPermissionsRegistry(pool)` already answered that question and still does. Reach for the fragment instead when the method does not fit: - **Multicall composition.** The method issues its own `readContract`, so it cannot be batched into a caller-built multicall. With the fragment the registry read joins the same batch as the rest of your pool reads. - **No instantiated client on that code path.** The method resolves a chain client lazily and needs one; the fragment is a static value and needs nothing. Previously the only route was a hand-copied fragment, since the `exports` map has no wildcard and no deep import could reach it — which is how a signature drifts in silence. ```ts import { spotPoolOperatorRegistryReadAbi } from "@somnia-chain/markets-sdk"; // `allowFailure: false` so a failed read throws instead of yielding a // `{ status, result }` wrapper. With the default (`true`) each element is that // wrapper, and comparing it to an address silently reports every pool as wired. const [registry] = await publicClient.multicall({ allowFailure: false, contracts: [{ address: pool, abi: spotPoolOperatorRegistryReadAbi, functionName: "getOperatorPermissionsRegistry" }], }); const wired = registry.toLowerCase() !== "0x0000000000000000000000000000000000000000"; ``` Two differences from the method, both of which matter for an authorization check: - **`address(0)` reaches you raw.** The method returns `null` for an unwired pool; a direct read returns the zero address, which is truthy. Compare it yourself, as above — such a pool denies every operator call, so a grant written anywhere will not make `placeOrderFor` succeed. The SDK's own grant reads and writes reject a zero registry with `NotConfiguredError` rather than acting on it. - **Read per pool.** Two pools on one deployment may name different registries, and the pool is the authority: a grant written to any other registry is inert. Do not cache one answer for all pools. The other read-side ABIs stay internal. - ### Added — a portfolio says when its trade history is incomplete `Portfolio`, `SpotPortfolio` and `PerpPortfolio` gain a `tradesTruncated` boolean. The three portfolio reads cap `trades` at 50 by default and page newest-first, so the cap drops the OLDEST fills. The returned shape carried no sign of this. A caller that folds `trades` into Net PnL, win rate, volume or a trade count got a total over the recent slice only, and read it as the whole history. This is the same signal `FundingRateSeries.truncated` already gives the funding chart. `tradesTruncated` is `trades.length >= tradesLimit`. A full page means older fills exist and were not returned. An empty page is not truncated, and neither is `tradesLimit: 0`, which asks for no trades at all. The default cap is unchanged, and raising `tradesLimit` moves the cap rather than removing it, so check the flag instead of assuming a large limit is enough. ### Changed (breaking) — perp markets are discovered from the chain, not only the indexer `loadMarkets()` now unions the indexer's perp rows with the PerpPoolFactory's and derives `active` from the live tradeability gates, so a close-only market no longer reads as tradeable. New `perpStatus` / `perpDiscoveryError` surface. **Breaking:** `indexed` is a required property on `UnifiedMarket`, so code that CONSTRUCTS one (fixtures, adapters) must set it; reading is unaffected. ### Added — the spot stop-order lifecycle is decodable, and the write ABIs are importable Protocol signatures were being hand-copied into consumer repositories, because this package held them and did not publish them. A transcription drifts in silence: it decodes nothing, or decodes wrong, and the failure looks like a missing trigger rather than an error. - **`spotStopRegistryEventsAbi` now carries the whole pending-order lifecycle.** It held `PendingOrderCreated` alone. It gains `PendingOrderTriggered(uint128 indexed pendingOrderId, bool success, uint128 indexed spotOrderId)`, `PendingOrderCancelled(uint128 indexed orderId)` and `InertOrderCancelled(uint128 indexed orderId, address indexed owner, uint256 somiCredited)` — so a consumer can decode a stop order firing, being cancelled by its owner, or being swept as inert, from a receipt. A new test checks every fragment's topic0 and argument shape against the compiled artifact `indexer/abis/SpotStopOrderRegistry.json`. That artifact carries no `PROVENANCE.json` entry, so the guard proves SDK-vs-artifact agreement, not SDK-vs-deployed-bytecode. Do not reuse the perp registry's shapes: its `PendingOrderTriggered` carries a drop reason the spot one does not have, and the test pins that divergence. - **`client.getOperatorPermissionsRegistry(pool)`** — the registry a SpotPool gates its operator calls through, at chain head, or `null` when the pool is unwired and denies every operator call. This is discovery for a caller who has not configured `addresses.operatorPermissionsRegistry`. 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 adds a path, it does not redirect one. - **Seven ABIs on the root barrel** — `erc20WriteAbi`, `erc20VaultWriteAbi`, `orderBookBatchWriteAbi`, `marginBankWriteAbi`, `spotStopRegistryWriteAbi`, `spotStopRegistryEventsAbi` and `operatorRegistryWriteAbi`. Token approvals, vault funding, batch order management, perp collateral, the stop-order lifecycle, and operator delegation are now encodable by hand from published surface. ```ts import { spotStopRegistryEventsAbi } from "@somnia-chain/markets-sdk"; import { decodeEventLog } from "viem"; for (const log of receipt.logs) { if (log.address.toLowerCase() !== registry.toLowerCase()) continue; const event = decodeEventLog({ abi: spotStopRegistryEventsAbi, ...log }); if (event.eventName === "PendingOrderTriggered") render(event.args); } ``` The read-side ABIs stay internal. A root export is permanent public surface, so the set is limited to what consumers have needed. ### Added — every placement path honours `selfMatchingOption` - **`selfMatchingOption` is now a caller input on all four placement paths**, so `CANCEL_MAKER` is reachable without leaving the SDK. It was pinned to `0` (`CANCEL_TAKER`) in each encoder, on a parameter the pools have always taken: `placeSpotOrder` / `buildPlaceSpotOrder` (`PlaceSpotOrderParams`), `placeSpotOrders` (`SpotOrderRequest`, per request), `placePerpOrder` / `buildPlacePerpOrder` (`PlacePerpOrderParams`), and `placeOrder` / `buildPlaceOrder` (`PlaceOrderParams`). `amendOrder` and `amendOrders` already took it, so every placement and amend verb now shares one vocabulary — the exported `SELF_MATCHING_OPTION`. Omitting the field encodes `CANCEL_TAKER`, exactly as before, so no existing call changes behaviour. Note that this default is the SDK's own: the pool reads the value out of every order request and has no default to fall back on. ```ts await trader.placeSpotOrder({ ...order, selfMatchingOption: SELF_MATCHING_OPTION.CANCEL_MAKER, // drop MY resting order }); ``` - **`userData` is settable on single spot placement** (`PlaceSpotOrderParams`), which the batch request shape already allowed. The single verb pinned the tag to `0`, so the same order encoded differently depending on which verb placed it. - **`placeSpotOrders` forwards each request's `builder` and `builderFeeBpsTimes1k`** instead of zeroing them. Choosing the batch verb silently dropped the routing attribution that `placeSpotOrder` honours. ### Added — a both-leg binary position can finally show either row - **`BinaryPositionPnL.outcomes`** — the same position split into its YES and NO books, as `{ yes, no }` of the new exported `BinaryOutcomePositionPnL` (`balance`, `costBasis`, `avgCost`, `markPrice`, `markValue`, `unrealizedPnl`, `realizedPnl`, all RAW). `OpenPositionPnL` extends `BinaryPositionPnL`, so `getBinaryPositionPnL` and `getOpenPositionsWithPnL` both carry it with no extra request. Every money field on the result is blended across both outcomes, which is unusable for a wallet holding both. Buy 10 YES at `0.20` and 10 NO at `0.80`, mark YES at `0.40`: the legs are `+2.00` and `-2.00` and the blended `unrealizedPnl` is `0.00`. Neither position row could show that zero as its own PnL, and consumers were falling back to local math for both-leg wallets. The fold already kept the two books separately in bigint space, mints and merges included — it computed each leg and then summed the values away. This publishes them. ```ts const [row] = await client.getOpenPositionsWithPnL(account); for (const leg of [row.outcomes.yes, row.outcomes.no]) { if (leg.balance > 0n) render(leg); // per-outcome, not blended } ``` Legs sum EXACTLY to the totals: `costBasis`, `markValue`, `unrealizedPnl` and `realizedPnl` are stored per leg and added up, so integer division cannot make a published leg disagree with the published total. `avgCost` and `markPrice` are per-token rates and do not sum — though while trading the two marks add up to one whole collateral unit. ### Added — the linked-wallet funding rail, and the margin surcharge that explains a refused order - **`getPerpLeverageImSurcharge(marginBank, account)`** and **`tryGetPerpLeverageImSurcharge`** — 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 closes a real gap rather than refining an existing read. `quotePerpOrderTopUp` funds ONE order and measures the account's *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 `InsufficientMarginForOrder` because of an override on a different one. Nothing in the SDK could name that amount. Note the magnitude before dismissing it: the order lock reserves only the market's margin factor, so a 5x setting on a 2%-IMF market needs 20% of notional, not 2%. The strict read reverts when a market that is both positioned and overridden is unpriceable; the `try` variant reports that as `null`, never `0n` — zero would under-state the requirement, which is the direction that produces an order the bank then refuses. - **The linked-wallet read surface** — `quotePerpFundingPayer`, `getPerpMainFunding`, `getPerpWalletPullCapacity`, `getPerpLinkedWalletRegistry`, `getPerpWalletLinkage`, `listPerpLinkedChildren`, `getPerpMaxLinkedChildren`. A linked child's position-increasing order draws its shortfall from its MAIN's wallet, and none of that was readable from the SDK. **`quotePerpFundingPayer` returns a discriminated union, not an address**, because the contract's single zero collapses three situations a UI must not render alike: the rail is `dormant` (the bank holds no registry, so the feature is off for everyone and linking would not help), the wallet is `unlinked` (the one case the user can fix), or the wallet `isMain` (linked, but funding flows main→child only). The arming check runs first and short-circuits, so a deployment with the rail off costs one read and cannot report a misleading "unlinked". **`getPerpMainFunding().payer` is the payer snapshotted at funding time**, not whoever is linked now. Both routes home settle against it, so an unlink or re-link between the pull and the repayment cannot misroute the money — read it rather than `mainOf` when the question is "who gets it back". `principal` is what the child may trade but not withdraw (`withdraw` frees at most `balance - principal`), and it is not a segregated bucket: the claim clamps to `min(principal, balance)` at flat moments, so the child's own contribution is the junior tranche and a loss eats it first. **`getPerpWalletLinkage` derives `isChild` / `isMain`** because the raw encoding is a trap — a main resolves to ITSELF in `mainOf`, so the natural test `main !== zero` is true for mains and children alike. `maturesAt` gates ADL netting only; the funding rail reads the raw graph, so a link can be fundable and not yet mature. All chain tier. The rail's five events are live on chain but not yet subscribed, so HISTORY is not available — these answer "what is true right now". Writes (`proposeLink` / `acceptLink` / `repayFunding` / `recallFromChild`) are deliberately not in this release. ### Added — a count can now say whether it is the whole truth - **`client.countMarketsBounded` / `client.countBinaryMarketsBounded`** — return `CountResult` (`{ count, truncated }`) instead of a bare number. `truncated: true` means `count` is a LOWER BOUND (10,000 rows): render it as "10,000+", and do not gate pagination on `rows.length < count`, which goes false while rows remain. Without the server-only `_aggregate` header every count falls back to a bounded row scan that returned *the rows it fetched* — so a scan that filled its cap reported exactly `10000`, indistinguishable from a real total. The fallback now requests `cap + 1` and reads the extra row as the signal; the probe row is never counted. `Fill` and `Order` are already past the cap in production and `Market` crosses it during 2026. The six bare-number count helpers are unchanged, and each now documents the bound on its client declaration — past the cap they return a lower bound as if it were exact. `countOperators`/`countVenues` get no variant: those tables are orders of magnitude below the cap. `countOrders`/`countUserFills` have none yet, and `Order`/`Fill` are both already past it — copy `countMarketsBounded` when a caller needs the signal. ### Added — a binary market's resolution mode, served - **`BinaryMarket.mode`** — `"reference"` (an up/down market whose threshold is another question's answer) or `"fixed"` (a threshold set at creation). Derived from `strike`, so it costs no extra query, and stamped on the live-tail path too — a market built from logs before the indexer has it reports the same mode it will report after. Exported as `BinaryResolutionMode`, with `binaryResolutionMode(strike)` as the one place that reading happens — both construction paths call it, so they cannot drift. Consumers previously inferred this from a LOOKUP MISS — "no opening answer, so it must be fixed-strike" — which conflates "no reference question" with "the reference question has not been answered yet". That reads as working code until an oracle is slow. - **`boundaryPrice(market, openingPrices)`** — the level a market's outcome is measured against, taken from whichever source `mode` names, with `posted` saying which. Only a posted answer has an "answered at" instant, so only it may be labelled as one; returning that alongside the value keeps a label and the number it labels derived from one decision. Returns the raw oracle value — scale stays the caller's to apply. ### Changed - **`BinaryMarketFilter.intervalSec` now matches a BAND, not an exact value.** A rolled market's indexed `intervalSec` is `expiry − tradingStart`, and trading routinely opens a second or two late, so one 15m series is indexed at 898s and 899s as well as 900s. The filter matched exactly, so it returned a fraction of a cadence and called it the whole thing — 5m was missing a quarter of its own markets. `listBinaryMarkets`, `listLiveBinaryMarkets`, `listPastBinaryMarkets` and `countBinaryMarkets` all inherit this, so **row counts change** for any caller passing `intervalSec`. The band is `± CADENCE_TOLERANCE_SEC` (5s); rungs are far enough apart that bands never overlap. A caller that genuinely wants one exact window should filter the returned rows itself. - **A non-finite or non-positive `intervalSec` now THROWS `RangeError`** rather than silently matching nothing. Previously `{ intervalSec: 0 }` sent `_eq: "0"` and `{ intervalSec: NaN }` sent `_eq: "NaN"`, both yielding `[]`. A filter that silently matches nothing reads as an empty result set rather than as the caller error it is, so it is rejected at the boundary. Callers parsing user input (a URL param, a form field) should validate first — the same way `operatorId` is already expected to be a positive integer. - **`marketIntervalLabel` snaps to the cadence ladder**, so `BinaryMarket.interval` and the labels stamped on trade-history and portfolio rows now read `"1m"` where they read `"56s"`, `"15m"` where they read `"898s"`. A window matching no rung is unchanged. ### Added - `BaseMarket.createdAtBlock` — the block a market was created in, the counterpart to `resolvedAtBlock`. A market is bracketed by two reads of an off-chain feed and only a block identifies which print each one saw: a `"fixed"`-mode market's `strike` is the feed's spot at `createdAtBlock`, and that print lands before `tradingStart` far more often than on it, so `createdAtTimestamp` cannot find it. **The field is required**, so any code constructing a `Market` by hand must supply it; it is non-null on the wire, so every indexed market carries one. - `getResolutionPrices(marketIds)` — batch settlement prices, the counterpart to `getOpeningPrices`. Joins each market's OWN `oracleQuestionId`, so fixed-strike markets (which have no reference question) are covered. **Read its note on scale before consuming it**: the value is a raw integer and the indexer does not carry the answer's decimals. - `getOnchainResolutionPrice(marketId)` and the `OnchainResolutionPrice` type — a chain fallback for a settled market whose answer the indexer never saw, because its oracle adapter is not the one the indexer ingests. Resolves the market's bound adapter through the module, so it works for any adapter, and carries its own `decimals` (adapters differ: 18 on the price-feed adapter, 2 on OracleHub). Returns null while the question is not final; a failed read throws rather than reporting absence. - `CADENCE_LADDER_SEC`, `CADENCE_TOLERANCE_SEC`, `snapToCadence` and `cadenceBandSec` — the SDK-canonical cadence rules, so grouping and filtering read one source instead of each re-deriving a tolerance. See the note on `CADENCE_LADDER_SEC`: these exist only because the markets indexer derives `intervalSec` from a market's own window instead of reading the exact value `MarketCreator.MarketCreated` already emits. ### Breaking — the MWRR capital base is deposited capital `mwrr.return` previously divided the window's gain by net trade flow: the carried-in position's value, plus buys, minus the full proceeds of sells. Net trade flow is not capital the account put in, so the figure overstated the return for an account trading a small part of its balance. An account that funded 10,000 USD, traded 500 USD and gained 50 USD reported 10 percent instead of 0.5 percent. Supply the new `funding` events to measure against real deposited capital; without them the base remains a trades-only proxy, and `mwrr.capitalBasis` now says which one produced the number. `mwrr.depositedUsd` keeps its name and its meaning of net capital, with one correction: a sell now returns only the capital it matched against a tracked position. Proceeds of tokens the account never bought on the venue no longer reduce the base, so an account selling externally-sourced tokens reads zero rather than a negative base — and receives a return where it previously received none. Returns computed from funding events are time-weighted (Modified Dietz): each deposit or withdrawal counts for the fraction of the window it was invested, so capital that arrived late no longer claims a whole window's return. Trade flows are deliberately not weighted. A trade moves capital that is already in the account, and weighting a sale as capital returned and a later repurchase as capital re-deployed would collapse the base for an account that merely rearranged what it held. A return can exceed 100 percent in either direction on the funding basis, because capital deployed for a few hours of a window earns or loses at a large period rate. That is what a money-weighted rate states. Read the new `weightedCapitalUsd` to see how much capital the figure is measured against before presenting it as a headline. Every account's reported return changes. Read `mwrr.capitalBasis` to detect which definition a build implements, rather than inferring it from the package version. ### Fixed - **Binary PnL no longer folds a recycled pool's PREVIOUS markets into the current market's cost basis.** A binary pool is reused by successive markets, and the PnL reads keyed a wallet's fills by pool address, so an earlier market's fills landed on whichever market held that pool next. `getBinaryPositionPnL` and `getOpenPositionsWithPnL` could both report a wrong `avgCost`, `costBasis`, `unrealizedPnl` and `realizedPnl`. They now key by the stable `market_id` that `FillRow.market` has carried since 0.28.0. **Reported money values change** for any wallet that traded more than one market on the same pool; spot and perp are unaffected, since their market id IS the pool address. - `getOpenPositionsWithPnL` now asks the indexer only for the fills and router actions of the markets it is folding. Both reads are capped at 1000 rows and the cap drops the OLDEST rows first — the buys and mints that establish the cost basis — so a wallet with a long cross-market history could be priced off a partial book. ### Fixed — portfolio analytics reject a non-finite sampling bound `computePortfolioAnalytics` sampled its equity curve until the sample time reached `asOf`. A non-finite `asOf`, or a window start derived from a non-finite event timestamp, left that comparison false forever while every iteration appended another point, so the call exhausted memory instead of reporting a bad argument. The fold now validates `asOf`, every event timestamp, and the derived window and bucket bounds before it sorts, allocates, or samples. An invalid value throws `InvalidInputError` naming the field. Nothing is substituted and no event is dropped: an invalid time is the caller's to fix, and guessing one would misplace money on the curve. The new `ComputePortfolioAnalyticsError` type states the errors the function can throw. `fetchPortfolioAnalytics` now skips a fill whose indexed timestamp is unusable — nullish, blank, or non-numeric — the same way it already skips a fill whose direction it cannot determine. The check runs before the market is recorded and before a candle range is derived, so one unusable row cannot move an `all`-window start. Blank strings matter here specifically: `Number("")` is zero, which would have placed a fill in 1970 rather than failing. A finite bound is not automatically a sampleable one. A fixed timeframe subtracts a constant, so its span is its own definition, but the `all` timeframe opens at the earliest event — one funding event dated far enough in the past asked the fold for millions of points and exhausted the heap. The fold now rejects a span above 100,000 sample points, naming the implied count. That is roughly 11 years of hourly buckets or 270 years of daily ones, so a real portfolio never meets it: a twenty-year history samples about 7,300 points and is unaffected. The sampling loop itself stays uncapped. Capping it would turn a loud failure into silently truncated financial output; refusing an impossible span is the loud version. ### Added - `getUserFills` / `countUserFills` take `market` (one bytes32 market id) and `markets` (several) alongside the existing `pool`, as the exported `FillsScope`. `getRouterActions` takes `markets` as `RouterActionsOptions`. The predicates run at the indexer, so a `limit` applies to the rows you asked for. Prefer `market` over `pool` on binary: a pool selects every market that ever used it. ### Added — closing-price snapshot voids (TRAD-106) Venue-selectable void payouts: a `CLOB_SNAPSHOT` venue's markets pay `[p, D−p]` at their closing YES price when they void, instead of the uniform 0.50 refund. - **Venue params v3**: `BinaryVenueParams` gains optional `voidPolicy` (`"UNIFORM"` default | `"CLOB_SNAPSHOT"`; exported as `VenueVoidPolicy`). `encodeBinaryVenueFeeParams` encodes v3 through the module's on-chain encoder; `decodeBinaryVenueFeeParams` (and the BINARY_V1 plugin codec) dual-decodes — legacy 192-byte v2 payloads stay valid with an implied `UNIFORM`. - **`trader.captureClose({ pool, maxSteps? })`** — the permissionless closing-price capture that lifts the pool's closing-book lock. Sweep keepers: a `CloseNotCaptured` revert on a post-expiry cancel/sweep means "capture first, then retry"; after a normal resolution the lock lifts by itself and capture is never needed. - **Reads**: `client.getClosingPrice(pool)` (returns `ClosingPriceState` or `null` on pre-capture pools — the selector doubles as the capability probe), `closingTop` in the pool read ABI, and `voidPolicy` on `getMarketOnchain` (null on pre-policy clones) + the indexed `BinaryMarket` row. - **Errors**: the contract-error table now decodes the capture surface (`CloseNotCaptured`, `CloseAlreadyCaptured`, `CaptureTooEarly`, `CaptureStepsExhausted`, `InvalidVenueVoidPolicy`, `InvalidVoidPolicy`). ### Added — dead-oracle recovery without `cast send` `Trader` gains the two entry points the recovery path was missing, so the whole chain is SDK-callable (`syncSettlement` / `finalizeMarket` / `releasePool` were already there): ```ts // 1. Always try the real answer first — voiding pays 1/N, resolution pays winners. await exchange.trader.pokeOracle({ oracleQuestionId }); // 2. Only once expiry + settlementWindow has lapsed: await exchange.trader.voidExpired({ marketId }); await exchange.trader.syncSettlement({ marketId }); // void bypasses the module await exchange.trader.finalizeMarket({ marketId }); await exchange.trader.releasePool({ marketId }); ``` - `pokeOracle` is keyed by **oracle question**, not market: the module fans out to every market bound to that question and resolves the ones whose adapter answers. A success is not "all bound markets resolved". `OracleNotAnswered` (none answered) and `UnknownOracleQuestion` (nothing bound) arrive as `ContractRevertError`, so a keeper loop can branch on `errorName`. - `voidExpired` writes to the market contract, bypassing the module — hence the `syncSettlement` follow-up to release the hub earmark. Before sending, it reads the market's state and throws `InvalidInputError` naming the exact unix second the window lapses, because the on-chain `SettlementWindowOpen` revert carries no timestamp. The gate is compared against the chain's `block.timestamp` (what the contract itself uses), not the local clock. Pass `skipPreflight: true` to send blind. OPERATOR-GUIDE §5's recovery runbook now shows these calls instead of `cast send`. ### Added — funding-aware capital base `mwrr` carries two new fields. `weightedCapitalUsd` is the Modified Dietz denominator. `capitalBasis` names the definition that produced the figures: `"funding"` when external capital movements bearing on the window were supplied, `"trades"` for the fallback proxy that cannot see capital which never passed through a trade. `fetchPortfolioAnalytics` accepts a `funding` option, and the new `PortfolioFundingEvent` type describes a deposit or withdrawal. Funding events refine the capital base only — they never enter the equity curve, profit and loss, or volume. They are caller-supplied, because the indexer has no wallet token-transfer entity and the public RPC caps log queries at 1,000 blocks. Source them from application records, bridge history, or a private RPC scan, and exclude transfers whose counterparty is a venue contract or the same capital is counted twice. `PortfolioFlowEvent` is now a union of `PortfolioTradeEvent` and `PortfolioFundingEvent`. Code that constructs trade events with an explicit `kind: "trade"` is unaffected. ### Fixed — `balanceFloor` proves its guarantee against the write path's conversion `balanceFloor` returns the largest number that does not exceed a raw balance, so a caller can size a "max" order without it reverting for insufficient funds. It verified that by round-tripping its candidate through `candidate.toFixed(decimals)`, which is not the conversion a write performs. A number-to-raw conversion prefers the shortest string that round-trips to the same double, so `1.001` converts as `"1.001"`, while `(1.001).toFixed(18)` is the smaller `"1.000999999999999890"`. Checking the smaller value passed candidates that the write path then converted to more raw units than the wallet held. Over a deterministic sweep of 4,004 balances around a lot boundary at 18 decimals, 407 results converted above the balance and 110 still exceeded it after the venue's lot floor, by up to 110 wei. Six-decimal balances were unaffected, so this reached only 18-decimal venues — currently the only mainnet precision. The check now uses the same conversion as the write path. Results move by at most a few hundred wei, and after the venue's lot floor the placeable maximum is unchanged for every balance in that sweep, so no caller loses usable size. `floorRawBalance` inherits the fix on its fallback path. `ceilRawAmount` was never affected: it returns `bigint` and never round-trips through a double. - Read one account's stored perp leverage cap in a single call: `getPerpMaxLeverage`. `MarginBank.getMaxLeverage(account, pool)` is one storage read, but the only published route to it was `getPerpLeverage`, which walks the whole account and throws when any market the account is active in has a stale mark. A per-position badge or leverage dialog can now read the cap alone — it survives dead feeds on other markets, accepts `opts.blockNumber` for pinned rows, and returns `0` unchanged when no cap is set (that means "no account cap", not zero leverage). - Report a perp pool's aggregator oracle address on `getPerpState`. `PerpStateOnchain` gains an `oracle` field, read from the pool's own `oracle()` view. A consumer building a perp market description from `getPerpState` no longer has to omit the oracle or keep a parity read of its own against the pool. The read joins the existing pinned multicall, so it costs no extra round trip on that path and one parallel read on the `ChainDoesNotSupportContract` fan-out. - ### Added — name a revert from your own call `decodeRevert`, `contractErrorsAbi` and the `RevertContext` type are now exported from the package root. The SDK could already name a protocol revert: `decodeRevert` turns whatever a node threw into a `ContractRevertError` carrying the Solidity error name, decoding against `contractErrorsAbi` (500 custom-error entries). Neither symbol was on the barrel, and the `exports` map has no wildcard, so a deep import could not reach them either. A consumer holding revert data from its own call had no path to a name and had to hand-copy error fragments — which is how a signature drifts in silence. `ContractRevertError` alone is not a substitute: it is a passive holder that decodes nothing, so constructing one from raw revert data yields `errorName: undefined`. ```ts import { decodeRevert } from "@somnia-chain/markets-sdk"; try { await publicClient.simulateContract(request); } catch (caught) { const err = decodeRevert(caught, { address: pool, functionName: "placeOrder" }); console.log(err.errorName); // e.g. "InvalidTriggerPrice", not opaque hex } ``` `contractErrorsAbi` is a generated artifact (`pnpm errors:gen`, verified in CI by `pnpm errors:check`). Publishing it freezes that artifact as public API deliberately: the point is that a consumer's copy stops drifting when ours is regenerated. Both values are pure over caller-held data — no transport, no client, no owner — so they sit at the root under `SDK-API-003` alongside the other ABI data. `toSdkError` and `isRevert` remain internal; ask if you need them. - ### Breaking — `UnifiedOrder.type` may be `undefined` `fetchOrders`, `fetchOpenOrders` and `watchOrders` now omit `type` instead of reporting `"limit"`. That `"limit"` was never a read value. The pools do not emit the order type — `OrderPlaced` carries a `placedOrder` struct with no order-type member, and binary pools emit only the YES/NO side — so the indexer has nothing to store and the SDK had nothing to read. Four read paths wrote the literal anyway, which made **every market order the SDK returned claim to be a limit order**, with no field a consumer could check to tell the difference. Omitting it is the honest answer: absent means unknown, where before a wrong value was indistinguishable from a right one. The field is still present wherever the value is genuinely known: - `createOrder()` echoes the caller's own argument. - `fetchOpenStopOrders()` reads it from the registry row — `PendingOrderCreated` does carry `orderType`. - `UnifiedStopOrder.type` is unchanged and still required. ```diff - if (order.type === "limit") { /* true for every order, including market ones */ } + if (order.type === "limit") { /* now only where the type is actually known */ } ``` If you branch on `order.type` from a read path, that branch was reading a fabricated value. Handle `undefined` explicitly; the honest source for how an order was placed is your own `createOrder` result. Populating it on read paths needs the pools to emit the order type, which is a contract change. - BREAKING — a binary market that has never traded reports NO mark, instead of a mark of zero `computePositionPnL` and `computeBinaryPnl` valued an unpriced market at a YES price of zero. A binary market has no price until its first trade: the indexer creates the row with no `lastPrice`, and only a fill writes one. `markYesPrice` reports that correctly as `null`. Both PnL folds discarded the `null` and put a confident `0` in its place. The NO leg is derived as the complement of the YES mark. A YES mark of zero is therefore a NO mark of the FULL collateral unit. On a 10.00 basis, a wallet holding only NO read as a 5.00 gain, and a wallet holding only YES read as a 5.00 total loss. A wallet holding both legs cancelled to 0.00, which hid the fault in the blended total while both legs stayed wrong. Minting a complete set is the ordinary way to take a position in a market that has not traded, so this state is reachable. The unknown price now travels as `null` rather than a number: - `BinaryOutcomePositionPnL.markPrice`, `.markValue` and `.unrealizedPnl` are `bigint | null`. - `BinaryPositionPnL.markValue` and `.unrealizedPnl` are `bigint | null`. - `BinaryOutcomePnl.mark`, `.value` and `.unrealized` are `number | null`. - `BinaryPnl.unrealized` and `.total` are `number | null`. **Migration.** Handle `null` on those fields before you display or total them. `null` means the market has no price to mark against — show it as unknown, and do not treat it as zero. Every field that does not depend on a mark keeps its old type and value: `balance`, `costBasis`, `avgCost` and `realizedPnl` stay exact. Nothing else changes. A market with a last trade or a resting quote marks as before. A resolved market still marks the winner at one whole collateral unit and the loser at zero, and a voided market still marks both legs at half, because a settlement payout needs no price. While a market is unresolved and priced, its two legs still sum to exactly one collateral unit. ### Patch Changes - Document `StaleMark` in the `Order.cancelReason` vocabulary. The indexer writes five cancel reasons but both published vocabularies listed four, so the served GraphQL description and the SDK contract told a consumer that a value it can actually receive does not exist. No behaviour or type change: `cancelReason` remains an open `string | null`. - ### Fixed — pre-fill maker cancellations now leave the live order book Deployed perp pools cancel resting maker orders before any fill — negative equity, stale mark, exceeds position, self-match — and the SDK's live tail dropped those events undecoded. The cancelled order stayed `Open` in the local store, so the order book kept counting its quantity at a price level the chain had already cleared: phantom depth in every rendered book and market-maker view, for the whole life of the watch. `OrderCancelledPreFill` (the base event for every pre-fill removal) and the perp reason tags `MakerOrderCancelledNegativeEquity` and `MakerOrderCancelledStaleMark` are now declared and terminate the order; `MakerOrderCancelledExceedsPosition` and `OrderCancelledSelfMatch` were already declared and are now covered by tests. Termination only — no store shape change and no new fields. - Account-scoped fill reads match indexed columns instead of joining through the taker's order Three reads found the fills an account participated in by OR-ing a predicate on the taker ORDER's `owner` alongside the denormalized columns: `getUserFills`/`countUserFills`, the binary `getPortfolio`, and the user snapshot the live store hydrates from. That arm is a relationship predicate, and Hasura compiles it to a correlated `EXISTS` subquery. Postgres cannot combine such a subquery with a bitmap OR over the `maker` and `taker` indexes: the plan walks the `timestamp` index backwards testing each row, and every row it walks past costs a lookup into `Order`. The penalty therefore falls hardest on ordinary wallets, which are sparse in a table that market makers fill. A busy maker reaches `limit` in a few rows and barely notices; a wallet with a handful of fills scans a long way and pays the subquery the whole way down. On the development indexer, four real single-fill wallets took 2.78s, 4.50s, 8.75s and 10.93s to sweep their tape, against 0.04s, 0.41s, 0.26s and 0.27s once the arm was gone. The arm found nothing the other two missed. `backfillTakerFills` in the indexer stamps the taker address from `OrderPlaced` for SPOT, PERP and binary alike, and the taker's order is placed in the same transaction as the fill it crosses — a resting order occupies the maker seat by definition — so no committed row can lack it. `takerOrder: Order!` is non-null in the schema for the same reason. The docblock that defended the arm described binary as leaving `taker` null; that stopped being true when binary side attribution moved to `BinaryOrderPlaced`. Reads that page a wallet's whole tape gain the most, because they pay the penalty once per page. The three also compound: a trader portfolio sweeps its fill tape, reads its binary positions and hydrates its snapshot, so one light wallet paid the scan three times over. Measured together on the development indexer, one page of each took 13.89s before and 0.27s after. No signature, option or row shape changes, and the rows returned are the same rows. `takerOrder { owner side }` is still SELECTED: `side` is what makes a binary row mappable when the fill's own `takerSide` copy is still lagging, and selecting a non-null relationship is an ordinary join rather than a filter. The invariant holds structurally: the indexer writes `Fill.taker` and `Order.owner` from the same local in the same handler, so the two cannot disagree — delegated and operator-placed orders included. `sdk-e2e` also asserts it against a live indexer, though that suite is hand-run rather than a CI gate. ## 0.28.1 (2026-08-21) A single fix on top of 0.28.0. ### Fixed — five perp names the client-scoped move left unreachable 0.28.0 internalized the connection-bound free functions, but five names left the root barrel without arriving on `SomniaMarketsClient`. They were reachable by no route at all: absent from the root, absent from the client, and not deep-importable, since the package publishes only `.` and `./react`. Each is now where the client-scoped rule puts it. Two are connection-bound, so they are client members: | Name | Use | |---|---| | `getPerpStopOrder` | `exchange.client.getPerpStopOrder({ registry, orderId })` | | `getPerpStopOrderSomiPayment` | `exchange.client.getPerpStopOrderSomiPayment(registry)` | `listPerpStopOrders` did become a client member in 0.28.0, so listing was unaffected. But `getPerpStopOrder` is the only way to read a LIMIT stop's `limitPrice`, its linked `siblingOrderId` and its `intent`: no event carries them, so `PerpStopOrder` cannot, and nothing off-chain could tell an opening bracket from a reduce-only stop. Three are pure functions — sync, no client, no `Writer` — so they are client-independent utilities and are exported from the root again: - `perpLiquidationPrice` - `perpOrderMarginQuote` - `perpPositionAnalytics` Their input and output types were never removed (`PerpLiquidationPriceInputs`, `PerpPositionAnalyticsInputs`, `PerpPositionMetrics`, `PerpOrderMarginQuote`, `PerpOrderMarginQuoteInputs`), nor was `PerpStopOrderOnChain`, whose only producer is `getPerpStopOrder`. No migration is needed for 0.28.0 code: every name above was unreachable, so nothing can depend on its old shape. The roster in `test/rootExports.test.ts` now covers all five, so the same gap fails CI instead of shipping. ## 0.28.0 (2026-08-20) The API is now client-scoped — the one breaking item — and the published package can be imported again. The write path aligns prices and amounts to the venue's own tick and lot grids, and gains build-only order verbs (unsigned calldata) plus single and batch order amendment. Reads gain the stable market id on order and fill rows and the liquidation-keeper views. ### Breaking — client-scoped entrypoints (53 free functions + the `./lend` subpath removed) Anything that uses a connection (indexer reads, chain reads) is now reachable ONLY through the client facade — the root barrel no longer exports free-function duplicates of `SomniaMarketsClient` members. The migration is mechanical: drop the trailing `indexerUrl`/`client` argument and call the same name on `exchange.client` (every removed function already existed as a same-named member; none changed behavior). Types, pure kernels, constants, and ABIs stay importable from the root. `./react` is untouched. The `@somnia-chain/markets-sdk/lend` entrypoint is REMOVED for the same reason: the lend entry is client-scoped (`client.lend`). Its standalone surface moved to the root — change `from "@somnia-chain/markets-sdk/lend"` to `from "@somnia-chain/markets-sdk"` for the lend types (`LendReserve`, `LendAccount`, …), the `SOMNIA_MAINNET_LEND` / `SOMNIA_TESTNET_LEND` deployment constants, the ray-math helpers (`lendRayRateToApy`, `rayMul`, `accrueLinear`, `accrueCompounded`, `RAY`), and the lend ABIs. `createLendWithDeps` is no longer public — the client builds the lend entry itself. ```ts // before import { getBookTops } from "@somnia-chain/markets-sdk"; const tops = await getBookTops(marketIds, indexerUrl); // after const tops = await exchange.client.getBookTops(marketIds); ``` | Removed root export | Use instead | |---|---| | `countOrders` | `exchange.client.countOrders(…)` | | `countUserFills` | `exchange.client.countUserFills(…)` | | `creditOf` | `exchange.client.creditOf(…)` | | `earmarkedOf` | `exchange.client.earmarkedOf(…)` | | `getAccountHealth` | `exchange.client.getAccountHealth(…)` | | `getAllOpenOrdersOnchain` | `exchange.client.getAllOpenOrdersOnchain(…)` | | `getBinaryBookParams` | `exchange.client.getBinaryBookParams(…)` | | `getBookTops` | `exchange.client.getBookTops(…)` | | `getFreePools` | `exchange.client.getFreePools(…)` | | `getFundingPayments` | `exchange.client.getFundingPayments(…)` | | `getFundingRateHistory` | `exchange.client.getFundingRateHistory(…)` | | `getLiquidationPrice` | `exchange.client.getLiquidationPrice(…)` | | `getLiquidations` | `exchange.client.getLiquidations(…)` | | `getMarginEvents` | `exchange.client.getMarginEvents(…)` | | `getMarketByPool` | `exchange.client.getMarketByPool(…)` | | `getMarketCreator` | `exchange.client.getMarketCreator(…)` | | `getMarketResolution` | `exchange.client.getMarketResolution(…)` | | `getOpenInterestHistory` | `exchange.client.getOpenInterestHistory(…)` | | `getOpeningPrices` | `exchange.client.getOpeningPrices(…)` | | `getOperatorHubAccount` | `exchange.client.getOperatorHubAccount(…)` | | `getOracleAdapter` | `exchange.client.getOracleAdapter(…)` | | `getOracleQuestion` | `exchange.client.getOracleQuestion(…)` | | `getOrderOnchain` | `exchange.client.getOrderOnchain(…)` | | `getOwnOpenOrdersOnchain` | `exchange.client.getOwnOpenOrdersOnchain(…)` | | `getPool` | `exchange.client.getPool(…)` | | `getPoolBindings` | `exchange.client.getPoolBindings(…)` | | `getPoolCreator` | `exchange.client.getPoolCreator(…)` | | `getRouterActions` | `exchange.client.getRouterActions(…)` | | `getSchedulingCost` | `exchange.client.getSchedulingCost(…)` | | `getVaultBalance` | `exchange.client.getVaultBalance(…)` | | `getVaultPayoutFallbacks` | `exchange.client.getVaultPayoutFallbacks(…)` | | `listBuilderApprovals` | `exchange.client.listBuilderApprovals(…)` | | `listBuilderFees` | `exchange.client.listBuilderFees(…)` | | `listFundingRateCandles` | `exchange.client.listFundingRateCandles(…)` | | `listFundingRateHistory` | `exchange.client.listFundingRateHistory(…)` | | `listMarketCreators` | `exchange.client.listMarketCreators(…)` | | `listOperatorHubAccounts` | `exchange.client.listOperatorHubAccounts(…)` | | `listOracleAdapters` | `exchange.client.listOracleAdapters(…)` | | `listOracleBinds` | `exchange.client.listOracleBinds(…)` | | `listOracleCallbacks` | `exchange.client.listOracleCallbacks(…)` | | `listOracleQuestions` | `exchange.client.listOracleQuestions(…)` | | `listPerpFees` | `exchange.client.listPerpFees(…)` | | `listPerpOrderHistory` | `exchange.client.listPerpOrderHistory(…)` | | `listPerpPositions` | `exchange.client.listPerpPositions(…)` | | `listPerpStopOrders` | `exchange.client.listPerpStopOrders(…)` | | `listProtocolFees` | `exchange.client.listProtocolFees(…)` | | `listSeries` | `exchange.client.listSeries(…)` | | `listSettlementFees` | `exchange.client.listSettlementFees(…)` | | `listSweepableOrders` | `exchange.client.listSweepableOrders(…)` | | `outstandingOf` | `exchange.client.outstandingOf(…)` | | `quoteCreateMarketValue` | `exchange.client.quoteCreateMarketValue(…)` | | `resolveReserve` | `exchange.client.resolveReserve(…)` | | `withdrawableOf` | `exchange.client.withdrawableOf(…)` | | `createLendWithDeps` (from `/lend`) | `exchange.client.lend` (built by the client) | | any other `/lend` import | same name, `from "@somnia-chain/markets-sdk"` | ### Fixed — a scoped or windowed `fetchMyTrades` returns the rows it was asked for `fetchMyTrades` read a wallet's history through three venue portfolio functions and called all three with no options, so the indexer capped fills at 50 per venue BEFORE any scoping happened and `since`/`limit`/`ref` were applied afterwards in memory. The visible symptom was not truncation. A market-scoped call returned an EMPTY list over fills that exist: if a wallet's fills on the asked-for market were older than its 50 newest fills overall, the query never returned them and there was nothing left to filter. `since` failed the same way — "my trades since last week" returned whichever of the newest 50 fell in last week, a smaller and different set. It now reads the unified fill tape (`getUserFills`), so the scope, the window and the limit are applied by the indexer. `limit` counts rows the caller receives: unresolvable rows are skipped and the read pages until the limit is satisfied or the tape is exhausted. Two behavioural changes worth knowing: - **Ordering.** An unscoped call now returns rows newest-first across all venues. It previously returned them grouped binary → spot → perp, so "the newest 50 trades" was a venue-ordered window rather than the newest 50. - **`UnifiedTrade.info`** is now the `FillRow` the tape returned, where it was previously a venue portfolio trade row. It remains typed `unknown` and documented as the native fill row. `since` stays in MILLISECONDS on this surface, matching `UnifiedTrade.timestamp`; the conversion to the indexer's unix seconds happens internally. ### Added — `fetchOpenOrders` accepts a row limit It took only `(ref?)`, so a caller could not raise the 200-per-venue default. It now takes `(ref?, limit?)` and forwards it to the query. The limit is per venue, not a merged total — an unscoped call reads all three. Note the spot portfolio query binds one limit variable to both its open orders and its pending stop orders; that coupling is now documented on the verb. ### Added — the stable market id on order and fill reads Every row of `getOrders`, `getOpenOrders`, `listSweepableOrders`, `getFills` and `getUserFills` now carries **`market`** — the bytes32 market id, the stable identity of the market the row belongs to. A pool address is not a market identity: on binary event contracts one pool is recycled by successive markets, so the same pool names a different market depending on when the order was placed. Pass the id straight to `client.getMarket(id)`; no new API. Order rows additionally carry **`marketInfo`** (`asset`, `question`, `expiry`, `tradingStart`, `quoteDecimals`, `intervalSec`, plus the derived `interval` label), so a history view can label rows without a second round-trip. ### Fixed — the published package can be imported Every release from 0.20.0 through 0.27.0 shipped a `dist` in which no relative import specifier carried a file extension. Node's ESM resolver requires them, so `import "@somnia-chain/markets-sdk"` threw `ERR_MODULE_NOT_FOUND` before any user code ran, on every declared subpath. `./chains` failed differently, with `ERR_UNSUPPORTED_DIR_IMPORT`, because two specifiers named a directory. This was not limited to plain Node. webpack — and therefore Next.js — failed too, with "resolved as fully specified" errors; a consumer could only compile by setting `resolve.fullySpecified: false`. esbuild, Rollup, Vite and `tsx` worked only by legacy extension guessing. There was no CommonJS fallback, and `src` in the tarball was unreachable behind a strict `exports` map. The package now compiles with `moduleResolution: "nodenext"`, so every relative specifier carries its extension and the compiler rejects the form that caused this. The public API, the exports map and the module format are unchanged — imports that used to throw now resolve. Nothing caught this for seven releases because vitest and `sdk-e2e` consume the SDK through the workspace `exports` block pointing at `src/*.ts`, so the test surface never loaded `dist`. Publishing is now gated on `scripts/publish-import-gate.mjs`, which packs the tarball, installs it into a bare `{"type":"module"}` project with no bundler, and imports every subpath the published exports map declares. ### Fixed — the write path now applies the venue's tick and lot grids `createOrder` converted the caller's price to raw units and sent it without ever snapping it to the market's tick grid — it never called `priceToPrecision`. So the pool rejected the order with `InvalidPrice` even when nothing had been lost in conversion: `createOrder(sym, "limit", "buy", 1, 0.25)` on a market with a `0.1` tick sent an off-tick price, and `0.25` is exactly representable as a double. Market orders were worse, because the caller never supplies the price. The protective limit was `best * (1 ± slippage)` computed in float and sent unaligned. Its binary clamp also bounded at `1 / 10 ** decimals` — one *wei*, not one tick — so on any venue whose tick exceeds a single raw unit the clamp's own bound was a value the pool rejects. `createOrder`, `createStopOrder` and the computed crossing price now align in bigint space against the same grid the precision helpers read. Aligning a value that is already on the grid returns it unchanged, so a caller who pre-snaps with `priceToPrecision` / `amountToPrecision` sees no behavioural change at all. **Direction is side-aware, and never moves a value against the caller.** A buy price rounds down, a sell price rounds up, and a quantity always rounds down — so an order is never larger, nor worse priced, than what was asked for. Rounding a sell price down (which is what `priceToPrecision` does, for either side) would be a real loss, so the write path and that helper can now differ by one tick on a sell; the helper's own spec pins its floor-only behaviour and is left alone. The one exception is a protective limit the SDK computes for a market order: that rounds *away* from the caller, so the cushion survives alignment and the order still crosses the level it was priced against. This matches how the stake and sell quote builders in `derivedReads` have always done it. Two visible consequences: - `UnifiedOrder.price` / `.amount` (and the stop-order equivalents) report what was actually placed, which may differ from the arguments by up to one tick or lot. `remaining` and `status` are derived from the placed amount, so an order that aligned down no longer reports a remainder that does not exist. - A quantity below one whole lot now throws `InvalidInputError` naming the market's minimum, instead of sending a zero-quantity order. Not breaking: every affected call previously either reverted on-chain or was already being pre-aligned by the caller to the same value. ### Fixed — a float price could not be placed on an 18-decimal venue `fromHuman` formatted numbers with `toFixed(decimals)`, which prints the float's binary expansion rather than the number the caller typed: at 18 decimals `(0.05).toFixed(18)` is `"0.050000000000000003"`. Three wei is enough to miss the live binary venue's 1e15 tick, so the pool rejected the order with `InvalidPrice`. Measured against the mainnet USDso venue: of fifteen ordinary probabilities only 0.25, 0.5 and 0.75 could be placed, the ones binary floating point represents exactly. A 6-decimal venue never shows it, so testnet stayed clean. Numbers now convert through their shortest round-tripping form (`String(n)`, i.e. `"0.05"`) whenever it fits the token's scale. `toFixed` still covers what it was there for: exponent notation and mantissas longer than `decimals` (which it rounds to scale, now stated in `fromHuman`'s docs rather than left implicit). The string path is unchanged. The same defect had been hand-rolled at two more sites, both fixed here so the write path has one definition of "the value the caller typed": - `Structs.toRaw`, which `createOrder` uses via `toNativePrice` — so the ccxt-shaped surface was broken too, and a fix to `fromHuman` alone would have left it that way. - `exchange.priceToPrecision` / `amountToPrecision`, the helpers a caller is told to use to AVOID off-tick values. They aligned to the grid in float space and then re-printed with `toFixed`, putting the expansion back — off-tick 16 times out of 19 on the live venue's ladder. Alignment now happens in bigint space, the only space the grid is defined in. Note that this fixes conversion, not arithmetic done before it: a caller who computes `3 * 0.05` still hands over `0.15000000000000002`, a genuinely different number. Snapping a computed price onto the venue's grid is `priceToPrecision`'s job. `priceToPrecision` keeps treating a value a hair BELOW a grid point as sitting on it, which the old float path did with a `+1e-9` nudge. A book mid like `(0.001 + 0.009) / 2` is `0.004999999999999999`, and flooring that would quote a whole tick away from what the caller asked for. The tolerance is now relative (one part in `2 ** 52`, the double's own resolution) rather than a fixed `1e-9`, so it scales with the price instead of being meaningless at 1e6 and overwhelming at 1e-9. `amountToPrecision` deliberately does NOT get that nudge — it snaps strictly down. An amount is usually bounded by something the caller cannot exceed (a wallet balance, a budget), and because the tolerance is relative it grows with magnitude: a balance one wei under a lot boundary would be rounded past it, producing the "insufficient balance" revert that `balanceFloor` / `floorRawBalance` exist to prevent. A price has no such ceiling. `Structs.snapToGrid` takes a `strict` option for callers in the first category, and under it the conversion INTO raw units truncates past `decimals` rather than rounding to scale — otherwise an over-precise number arrives already inflated and the floor starts from the wrong value (`amountToPrecision(0.1234567)` on a 6-decimal base returned `0.123457`, above the caller's own number). `fromHuman` and `probabilityToPrice` now reject non-finite numbers with `InvalidInputError` instead of letting viem's `InvalidDecimalNumberError` escape. `probabilityToPrice(NaN)` previously slipped past its own range check, since `NaN < 0` and `NaN > 1` are both false. ### Fixed — raw → human scaling no longer divides floats `Structs.toHumanNum` scaled with `Number(raw) / 10 ** decimals`. The division is a float operation, so it could land a few wei off the value it was handed: `19000000000000000000000` came back as `19000.000000000004`, which is not on a 1e15 grid. That silently undid the bigint alignment `priceToPrecision` had just performed — about a quarter of ordinary prices above ~1000 were returned OFF the grid they had been snapped onto, and `createOrder` re-converts that number before sending it, so the result was `InvalidPrice` again. Spot and perp prices live at exactly those magnitudes; the binary probabilities under 1 that the rest of this entry is about never showed it. It now scales through the exact decimal string, like `toHumanString` already did. The result is still a `number`, so it is still display-grade past ~15 significant digits — but it is the closest double to the true value rather than the closest double to a lossy quotient. This affects every `toHumanNum` caller, and only ever in the direction of accuracy: the two differ solely where the division was wrong. ### Fixed — `getPerpState` reads every field at ONE block `getPerpState` fanned out with `Promise.all` over nine independent `readContract` calls, so its values could come from different blocks. A mark price from block N beside a funding rate from block N+2 describes a market state that never existed — and a price bar rendering the pair presents it as if it did. Every read is now pinned to a single block number. The pin, not the multicall, is what provides the guarantee: viem splits a batch into several `eth_call`s once the calldata exceeds `batchSize`, and those can straddle blocks. Where the client's chain declares a Multicall3 — `viem/chains`' `somnia` and `somniaTestnet` both do — the nine reads also batch into one `aggregate3`, so the call costs two round-trips instead of nine. A chain built with a bare `defineChain` declares no contracts, so it keeps the fan-out and costs one MORE round-trip than before (the block pin). Correctness is identical either way. No API change — `PerpStateOnchain` and the `getPerpState(pool)` signature are unchanged. `tryGetMarkPrice` is still the mark read, so a stale feed still returns `markPriceOk: false` rather than throwing. `withTypedReadErrors` now also wraps `multicall`. Viem binds `client.multicall` to the raw client, so the existing `readContract` wrapper never fired for batched reads — without this, a revert read through multicall escaped as a bare viem error while the identical read through `readContract` threw a typed SDK error. ### Added — caller-set expiry and builder attribution on spot and perp orders `placeSpotOrder` and `placePerpOrder` now accept the expiry and builder fields the binary `placeOrder` already threaded. They were hardcoded before, so a caller could not set a spot order's expiry at all and could not attribute a spot or perp order to a builder: ```ts await exchange.trader.placeSpotOrder({ pool, isBid: true, price, quantity, baseDecimals, quoteToken, baseToken, expireTimestampNs: 1_800_000_000_000_000_000n, // was pinned to ~50y (GTC) builder: "0xYourFrontend", // was pinned to the zero address builderFeeBpsTimes1k: 25_000n, // was pinned to 0 }); ``` - `PlaceSpotOrderParams` gains `expireTimestampNs`, `builder`, and `builderFeeBpsTimes1k`. `PlacePerpOrderParams` gains the two builder fields (it already had `expireTimestampNs`). - Every field is optional and defaults to the value that was hardcoded before (`farFutureNs()`, the zero address, `0n`), so existing callers are unaffected. - A nonzero builder fee still requires a prior `Trader.approveBuilder` on that pool — the approval is stored **per pool**. See `docs/SPOT.md` and `docs/PERPS.md` for the fee ceiling and the two spot-expiry traps (a past expiry places nothing silently; an expired order does not auto-return its escrow). ### Fixed — `SomniaMarkets.createOrder` dropped builder attribution on spot and perp `createOrder` accepted `builder` / `builderFeeBpsTimes1k` but only forwarded them on binary markets. A spot or perp order placed through the unified surface rested with the zero-address builder: the call reported success, and no fee was attributed. Both fields now reach all three branches, and they are no longer documented as "BINARY only". ### Added — liquidation-keeper reads: `getPerpSideHolders` + `getBankruptcyPrice` The two MarginBank views the agreed permissionless liquidation-keeper design consumes, from head state alone — no off-chain indexer: - **`getPerpSideHolders({ marginBank, pool, isLong }, opts?)`** — every account holding an open position on one side of one perp market. Pages through the bank's bounded slice view (`getSideHoldersPaginated`; many holders per round-trip, never one call per holder) with every page pinned to ONE block — `opts.blockNumber`, or the head sampled once — and returns `{ holders, asOfBlock }`. Feed `asOfBlock` into `getBankruptcyPrice`'s `blockNumber` option (and the other side's call) so a sweep describes one consistent state. - **`getBankruptcyPrice({ marginBank, account, pool }, { blockNumber? })`** — the bank's OWN price at which the position's allocated equity is exhausted, verbatim. A different quantity from the client-side `getLiquidationPrice` estimate (where liquidation *triggers*): keepers settle and bid against this one. Reverts arrive **named** — `ContractRevertError` with `errorName: "NoOpenPosition"` when the account is flat in that pool (and `"AdlZeroNotional"` in the dust degenerate) — even though the generated error table does not cover MarginBank yet: the module fills the name in from the ABI-declared selectors, and the seam is a structural no-op once the table grows to cover the submodule's perp contracts. New exports: `PerpSideHolders`, `PerpSideHoldersRef`, `GetPerpSideHoldersOptions` (types only — the reads live on the client, deliberately not as standalone connection-bound exports, matching the client-scoped API direction). ### Added — build-only order placement (unsigned calldata) `trader.buildPlaceOrder`, `buildPlaceSpotOrder`, and `buildPlacePerpOrder` take the same parameters as their sending twins but hand back the unsigned call instead of signing and broadcasting it: ```ts const { order, approval } = await trader.buildPlaceOrder({ pool, side: "BUY_YES", price, quantity }); if (approval) await walletClient.sendTransaction({ ...approval, account }); // `order` is {to, data, value} — pre-sign it, batch it, relay it, or simulate it. ``` For pre-signing an ERC-4337 UserOp off the form input, batching a placement into a multicall, handing it to a relayer, or simulating it. Ordinary "place this now" stays on `placeOrder`. The approval is **returned, not sent** — `placeOrder` approves as a side effect, which a build-only verb cannot do. Send `approval` first when it is present. It is absent when nothing needs approving (a native-base spot sell, every perp placement). Also newly exported from the root, so a caller can encode a placement by hand: `ORDER_KIND`, `binaryPoolWriteAbi`, `spotPoolWriteAbi`, `perpPoolWriteAbi`, and the `UnsignedCall` / `UnsignedOrder` types. (A returned `approval` is a standard ERC-20 `approve` or ERC-6909 `setOperator` — decode it with viem's own `erc20Abi` or the already-exported `erc6909Abi`.) ### Added — `ceilRawAmount` The SDK could round an amount DOWN in a controlled way but not UP. Flooring exists because a "max" one ULP above the wallet is an insufficient-balance revert; a **minimum** has the mirror failure, rejected as under the minimum. - **`ceilRawAmount(raw, decimals, quantum)`** — `raw` rounded UP to a whole multiple of `quantum`. The mirror of `floorRawBalance`, for sizing minimums. It returns a `bigint` rather than a `number` like the floors do: a lot boundary such as `0.1` at 18 decimals has no exact `double`, and the nearest one sits below the minimum. Convert at the edge with `Number(formatUnits(...))` if you need a number. ### Fixed — stop-order and SpotPool reverts have names instead of hex A failed `placeSpotStopOrder` or `cancelStopOrder` reported opaque hex. The generated revert-decoding table was extracted from this repo's Foundry artifacts only, and forge emits artifacts for just the DEX contracts our own contracts import — so `SpotStopOrderRegistry` and `SpotPool`, which nothing here imports, had no artifacts and no decodable errors at all. `Trader`'s docs promised `errorName` would carry the protocol's own error; for those paths it never could. `errors:gen` now builds the DEX submodule as its own forge project and merges its artifacts, so what the SDK can name no longer depends on what this repo happens to reference. Newly decodable: - **All 28 `ISpotStopOrderRegistry` errors** — including `InsufficientVaultBalance`, `InsufficientSomiPayment`, `NoActiveSubscription`, `LimitPriceIncompatibleWithTrigger` and `ExceedsWithdrawableBalance`. - **The `ISpotPool`-only errors** — `OrderIdMismatch` (cancelling an order that already filled) and the builder-code family (`BuilderNotApproved`, `BuilderFeeExceedsApproval`, `BuilderCodesNotSupported`). - **The parameterless `QuantityBelowMinimum()`** the registry declares, alongside the CLOB's existing `QuantityBelowMinimum(uint256,uint256)`. Different selectors, so both entries are needed; only the two-argument one was present before. `errors:check` is unchanged and still hermetic — it recomputes the stamp from this repo's files plus the submodule's pinned commit, with neither forge nor a submodule checkout, so CI needs no access to the private DEX clone. Only `errors:gen` now requires the submodule checked out, and it fails loudly rather than quietly writing a smaller table. ### Added — `trader.amendOrders`, cancel and replace N orders atomically Amending a quote one order at a time costs two transactions per rung and leaves the book briefly one-sided. `amendOrders` does the whole set in a single transaction: every old order is cancelled and its replacement placed, or the batch reverts and nothing moves. `alwaysPlace` handles the race where an order you meant to amend has already filled or been cancelled by the time the tx lands. False (the default, and the industry-standard posture) reverts `AmendOldOrderGone`; true skips the cancel leg and places the replacement anyway. It only tolerates a *gone* order — someone else's live order still reverts `IncorrectSender`. `newOrderIds` comes back index-aligned with the submitted amendments. The pool returns those ids on-chain, but a mined receipt exposes only logs, so they are reconstructed from `OrderPlaced` — which fires for every accepted order, including one that fills completely without ever resting. A rejected replacement reverts `AmendReplacementRejected(requestIndex, reason)`, which names both the rung and the `OrderRejectionReason` — the signal to branch on. Note the cancel-all-first phase shields replacements from the orders they replace but **not from each other**: a new bid crossing a new ask self-matches and, being all-or-nothing, takes the whole re-ladder with it. Unlike `placeSpotOrder`, this does not auto-approve escrow. On an auto-pull pool the cancel leg returns freed tokens to the wallet and the place leg pulls them back, so a trader whose first call is `amendOrders` needs an allowance already in place. **SpotPool and PerpPool only.** A BinaryPool reverts `UseBinaryPlacement` for the whole transaction: binary placement carries the YES/NO kind through a transient slot that only `placeBinaryOrder` sets, and there is no batch binary entry. ### Added — `trader.amendOrder`, the single-order re-quote The batch `amendOrders` landed without its singular sibling, so re-quoting ONE order meant either a two-transaction cancel-then-place (which opens a gap on the book — the thing amend exists to prevent) or a one-element batch with a worse error surface. `amendOrder({ pool, oldOrderId, alwaysPlace?, newOrder })` calls the pool's own `amendOrder`, so a rejected replacement raises its landing-time reason directly (`PostOnlyWouldCross`, `SelfMatchCancelTaker`, `ImmediateOrCancelNoFill`, `FillOrKillNotFillable`, `OrderAlreadyExpired`). The batch wraps the same failure as `AmendReplacementRejected(requestIndex, reason)`, which for a single order is an index the caller already knew and a reason they then have to unwrap. Everything else matches the batch verb: `alwaysPlace` defaults to false and reverts `AmendOldOrderGone` on a vanished order (true opts into an upsert, and never tolerates an ownership failure); the replacement gets a NEW id and loses queue priority — use `reduceOrder` to shrink in place; and the call is non-payable, so native replacements need a manual-vault balance rather than auto-pull. ### Added — claim the SOMI a perp stop registry owes you `trader.claimPerpStopSomi` and `client.getUnclaimedPerpStopSomi` — the registry holds SOMI for an account in two cases, and neither was reachable from the SDK: a cancel whose direct refund transfer failed (a contract owner with no payable receiver), and an operator winding a registry down, which credits **every** owner including EOAs. Read the balance first; the claim reverts `NothingToClaim` on zero. Deliberately not wrapped: `withdrawSomi` is owner-only and cannot touch unclaimed balances, and `poke()` — permissionless, but the caller subsidises every eligible trigger, the `somiPaid` is consumed rather than reimbursed, and below the gas reserve it breaks out and the transaction succeeds having done nothing. ### Changed — faster log decoding on the live tail and the write path `decodeEventLog` memoizes nothing: for every log it walks the ABI deriving each candidate selector, and a log the ABI does NOT carry costs a full scan plus a thrown error that the caller immediately swallows. Foreign logs are the common case — any ERC-20 `Transfer` from a token touched in the same transaction lands in the same receipt — and the live tail decodes every block. A topic0 membership check now runs first. Against `liveEventsAbi` (29 events) an unmatched log cost 223 µs and now costs 0.054 µs; on a realistic block carrying four pool events among forty foreign logs, decoding went from **9.00 ms to 0.10 ms**. Internal only — no API change, and the decoded type is unchanged: the full ABI still does the decoding, so the discriminated union callers rely on is intact. ### Added — `useIndexerQuery` aborts superseded requests + exported query-key factories `useIndexerQuery` now creates an `AbortController` per run, hands its signal to the fetch function (the `fn` signature widened to `(client, signal)`, an additive change), and aborts on dependency change, refetch and unmount — a late settle from a superseded run never reaches state, even when `fn` ignores the signal. The root entry also exports query-key factories for callers wiring client reads into their own query library: `marketsKey`, `portfolioKey`, `candlesKey`, `marketFeesKey`, `operatorsKey`, `marketCreatorsKey`, `oracleAdaptersKey`, `syncStatusKey`, `maxVenueFeeBpsKey` and `marketOnchainKey`. Plain functions, no query-library dependency, returning JSON-serializable, case-folded, scope-prefixed arrays. Client reads themselves still take no per-call `AbortSignal` — cancellation remains client-scoped via `ClientConfig.signal`; the hook's signal benefits fetch functions that do their own fetching. ## 0.27.0 (2026-08-14) The first release since 0.25.0. Three new entry points (`/chains`, `/reactivity`, `/native`), the perp trading surface filled in end to end, and batch order writes. One breaking item — the `somnia-dex-protocol` re-pin. ### Breaking - **`somnia-dex-protocol` re-pinned to `main` (DEX-1761).** Reinstall to pick up the corrected revert ABI. Four order rejections that used to be silent — post-only would cross, self-match cancel, IOC no-fill, already-expired — are now named reverts. ### Added — new entry points - **`/chains`** — every Somnia network as a viem `Chain` (mainnet, Shannon, Elwood, Hideki, local). The only place chain definitions live. - **`/chains` bridge** — the Hyperlane warp-route registry plus `createBridgeTransfer` / `sendBridgeStep`. Pure: no client, no RPC. - **`/reactivity`** — the upstream `@somnia-chain/reactivity` package re-exported, as an optional peer dependency. - **`/native`** — the node's `somnia_*` namespace: native ledger blocks, statistics, node public keys, reactivity subscription reads and session transactions. ### Added — perps - **Per-position analytics.** Unrealised PnL, accrued funding, position margin and return on margin, instead of account-level equity that folded them together and exposed neither. - **Leverage and a projected liquidation price.** `getPerpLeverage`, plus `previewPerpLiquidationPrice` for an order not yet placed. - **Max order size.** `getMaxPerpOrderSize` — what a Max button should call. It binary-searches the pool's own sizing rule rather than keeping a second copy, so the size it returns cannot be one the pool then rejects. - **Close preview.** `previewPerpClosePnl` for a full or partial close. Handles the two subtleties: size snaps down to a lot multiple before anything realises, and a close settles funding on the whole position rather than the closed share. - **Auto-pull.** Placement can now fund itself from the wallet, so opening a position is one transaction rather than approve + deposit + place. Both order-form previews take an `autoPull` flag, and `quotePerpOrderTopUp` exposes the bank's own sizing. See `docs/PERPS.md` — the flag is opt-in because the pool gates it on `msg.sender == order.owner`, so it must stay off for `placeOrderFor` and operator-grant flows. - **Stop orders (DEX-2154).** `placePerpStopOrder` with linked one-cancels-other TP/SL pairs and opening triggers, plus `listPerpStopOrders` / `getPerpStopOrder`. - **Build-only writes.** `buildPlacePerpStopOrder`, `buildCancelPerpStopOrder(s)`, `buildDepositMargin` and `buildWithdrawMargin` return the unsigned call instead of broadcasting it, so writes that are only safe together — an order with TP/SL attached, approve + deposit, withdraw + forward — fit in one UserOp, Safe batch or multicall. Approvals come back rather than going out and must execute first; ids come from your own receipt via `decodePerpStopOrderIds`. See `docs/PERPS.md`. - **Funding-rate series (DEX-2025).** `buildFundingRateSeries` and the matching React hook, for a chart — poll plus live nudge. ### Added — everything else - **Batch order writes (MAR2-95).** `placeSpotOrders` / `cancelOrders` / `reduceOrders` — a ladder in one transaction instead of a loop of single sends. - **Operator grants (TRAD-140).** Grant/revoke writes plus registry approval views. - **Dead-oracle recovery.** The two entry points the recovery path was missing, so it no longer needs `cast send`. - **Vault funding.** Deposits, and the auto-pull opt-out. - **SpotPool funding + lock reads** are public. ### Fixed - **Short-side liquidation price.** `getLiquidationPrice` reported the liquidation further away than it actually is on shorts. No call-site change, but the numbers move. - **CLOB reverts are named** rather than surfacing opaque hex. - **Perp reverts are named too.** A failed `PerpPool` / `MarginBank` / `PerpStopOrderRegistry` call now reports `ContractRevertError.errorName` — `InsufficientCollateral`, `MarketRestricted`, `InsufficientSomiPayment` — across 122 error names, so an app no longer needs a hand-copied list that goes stale. - **`stopRegistry` reaches perp market rows.** Every perp stop write takes the per-pool registry as a required argument, and the SDK gave no way to find that address. ### Changed - **`AsyncCache` (MAR2-80)** for promise-memoizing maps. ### Perp stop orders — linked (OCO) TP/SL and opening triggers `placePerpStopOrder` is now the single create entry point for perp stops, and it covers three registry functions that a caller no longer has to choose between: - **A linked (OCO) pair** — pass `pair` with the second leg. Both are created and linked atomically, at twice the SOMI (one payment funds one trigger). When one leg triggers **and fills**, the registry cancels the other and credits its SOMI back. Legs are routed by operator, not by argument order, so it does not matter which you pass first. The result carries `pairedStopOrderId` alongside `stopOrderId`, caller's own leg first. - **An opening (non-reduce-only) trigger** — pass `intent: "opening"` for a stop-entry or breakout, gated on initial margin at creation so an order that could never margin itself is refused rather than burning its SOMI at trigger. - **Unchanged by default.** A call passing neither `intent` nor `pair` still routes to `createPendingOrder` and produces byte-identical calldata to before. Also **`linkPerpStopOrders`** (pair two stops that already exist, moving no SOMI), **`cancelPerpStopOrders`** (batch teardown in one transaction with a single refund — the way to close a pair), and **`getPerpStopOrder`** (read one stop straight from the registry). That last one closes a gap this SDK previously recorded as permanent: a LIMIT stop's `limitPrice` never leaves calldata and private storage, so nothing off-chain could show the limit a trader chose. It also answers during an indexer outage, and is currently the only way to read a pair's `siblingOrderId` and an order's `intent`. Cancelling one leg of a pair yourself cancels **one order** — the other stays armed and becomes unlinked. That is the registry's behaviour, not a limitation here. `getPerpStopOrder().intent` is `null`, not `"reduceOnly"`, when the registry reports an intent this SDK version does not know. The registry appends to its enums (`DropReason` just gained `NoFill`), and defaulting an unrecognized member to reduce-only would assert that an order cannot increase a position when a newer member might let it. `listPerpStopOrders` decodes the new `NoFill` drop reason, and now breaks a `createdAt` tie with `id` so its `offset` paging cannot repeat or lose a row — two stops created in the same block share a timestamp, which left the boundary between two pages undefined. The listing does **not** yet carry pairing, intent, or a cancellation cause. Those are new indexer columns behind a from-scratch reindex, and selecting a column the deployed Hasura does not serve is a validation error rather than a null — it would take the whole read down for every caller. They arrive in a follow-up release once that reindex has cut over. ## 0.25.0 (2026-08-07) `getOpenPositionsWithPnL(account)` — reliable avg-cost PnL for ALL of an account's open binary positions in one batched call. ### Added - `client.getOpenPositionsWithPnL(account)` → `OpenPositionPnL[]`: each open position's market joined with its `costBasis` / `avgCost` / `markValue` / `unrealizedPnl` / `realizedPnl`, computed identically to `getBinaryPositionPnL` (weighted-average cost from the account's own fills, marked to the book-clamped price) but for every open market at once, in a bounded number of indexer round-trips (fills + router actions + top-of-book batched) instead of a per-position loop. Prefer this over deriving PnL from book stats. - Exported the pure `computeOpenPositionsPnL` fold + the `OpenPositionPnL` type. Additive; no breaking changes. ## 0.24.0 (2026-08-07) The perp read surface, in one release: discovery, positions, orders, risk, margin preview and protocol state. Plus order state at chain head for every market type. **Requires a reindex from scratch.** The perp stop registries are newly subscribed, so their history only exists after a full re-run. ### Breaking — `SpotStopOrder.spotOrderId` is now `placedOrderId` The field is the id of the order the stop PLACED when it triggered, and both the spot and perp registries now record it. Rename at the call site; type and meaning are unchanged. The chain event keeps its own name — this is the SDK/entity field only. ### Added — perp market discovery `listPerpPoolStatuses({ factory })`, `listTradeablePerpPools(…)`, `isPerpPoolRegistered(…)`. An on-chain source of truth, so a market deployed after the indexer's curated manifest is still visible. **"Deployed" is not "tradeable"** — two independent gates: `restricted` (close-only; position-increasing orders revert, and it is reversible) and `registered` (the MarginBank has activated the pool). `tradeable` folds both. `getPoolTier` is not a substitute — it is itself gated on registration. Do not build a market list from the factory's raw pool list; that is deployment history and lists wound-down markets as tradeable. Each row carries its pool's own `marginBank`, ready for the reads that follow. Feature-detected by ERC-165 on `IPerpPoolFactoryMarketStatus` (`0xa874fb70`, exported) with a per-pool fallback; on a chain old enough to need that fallback, `registered`/`tradeable` come back `null` rather than guessed, and `listTradeablePerpPools` throws instead of returning a short list that looks authoritative. Only a missing-selector revert is treated this way — an RPC failure still propagates. ### Added — `listPerpPositions` `listPerpPositions(account, opts?)` returns every pool's position from the indexer, replacing a chain-read-per-market fan-out. Additive; `getPerpPosition` remains the authority for a single pool. Three fields are translated at this boundary because the raw shape would produce plausible wrong numbers: `size` is **signed** (folded from the entity's absolute size + `isLong`), `entryPriceX18` is exported as `avgEntryPrice` (the column name is a misnomer — the value is raw quote units per whole base, not 1e18-scaled), and `realizedPnl` is exported as `lastUpdateRealizedPnl` (most recent update only, not cumulative, not summable). Fully-closed positions are excluded by default (`includeFlat: true` returns them). Nothing is marked to market — unrealized PnL, liquidation price and margin health remain chain reads. ### Added — `listPerpOrderHistory` `getPerpPortfolio` hard-filters `status = "Open"`, so finished perp orders were unreadable. This is the other half, most-recently-**ended** first — a long-resting order that just filled belongs at the top of a history view, not at its placement date. Note `Closed` is terminal, not transitional: an IOC that partially filled without resting stays `Closed` forever. ### Added — perp stop orders are listable `listPerpStopOrders` over the indexed `PerpStopOrderRegistry` set. The registry keeps pending orders in private storage with no getter, so before this there was no read — chain or otherwise — answering "what stops do I have"; a trader could create stops but not see or cancel them. `builderFeeBpsTimes1k` is captured now precisely because it cannot be captured later: the registry deletes a pending order on every fire, so `PendingOrderCreated` is the only record the fee ever existed. One field stays out of reach — a LIMIT stop's `limitPrice` never leaves calldata and private storage. ### Added — per-market risk parameters `getPerpRiskParams(pool)`, `getPerpHealthSnapshot(pool)`, `getEffectiveImfBps(pool)`. `maintenanceMarginBps` was exposed nowhere, so a projected liquidation price for an unplaced order was impossible. **Initial margin is not a constant; maintenance margin is.** `initialMarginBps` is the floor of the curve — with dynamic IMF the pool scales it with open interest, and `effectiveImfBps` is what an order is actually charged. Sizing off the static base under-margins whenever OI has pushed the curve up. Maintenance margin deliberately does not scale. On testnet today both are 500 bps (dynamic IMF off), which is why the distinction is documented rather than left to be discovered. `getPerpHealthSnapshot` returns a discriminated union: an unpriceable market surfaces as `{ priceable: false }` rather than an all-zero snapshot, where a `maintenanceMarginBps` of `0` would read as "can never be liquidated". ### Added — `previewPerpOrderMargin` Predicts what a perp order will lock and whether the pool will accept it, before sending. The two contract probes are also exposed verbatim: `quoteMeetsPerpImForOrder`, `meetsPerpImForFill`. **`quoteMeetsIMForOrder` looks like the pre-trade check and is not.** It runs with `baseImReserved = true`, mirroring the check that happens *after* `lockCollateral` has already reserved the order's base margin — so called cold it collapses to "does existing equity cover existing positions" and returned `true` for 10^18 base units against a live testnet account. It cannot gate an order form. The preview instead ports `PerpPool._computeLockAmount` and the `MarginBank` gate it feeds: the reducing/increasing split, **the adverse mark-to-entry reserve** (the usual reason a naively-sized "max" order is rejected, and a term a `notional × IMF` estimate misses entirely), the OI-scaled effective IMF, the per-market leverage cap, and the credit-voucher floor. Two gates are reported separately because they fail for different reasons: `hasCollateralForLock` means "deposit more", `meetsInitialMargin` means "close something". Every read is pinned to one block and `asOfBlock` is returned — composed across blocks these values tear. A purely reducing order trips neither gate, so a close is reported as accepted even from an account below initial margin. Not modelled: tick/lot quantization, position/OI caps, market restriction, the resting-order cap, isolated margin — all reject independently of margin. Verified against a live testnet account to the unit: the computed boundary is accepted at `q` and rejected at `q + 1`, matching the chain's own `meetsIMForFill`. ### Added — perp protocol state `getPerpSystemConfig`, `getInsuranceFundState`, `getLiquidationEngineConfig`, `tryGetPerpAccountEquity`, `getPerpCollateralBasis`. `getPerpSystemConfig` is the entry point — every other contract in the plane is reachable from it, as the bank's own view of them, so nothing is hardcoded per chain. Its `fullyWired` flag covers the factory, liquidation engine and insurance fund but **not** `feeRecipient`, so a go-live check must look at that separately. Insurance-fund tiers are indexed `0..maxTiers` **inclusive** — `maxTiers` is the maximum index, not a count, so the fund has `maxTiers + 1` buckets. `totalBalance` is deliberately not described as absorbable bad debt: it includes tier 0, which never absorbs anything. `liquidationEngine` is the proxy, and that distinction bites — an implementation address answers with unset defaults (zero bidders, zero penalty), which looks like a configured-but-idle engine rather than the wrong address; the returned `marginBank` is the cross-check. `bidderCount === 0n` is an operational signal: with no stage-4 backstop bidders the waterfall reaches ADL sooner than the configuration implies. `tryGetPerpAccountEquity` returns `null` where `getAccountHealth` would revert. Null is "not computable right now", never "zero equity" — the two mean opposite things. `getPerpCollateralBasis` is the complement: one storage pair, no oracle, cannot revert. ### Added — perp fields on `fetchTicker` `UnifiedTicker` gains `markPrice`, `indexPrice`, `fundingRate`, `fundingTimestamp` and `openInterest`, populated on perp symbols and `undefined` elsewhere, so one call answers a market header. A non-perp spends no chain round-trip. `fundingRate` is on the **same per-8h axis** as `fetchFundingRate` — a header reading one basis beside a chart reading another is a wrong number that looks right. It is not the per-settlement amount. `markPrice` is omitted rather than reported when the feed is stale: the contract's `0` sentinel reads as a real price, and an unguarded `markPrice - entryPrice` becomes a 100% loss on every open position. ### Added — order state at chain head `getOrderOnchain`, `getOwnOpenOrdersOnchain`, `getAllOpenOrdersOnchain` — so a caller can read its own writes instead of waiting for the indexer. All three work for binary, spot and perp pools; fields are raw `bigint` units. `getOrderOnchain` returns `null` for any id the pool has no **active** order for (unknown, filled, cancelled, or replaced by `reduceOrder`) — chain head knows what is open now, the indexed `getOrders` keeps the history. `getOwnOpenOrdersOnchain` takes the owner explicitly and needs no signer. `getAllOpenOrdersOnchain` never forwards a configured signer — the pool accepts that view only from the zero address — and surfaces the contract's own pagination as-is. ### Added — `listSweepableOrders` `listSweepableOrders({ pool?, marketType?, owner?, asOfSec? })` returns orders past expiry that are **still resting**, across the whole book — the work-list for a permissionless sweep. Each row carries `orderId` for `cancelExpiredOrders` and `isBid` + `price` for `sweepExpiredAtLevel`. **Deliberately not `status: "Expired"`.** That status is written when the chain emits `OrderExpired` — i.e. once an order has already been swept. A keeper needs the opposite: still `Open`, already past expiry. The cutoff is scaled to nanoseconds; comparing against unix seconds would make every order look unexpired by a factor of a billion. GTC excludes itself (written as now + 50 years). Longest-overdue first. ### Fixed — binary precision comes from the pool, not a one-token guess `amountToPrecision` returned `0` for any binary amount below a whole token. Binary rows arrive from the indexer with `tickSize` / `lotSize` / `minQuantity` undefined, so the helper fell back to a one-whole-token lot — while every deployed venue enforces a 0.001-token lot: ```ts // BEFORE — 0.005 outcome tokens, on a venue whose lot is 0.001 exchange.amountToPrecision("BTC-UP/USDC#YES", 0.005); // 0 ✗ // AFTER exchange.amountToPrecision("BTC-UP/USDC#YES", 0.005); // 0.005 ``` `loadMarkets()` now reads each distinct binary pool's `getOrderBookParameters` (pipelined, cached per pool, re-read on `loadMarkets(true)`), feeding `amountToPrecision`, `priceToPrecision` and `UnifiedMarket.limits.amount`. If a pool's parameters cannot be read the helpers throw `InvalidInputError` for that market rather than quantizing against the fallback — callers that treated `0` as "too small to trade" should catch it. Spot and perp precision is unchanged. ### Fixed — the baked mainnet `marketCreator` pointed at a retired venue `SOMNIA_MAINNET_ADDRESSES.marketCreator` was `0xfc4Ecc01…` (venue 3, `status: "retired"`); the active venue 5 creator is `0xfe81C4e8…`. The venue-5 recovery changed `venues.json` without rerunning `pnpm gen:addresses`, so the stale value shipped in 0.21.0–0.23.0. Mainnet consumers using the baked addresses were filtering the realtime tail (`liveTail`) on a dead contract's events. Testnet was unaffected. ## 0.23.0 (2026-08-06) Perp data corrections (open interest, mark staleness, liquidation accounting), funding-rate series reads, vault funding writes, and a type-tightening sweep across the client surface. ### Breaking — perp open interest is ONE counter `PerpMarket.longOpenInterest` / `shortOpenInterest` and the same pair on `PerpStateOnchain` and `OpenInterestSnapshot` are replaced by a single `openInterest`. Not a simplification — a correction. The contract emits `OpenInterestUpdated(uint256)` and exposes `getOpenInterest() -> uint256`, because in a matched CLOB the short side is provably equal. The two-field form never matched the deployed ABI, so the indexed pair was null on every row (its subscription's `topic0` could not match) and the chain read **threw on every call**. ```diff - const oi = BigInt(m.longOpenInterest ?? 0) + BigInt(m.shortOpenInterest ?? 0) + const oi = BigInt(m.openInterest ?? 0) ``` ### Breaking — `UnifiedFundingRate.markPrice` may be `undefined` `fetchFundingRate()` now reports `undefined` rather than a number when the pool's mark feed is stale. The pool signals staleness with a **0 price word** (`tryGetMarkPrice` returns `(ok, price)`; the event uses a 0 sentinel). That was being converted straight to a number, putting a mark of `0` on the wire as though it were a real price — and downstream, an unguarded `markPrice - entryPrice` reads as a 100% loss on every open position. `info.markPriceOk` carries the flag if you want to distinguish "stale" from "not a perp". For marking a position rather than reporting a reading, `perpMarkForPnl(state)` falls back to the index price and tells you which it used. ### Breaking — `LiquidationEvent.badDebt` is narrower, and there are three new columns `badDebt` used to receive five different quantities while being documented as "safe to SUM". It now carries **only** the uncovered, insolvent hole (`ResidualBadDebt`, `AdlPriceCapacityExhausted`). Alongside it: | column | source | aggregation | |---|---|---| | `badDebt` | `ResidualBadDebt`, `AdlPriceCapacityExhausted` | a LEVEL — never SUM | | `insuranceCovered` | `BadDebtAbsorbed.covered` | a FLOW — SUM is exact | | `deficit` | `BadDebtAbsorbed.badDebt`, `ResidualBackedByOpenPnl` | a LEVEL — never SUM | | `coverageDeclined` | `CoverageDeclinedByEquityCap` | a FLOW — SUM is exact | If you were summing `badDebt` for a bad-debt figure, that total was double-counting: the gross hole and its uncovered remainder both landed there, as did a PnL-backed hole that is explicitly *not* bad debt and a coverage amount the equity cap deliberately deferred. The correct point-in-time figure is the sum of the **latest** `badDebt` row per account — a residual is a state sample, so successive liquidations on one account re-report the same hole. `BadDebtAbsorbed.covered` and `absorbedBy` are now exposed at all (they were being dropped); `absorbedBy` arrives on `counterparty`. ### Changed — `getFundingRateHistory` → `listFundingRateHistory` Renamed for the `get*` = value-or-null / `list*` = array convention in CONVENTIONS.md. The old name forwards verbatim for one release cycle and is marked `@deprecated`. New in the same read: `order: "asc" | "desc"`. The default `"desc"` returns the newest page, so `from` is a window bound; pass `"asc"` to make it a forward **cursor**. `fetchFundingRateHistory(symbol, since, limit)` now ascends whenever `since` is given, which is what makes the ccxt pagination idiom (`since = last.timestamp + 1`) terminate instead of re-reading the tail. ### Added — funding as a series `listFundingRateCandles(pool, intervalSeconds, opts)` serves 1h / 4h / 1d rollups for ranges the raw series is too dense for, plus `densifyFundingBuckets` to fill the grid slots a sparse query legitimately omits. Rollup buckets are **absent** where no settlement's span reached them and **revised** when a catch-up settlement reaches backwards; both are properties of lazy settlement, and the TSDoc on each says so. Funding-rate normalization helpers (`fundingRate8h`, `fundingRatePerInterval`, `annualizedFundingRate`, `realizedFundingPerBase`, …) are exported. A perp funding rate is per **calculation window** (28800s), not per interval and not annual, and `fundingWindowSec / fundingIntervalSec` is 96 on testnet against an expected 8 on mainnet — so the same rate value means a 12× different per-interval accrual. Normalize with the row's own `fundingWindowSec`; a hardcoded denominator produces a plausible-looking wrong chart rather than an error. ### Breaking — market addresses and hashes are `Address` / `Hex`, not `string` Every address and hash on `Market` (and its `SpotMarket` / `PerpMarket` / `BinaryMarket` variants) is now typed with viem's `Address` or `Hex` instead of `string`: - **`Address`** — `poolAddress`, `baseToken`, `quoteToken`, `stopRegistry`, `marginBank`, `marketAddress`, `collateral`, `creator` - **`Hex`** — `marketId`, `createdByTx`, `venueId`, `context` The live-book types follow for the same reason — a field fed from a typed source but declared `string` widens it straight back and keeps the casts this change exists to remove: - `Tradable.pool` (always `market.poolAddress`) - `LiveFill.pool` / `.maker` / `.taker`, `LiveOrder.pool` / `.owner` - `DecodedEvent.address` (viem already types the log source; the SDK was casting the type away and then widening it with `.toLowerCase()`) **Lookup-key parameters stay `string`** and are not part of this change: `getLiveFills(pool, …)`, `getLiveMarketByPool(pool)`, `getLiveSpotOrderBook(pool, …)` and the other live reads take a pool address as a map KEY, which they lowercase before lookup. Tightening those would break callers holding a plain string for no safety gain — the value is being matched, not carried. ```ts // BEFORE — cast at every use await client.getBinaryOrderBook(market.poolAddress as `0x${string}`); await client.getMarketOnchain(market.marketAddress as Address); // AFTER — the type is already right await client.getBinaryOrderBook(market.poolAddress); await client.getMarketOnchain(market.marketAddress); ``` Most code needs no change at all. Existing `as Address` casts keep compiling (now no-ops), and reading a field into a `string` still works, because `Address` *is* a `0x`-prefixed string. What breaks is only the reverse direction — assigning a plain `string` INTO one of these fields, e.g. building a `Market`-shaped object from untyped data: ```ts const m: SpotMarket = { ...rest, poolAddress: someString }; // now an error const m: SpotMarket = { ...rest, poolAddress: someString as Address }; // fix ``` Values are unchanged: still lowercase, exactly as the indexer stores them. viem's `getAddress` is deliberately not used — it returns EIP-55 checksummed addresses, and the SDK's own store keys its pool/market lookup maps on the lowercase form. `Address` is a template-literal type that lowercase satisfies, so nothing is normalized at runtime and there is no per-row cost. Not retyped, because they only look hex-ish: `yesTokenId`, `noTokenId`, `strike` and `nonce` are **decimal** uint256 strings, and `id` is a bytes32 for binary markets but a pool address for spot/perp. ### Breaking — the viem escape hatch is explicit, and undecorated `SomniaMarketsClient.publicClient` is replaced by `getViemClient()`. The property was typed `PublicClient` and named `publicClient`, but it was the client the SDK had **decorated** — `readContract` / `call` rethrow as typed SDK errors. So a consumer reading their **own** contract through it lost viem's error types silently: `catch (e) { if (e instanceof ContractFunctionRevertedError) … }` simply stopped matching, no error, no warning. Worse on a foreign contract, where the decoder can't match the selector and produces a `ContractRevertError` with `errorName: undefined` — viem's typed error traded for nothing. `getViemClient()` returns the **undecorated** client, over the same WebSocket (no second connection). Reads through it keep viem's error contract. Everything reachable from the client interface still uses the decorated one, so protocol reverts arrive decoded as before. ```diff - await client.publicClient.getBalance({ address }) + await client.getViemClient().getBalance({ address }) ``` A method rather than a property, so reaching outside the SDK's error contract is a visible act — and because the call opens the socket, which a field read hid. ### Breaking — `createLend` is no longer exported `client.lend` (backed by `config.addresses.lend`) is the only entry to the lend surface. The factory took a whole `SomniaMarketsClient` to use two of its members, and let one chain's addresses be grafted onto another chain's socket — `createLend(mainnetClient, SOMNIA_TESTNET_LEND)` type-checked and silently read nothing, which the `*_MAINNET_*` / `*_TESTNET_*` constants make an easy mistake. A different deployment means a different client: ```diff - const lend = createLend(exchange.client, SOMNIA_MAINNET_LEND); + const exchange = new SomniaMarkets({ chain, wsRpcUrl, addresses: { lend: SOMNIA_MAINNET_LEND } }); + const lend = exchange.client.lend; ``` `@somnia-chain/markets-sdk/lend` still publishes the types, `SomniaLendClient`, both deployment constants, the ray-math helpers and the ABIs — only the factory is gone. ### Breaking — three-identifier reads take one params object Six methods keyed on three positional identifiers. All the perp/vault fields are `Address`, so any two swapped still compiled — and two siblings even ordered the **same** triple differently (`getPerpPosition(marginBank, account, pool)` vs `getLiquidationPrice(marginBank, pool, account)`), making the silent swap the easy mistake rather than the freak one. Each now takes a single object; the field names carry the order. On `SomniaMarketsClient`: ```diff - client.getPerpPosition(marginBank, account, pool) - client.getLiquidationPrice(marginBank, pool, account) + client.getPerpPosition({ marginBank, account, pool }) // PerpPositionRef + client.getLiquidationPrice({ marginBank, account, pool }) // PerpPositionRef (same shape, same order) - client.getVaultBalance(vault, owner, token) + client.getVaultBalance({ vault, owner, token }) // GetVaultBalanceParams - client.getOutcomeBalance(outcomeToken, account, id) + client.getOutcomeBalance({ outcomeToken, account, id }) // GetOutcomeBalanceParams - client.getBuilderApproval(pool, user, builder) - client.getEffectiveBuilderApproval(pool, user, builder) + client.getBuilderApproval({ pool, user, builder }) // BuilderApprovalRef + client.getEffectiveBuilderApproval({ pool, user, builder }) // BuilderApprovalRef ``` `Trader.getBuilderApproval` / `Trader.getEffectiveBuilderApproval` change the same way. The param types are exported from the package root. ### Changed — input/config failures throw the typed classes everywhere The last ten `throw new Error(...)` sites in the SDK now throw the documented classes — `InvalidInputError` (stop-order validation, the `quote*` methods' `{pool | marketId}` target), `NotConfiguredError` (missing `config.addresses.lend` entries), `ContractRevertError` (a lend write mined but reverted), and `RpcError` (`createStopOrder` receipt missing `PendingOrderCreated`). Messages are unchanged; only the classes (and their fields) are new. Code that caught plain `Error` still works — every class extends it. ## 0.22.0 (2026-08-05) `getPortfolio` now carries the binary contract's series cadence on every active position and open order, so a Positions / Trade History row can show whether a contract is a 15m / 1h / 4h / 24h event. ### Added - `PortfolioMarket.intervalSec` (raw seconds) + `PortfolioMarket.interval` (the derived `"15m"`/`"1h"`/… label), populated on `portfolio.positions[].market` and `portfolio.openOrders[].market`. `portfolio.trades[].market.interval` and `BinaryMarket.interval` already carried it — this closes the gap on active positions/orders. Additive; no breaking changes. ## 0.21.0 (2026-08-05) The typed error tier, and indexer reads regenerated from the schema the indexer actually serves. ### Added — the typed error tier Every SDK failure now has a class: `SomniaMarketsError` and its six subclasses (`InvalidInputError`, `NotConfiguredError`, `SignerRequiredError`, `IndexerError`, `RpcError`, `ContractRevertError`), exported from the package root. `ContractRevertError` decodes revert data against the protocol's custom errors (the generated `contractErrorsAbi`, kept current by the offline `errors:check` CI gate), so a failed call can report its Solidity error name. Pure addition in this release — the SDK's own call sites adopt the classes in the follow-up refactor; nothing thrown today changes class. Indexer reads are now typed against the GraphQL schema the indexer actually serves, instead of hand-written types kept in sync by memory. Internal change — the exported type surface, its TSDoc, and every method signature are unchanged apart from the nullability corrections below. ### Notes — why the indexer types are generated Queries were template strings with self-declared result types, so both halves could drift silently: a query could select a field Hasura no longer had (throws on every call), and a type could promise a field the wire never carried (`tsc` green, consumer reads `undefined`). `0.16.0` shipped both at once. A committed snapshot of the served schema now drives generation, so a renamed, removed, or retyped field fails `pnpm gql:codegen` / `pnpm typecheck` in the same PR that changes the schema. Public types stay hand-written; the mapping between wire and public is compiler-checked. ### Breaking — types corrected to match what the indexer actually returns Each of these promised non-null on a column the indexer genuinely leaves unset: `indexer/schema.graphql` declares them nullable, and the handlers carry `prior?.` forward, so an event arriving before the row's creation event leaves them empty. - `IndexerSyncStatus.numEventsProcessed` → `number | null` - `IndexedOracleAdapter.createdAtTimestamp` → `string | null` - `IndexedMarketCreator.createdAtTimestamp` / `.factory` → nullable; `.createdAtBlock` → `number | null` - `IndexedSeries.createdAtTimestamp` / `.updatedAtTimestamp` → `string | null` Migration: handle `null` where you read these (usually `?? "—"` at the render site). If you formatted them as timestamps, you were rendering January 1970 for the absent case. ### Notes - `schema:pull` now refuses to run against a Hasura that has not finished being configured. envio creates relationships ~25s after it starts tracking tables, and a snapshot pulled in that window is silently missing every relationship field — which then validates cleanly against every offline check. ## 0.20.0 (2026-08-04) **First public npm release.** The package now publishes to the public npm registry (`registry.npmjs.org`) — install is just `pnpm add @somnia-chain/markets-sdk viem`, no GitHub Packages registry config or token. Versions ≤ 0.19.0 remain on GitHub Packages. ### Breaking — token symbols preserve case - **Token symbols preserve case.** `sanitizePart` and `loadMarkets` no longer uppercase ERC-20 `symbol()` reads. Venue token symbols are mixed-case identities (`USDso`, `USDC.e`) and consumers key on them verbatim, so forcing uppercase was silently breaking lookups. If you persisted symbol strings from an earlier SDK version (e.g. `"SOMI/USDSO"`), they will no longer match the registry (`"SOMI/USDso"`) — re-derive stored symbols from `loadMarkets()` after upgrading. Symbols that were already all-uppercase are unaffected. ### Added — baked-in per-chain addresses New `SOMNIA_TESTNET_ADDRESSES` / `SOMNIA_MAINNET_ADDRESSES` constants — the full `SomniaMarketsAddresses` map per chain (including the SomniaLend wiring), generated from the canonical deployment manifests at release time (`pnpm gen:addresses` → `src/addresses.ts`). External consumers get a zero-setup `config.addresses` without the monorepo's private deployments hub. ### Added — book-clamped PnL marks PnL helpers used to mark unresolved positions to `lastPrice` alone. On a one-sided book that freezes the mark at a stale print — we saw a deep-ITM position showing +7.4% uPnL when it was really down 60%, because the losing side's makers had pulled their quotes and only a far-side bid remained. - **`markYesPrice(top, lastPrice)`** (new, exported): returns the two-sided mid, or the last trade clamped into the surviving side's bound. A resting quote beyond the last print is live, executable information and supersedes it; a last print inside the bound still wins (so a bid-ask spread doesn't flash as a loss right after a taker clears the top of the book). - `computePositionPnL` and `computeBinaryPnl` accept an optional **`opts.bookTop`** (`YesBookTop`, best YES bid/ask) and mark with the clamped price. Omit it and behaviour is unchanged (mark to `lastPrice`). - `client.getBinaryPositionPnL` now fetches top-of-book alongside the indexer fan-out (one extra `eth_call`) and passes it through. An indexer-only client or a failed read falls back to `lastPrice` alone — no breaking change for existing callers. - `BinaryPnl` legs (now named **`BinaryOutcomePnl`**) additionally report **`avgCost`**, **`mark`**, and **`value`**, so a per-leg positions UI can render entry/mark/value/uPnL% straight from the SDK instead of hand-rolling the fold. - **`binaryFillsFromPortfolio(trades, decimals)`** (new): derive `BinaryPnlFill`s from one market's slice of `getPortfolio().trades`, which already carries the account's own side per fill. - The unified `markYesPrice` replaces the simpler mid-or-last version that shipped unreleased with the presentation tier. Same name, now `(top: YesBookTop, lastPrice)` with the one-sided clamp, exported from the barrel. `midYesPrice` (odds display) is unchanged. ### Added — the unified presentation tier A unified exchange facade (`SomniaMarkets`) for presentation apps — the surface a frontend needs to render tickers, order books, and account state without reaching into the low-level client. - **`fetchTicker`**: ticker snapshots (last price, bid/ask, 24h volume). - **`fetchOrders`**: open and historical orders with a unified shape. - **Stop orders**: place and track stop orders through the same facade. - **Portfolio analytics**: `getPortfolio()` returns trades and positions with enough context to compute per-market PnL without extra calls. - **`takerIsBid`** on live fills: know which side of the book a fill took liquidity from. - **`txHash`** on `UnifiedTrade` and `UnifiedOrder`: link trades and orders back to their on-chain transaction. ### Added — stake-sized binary quotes - **`quoteBinaryStake`**: get a buy quote sized by stake (the amount you want to spend) rather than by quantity. - **`quoteBinarySell`**: get a sell quote that walks the crossable bids — like the buy side walks the asks — so a thin book surfaces as a partial unwind up front instead of a silent IOC cancel. - `BinarySellQuote` gains **`fillableQuantity`** and **`estProceeds`**: see how much of your position the book can actually absorb and what you'd get for it before you submit. ## 0.19.0 (2026-08-03) **Market timeframe served with markets & trade history** — the series cadence a binary market trades on (15m / 1h / 4h / 24h) is now a ready-to-render label on every market AND every trade-history row, so consumers stop re-deriving `expiry − tradingStart` and hand-formatting it. ### Added - **`BinaryMarket.interval`** — a new derived field on every market the SDK returns (all list + point reads flow through it): the timeframe label (`"15m"` / `"1h"` / `"4h"` / `"24h"`), computed from `intervalSec` (falling back to `expiry − tradingStart`). The label uses the largest unit up to hours that divides the cadence cleanly, so a 10-minute market reads `"10m"`. `null` on SPOT/PERP. - **Trade history carries the market's timeframe.** `FillRow` (from `getFills` / `getUserFills`) gains a joined **`market`** context — `{ asset, intervalSec, interval, tradingStart, expiry }` (new `FillMarketContext` type) — so a trade row can show which timeframe the order was for without a second query. `PortfolioTrade.market` (from `getPortfolio`) likewise gains `intervalSec`, `interval`, `tradingStart`, `expiry`. - **New canonical cadence helpers** (exported from the barrel): `resolveIntervalSec`, `snapIntervalSec`, `formatIntervalLabel`, `marketIntervalLabel`, and the `IntervalSource` type — the single `intervalSec → "15m"` mapping the explorer and other UIs now share instead of each re-implementing it. ## 0.18.0 (2026-08-03) **SomniaLend integration** — the SDK now wraps the third-party SomniaLend money market (an Aave v3.0 fork on Somnia mainnet 5031 + testnet 50312) so trading capital can earn while idle: supply USDso between sessions, post collateral, borrow working capital against it. ### Added - **New `client.lend` namespace** on `SomniaMarketsClient`: `lend.listReserves()` (every listed asset — config, caps, live ray rates, indexes, liquidity, oracle price, one aggregated eth_call), `lend.getAccount(address)` (health factor, borrowing power, and every non-empty position, balances accrued to head with Aave's own interest math), and `lend.createLender(signer)` — the write surface (`supply` / `withdraw` / `borrow` / `repay` / `setUseAsCollateral` plus native-SOMI gateway variants `supplyNative` / `withdrawNative` / `borrowNative` / `repayNative`). Auto-approval follows the trader doctrine (one allowance read, `maxUint256` grant, in-memory cache); `borrowNative` additionally auto-delegates credit on the WSOMI variable-debt token. Variable rate only. - **New subpath entry `@somnia-chain/markets-sdk/lend`** — the same module standalone: `createLend(client, addresses)`, all types, the ray-math helpers (`lendRayRateToApy`, `rayMul`, `accrueLinear`, `accrueCompounded`, `RAY`), and the verified minimal ABIs. - **`addresses.lend?: LendAddresses`** on `ClientConfig` wires the deployment; the published addresses ship as `SOMNIA_MAINNET_LEND` / `SOMNIA_TESTNET_LEND` (NOT in the deployments manifests — SomniaLend is third-party; the testnet addresses are undocumented upstream, extracted from the official app's testnet mode and verified on-chain). Lend methods throw a clear error when the address they need is unset. - **React**: `useLendReserves()` / `useLendAccount(address)` in `@somnia-chain/markets-sdk/react`. - Docs: `docs/LEND.md` guide; ABI shapes pinned against the verified deployed contracts (UiPoolDataProviderV3's v3.0 54-field reserve tuple — do not hand-edit). ## 0.17.0 (2026-07-29) Two related price-feed changes: reads are pinned to a **quote asset**, and the feed's **freshness surface** becomes readable. ### Changed — quote pinning The feed publishes more than one pair per base — `BTC/USDC` and `BTC/USDT` both carry `base: "BTC"` — so `base` alone stopped being a unique feed key and every read matched two rows. The oracle has migrated to USDC: the USDC rows are live, the USDT rows froze on 2026-07-21, and they have since drifted ~5% apart. `Feed(where: {base})` returned both and the SDK took `[0]`, so the current price was a coin-flip between a live value and a week-stale one. - `PriceFeedConfig` gains an optional **`quote`** (case-insensitive, e.g. `"USDC"`). When set, every read — snapshot, feed info, history, candles, the catalog, and both live subscriptions — adds a `quote: {_eq}` clause, so a base resolves to exactly one feed. `$quote` is passed as a GraphQL variable, never interpolated. - `SOMNIA_TESTNET_PRICE_FEED` is now pinned to **`quote: "USDC"`**. - Leaving `quote` unset preserves the old unfiltered behaviour (correct only where each base has a single quote). Beyond the wrong current price, an unpinned multi-quote base merged two series into one candle response, producing duplicate `bucketStart` values — a hard error in charting libraries that require strictly ascending, unique timestamps (observed at `H1` and `D1`; `M1` windows are currently short enough to miss it). **Behaviour change:** an unfiltered `listPriceFeeds()` against the testnet feed no longer returns bases that lack a USDC pair — today that is `BCH` (USDT-only), so the catalog goes 31 → 30 rows. Pass `quote: undefined` to opt out. ### Added — freshness The SDK previously selected no timestamp beyond the block, so a consumer could not distinguish a 1-second-old price from a day-old one — and since a stalled feed simply stops pushing, a live subscription looks identical to a healthy one. On 2026-07-28 `SOMI/USDC` was 26.8h stale while every consumer reported it live. - `PriceFeedInfo` gains **`updatedAtMs`** (when the oracle last wrote the feed), **`sourceUpdatedAtMs`** (when the underlying market data was timestamped), and **`resynced`**. All unix **milliseconds**, null when unknown. - New **`useLivePriceFeedInfo(asset)`** hook — `getLivePriceFeedInfo` already existed on the client but had no reactive React binding. Comparing the two timestamps separates the two distinct failures: a large `updatedAtMs - sourceUpdatedAtMs` gap means the oracle is still writing but with stale source data, whereas a growing `updatedAtMs` age means it stopped writing. Both fields ride the shared selection set, so they populate from the snapshot **and** the live `Feed` subscription. Note that neither re-renders as a price ages: age must be computed against a local clock on a timer, because a stalled asset delivers no event to react to. ## 0.16.0 (2026-07-24) `listBuilderApprovals` / `BuilderApproval` reconciled with the indexer entity, plus follow-ups from the docs pass. ### Breaking — `listBuilderApprovals` matches the indexer entity The old query selected `pool` and `updatedAt` and ordered by `updatedAt`, none of which exist on the `BuilderApproval` entity — every call threw `field 'updatedAt' not found in type: 'BuilderApproval_order_by'` against a live indexer. - `BuilderApproval.updatedAt` → **`timestamp`** (unix seconds of the last `BuilderApproved` upsert; also the sort key, newest first). - New fields mirroring the entity: **`market`** (market id), **`blockNumber`**, **`txHash`**. `pool` is kept, now joined via the market row. - Migration: `approval.updatedAt` → `approval.timestamp`; everything else is additive. ### Changed — follow-ups from the docs pass - **`exchange.fetchStatus()` gains `"connecting"`** (union widening): a watch whose WS handshake hasn't delivered a head yet reports `"connecting"` instead of a false `"error"` — `"error"` now means a previously-live socket was LOST. Callers switching exhaustively on `status` must handle the new member. - `claimableFrom` now enforces the lowercased `pool` its result type documents (previously true only via the indexer wiring). - Docs: `RegisterSeriesParams.asset` / `SeriesOnchain.asset` corrected to a plain display ticker (`"BTC"`, not `"BTC/USDT"`) per the MarketCreator natspec — it must match the source exchanges' spot listing for candle sources; `binaryPoolImpl` doc no longer claims it is unread (the explorer renders it). - Dead code: unused `PortfolioTrade` import (exchange.ts) and unused `resolved` local (derivedReads.ts) removed. ## 0.15.0 (2026-07-21) A1 — resolution surplus refunded to the reserve-PAYER (the market creator) instead of the operator, and the autonomous MarketCreator self-reclaims its own surplus. Additive to the 0.14.0 OracleHub surface (no breaking changes). ### Added — OracleHub payer credit - **ABI** (`machineryAbi.ts`): `payerCreditOf(address)`, `payerOf(bytes32)`, `withdrawMyCredit(uint256,address)`; events `PayerSurplusCredited(address indexed payer, bytes32 indexed marketId, uint256)` + `PayerCreditWithdrawn(address indexed payer, address indexed to, uint256)`. - **Reads**: `client.payerCreditOf(payer)`, `client.payerOf(marketId)`. - **Write**: `createOracleHubAdmin().withdrawMyCredit({ amountWei, to })` — msg.sender-gated (the connected signer draws only its own accrued payer surplus). `WithdrawMyCreditParams`. ### Added — MarketCreator self-reclaim + migration - **ABI**: `reclaimOracleCredit()`, `armFirstRoll(uint32,uint256)`, plus reads `firstRollArmed`/`latestExpiryBySeriesId`/`armedBoundary`/`marketCount` and `withdrawNative`/`cancelSubscription`. - **Admin**: `createMarketCreatorAdmin().reclaimOracleCredit({ creator })` (manual sweep of the leftover surplus; runs automatically each roll cycle on-chain) and `.armFirstRoll({ creator, seriesId, firesAtSec })` (deferred first roll for a seamless MarketCreator migration — start the new creator exactly at the old market's expiry). `ReclaimOracleCreditParams` / `ArmFirstRollParams`. ## 0.14.0 (2026-07-20) Oracle v2 + Settlement v3 for the binary CLOB, plus the operator "market machinery" management layer. This entry consolidates ALL work since 0.13.0 — the branch-internal 0.15–0.18.x iterations (escrow → prepaid → earmark) were never released, so only the final state is described here. BREAKING for the OracleHub surface and the binary settlement/resolution reads. ### Breaking — Oracle v2: earmark-at-creation resolution funding - Funding is now EARMARK-AT-CREATION: the per-market resolution reserve is attached to the market-creation value and LOCKED per-market at `onBind` (never withdrawable while the market is live). At resolution the exact metered gas cost is charged against the earmark and the surplus (`reserve − charged`) is credited to the operator's WITHDRAWABLE credit. No prepaid pool, no per-bind escrow. Bounded-drain resolution (batched callback + self-armed `Schedule` continuation) + content-addressed question dedup. - **OracleHub ABI** (`machineryAbi.ts`): `earmarkedOf`/`creditOf`/`outstandingOf`/ `withdrawableOf(uint32)`, `resolveReserve()`, `reservedFor(bytes32)`, `operatorOf(bytes32)`, `marketsForQuestion`, `pendingResolves`, `continuationSubId`, `setDrainParams`. `withdraw(uint32,uint256,address)` is credit-only. The prepaid/escrow surface is removed. - **Events**: `ReserveEarmarked`, `SurplusCredited`, `CreditWithdrawn`, `MarketBound`, `MarketResolveCharged`, `AnswerDelivered`, `CallbackAccounted`, `DrainContinuation` (indexed-ness byte-for-byte with `OracleHub.sol`). - **`quoteCreateMarketValue(def)` = `getSchedulingCost(def) + resolveReserve()`** (both attached to the create; excess refunded). - **`syncSettlement(marketId)`** (module write): permissionless earmark reconcile for a market voided via `BinaryMarket.voidExpired()` (which bypasses the module, so the hub's earmark release never fires). Idempotent; reverts `MarketNotSettled` while still live. - **Indexer reads** (`query.ts`, matching `indexer/schema.graphql`): `OperatorHubAccountRecord` (`earmarked`/`credit`/`outstanding`), `getOperatorHubAccount`/`listOperatorHubAccounts`; reshaped `OracleBindRecord`/`OracleCallbackRecord`. `preflight.ts` gates on the full create value. Client surface (`oracleHub.ts`/`createClient.ts`/`somniaMarketsClient.ts`) follows. ### Breaking — Settlement v3: payout vectors - Binary markets settle to a payout VECTOR (`payoutNumerators`, denominator 10_000_000); redemption pays `amount × num[idx] / D` — one formula for win / loss / void (a losing redeem pays 0 without reverting). Reusable pools + a permanent `BinarySettlement` singleton. - **`getSettlement`** (`readsAbi.ts`) returns `(…, uint256[] payoutNumerators)` — removed the `uint8 winningOutcome` slot. `SettlementRecord` exposes `payoutNumerators` + a derived `winningOutcome`. - **`winningOutcome()` was REMOVED from BinaryMarket** — the SDK derives the winner as the argmax of `payoutNumerators` in `getMarketOnchain`, the `redeem()` auto-winner lookup, and the `Resolved(uint32 payoutDenominator, uint256[] payoutNumerators)` live-tail decode. ### Added — the operator "market machinery" management layer - Machinery admins (same signer doctrine as `createOperatorAdmin`): `createOracleAdapterAdmin` (create/fund/enableReactivity/gas params + adapter status), `createGovernanceAdmin` (`setAdapterApproved`, module-owner gating), `createMarketCreatorAdmin` (create/fund/registerSeries/updateSeries/triggerRoll/gas params + creator & series reads). - Indexer machinery reads (`listMarketCreators`/`getMarketCreator`/`listOracleAdapters`/ `getOracleAdapter`/`listSeries` + `Indexed*` mirrors), the `MarketTypePlugin` registry (fee-codec + machinery step descriptor keyed off the bytes4 `marketType`), and per-step preflight validators. - Deployments hub + SDK config gain `marketCreatorFactory`/`oracleAdapterFactory`/ `sharedOracleAdapter` (all optional, degrade cleanly when unset). ## 0.13.0 (2026-07-18) Settlement-extraction v2 — the binary release. A BinaryPool is no longer the permanent redemption custodian: on finalize its backing + resolution snapshot sweep to the ONE `BinarySettlement` singleton (the redemption home, forever), and the pool is recycled onto the next market — the same pool address serves SUCCESSIVE markets. This release also lands the full trader write surface, the pool-reuse / binding reads, the recycle-safe live order book, and the derived analytics bundle a frontend needs for a full-lifecycle up/down prediction-market product. Requires a v2 deployment (BinarySettlement + v2 pool impl + v2 OutcomeToken6909) and the WS5 indexer schema. Supersedes the 0.12.x binary surface; carries all of `main` through 0.12.3 (price-feed `PriceFeedScheduler` realignment + `PricePoint.requestId`). ### Breaking - **Outcome-id encoding changed** — v2 wedges the pool's per-market `nonce` between the pool address and the outcome index: `id = (uint160(pool) << 72) | (nonce << 8) | idx`; `marketKey = id >> 8 = (pool << 64) | nonce` keys settlement records. The old `outcomeIdFor(pool, idx)` (`pool << 8 | idx`) is REMOVED — use the new exported helpers `outcomeId(pool, nonce, idx)` / `decodeOutcomeId(id)` / `marketKey(outcomeId)` from the package root. Any cached v1 ids are invalid. - **`kindOf(isBid, userData)` is REMOVED** — v2 stopped encoding the YES/NO side in `userData` (it is opaque market-maker bookkeeping now, forwarded verbatim). The side comes from the pool's new `BinaryOrderPlaced(orderId, kind)` event; map the enum with the new `sideOfKind(kind)` / `ORDER_KIND_SIDE`. Never decode `userData`. - **`getMarketOnchain(marketId)` replaces `getMarketOnchain(marketAddress)`** — market identity is the module's bytes32 `marketId` (pools/market contracts are recycled/per-market). Resolves through `BinaryMarketsModule.markets(marketId)`; requires `addresses.binaryModule`. A 20-byte address argument throws loudly. The result gains `marketAddress` / `nonce` / `finalized`, and `backing` falls back to the settlement record's NET backing once finalized (the pool-side `market.backing()` reads 0 from then on). - **`Trader.redeem` routes through the module, keyed by `marketId`** — `RedeemParams.marketId` (bytes32) is required; `market` (address) is now only an optional lookup aid for `outcomeIdx`/`outcomeToken`. The module pulls the winning tokens under an ERC-6909 operator grant to the MODULE (auto-approved), finalizes-if-needed, and redeems via settlement. The v1 pool `redeem` no longer exists on-chain. - **Pool write ABI**: `placeOrder` → `placeBinaryOrder(kind, price, quantity, expireTimestampNs, orderType, selfMatchingOption, builder, builderFeeBpsTimes1k, userData)` (+`placeBinaryOrderFor`). The generic `placeOrder`/`placeOrderFor`/`amendOrder` REVERT (`UseBinaryPlacement`) on binary pools. `redeem` is gone from `binaryPoolWriteAbi`. - **Order expiry must satisfy `0 < expireNs ≤ pool.marketExpiryNs`** — the pool rejects never-expiring / beyond-market orders (`OrderExpiryBeyondMarket`). `Trader.placeOrder` now DEFAULTS the expiry to the market's expiry (one `marketExpiryNs` read) instead of ~50y; an explicit `expireTimestampNs` is forwarded verbatim (no silent clamping). - **Live-tail events**: the pool `Redeemed` / `SettlementFeeCharged` events no longer exist (redemption + the one-time fee skim live on the settlement singleton). New events consumed: pool `BinaryOrderPlaced` / `PoolFinalized` / `PoolRecycled`; module `MarketFinalized` / `PoolReleased`; settlement `MarketFinalized` / `SettlementFeeCharged` / `Redeemed` / `PayoutOwed` / `OwedClaimed`. The module `MarketCreated` gained a `nonce` field. - **Pool address is a TIME-VARYING market binding** — never key a market by pool address. `getMarketByPool` now returns the pool's NEWEST (current) market and documents the caveat; `BinaryMarket` rows expose `nonce` for disambiguation. ### Added **Settlement + redemption** - **Trader methods**: `redeemDirect({ outcomeId, amount, to? })` (settlement redemption by raw id), `claimOwed({ token })` (push-fallback pull), `finalizeMarket({ marketId })` + `releasePool({ marketId })` (permissionless keeper entries), `getSettlement(marketId)` → `SettlementRecord | null`. - **`trader.signRedeemAuth(params)` + `trader.redeemFor(params)`** — the relayed (gasless) redeem pair. `signRedeemAuth` has the position OWNER sign an EIP-712 `RedeemAuthorization` over the module's `REDEEM_AUTH_TYPEHASH` in the `SomniaMarkets`/`1` domain (`verifyingContract` = the `binaryModule`); no tx is sent. A relayer then submits it via `redeemFor` — they pay the gas, the module pins the payout to `owner` (never the relayer). New types `RedeemAuthorization`, `SignRedeemAuthParams`, `RedeemForParams`. - **Config**: `addresses.binarySettlement` (and `@somnia-chain/deployments` maps the manifest's `BinarySettlement` proxy key onto it). **Pool reuse / bindings** - **`client.getPoolBindings(pool)` → `PoolBindingRecord[]`** — a pool's full pool→market binding history from the indexer (WS5 `PoolBinding`; newest nonce first; `toBlock === null` marks the current binding; `closedBy` is `"Released" | "Rotated"`). - **`client.getPool(address)` → `IndexedPool | null`** — the indexer's per-pool aggregate (creator, collateral, `currentMarketId`, `currentNonce`, `generationCount`). - **`client.getPoolCreator(pool)` / `client.getFreePools(creator, collateral)`** — the chain reads previously only reachable through the signer-bearing trader, now on the unsigned client tier (an unconnected explorer can render them). Standalone `getPoolCreator` / `getFreePools` are exported from the package root too; the Trader methods (`poolCreator(pool)`, `getFreePools(creator, collateral)`) remain. Pool "sponsor" is uniformly "creator" across the SDK, matching the on-chain `poolCreator()` view and the indexer `Pool.creator` field. - **`"Finalized"` in `BinaryMarketStatus`** — the indexer's `ClobMarketStatus` terminal state (set when the market's backing + resolution sweep to the BinarySettlement singleton; supersedes Resolved/Voided). Flows through every `status` filter (`listBinaryMarkets` / `listLiveBinaryMarkets` / `listPastBinaryMarkets` / `countBinaryMarkets`). The live-tail reducer now also sets it on the module/settlement `MarketFinalized` events. The on-chain `BINARY_MARKET_STATUS` index map is deliberately unchanged (no on-chain enum member exists). **Trader writes** - **`trader.reduceOrder(params)`** — shrink a resting order's remaining quantity IN PLACE, keeping its price-time queue priority (unlike an amend, which re-queues at the back). Works on spot AND binary pools — `BinaryPool` implements the `_onOrderReduced` → `_refundPartial` hook, so the freed escrow returns to the owner. New `ReduceOrderParams`; new `reduceOrder` entry on `binaryPoolWriteAbi`. - **`trader.cancelExpiredOrders(params)` / `trader.sweepExpiredAtLevel(params)`** — the permissionless keeper drains for the resting book (inherited from the OrderBook base, callable by anyone on a binary pool). `cancelExpiredOrders` cleans an explicit list of expired ids; `sweepExpiredAtLevel` walks one price level from the best order cleaning up to `maxCount`. Each returns locked escrow to the order owner (best-effort — non-expired / stale entries are skipped on-chain). New `CancelExpiredOrdersParams`, `SweepExpiredAtLevelParams`; new `cancelExpiredOrders` / `sweepExpiredAtLevel` entries on `binaryPoolWriteAbi`. - **`PlaceOrderParams.userData?: bigint`** — opaque MM bookkeeping tag, default `0n`, forwarded verbatim (the SDK never sets or interprets it). **Live order book (recycle-safe)** - **`store.bookLevels(pool)` filters by the pool's CURRENT `market_id`, structurally.** A `BinaryPool` is recycled across markets (one pool serves successive markets, never concurrently). The live book now requires `o.market_id` to equal the pool's current binding (`marketByPool(pool)?.id`), and returns an EMPTY book when the pool has no current binding — the exclusion of a prior market's orders is now structural, not reliant on expiry timing. - **`client.getLiveBinaryOrderBookByMarket(marketId, { depth? })`** + the **`useLiveBinaryOrderBookByMarket`** hook — resolve a binary book by `marketId` rather than pool address. If `marketId` is no longer the pool's current binding (stale/ended), returns an EMPTY book so a stale page can't render the successor market's orders. Backed by the new `store.bookLevelsByMarket`. **Reads & analytics (derived; no new indexer field)** - **`client.quoteBinaryOrder({ pool | marketId, side, quantity, depth? })`** — a market-order preview over the live book (`{ avgPrice, cost, filledQuantity, wouldRest, levelsConsumed, slippageVsMid }`). BUY consumes asks, SELL consumes bids, respecting the YES/NO price inversion. Also exported as the kernel `quoteBinaryOrderOverBook`. New type `BinaryOrderQuote`. - **`client.getMarketStats24h({ pool | marketId })`** — trailing-24h `{ volume24h, trades24h, priceChange24h, high24h, low24h, openPrice24h }` summed from 1h candle buckets. Kernel `marketStats24hFromCandles`; new type `MarketStats24h`. - **`BinaryMarketFilter.orderBy`** (`"newest" | "closingSoon" | "volume" | "tradeCount"`) threaded into `listBinaryMarkets` + `listLiveBinaryMarkets` as the Hasura `order_by` (server-side). `listBinaryMarkets` still defaults to newest, `listLiveBinaryMarkets` to closingSoon; an explicit `orderBy` overrides. New type `BinaryMarketOrderBy`. - **`client.getBinaryPositionPnL(account, marketId)`** — avg-cost position PnL (`{ balanceYes, balanceNo, costBasis, avgCost, markValue, unrealizedPnl, realizedPnl }`, RAW units) reconstructed from the account's order-book fills folded with complete-set mints/merges, marked to `lastPrice` (or the settlement payout once resolved). Kernels `pnlEventsFor` + `computePositionPnL`; new types `BinaryPositionPnL`, `PnLEvent`. - **`client.getClaimable(account)`** — redeemable positions across settled (resolved/voided) markets, each shaped to feed `trader.redeemMany({ entries })`: `{ marketId, pool, outcomeIdx, amount, estPayout, status }`. Winner payout skims the settlement fee; voided pays half both sides; losers omitted. Kernels `claimableFrom` + `estPayoutFor`; new types `ClaimablePosition`, `ClaimableInput`. - `RouterActionRecord` now surfaces the existing indexer `amount` field (each outcome's set size) so mint/merge cost basis folds in; `PortfolioMarket` now carries `id` (the bytes32 marketId). - **`getMarketResolution`** now returns **`openingAnswer`** (the reference-question oracle answer — a reference-mode market's OPENING price) and **`closingAnswer`** (its own resolution answer — the CLOSING price) alongside the outcome. `oracleAnswer` is kept as a deprecated alias of `closingAnswer`. Requires the deployment manifest to record `OracleCore` (its `AnswerPosted.numericValue` is the price) — the deploy script now writes it. - **`client.getOpeningPrices(marketIds)`** — batch opening (reference) prices for many markets in one pair of round-trips (map `marketId → raw numericValue`), for list views that show each up/down market's opening price without an N+1 fan-out. **Id helpers, ABIs, rows, live tail** - **Id helpers** (single source of truth, exported): `outcomeId(pool, nonce, idx)`, `decodeOutcomeId(id)`, `marketKey(outcomeId)`, types `DecodedOutcomeId` / `OutcomeIdx`. - **ABIs**: `binarySettlementAbi` (redeem / finalizeAndRedeem / finalize / claimOwed / getSettlement / isFinalized / owed / isPoolApproved / poolRegistrar / outcomeToken), `binaryModuleWriteAbi` / `binaryModuleReadAbi` (module redeem rails + finalizeMarket / releasePool + settlement / poolCreator / getFreePools / freePoolCount / marketNonce / markets), pool v2 reads on `binaryPoolReadAbi` (marketNonce / settlement / finalized / booksEmpty / marketExpiryNs / setBacking / getBinaryPoolParams), event ABIs `binaryPoolEventsAbi` / `binarySettlementEventsAbi`. - **`BinaryMarket` rows**: `nonce` / `finalized` / `netBacking` (WS5 indexer schema). `MarketOnchain`: `marketAddress` / `nonce` / `finalized`. - **Live tail**: watches the module + settlement whenever any market is watched; reducer implements the v2 binding model (`MarketCreated` opens/re-points a pool→market binding, `PoolReleased` closes it — order events attribute via the pool's CURRENT binding), takes sides from `BinaryOrderPlaced`, zeroes pool backing on `PoolFinalized`, and tracks the settlement-side `netBacking` via the settlement `MarketFinalized` / `Redeemed`. ### Migration 1. Regenerate/refresh the deployment manifest (v2 deploy adds `BinarySettlement`); `addresses.binarySettlement` flows through `@somnia-chain/deployments` automatically. 2. Replace `outcomeIdFor(pool, idx)` with `outcomeId(pool, nonce, idx)` — get the nonce from `BinaryMarket.nonce`, `MarketOnchain.nonce`, or `pool.marketNonce()`. Purge any cached v1 ids. 3. Replace `kindOf(isBid, userData)` with `sideOfKind(kind)` joined from `BinaryOrderPlaced` (indexer rows keep serving `side` precomputed). 4. `client.getMarketOnchain(...)`: pass the bytes32 `marketId` (from `listBinaryMarkets` / `BinaryMarket.marketId`), not the market address. 5. `trader.redeem(...)`: pass `marketId` (+ optionally `outcomeIdx` to skip a read). Native redemption (`redeemNative`) and complete-set methods are unchanged. 6. Market makers: tag orders with `userData` freely — it round-trips verbatim and appears on indexed orders; it no longer selects the book side. ## 0.12.3 (2026-07-17) Re-add `PricePoint.requestId` — the on-chain feed re-added `requestId` to `PriceUpdated` (as an indexed arg) and the indexer now exposes it again, so the SDK surfaces it once more. Additive; the field 0.12.2 dropped is back. ### Added - `PricePoint.requestId` (decimal string) — the Somnia-Agents batch request that produced a tick. One request prices every symbol in the tick, so all of a tick's rows share the same `requestId` (group by it for a whole batch / join to agent provenance). Read via `getPriceHistory` / the live tick tape. ## 0.12.2 (2026-07-17) Price-feed schema realignment — the price feed is now the on-chain `PriceFeedScheduler` (spot index + EMA mark) rather than the per-asset EMA oracles. The `Feed` / `PricePoint` / `Candle` reads and the live tail target the scheduler's fields. Requires the price-feed indexer at the PriceFeedScheduler schema (a full reindex — already live on dev). ### Changed - Price-feed GraphQL reads map the feed's new server fields onto the SDK's stable shape: `price` ← `spot` (median spot index), `ema` ← `mark` (the EMA-smoothed perpetual mark), `emaClose` ← `markClose`. The public `LivePrice` / `PricePoint` / `PriceCandle` field names are unchanged, so consumers need no code changes. ### Removed - `PricePoint.requestId` — the scheduler batches every symbol into one agent request, so there is no per-tick request id. ## 0.12.1 (2026-07-16) Docs-only release — no API, ABI, or behavior change. ### Docs - Completed guide coverage for 20 previously reference-only client methods: the batch price reads (`watchPrices` / `getLivePrices` / `fetchPrices`) + `isTailing` (PRICES), spot discovery (`listSpotMarkets` / `getSpotMarket`, SPOT), binary discovery (`listBinaryAssets` / `countBinaryMarkets`, BINARY), and the cross-cutting reads (`getBalances`, `getOutcomeBalance`, `getErc20Metadata`, `getErc20Allowance`, `getContractMeta`, `getMaxVenueFeeBps`, `getOrders`, `getUserFills`, `getMarketStatusHistory`, `countMarkets` / `countVenues` / `countOperators`, ENGINE). Every public method was already in the generated API reference; these are the narrative-guide additions. - Fixed three broken `{@link}` cross-references in TSDoc (`binaryFillsFor`, `computeBinaryPnl`, `listBuilderApprovals`) that rendered as dead links in the API reference. ## 0.12.0 (2026-07-16) Coverage-gaps wave — close the read/write/hook gaps against the coverage-gaps indexer schema (new perp-account, fee-stream, resolution, router, and vault-credit entities). Requires an indexer at that schema (a full reindex). ### Added - **Router action history** — `getRouterActions(account, opts?)` → `RouterActionRecord[]` (redeem / mint / merge, from the indexer `RouterActionRecord`). - **Resolution visibility** — `getMarketResolution(marketId)` → `{ events, reference, oracleAnswer }` joining `MarketResolutionEvent` / `MarketReferenceLink` / `OracleAnswer` (by `oracleQuestionId`). - **Fee-record streams** — `listProtocolFees` / `listBuilderFees` / `listSettlementFees` (the per-fill streams behind `getMarketFees`' running total; support a `payer` filter). - **Builder-approval directory** — `listBuilderApprovals({ user?, builder?, … })` → `BuilderApproval[]`, complementing the on-chain point read `getBuilderApproval`. `ApproveBuilderParams` is now exported. - **Markets-by-creator** — `BinaryMarketFilter.creator` (applied across `listBinaryMarkets` / `listLiveBinaryMarkets` / `listPastBinaryMarkets` / `countBinaryMarkets`). - **Vault credits** — `getVaultPayoutFallbacks(owner, opts?)` (append-only credit history), `client.getVaultBalance(vault, owner, token)` (live claimable, `ERC20Vault.getWithdrawableBalance`), and `trader.withdrawVault({ vault, token, amount })` (`ERC20Vault.withdraw`). - **Perp margin health + liquidation price** — `getMarginAccount` now also returns `imReq`/`mmReq`/`cmReq`/`marginStatus` (from `MarginBank.getAccountHealth` / `getMarginStatus`); new `client.getAccountHealth(marginBank, account)` and `client.getLiquidationPrice(marginBank, pool, account)`. `MarginStatus` / `MARGIN_STATUS` / `AccountHealth` are exported. The unified `fetchPositions` now populates `UnifiedPosition.liquidationPrice`. - **Perp/funding history reads** — `getFundingPayments`, `getMarginEvents`, `getLiquidations`, `getFundingRateHistory`, `getOpenInterestHistory` (the indexer's perp-account + funding/OI history). - **Lookups + pagination totals** — `getMarketByPool(pool)` (resolve a market by pool address), and `countOrders(owner, opts?)` / `countUserFills(account, opts?)` (history-page totals via the `_aggregate` fallback helper, now extended to `Order`/`Fill`). - **Unified balances** — `fetchBalance` now includes binary YES/NO ERC-6909 holdings (keyed by tradable symbol). - **Pure helpers + constants** — `CANDLE_INTERVALS` (in lockstep with `indexer/src/intervals.ts`), and `computeBinaryPnl(fills, balances, market)` / `binaryFillsFor(account, fills)` (avg-cost basis, no indexer/chain dependency). - **React hooks** (`@somnia-chain/markets-sdk/react`) — a generic `useIndexerQuery(fn, deps)` plus `usePortfolio`, `useMarkets`, `useCandles`, `useMarketFees`, `useOperators`, and the live-store `useLiveMarkets`. ## 0.11.1 (2026-07-16) ### Fixed - Count helpers (`countMarkets`/`countBinaryMarkets`/`countOperators`/`countVenues`) now fall back to a bounded row count when Hasura `_aggregate` is not exposed to the requesting role (public role, no admin-secret header) instead of throwing `field 'X_aggregate' not found`. The fast aggregate path still runs when the privileged header is present. Real query/network errors still surface. ## 0.11.0 (2026-07-16) Operator/venue + fee refactor follow-up — resync the SDK to the post-refactor contracts, deployment hub, and indexer schema. ### Added - **Per-venue collateral.** `SomniaMarketsAddresses` gains `collateral` (the per-venue collateral ERC-20). `testUsdc` remains as a legacy/fallback alias. `getSystemInfo`, `trader.faucet`, and collateral reads now resolve `collateral ?? testUsdc`, so hub-fed testnet clients (where the protocol `addresses.json` no longer carries TestUSDC) work correctly. - **Settlement-fee backing.** The live tail now consumes `SettlementFeeCharged(address indexed feeRecipient, uint256 winningBacking, uint256 fee)` and debits the market's `backing` running total, so the tail tracks on-chain `setBacking` after settlement instead of overstating it by the fee. - **Module-created market discovery.** `watchAllMarkets({ discover: true })` now also discovers markets created via `BinaryMarketsModule.createMarket` (the 19-field module `MarketCreated`), not just the `MarketCreator` rolling series. ### Fixed - `getSystemInfo.binaryMarketImpl` no longer falls back to the (different) `binaryPoolImpl` address when the live factory read fails. ### Notes - Addresses are provided entirely by `@somnia-chain/deployments` (the single source of truth). `SomniaMarketsAddresses` now carries `marketsCore` and `collateralRouter` first-class, so consumers feed the hub map straight into `new SomniaMarkets({ addresses })` with no hand-mapping. --- # /docs/typescript/tutorials/stream-a-live-order-book # Stream a live order book In this tutorial we install the SDK in an empty project, load the markets on the Somnia testnet, and read an order book and the latest trades. Then we follow the top of the book live for thirty seconds. At the end you will have a running script that prints a line each time the best bid or ask on `SOMI/USDso` changes. No wallet and no funds are needed. Everything in this tutorial reads public data. ## Before you start You need: - Node.js 22 or newer. Check with `node --version`. - npm, which ships with Node.js. - An empty directory to work in. - A network connection to the Somnia testnet endpoints. We run TypeScript directly with `tsx`, so there is no build step. ## 1. Create the project In your empty directory, run these three commands: ```sh npm init -y npm pkg set type=module npm install @somnia-chain/markets-sdk@0.29.0 viem@2.55.10 tsx@4.23.1 ``` The first creates `package.json`. The second lets Node.js load our files as ES modules, which the SDK requires. The third installs the versions used to verify this tutorial: SDK 0.29.0, viem 2.55.10, and tsx 4.23.1. `tsx` runs TypeScript files directly but does not check types, so no `tsconfig.json` is needed. Your editor may underline `process.env` in the next tutorial because Node's type definitions are not installed; the scripts still run. You should see npm report the added packages, and a `node_modules` directory should exist. ## 2. Create the exchange and load the markets Create a file named `watch.ts` with this content: ```ts import { SomniaMarkets, SOMNIA_TESTNET_ADDRESSES } from "@somnia-chain/markets-sdk"; import { somniaTestnet } from "viem/chains"; const exchange = new SomniaMarkets({ indexerUrl: "https://dev.smk.somnia.host/v1/graphql", chain: somniaTestnet, wsRpcUrl: "wss://api.infra.testnet.somnia.network/ws", addresses: SOMNIA_TESTNET_ADDRESSES, }); const markets = await exchange.loadMarkets(); const spot = Object.values(markets).filter((m) => m.type === "spot"); console.log( `${exchange.symbols.length} symbols, ${spot.length} spot markets:`, spot.map((m) => m.symbol), ); await exchange.close(); ``` `SomniaMarkets` is the SDK's single entry point. The three fields point it at the testnet: the indexer URL for history, the chain definition, and the deployed contract addresses. `loadMarkets` fetches every market and builds the symbol table. Run it: ```sh npx tsx watch.ts ``` You should see one line naming the spot markets. The counts change as markets are created and expire; the three spot symbols are stable: ```text 597 symbols, 3 spot markets: [ 'WBTC/USDso', 'SOMI/USDso', 'WETH/USDso' ] ``` Notice that most symbols are binary markets, short-lived questions about BTC and ETH prices. We work with the spot market `SOMI/USDso`. SOMI is the market's name for the chain's native token, which the testnet calls STT. USDso is a test stablecoin. ## 3. Read the order book and the last trades Replace the `await exchange.close();` line with this, so the new code runs before the exchange closes: ```ts const book = await exchange.fetchOrderBook("SOMI/USDso", 3); console.log("bids", book.bids); console.log("asks", book.asks); const trades = await exchange.fetchTrades("SOMI/USDso", undefined, 3); for (const t of trades) console.log(t.datetime, t.side, t.amount, "@", t.price); await exchange.close(); ``` The middle argument of `fetchTrades` is a `since` timestamp we do not need. Run the file again. You should see three levels per side and three trades: ```text 597 symbols, 3 spot markets: [ 'WBTC/USDso', 'SOMI/USDso', 'WETH/USDso' ] bids [ [ 0.1153, 445 ], [ 0.1152, 1222 ], [ 0.1151, 752 ] ] asks [ [ 0.1154, 530 ], [ 0.1155, 1378 ], [ 0.1156, 1810.46 ] ] 2026-09-03T21:40:52.000Z sell 25 @ 0.1153 2026-09-03T21:40:43.000Z sell 25 @ 0.1153 2026-09-03T21:40:33.000Z sell 25 @ 0.1153 ``` Notice the shapes. A book level is a `[price, amount]` pair in plain numbers: 445 SOMI bid at 0.1153 USDso each. Trades come newest first with an ISO timestamp. `fetchOrderBook` read the pool contract on the chain; `fetchTrades` read the indexer. Both are one-shot reads. Notice also the timestamps: on the testnet a market-making bot trades this market every few seconds. That activity is what we watch next. ## 4. Follow the top of the book live Replace the `await exchange.close();` line again, this time with a loop: ```ts // Follow the book for 30 seconds. Print a line whenever the best bid or ask changes. const stop = new Promise((resolve) => setTimeout(() => resolve(null), 30_000)); let last = ""; while (true) { const live = await Promise.race([exchange.watchOrderBook("SOMI/USDso", 1), stop]); if (!live) break; const top = `bid ${live.bids[0]?.[0]} × ${live.bids[0]?.[1]} / ask ${live.asks[0]?.[0]} × ${live.asks[0]?.[1]}`; if (top !== last) console.log(new Date().toISOString(), top); last = top; } await exchange.close(); console.log("done"); ``` `watchOrderBook` is different from `fetchOrderBook`. The first call opens a live watch on the market, and every later call resolves the next time the book changes, with no request to any server. [Read tiers](../reference/read-tiers.md) describes how the watch works. The `Promise.race` against a 30-second timer is only there to end the tutorial. `close()` releases the watch and the WebSocket to the node, so the script prints `done` and exits. Run the file one more time. The first live line prints at once. After that, a line appears only when the best level changes; the testnet bot usually moves it every few seconds, so expect several lines in thirty seconds. On a quiet market you see one live line and then `done`. This run looked like this: ```text 597 symbols, 3 spot markets: [ 'WBTC/USDso', 'SOMI/USDso', 'WETH/USDso' ] bids [ [ 0.1153, 445 ], [ 0.1152, 1222 ], [ 0.1151, 752 ] ] asks [ [ 0.1154, 530 ], [ 0.1155, 1378 ], [ 0.1156, 1810.46 ] ] 2026-09-03T21:40:52.000Z sell 25 @ 0.1153 2026-09-03T21:40:43.000Z sell 25 @ 0.1153 2026-09-03T21:40:33.000Z sell 25 @ 0.1153 2026-09-03T21:41:03.545Z bid 0.1153 × 445 / ask 0.1154 × 1165.4 2026-09-03T21:41:03.974Z bid 0.1153 × 420 / ask 0.1154 × 1165.4 2026-09-03T21:41:10.083Z bid 0.1153 × 420 / ask 0.1154 × 635.4 2026-09-03T21:41:10.084Z bid 0.1152 × 470.5 / ask 0.1154 × 635.4 2026-09-03T21:41:13.866Z bid 0.1152 × 1010.1 / ask 0.1154 × 1164.9 2026-09-03T21:41:22.768Z bid 0.1152 × 985.1 / ask 0.1154 × 1164.9 2026-09-03T21:41:30.078Z bid 0.1152 × 470.5 / ask 0.1153 × 529.5 done ``` Notice that in this run the bid size dropped by 25 a few seconds in: a trade of the same size as the ones from step 3, seen from the chain event rather than from the indexer. Two lines can carry almost the same timestamp when one block moves more than one level. Notice too that the book copy changes more often than its top. The `if (top !== last)` check keeps the output to what changed at the best level. ## What you can do now You can create an exchange for the Somnia testnet, load its markets, and read any spot market's book and trades on demand. You can open a live watch and react each time the book changes, without a polling loop. The same `fetchOrderBook`, `fetchTrades`, and `watchOrderBook` calls work on every symbol `loadMarkets` returned, including the binary markets. Next, [Place and cancel your first order](./place-and-cancel-your-first-order.md) adds a signer to this project and puts an order on this book. To see which reads are live, on-chain, or indexed, read [Read tiers](../reference/read-tiers.md). --- # /docs/typescript/tutorials/place-and-cancel-your-first-order # Place and cancel your first order In this tutorial we place a real limit order on the Somnia testnet, watch it appear in our open orders, and cancel it. At the end you will have sent two transactions through the SDK and seen how a resting order shows up in the live data. The order tries to sell 1 SOMI at four times the current price. We submit it as post-only, so the pool either rests it on the book or rejects it; nothing is bought or sold. Your balance still changes temporarily while a resting order reserves its funding requirement, and permanently by the testnet gas you spend. ## Before you start You need: - The project from [Stream a live order book](./stream-a-live-order-book.md). We add one file to it. - A private key, including its `0x` prefix, for an account on the Somnia testnet that holds at least 2 STT. The testnet is called Shannon; it is the `somniaTestnet` chain we already import from viem. Create a fresh key for this tutorial and never use a key that holds real funds. [Get testnet funds](../how-to/get-testnet-funds.md) lists the faucets. Why 2 STT: the pool's required reserve includes the 1 SOMI quantity and any configured fee headroom. A native sell sends only the part not already credited to your pool vault. The transaction also needs room under the SDK's gas ceiling; unused gas is not charged. Put the key in your shell for this session. Replace the value with your own key. ```sh export SOMNIA_PRIVATE_KEY=0x… ``` We run the file twice in this tutorial: once after step 1, to check the key, and once after step 5, to place and cancel the order. Steps 2 to 4 only add code. ## 1. Create the exchange with a signer Create `trade.ts` next to `watch.ts`: ```ts import { isHex } from "viem"; import { somniaTestnet } from "viem/chains"; import { SomniaMarkets, SOMNIA_TESTNET_ADDRESSES } from "@somnia-chain/markets-sdk"; const privateKey = process.env.SOMNIA_PRIVATE_KEY; if (!privateKey || !isHex(privateKey, { strict: true }) || privateKey.length !== 66) { throw new Error("set SOMNIA_PRIVATE_KEY to a 32-byte 0x-prefixed key"); } const exchange = new SomniaMarkets({ indexerUrl: "https://dev.smk.somnia.host/v1/graphql", chain: somniaTestnet, wsRpcUrl: "wss://api.infra.testnet.somnia.network/ws", addresses: SOMNIA_TESTNET_ADDRESSES, privateKey, }); await exchange.loadMarkets(); console.log("trading as", exchange.walletAddress); const before = await exchange.fetchBalance(); console.log("STT before:", before.STT?.total); await exchange.close(); ``` The one new field is `privateKey`. With it, the SDK signs transactions locally and every authenticated method knows whose data to return. The closing `close()` is the same ending as `watch.ts`. Run it: ```sh npx tsx trade.ts ``` You should see your own address and your STT balance: ```text trading as 0x0a9753f040E0cC077eB514c207F8ba2c14230b42 STT before: 19997.22114964 ``` Notice that `fetchBalance` took no address. It answers for the signer. If the balance is below 2, stop here and fund the account before you continue. ## 2. Open the live watch Replace the closing `close()` line of `trade.ts` with this: ```ts const book = await exchange.watchOrderBook("SOMI/USDso", 1); const bestAsk = book.asks[0]?.[0]; if (bestAsk === undefined) throw new Error("the ask side is empty right now; run again in a moment"); console.log("best ask:", bestAsk); ``` We open the live watch before placing the order. From now on the SDK keeps a local copy of this market current from the chain's events, so our own order will appear in that copy in the block it lands. No need to run yet; step 3 uses `bestAsk`. ## 3. Place the order Append: ```ts const order = await exchange.createOrder("SOMI/USDso", "limit", "sell", 1, bestAsk * 4, { postOnly: true }); console.log("placed:", order.id, order.status, `${order.amount} @ ${order.price}`); ``` The first five arguments are the symbol, the order type, the side, the amount in SOMI, and the price in USDso per SOMI. `{ postOnly: true }` guarantees the order cannot take liquidity. Four times the best ask should rest far above the market, but the book can move before the transaction lands. If that makes the order cross, `createOrder` throws a `ContractRevertError` named `PostOnlyWouldCross`; run the script again so step 2 reads a fresh book. `createOrder` resolves only after the transaction is mined; there is nothing to wait for afterwards. ## 4. See the order in your open orders Append: ```ts let orders = await exchange.watchOrders("SOMI/USDso"); while (!orders.some((o) => o.id === order.id)) orders = await exchange.watchOrders("SOMI/USDso"); console.log("in my open orders:", orders.find((o) => o.id === order.id)?.status); const during = await exchange.fetchBalance(); console.log("STT while resting:", during.STT?.total); ``` `watchOrders` returns your orders on this market from the local copy the watch keeps current, with no request to a server. Its first call returns what the copy holds now, and each later call resolves when the copy changes. The `while` loop covers the moment between the transaction being mined and its event reaching the copy, which is usually zero calls. ## 5. Cancel the order Append: ```ts const cancel = await exchange.cancelOrder(order.id, "SOMI/USDso"); console.log("cancel:", cancel.status); const after = await exchange.watchOrders("SOMI/USDso"); console.log("after cancel:", after.find((o) => o.id === order.id)?.status); const final = await exchange.fetchBalance(); console.log("STT after:", final.STT?.total); await exchange.close(); ``` Run the file. It takes a few seconds longer than the first run, because two transactions are mined. The output should look like this, with your own address, order id, price, and balances: ```text trading as 0x0a9753f040E0cC077eB514c207F8ba2c14230b42 STT before: 19997.… best ask: 0.1147 placed: 793209995169529057822 open 1 @ 0.4588 in my open orders: open STT while resting: 19996.… cancel: canceled after cancel: canceled STT after: 19997.… ``` Notice five things. - `status` is `open` after placement: the order rests on the book. The `id` is the pool's order id, a long decimal string. - The price prints as `0.4588`, four times `0.1147` rounded onto the market's allowed price steps, in the direction that favours you. - `STT while resting` is below `STT before`. The pool reserves enough for the 1 SOMI sale and its configured fee headroom, less any native balance you already had in the pool vault, and gas was paid. SOMI is the market's name for the chain's native token, which the testnet calls STT. - The second `watchOrders` call returned the same order with status `canceled`. The local copy saw the cancel event and updated. - `STT after` is `STT before` minus the gas for two transactions. The unused reserve came back; the exact difference depends on current gas fees and the pool's fee settings. `close()` releases everything the instance opened, including the WebSocket to the node, so the script ends on its own. ## If a run stops halfway A run that fails after `placed:` leaves that order resting with 1 STT locked. Cancel it by id with a one-line script, replacing the id with the one the run printed: ```ts await exchange.cancelOrder("793209995169529057822", "SOMI/USDso"); ``` Use the same construction lines as `trade.ts` above it, and the same two closing lines below it. Cancelling an order that is already gone throws a `ContractRevertError` named `IncorrectSender`; that means there is nothing left to cancel. ## What you can do now You can place a limit order on any spot market the SDK lists, read it back from the live data, and cancel it. The same `createOrder` call with `"buy"` and a price above the best ask fills immediately and returns `status: "closed"` with the fills in `order.info`. To run this as a bot, continue with [Run a quoting loop](../how-to/run-a-quoting-loop.md). To learn when a resting order fills, read [Detect when an order fills](../how-to/detect-fills.md). To see what the SDK did during each step, add a debug sink as shown in [Debug what the SDK is doing](../how-to/debug-the-sdk.md). --- # /docs/typescript/how-to/configure-for-a-network # How to configure the SDK for testnet, mainnet, or a local chain This guide shows you how to build a `SomniaMarkets` instance for each network the SDK supports. It assumes you can install an npm package and write a TypeScript module. The field-by-field reference is [Configuration](../reference/configuration.md); the values are in [Networks and endpoints](../reference/networks-and-endpoints.md). ## Shannon testnet Use the testnet for development. Markets exist, bots trade on them, and funds are free. ```ts import { somniaTestnet } from "viem/chains"; import { SomniaMarkets, SOMNIA_TESTNET_ADDRESSES } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets({ indexerUrl: "https://dev.smk.somnia.host/v1/graphql", chain: somniaTestnet, wsRpcUrl: "wss://api.infra.testnet.somnia.network/ws", addresses: SOMNIA_TESTNET_ADDRESSES, }); ``` The viem chain definition does not carry a WebSocket URL. Set `wsRpcUrl` to the Somnia endpoint that the SDK must use for chain reads, writes, and watches. ## Mainnet Swap the three network-specific values. ```ts import { somnia } from "viem/chains"; import { SomniaMarkets, SOMNIA_MAINNET_ADDRESSES } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets({ indexerUrl: "https://prd.smk.somnia.host/v1/graphql", chain: somnia, wsRpcUrl: "wss://api.infra.mainnet.somnia.network/ws", addresses: SOMNIA_MAINNET_ADDRESSES, }); ``` ## Local anvil stack Start the stack from the repository root with `./demo-clob.sh up`. It deploys the contracts to anvil on chain id 31337, runs the indexer, and writes the address manifest. ```ts import { selectDeployment } from "@somnia-chain/deployments/local"; import { SomniaMarkets } from "@somnia-chain/markets-sdk"; import { defineChain } from "viem"; const somniaLocal = defineChain({ id: 31337, name: "Somnia Local", nativeCurrency: { name: "Somnia Test Token", symbol: "STT", decimals: 18 }, rpcUrls: { default: { http: ["http://127.0.0.1:8545"], webSocket: ["ws://127.0.0.1:8545"] } }, }); const deployment = selectDeployment("my-bot", "local"); // reads the anvil manifest const exchange = new SomniaMarkets({ indexerUrl: "http://localhost:8085/v1/graphql", chain: somniaLocal, wsRpcUrl: "ws://127.0.0.1:8545", addresses: deployment.addresses, }); ``` `@somnia-chain/deployments` is the workspace package that reads the manifests; it is available to packages inside the repository. Outside the repository, copy the addresses from `smart-contracts/deployments/31337/local/addresses.json` into an object instead. A restarted anvil is a new chain under the same id: redeploy and reindex, or the indexer rows point at contracts that no longer exist. ## Add a signer Pass one of three signer fields to unlock writes and the authenticated reads. Keep the key out of source control; read it from the environment. Validate the environment value before construction. The `privateKey` variable below must be a 32-byte, `0x`-prefixed hex string. The tutorial [Place and cancel your first order](../tutorials/place-and-cancel-your-first-order.md#create-the-exchange-with-a-signer) shows the guard. ```ts const exchange = new SomniaMarkets({ ...config, privateKey, }); ``` For a browser wallet, see [Sign with a browser wallet](./sign-with-a-browser-wallet.md). ## Add the price feed The price methods need a separate endpoint. On testnet: ```ts import { SOMNIA_TESTNET_PRICE_FEED } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets({ ...config, priceFeed: SOMNIA_TESTNET_PRICE_FEED }); ``` ## Run indexer-only No extra field is needed. The WebSocket opens on the first chain read, write, or watch, so an instance that only calls `listMarkets`, `getCandles`, or `getPortfolio` never opens one. This suits server-side rendering. The examples above set `wsRpcUrl` explicitly. The first chain touch throws `NotConfiguredError` when neither this field nor `chain.rpcUrls.default.webSocket[0]` is present. ## Cancel indexer reads from a request scope Pass an `AbortSignal` to stop in-flight indexer reads when the caller goes away, for example on a server per request. ```ts const controller = new AbortController(); const exchange = new SomniaMarkets({ ...config, signal: controller.signal }); // later, when the request is abandoned: controller.abort(); ``` An abort re-throws your own reason. Chain reads are not covered by the signal; they time out after 4 seconds on their own. ## Check the result `await exchange.loadMarkets()` proves the indexer URL. `await exchange.fetchOrderBook(symbol)` proves the chain transport. `await exchange.fetchBalance()` proves the signer. Each one throws the class named in [Errors](../reference/errors.md) when its input is wrong. --- # /docs/typescript/how-to/get-testnet-funds # How to get testnet funds This guide shows you how to fund an account on the Shannon testnet for the three things trading needs: gas, spot and perp collateral, and binary collateral. It assumes you have a private key and know its address. ## Gas: STT Every transaction pays gas in STT. A write also needs the account to hold the SDK's gas ceiling times its fee ceiling on top of the transaction value: 0.6 STT at the defaults (see [Configuration](../reference/configuration.md#gas)). The chain refunds unused gas. Request STT from one of the faucets listed on the Somnia network page: the official faucet at `https://testnet.somnia.network/`, the Google Cloud faucet for Somnia Shannon, or the Stakely and Thirdweb faucets. Each faucet pays a fixed amount per request; repeat until the balance covers what you need. Some faucets require the requesting address to hold funds on another network first. If none works, ask in the `#dev-chat` channel of the Somnia Discord. Check the balance with a configured exchange: ```ts const balances = await exchange.fetchBalance(); console.log(balances.STT?.total); ``` `fetchBalance` needs a signer in the configuration. Without one, read `exchange.client.getNativeBalance(address)` instead; it returns wei as a `bigint`. ## Spot and perp collateral: USDso `USDso` is the quote token of the spot pairs and the settlement token of the perps. On Shannon it has a public `mint(address, uint256)` with 18 decimals. Mint it with viem: ```ts import { createWalletClient, http, parseUnits } from "viem"; import { privateKeyToAccount } from "viem/accounts"; const account = privateKeyToAccount(privateKey); const wallet = createWalletClient({ account, chain: exchange.client.config.chain, transport: http() }); const hash = await wallet.writeContract({ address: "0x9c32f3827a1a99f0cf9b213de8b53ec3d57bb171", // USDso on Shannon abi: [ { type: "function", name: "mint", stateMutability: "nonpayable", inputs: [ { name: "to", type: "address" }, { name: "amount", type: "uint256" }, ], outputs: [], }, ], functionName: "mint", args: [account.address, parseUnits("1000", 18)], gas: 500_000n, }); await exchange.client.getViemClient().waitForTransactionReceipt({ hash }); ``` The SDK does not wrap this call. USDso is a test token; the mainnet collateral has no mint. To sell SOMI on `SOMI/USDso`, no USDso is needed: the base of that pair is the native token, and a sell escrows STT. ## Binary collateral: tUSDC The binary markets on Shannon settle in `tUSDC`, a 6-decimal test token with a faucet. The SDK wraps it: ```ts await exchange.trader.faucet(); // mints 10,000 tUSDC to the signer ``` `faucet()` needs `addresses.collateral` (present in `SOMNIA_TESTNET_ADDRESSES`) and a signer. Pass `{ amount }` in raw units to mint less. The contract caps the amount per call; a larger request reverts with `FaucetCapExceeded`. ## Verify ```ts console.log(await exchange.fetchBalance()); ``` The result keys balances by currency code: `STT`, `USDso`, `tUSDC`, and one key per binary tradable you hold shares of, for example `BTC-0-04SEP26/tUSDC#YES`. ## Perps Perp orders draw margin from the MarginBank, not from the wallet. After minting USDso, deposit it: ```ts await exchange.depositMargin("BTC/USDso:USDso", 100); ``` See [Perps](../PERPS.md) for margin, leverage, and funding. --- # /docs/typescript/how-to/run-a-quoting-loop # How to run a quoting loop This guide shows you how to keep a two-sided quote on a spot market from a Node bot: read the live book, place a bid and an ask, re-quote when the market moves, and cancel everything on exit. It assumes a configured `SomniaMarkets` instance with a `privateKey` and funds on the market (see [Get testnet funds](./get-testnet-funds.md)). The example quotes `SOMI/USDso` on the Shannon testnet. ## Open the watch before you quote `watchOrderBook` opens the market watch on its first call and returns the current book. Every later call resolves when the book changes. Open it once before the loop so your own orders show up in `watchOrders` the moment they land. ```ts const symbol = "SOMI/USDso"; await exchange.loadMarkets(); let book = await exchange.watchOrderBook(symbol, 1); ``` ## Quote around the mid Use the exchange verbs for a simple loop. `createOrder` aligns price and amount to the market's tick and lot grids and echoes the aligned values, so compute freely and read the result. ```ts import { ContractRevertError } from "@somnia-chain/markets-sdk"; const size = 5; // SOMI per side const spread = 0.002; // 0.2 % each side let bidId: string | undefined; let askId: string | undefined; let running = true; function isPostOnlyWouldCross(error: unknown) { return error instanceof ContractRevertError && error.errorName === "PostOnlyWouldCross"; } async function cancelIfResting(orderId: string) { try { await exchange.cancelOrder(orderId, symbol); } catch (error) { if (error instanceof ContractRevertError && error.errorName === "IncorrectSender") return; throw error; } } async function requote(book: Awaited>) { const bestBid = book.bids[0]?.[0]; const bestAsk = book.asks[0]?.[0]; if (bestBid === undefined || bestAsk === undefined) return; // one-sided book: skip this tick const mid = (bestBid + bestAsk) / 2; if (bidId) { const previousBidId = bidId; await cancelIfResting(previousBidId); if (bidId === previousBidId) bidId = undefined; } if (askId) { const previousAskId = askId; await cancelIfResting(previousAskId); if (askId === previousAskId) askId = undefined; } if (!running) return; let bid: Awaited>; try { bid = await exchange.createOrder(symbol, "limit", "buy", size, mid * (1 - spread), { postOnly: true }); } catch (error) { if (isPostOnlyWouldCross(error)) return; throw error; } bidId = bid.status === "open" ? bid.id : undefined; if (!running) return; try { const ask = await exchange.createOrder(symbol, "limit", "sell", size, mid * (1 + spread), { postOnly: true }); askId = ask.status === "open" ? ask.id : undefined; } catch (error) { const failures: unknown[] = [error]; const placedBidId = bidId; if (placedBidId) { try { await cancelIfResting(placedBidId); if (bidId === placedBidId) bidId = undefined; } catch (cancelError) { failures.push(cancelError); } } if (failures.length > 1) throw new AggregateError(failures, "ask placement and bid cleanup failed"); if (isPostOnlyWouldCross(error)) return; throw error; } } ``` `postOnly: true` makes the pool reject a quote that would cross instead of taking liquidity; the rejection arrives as `ContractRevertError` with `errorName` `PostOnlyWouldCross`. This loop waits for the next book change after that outcome. If the ask fails after the bid rests, it cancels the bid before it continues. If that cancellation also fails, the loop preserves both errors and the bid id for final cleanup. See [Handle errors and reverts](./handle-errors.md). ## Re-quote on change Each `await exchange.watchOrderBook(symbol, 1)` resolves on the next change of the book. On a busy market that is every block, so compare the top of book and skip unchanged ticks. ```ts let requestStop: (() => void) | undefined; const stop = new Promise((resolve) => { requestStop = () => resolve(null); }); process.once("SIGINT", () => { running = false; requestStop?.(); }); async function cleanupQuotes() { const failures: unknown[] = []; if (bidId) { const orderId = bidId; try { await cancelIfResting(orderId); if (bidId === orderId) bidId = undefined; } catch (error) { failures.push(error); } } if (askId) { const orderId = askId; try { await cancelIfResting(orderId); if (askId === orderId) askId = undefined; } catch (error) { failures.push(error); } } try { await exchange.close(); } catch (error) { failures.push(error); } if (failures.length > 0) throw new AggregateError(failures, "quote cleanup failed"); } let lastTop = `${book.bids[0]?.[0]}/${book.asks[0]?.[0]}`; const failures: unknown[] = []; try { if (running) await requote(book); while (running) { const nextBook = await Promise.race([exchange.watchOrderBook(symbol, 1), stop]); if (nextBook === null || !running) break; book = nextBook; const top = `${book.bids[0]?.[0]}/${book.asks[0]?.[0]}`; if (top === lastTop) continue; lastTop = top; await requote(book); } } catch (error) { failures.push(error); } try { await cleanupQuotes(); } catch (error) { failures.push(error); } if (failures.length > 0) throw new AggregateError(failures, "quoting loop stopped with errors"); ``` Each `createOrder` and `cancelOrder` awaits its receipt. A full re-quote sends two cancellation transactions and two placement transactions. The SDK can also perform prerequisite reads: in particular, every native-base sell reads the pool's current funding requirement and vault shortfall before it sends. ## Re-quote in one transaction For lower latency, move to the engine and use the batch writes. `amendOrders` cancels and replaces several orders in one transaction, all or nothing. It works on spot and perp pools, not on binary pools. ```ts import { ORDER_TYPE, fromHuman, isSpotMarket } from "@somnia-chain/markets-sdk"; const t = exchange.market(symbol); if (!isSpotMarket(t.market)) throw new Error("spot only"); const { quoteDecimals, baseDecimals } = t.market; if (!bidId || !askId) throw new Error("place both quotes before amending them"); const bestBid = book.bids[0]?.[0]; const bestAsk = book.asks[0]?.[0]; if (bestBid === undefined || bestAsk === undefined) throw new Error("two-sided book required"); const mid = (bestBid + bestAsk) / 2; const newBid = exchange.priceToPrecision(symbol, mid * (1 - spread)); const newAsk = exchange.priceToPrecision(symbol, mid * (1 + spread)); const newSize = exchange.amountToPrecision(symbol, size); const result = await exchange.trader.amendOrders({ pool: t.pool, amendments: [ { oldOrderId: bidId, newOrder: { isBid: true, price: fromHuman(newBid, quoteDecimals), quantity: fromHuman(newSize, baseDecimals), orderType: ORDER_TYPE.POST_ONLY, }, }, { oldOrderId: askId, newOrder: { isBid: false, price: fromHuman(newAsk, quoteDecimals), quantity: fromHuman(newSize, baseDecimals), orderType: ORDER_TYPE.POST_ONLY, }, }, ], }); [bidId, askId] = result.newOrderIds.map(String); ``` Prices and quantities are raw `bigint` here; `fromHuman` scales the aligned values by the market's decimals. `ORDER_TYPE.POST_ONLY` preserves the quoting behavior of `createOrder(..., { postOnly: true })`. An unaligned value reverts with `PriceNotAlignedToTickSize` or `QuantityNotAlignedToLotSize`. An amendment whose old order is already gone fails the whole batch with `AmendOldOrderGone`; pass `alwaysPlace: true` on that amendment to place the new order anyway. To place a ladder, use `placeSpotOrders`; to pull one, use `cancelOrders`. Batches are not payable, so on a market whose base is the native token a batched sell needs a vault balance deposited beforehand with `trader.depositVaultNative`. [Spot markets](../SPOT.md) covers the batch parameters and the vault. ## Set an expiry so a crashed bot's quotes die On the engine every order takes `expireTimestampNs`. Set it a few minutes ahead so a crashed bot's quotes die on their own. Expiry is lazy: an expired order stays on the book until a cancel or a fill attempt touches it, and a fill attempt reverts with `ExpiredOrderMustBeCancelled`. When unset, a spot or perp order expires in about 50 years and a binary order at its market's expiry. ```ts const inFiveMinutes = BigInt(Date.now() + 5 * 60_000) * 1_000_000n; ``` ## Stop cleanly The handler is installed before the first quote. The loop quotes once from the book already returned by the initial watch, then waits for later changes. The handler resolves a pending book read and stops new placements. If a placement is already in flight, the loop waits for its receipt and records its order id before cleanup starts. Cleanup preserves each id until its cancellation succeeds. It attempts both sides even if one cancellation fails. It closes the exchange and then reports every loop or cleanup failure. `cancelIfResting` contains only `IncorrectSender`, which means the known order is no longer cancellable. ## Know what filled Track fills with `watchMyTrades` or `watchOrders` in a second loop. See [Detect when an order fills](./detect-fills.md). --- # /docs/typescript/how-to/detect-fills # How to detect when an order fills This guide shows you how to learn that a resting order was filled, partially filled, or cancelled, with the least latency and without polling. It assumes a configured `SomniaMarkets` instance with a signer, and a market watch opened before the order was placed. ## Read the placement result first A `createOrder` that crosses the book fills in the same transaction. Its result already says so. ```ts const order = await exchange.createOrder("SOMI/USDso", "limit", "buy", 10, 0.116); if (order.status === "closed") { // fully filled in the placement transaction } else if (order.status === "open") { // resting: order.filled may still be > 0 for a partial fill } ``` `status` is `"closed"` when `remaining` is zero, `"open"` when a remainder rests, and `"canceled"` when an immediate-or-cancel or market order left an unfillable remainder. The raw fills are in `order.info.fills`. ## Wait for the status to flip `watchOrders(symbol)` returns your orders on the market from the live store. The first call returns the current list; each later call resolves when the list changes. Loop until your order is no longer open. ```ts let mine = order; while (mine.status === "open") { const orders = await exchange.watchOrders("SOMI/USDso"); mine = orders.find((o) => o.id === order.id) ?? mine; } console.log(mine.status, "filled", mine.filled, "of", mine.amount); ``` The list changes on every order event for your account on that market, including partial fills, so the loop also observes `filled` growing while `status` stays `"open"`. Open the market watch before placing. `watchOrderBook`, `watchTrades`, or `watchOrders` on the symbol all open it. The watch learns about an order placed after it opened from the chain event, in the block the order lands. It learns about an order placed before it opened from the indexer snapshot, which lags the chain by the indexing delay, typically a few seconds. ## Watch your trades `watchMyTrades(symbol)` returns your fills on the market, newest first, and resolves on each new one. Use it when you care about executions rather than order state, for example to update inventory. ```ts let seen = new Set(); while (true) { const trades = await exchange.watchMyTrades("SOMI/USDso", 20); for (const t of trades) { if (seen.has(t.id)) continue; seen.add(t.id); console.log(t.datetime, t.side, t.amount, "@", t.price, "cost", t.cost); } } ``` On spot and perp markets `side` is absent: the pools do not attribute a fill to a side in a way the SDK can map to you. Read `t.info.takerIsBid` and compare `t.info.maker` with your address instead. On binary markets `side` is your own side when the fill carries one. ## Use the engine for raw values `exchange.client.getLiveUserOrders(pool, owner)` and `getLiveUserFills(pool, owner)` are the synchronous views behind the two verbs. They return `LiveOrder` and `LiveFill` rows with exact raw values as decimal strings; wrap a value in `BigInt()` to compute with it. The API reference lists the fields. Subscribe to changes with `client.subscribeLive(listener)`. In React, `useLiveUserOrders` and `useLiveUserFills` re-render on the same changes. See [Use the React hooks](./use-the-react-hooks.md). ## Read your own writes at chain head When a write threw `RpcError` after sending, or when no watch is open, ask the pool directly. These reads answer from the contract in one round-trip and know only what is open now. ```ts const t = exchange.market("SOMI/USDso"); const owner = exchange.walletAddress; if (!owner) throw new Error("configure a signer before reading your open orders"); const openIds = await exchange.client.getOwnOpenOrdersOnchain(t.pool, owner); const stillOpen = openIds.some((id) => id.toString() === order.id); ``` `getOrderOnchain(pool, orderId)` returns one order's on-chain state. For history, including filled and cancelled orders, use the indexer reads `getOpenOrders`, `getOrders`, and `getOrderFills`; they lag the chain by the indexing delay. ## Read a maker order a fill already removed Decoding `OrderFilled` yourself gives you the fill's `fillPrice`, `quantityFilled` and `makerRemainingQuantity`, but names the maker only by id - and a fill removes the maker order in the same transaction, so at head it is gone. Pin the read one block earlier to recover the side the fill took: ```ts const maker = await exchange.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; ``` What it answers, and what it does not: - The maker's identity - `isBid`, `owner`, `userData`, `expireTimestampNs` - cannot change under a given id, so the pinned read is exact for it, and no fill log carries it: `OrderFilled` names the maker by id alone. `OrderPlaced` carries it, but only a consumer that was already listening when the maker rested has that log, which is the case this read exists for. - **Not** the price. It is immutable too, but a fill executes at the maker's resting price and the book emits exactly that, so `OrderFilled.fillPrice` already is the maker's price. Reading for it is redundant work. - **Both** quantities are the values at the **block boundary**, not at your fill. `quantityRemaining` moves on every fill, and `reduceOrder` decrements `fullQuantity` and `quantityRemaining` together under the same id - so an earlier transaction in the fill's own block makes either value stale for your fill, and no block-level read can see between transactions. Take `quantityFilled` and `makerRemainingQuantity` from the event instead. Two edges answer plausibly rather than failing: - A **partial** fill leaves the maker order in place with a smaller `quantityRemaining`, so reading at the fill's own block succeeds with different numbers instead of returning `null`. - An order placed and filled inside **one** block does not exist at `fillBlock - 1n`. That read is `null`, and the placement is in the same block's `OrderPlaced`. A recent block answers against a full node. An older one needs archive state, so this suits a live tape rather than a backfill. ## Choose by need | Need | Use | Latency | | ----------------------------------------- | ---------------------------- | -------------- | | Did the placement itself fill | `createOrder` result | none | | Did a resting order change | `watchOrders` | next block | | What executed, for inventory | `watchMyTrades` | next block | | Is it still open, after a transport error | `getOwnOpenOrdersOnchain` | one round-trip | | Full history for a report | `getOrders`, `getOrderFills` | indexing delay | --- # /docs/typescript/how-to/sign-with-a-browser-wallet # How to sign with a browser wallet This guide shows you how to let a user trade through an injected wallet such as MetaMask instead of a private key held by your code. It assumes a React app with wagmi or another source of a viem `WalletClient`. For a Node process, use `privateKey` instead; see [Configure the SDK](./configure-for-a-network.md). ## Construct without a signer, bind on connect A browser app has no signer at boot. Construct the exchange for public reads, then bind the wallet when it connects and unbind it when it disconnects. ```tsx import { useEffect } from "react"; import { useWalletClient } from "wagmi"; import { exchange } from "./exchange.js"; // the module-scope SomniaMarkets instance export function SignerBinding() { const { data: walletClient } = useWalletClient(); useEffect(() => { exchange.setSigner(walletClient ? { walletClient } : {}); }, [walletClient]); return null; } ``` `setSigner` replaces the trader that every authenticated verb uses and updates `exchange.walletAddress`. Live watches and market data are unaffected. After binding, the exchange verbs work as they do with a private key: ```ts const order = await exchange.createOrder("SOMI/USDso", "limit", "buy", 10, 0.11); ``` ## What differs from a local key The wallet signs after a user prompt, sends through `eth_sendTransaction`, and the SDK reads the receipt on the next block heads instead of in one round-trip. The first order per token also prompts for an approval. Both paths resolve to the same result shape once the transaction is mined. The [Configuration reference](../reference/configuration.md#signer-paths) tabulates the differences. ## Make sure the wallet is on the right chain The SDK does not switch chains. Check `walletClient.chain?.id` against `exchange.client.config.chain.id` before a write, and ask the wallet to switch with wagmi's `useSwitchChain` when they differ. A write from the wrong chain is rejected by the wallet or the node, not by the SDK. ## Use the owner-derived trader with a wallet After `setSigner` binds the wallet, use the trader owned by the same exchange. It inherits the exchange's chain, read client, addresses, and lifecycle. ```ts await exchange.trader.faucet(); ``` ## Show the connected account's data `fetchBalance`, `fetchOpenOrders`, `watchOrders`, and `watchMyTrades` answer for `exchange.walletAddress`. In React, prefer the hooks with the account from wagmi's `useAccount`: `useWatchUser(address)` plus `useLiveUserOrders(pool, address)`. See [Use the React hooks](./use-the-react-hooks.md). ## Handle a rejected prompt A user who dismisses the wallet prompt produces an error from the wallet, not from the SDK. It does not extend `SomniaMarketsError`, so keep a final `throw` or a wallet-specific branch in your handler. See [Handle errors and reverts](./handle-errors.md). --- # /docs/typescript/how-to/use-the-react-hooks # How to use the React hooks This guide shows you how to wire `@somnia-chain/markets-sdk/react` into a React app: provide the client once, render live data that updates itself, and fetch indexer data with your own query library. It assumes you know React hooks and context. The hook signatures are in the API reference under "React hooks". ## Provide the client once Construct one exchange at module scope and pass its engine, `exchange.client`, to the provider near the root. Every hook reads the client from context. ```tsx import type React from "react"; import { SomniaMarkets, SOMNIA_TESTNET_ADDRESSES } from "@somnia-chain/markets-sdk"; import { SomniaMarketsProvider } from "@somnia-chain/markets-sdk/react"; import { somniaTestnet } from "viem/chains"; export const exchange = new SomniaMarkets({ indexerUrl: "https://dev.smk.somnia.host/v1/graphql", chain: somniaTestnet, wsRpcUrl: "wss://api.infra.testnet.somnia.network/ws", addresses: SOMNIA_TESTNET_ADDRESSES, }); export function App({ children }: { children: React.ReactNode }) { return {children}; } ``` Do not construct the exchange inside a component. A new instance per render means a new socket and a new store per render. ## Render a live order book The pool-keyed `useLive*` hooks open the market watch while the component is mounted and re-render on every change. Ten components on one pool share one watch. ```tsx import { toHuman } from "@somnia-chain/markets-sdk"; import { useLiveSpotOrderBook, useWatchMarket } from "@somnia-chain/markets-sdk/react"; export function SpotBook({ pool, baseDecimals, quoteDecimals, }: { pool: string; baseDecimals: number; quoteDecimals: number; }) { const status = useWatchMarket(pool); // "unwatched" | "hydrating" | "live" const book = useLiveSpotOrderBook(pool, 10); if (status !== "live") return

loading…

; return ( {book.asks.map((l) => ( ))} {book.bids.map((l) => ( ))}
{toHuman(l.price, quoteDecimals)} {toHuman(l.quantity, baseDecimals)}
{toHuman(l.price, quoteDecimals)} {toHuman(l.quantity, baseDecimals)}
); } ``` Live values are raw `bigint`. Convert at the edge with `toHuman` and the market's decimals. Read the decimals off the market row, from `useMarkets` or from `exchange.markets[symbol].info`. Pass `undefined` as the pool to render nothing and open no watch, for example while a route parameter loads. The other `useLive*` hooks follow the same pattern; the API reference under "React hooks" lists them. ## Show your own orders and fills Combine `useWatchUser` with the user-scoped hooks. `useWatchUser` hydrates the account's order and fill history; the pool watch keeps it current. ```tsx import { useLiveUserOrders, useWatchUser } from "@somnia-chain/markets-sdk/react"; export function MyOrders({ pool, account }: { pool: string; account: string }) { useWatchUser(account); const orders = useLiveUserOrders(pool, account, 50); return (
    {orders.map((o) => (
  • {o.orderId} {o.status}
  • ))}
); } ``` ## Fetch indexer data with TanStack Query or SWR The SDK ships no cache wrapper. Every client read is a promise, which is a ready-made `queryFn`, and the root entry exports one key factory per read so your keys never drift. ```tsx import { useQuery } from "@tanstack/react-query"; import { candlesKey } from "@somnia-chain/markets-sdk"; import { useSomniaMarketsClient } from "@somnia-chain/markets-sdk/react"; export function useCandles1h(pool: string) { const client = useSomniaMarketsClient(); return useQuery({ queryKey: candlesKey(pool, 3600, { limit: 500 }), queryFn: () => client.getCandles(pool, 3600, { limit: 500 }), refetchInterval: 15_000, }); } ``` After a write, invalidate with the same factory, for example `queryClient.invalidateQueries({ queryKey: portfolioKey(account) })`, or everything SDK-shaped with the `QUERY_KEY_SCOPE` prefix. Do not wrap the `useLive*` hooks in a query cache. They already read a shared, push-fed store. ## Fetch indexer data without a query library `useIndexerQuery(fn, deps)` re-runs `fn` when `deps` change and keeps `data`, `loading`, `error`, and `refetch`. It discards a superseded result. It also passes an `AbortSignal` to `fn`, but current client read methods do not accept a per-request signal, so the example below does not cancel its HTTP request. ```tsx import { useIndexerQuery } from "@somnia-chain/markets-sdk/react"; export function useOpenOrders(owner: string | undefined) { return useIndexerQuery((client) => (owner ? client.getOpenOrders(owner) : Promise.resolve([])), [owner]); } ``` The built-in indexer hooks such as `usePortfolio` and `useCandles` return the same shape. ## Write from a component Hooks read; writes go through the exchange or a trader. With a browser wallet, bind it first as shown in [Sign with a browser wallet](./sign-with-a-browser-wallet.md), then call `exchange.createOrder(...)` from an event handler. The live hooks pick up the resulting order and fills without any refetch. ## Render prices `useWatchPrice(asset)` opens the price watch; `useLivePrice(asset)` returns the latest `LivePrice` or `null`. Both need `priceFeed` in the configuration. `useLivePriceFeedInfo` does not re-render as a price ages; drive an age display from your own timer. --- # /docs/typescript/how-to/handle-errors # How to handle errors and reverts This guide shows you how to branch on the errors the SDK throws so a bot or a UI reacts correctly to a bad input, an outage, and a rejected transaction. It assumes you write `try`/`catch` in TypeScript. The complete list of classes and contract error names is in [Errors](../reference/errors.md). ## Branch on the class, not the message Every SDK error is an instance of one of seven classes. Test with `instanceof`, most specific first, and keep a final `throw` for errors the SDK does not own. ```ts import { ContractRevertError, IndexerError, InvalidInputError, RpcError, SignerRequiredError, SomniaMarketsError, } from "@somnia-chain/markets-sdk"; try { await exchange.createOrder("SOMI/USDso", "limit", "buy", 10, 0.11); } catch (e) { if (e instanceof ContractRevertError) { // the chain rejected it: read e.errorName } else if (e instanceof InvalidInputError) { // the call is wrong: fix the arguments, do not retry } else if (e instanceof SignerRequiredError) { // configure a privateKey, account, or walletClient } else if (e instanceof RpcError || e instanceof IndexerError) { // the request did not complete: retry with backoff, or degrade } else if (e instanceof SomniaMarketsError) { // NotConfiguredError and anything else the SDK raised } else { throw e; // not ours: a wallet or an application bug } } ``` Message text is not stable. `errorName`, `operation`, and `what` are. ## Decide from a revert `ContractRevertError.errorName` is the contract's own error name when the revert data matched a known error. Branch on it with a fallback arm; `errorName` is `undefined` for a bare `require` string or unknown data. ```ts import { ContractRevertError } from "@somnia-chain/markets-sdk"; try { await exchange.trader.placeOrder(params); } catch (e) { if (!(e instanceof ContractRevertError)) throw e; switch (e.errorName) { case "ExpiredOrderMustBeCancelled": { // An expired maker sits in the way. Sweep the expired orders, then retry. const expired = await exchange.client.listSweepableOrders({ pool: params.pool }); await exchange.trader.cancelExpiredOrders({ pool: params.pool, orderIds: expired.map((o) => o.orderId) }); break; } case "InsufficientBalance": case "ERC20InsufficientBalance": // top up, then retry break; case "PostOnlyWouldCross": // re-quote one tick away break; case undefined: console.error("unrecognised revert", e.reason ?? e.data); break; default: throw e; } } ``` `e.args` holds the decoded arguments in order. `IncorrectSender(sender, expected)`, for example, is what a cancel of an already-cancelled order returns; `expected` is the zero address because the order no longer exists. ## Retry only what can succeed Retry `RpcError` and `IndexerError` with backoff; the request never reached a conclusion. Retry a `ContractRevertError` only after the state that caused it changes; the same call reverts the same way. Never retry `InvalidInputError`, `NotConfiguredError`, or `SignerRequiredError`; fix the code or the configuration. A write that throws `RpcError` after the transaction was sent may still have landed. Before re-sending, read your open orders at chain head with `exchange.client.getOwnOpenOrdersOnchain(pool, owner)`; see [Detect when an order fills](./detect-fills.md). ## Degrade an indexer read An indexer failure is never "no rows". Catch `IndexerError` deliberately when a page should render with stale or empty data rather than fail. ```ts import { IndexerError } from "@somnia-chain/markets-sdk"; const trades = await exchange .fetchTrades("SOMI/USDso", undefined, 50) .catch((e) => (e instanceof IndexerError ? [] : Promise.reject(e))); ``` Do not apply the same pattern to a chain read: a chain read throws only on real failure, and an empty fallback would hide it. ## Tell cancellation apart from failure When you pass `signal` in the configuration and abort it, in-flight indexer reads re-throw your abort reason, not an `IndexerError`. Check `e.name === "AbortError"` before the SDK classes. ## Decode a revert you sent yourself If you build a transaction with the exported ABIs and send it through your own client, `decodeRevert(caught)` turns the failure into a `ContractRevertError` with the same `errorName` decoding. It always returns an error and never throws. Call it only on failures you know are reverts; a transport error passed to it comes back without `errorName`. ```ts import { decodeRevert } from "@somnia-chain/markets-sdk"; try { await wallet.writeContract(request); } catch (caught) { const revert = decodeRevert(caught); console.error(revert.errorName ?? revert.reason); } ``` ## See the failure in context Pass a `debug` sink to see which span failed and with what arguments. See [Debug what the SDK is doing](./debug-the-sdk.md). --- # /docs/typescript/how-to/debug-the-sdk # How to debug what the SDK is doing This guide shows you how to see every trader call, the sign-and-send pipeline, and live-tail hydration as structured events, and how to capture them in tests. It assumes a working `SomniaMarkets` configuration. The SDK is silent by default. A `debug` sink in the configuration receives `DebugEvent` values: log lines, and span start, annotate, and end events with ids, parent ids, and durations. The sink owns filtering and formatting. ## Print an indented span tree `consoleDebugSink()` renders the stream to the console as a tree reconstructed from `parentId`. ```ts import { SomniaMarkets, consoleDebugSink } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets({ ...config, debug: consoleDebugSink() }); ``` A `createOrder` on a spot market printed these lines on the testnet: ```text [sdk] ▶ trader.placeSpotOrder { params: { pool: '0x259f…fff4', isBid: false, price: 459600000000000000n, … } } [sdk] ▶ trade.execute { functionName: 'placeOrder', address: '0x259f…fff4' } [sdk] ▶ trade.signCall [sdk] ◀ trade.signCall 224.2ms [sdk] ▶ trade.broadcast [sdk] ◀ trade.broadcast 948.4ms [sdk] · trade.execute { hash: '0xc164…b18a17' } [sdk] ◀ trade.execute 1173.2ms [sdk] ◀ trader.placeSpotOrder 1174.5ms ``` The trader span and the `trade.execute` span are both roots: a parent is only recorded where the SDK sets one explicitly, and `trade.signCall`, `trade.broadcast`, and `trade.confirm` are the spans that carry one. Pass `{ prefix }` to change the `[sdk]` label. A span that ended with an error prints through `console.warn`. ## Toggle it from your app The toggle belongs to the app, not the SDK. Two common shapes: ```ts // Browser: flip on from devtools with localStorage.setItem("sdk-debug", "1") and reload. const exchange = new SomniaMarkets({ ...config, debug: localStorage.getItem("sdk-debug") ? consoleDebugSink() : undefined, }); ``` ```ts // Node bot: JSON lines behind an environment variable. const exchange = new SomniaMarkets({ ...config, debug: process.env.SDK_DEBUG ? (e) => console.log(JSON.stringify(e, (_, v) => (typeof v === "bigint" ? v.toString() : v))) : undefined, }); ``` Events carry `bigint` values, so a plain `JSON.stringify` throws without the replacer. ## Capture events in a test `debugCollector()` returns a sink and typed filters over what it received. Each collector is independent, so parallel tests can each have their own. ```ts import { SomniaMarkets, debugCollector } from "@somnia-chain/markets-sdk"; const c = debugCollector(); const exchange = new SomniaMarkets({ ...config, debug: c.sink }); await exchange.trader.placeOrder(params); expect(c.starts("trade.execute").length).toBeGreaterThan(0); // 2 when a first order also sent an approve expect(c.ends("trade.execute").every((e) => e.error === undefined)).toBe(true); ``` `c.starts(name?)`, `c.ends(name?)`, `c.annotations(name?)`, and `c.logs(scope?)` filter `c.events`. ## Send spans to a tracer The span events map onto OpenTelemetry (`name`, `data` as attributes, `error` as status, `parentId` as parent). A sink that keeps a `Map` from span id to tracer span calls `startSpan` on `phase: "start"` and `end()` on `phase: "end"`; the tracer dependency stays in your app. ## What to look for | Symptom | Where it shows | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | A write is slow | `trade.execute` duration, split into `trade.signCall` and `trade.broadcast`; `trade.confirm` appears only on the external-wallet path, where the receipt is read separately | | A watch never goes live | The `liveTail.hydrate:` span ends with `error` set. In React, a `hooks` log line at level `warn` reads `watch failed for …` | | A first write does an extra round-trip | An `approve` transaction before the order: the allowance is cached per token and spender afterwards | The SDK swallows a sink that throws. A broken sink never breaks trading. --- # /docs/typescript/reference/configuration # Configuration This page lists every field a `SomniaMarkets` instance accepts, with its type, whether it is required, and its default. The same fields, minus the three signer fields, form `ClientConfig`, the configuration of the engine. For the values to put in these fields on each network, see [Networks and endpoints](./networks-and-endpoints.md). ```ts import { SomniaMarkets } from "@somnia-chain/markets-sdk"; const exchange = new SomniaMarkets(config); // config: SomniaMarketsConfig ``` ## `SomniaMarketsConfig` `SomniaMarketsConfig` is `ClientConfig` plus the signer fields `privateKey`, `account`, and `walletClient`. | Field | Type | Required | Default | Description | | ---------------- | ----------------------------- | -------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `indexerUrl` | `string` | yes | none | Envio/Hasura GraphQL endpoint over HTTP. A same-origin relative path is accepted in a browser. | | `chain` | `Chain` (viem) | yes | none | The chain the markets live on. | | `wsRpcUrl` | `string` | no | `chain.rpcUrls.default.webSocket[0]` | The WebSocket RPC endpoint. It is the only chain transport: subscriptions, reads, and writes all use it. There is no HTTP fallback. Required when `chain` carries no WebSocket URL. | | `indexerHeaders` | `Record` | no | none | Extra headers on every indexer request, for example a Hasura admin secret. Server-side only. | | `signal` | `AbortSignal` | no | none | Aborts in-flight indexer reads. Client-wide, not per read. An abort re-throws the caller's own reason, not an `IndexerError`. Chain reads are not covered; they have a 4-second request timeout of their own. | | `fees` | `FixedFees` | no | `DEFAULT_FEES` | Fixed EIP-1559 fees for SDK-signed writes. | | `addresses` | `SomniaMarketsAddresses` | no | `{}` | Protocol contract addresses. Every entry is optional. A method that needs a missing address throws `NotConfiguredError` when it is called. | | `priceFeed` | `PriceFeedConfig` | no | none | The realtime price-feed endpoint. Required only by the price methods that fetch or watch (`watchPrice`, `fetchPrice`, `fetchPriceOHLCV`, and the client's `fetchPrice*` and `listPriceFeeds`). The `getLivePrice*` reads return `null` or `[]` until a watch is open. | | `debug` | `(event: DebugEvent) => void` | no | none | Receives structured debug events. When unset the SDK emits nothing and does no debug-only work. | | `privateKey` | `` `0x${string}` `` | no | none | A local signing key. The SDK signs locally and confirms in one round-trip. | | `account` | `Account \| Address` | no | none | A viem account, or a plain address to trade as through `walletClient`. | | `walletClient` | `WalletClient` | no | none | An external signer, for example an injected browser wallet. | ### Signer resolution A method that writes, or reads data scoped to the caller, resolves the caller's address in this order: `walletClient.account.address`, then `account.address`, then `account` when it is a string, then the address derived from `privateKey`. When none is set, `walletAddress` is `undefined` and every authenticated method throws `SignerRequiredError`. `setSigner(signer)` replaces the signer after construction. Passing `{}` removes it. Live watches and market data are unaffected. ### Signer paths | Aspect | `privateKey` or a signing `account` | `walletClient` | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | Who signs | The SDK, locally | The wallet, after a user prompt | | Fees and gas | The fixed values from `fees` and the gas ceiling | The same fixed values, passed to the wallet as `maxFeePerGas`, `maxPriorityFeePerGas`, and `gas` | | Send path | `realtime_sendRawTransaction`: send and receipt in one round-trip; falls back to `eth_sendRawTransaction` when the node does not serve it | `eth_sendTransaction` through the wallet; the receipt is read on each new block head over the SDK's WebSocket | | Reverts | Decoded by replaying the failed call at the receipt's block | Surfaced by the wallet's simulation before the prompt, with revert data | | Approvals | One `approve(maxUint256)` per token and spender, on the first order that needs it, cached for the trader's lifetime | The same, as a second wallet prompt | | Nonce | Tracked locally after one fetch; reset on a rejected send | Managed by the wallet | ### Lazy connections The viem chain WebSocket opens on the first chain read, write, or watch. An instance that only performs indexer reads never opens one. The price-feed WebSocket opens on the first `watchPrice`. `close()` stops the watches and channels and closes every socket the instance opened, both the price-feed WebSockets and the viem chain transport, so a Node process exits on its own afterwards. Instances sharing a `wsRpcUrl` share one chain socket, which closes when the last of them closes. ## `FixedFees` | Field | Type | Description | | ---------------------- | -------- | ----------------------------------------------------------------------------------- | | `maxFeePerGas` | `bigint` | Fee ceiling in wei per gas. The unspent margin above base fee plus tip is refunded. | | `maxPriorityFeePerGas` | `bigint` | Tip in wei per gas. | `DEFAULT_FEES` is `{ maxFeePerGas: 60_000_000_000n, maxPriorityFeePerGas: 0n }`: a 60 gwei ceiling and no tip. ### Gas Every SDK-signed write uses a fixed gas ceiling of 10,000,000 gas. Gas is never estimated. Unused gas is not charged. The mempool accepts a transaction only when the account holds `gas × maxFeePerGas` on top of the transaction value: 0.6 STT or SOMI at the defaults. A lower-level write accepts a per-call `gas` override only when its public parameter type declares one. Unified exchange methods such as `createOrder` and `cancelOrder` do not expose that override. ## `SomniaMarketsAddresses` Every field is optional and typed `Address`, except `lend`. | Field | Used by | | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `collateral` | The venue's collateral ERC-20. `faucet()` mints it on test networks. | | `testUsdc` | Legacy alias for `collateral`. `collateral` takes precedence. | | `binaryModule` | Complete-set mint and redeem, market creation, hub-approval reads, system diagnostics. | | `marketCreator` | The live tail watches `MarketCreated` on it to discover new binary markets. | | `clobFactory` | System diagnostics fallback. | | `binaryPoolImpl`, `binaryPoolBeacon` | Surfaced to apps. Not read by the SDK. | | `binarySettlement` | `redeemDirect`, `claimOwed`, `getSettlement`. | | `operatorPermissionsRegistry` | Operator approval of a stop-order registry. Discoverable at runtime with `getOperatorPermissionsRegistry(pool)`. | | `marketsCore` | Operator and venue reads, `createOperatorAdmin`. | | `collateralRouter` | The native-token and Permit2 complete-set path (`mintSetNative`, `mintSetPermit2`, `redeemNative`). | | `marketCreatorFactory`, `marketCreatorFactoryV2` | `createMarketCreatorAdmin`. | | `oracleHub` | OracleHub reads and `createOracleHubAdmin`. | | `perpPoolFactory` | Perp discovery when the indexer has no perp rows. Normally unnecessary: `loadMarkets` resolves the factory from `MarginBank.getSystemConfig()`. When set it takes precedence. | | `lend` | `LendAddresses` for the third-party SomniaLend deployment. Backs `client.lend`. | | `fakeOracle` | `resolve` and `voidMarket` on demo stacks. | | `oracleAdapterFactory`, `sharedOracleAdapter` | Deprecated. Kept so old configurations type-check. Not read. | `SOMNIA_MAINNET_ADDRESSES` and `SOMNIA_TESTNET_ADDRESSES`, exported from the root entry, hold the current deployments. `SOMNIA_MAINNET_LEND` and `SOMNIA_TESTNET_LEND` hold the SomniaLend addresses and are already included in the two address constants. ## `PriceFeedConfig` | Field | Type | Required | Default | Description | | ------- | -------- | -------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `url` | `string` | yes | none | HTTP GraphQL endpoint of the price-feed indexer. One endpoint serves every asset. | | `wsUrl` | `string` | no | `url` with `http` replaced by `ws` | WebSocket GraphQL endpoint for live subscriptions. | | `quote` | `string` | no | none | Quote asset to pin every read to, case-insensitive. When unset, a base that trades against two quotes is double-counted. | `SOMNIA_TESTNET_PRICE_FEED` is `{ url: "https://price-feed.dev.oracle.somnia.host/v1/graphql", quote: "USDC" }`. `SOMNIA_MAINNET_PRICE_FEED` is `{ url: "https://price-feed.prd.oracle.somnia.host/v1/graphql", quote: "USDC" }`. They index different chains; see [networks and endpoints](./networks-and-endpoints.md). ## Transport constants | Constant | Value | Where | | --------------------------- | ------------------------------ | ------------------------------------------------------------ | | WebSocket request timeout | 4,000 ms | Every chain read and write. | | Indexer request timeout | 30,000 ms | Every indexer read. | | Default gas ceiling | 10,000,000 | Every SDK-signed write. Not exported. | | `DEFAULT_FEES.maxFeePerGas` | 60 gwei | Exported from the root entry. | | Reconnect backoff | 500 ms, doubling to an 8 s cap | Live watches after a socket error. | | Watch linger | about 30 s | Time a scope stays materialised after its last handle stops. | --- # /docs/typescript/reference/networks-and-endpoints # Networks and endpoints This page lists the Somnia networks and the endpoint and address values that go into a [configuration](./configuration.md). The SDK accepts a viem `Chain`. The address constants come from the SDK root entry. ## Chains Use viem's `somnia` or `somniaTestnet` definition where the table names that export. Set `wsRpcUrl` explicitly because these viem definitions do not include a WebSocket URL. Define Elwood, Hideki, or the local chain as a custom viem `Chain` when you need those networks. | viem export | Chain id | Name | Native currency | Block time | HTTP RPC | WebSocket RPC | | --------------- | -------- | --------------------- | --------------- | ---------- | ------------------------------------------------- | -------------------------------------------------- | | `somnia` | 5031 | Somnia | SOMI (18) | 100 ms | `https://api.infra.mainnet.somnia.network` | `wss://api.infra.mainnet.somnia.network/ws` | | `somniaTestnet` | 50312 | Somnia Testnet | STT (18) | 100 ms | `https://api.infra.testnet.somnia.network` | `wss://api.infra.testnet.somnia.network/ws` | | custom | 50313 | Somnia Elwood Testnet | STT (18) | 100 ms | `https://api.elwood.infra.testnet.somnia.network` | `wss://api.elwood.infra.testnet.somnia.network/ws` | | custom | 50383 | Hideki Testnet | STT (18) | 10 ms | `https://api.hideki.infra.testnet.somnia.network` | `wss://api.hideki.infra.testnet.somnia.network/ws` | | custom | 31337 | Somnia Local | STT (18) | none | `http://127.0.0.1:8545` | `ws://127.0.0.1:8545` | Shannon also serves `https://dream-rpc.somnia.network` and `wss://dream-rpc.somnia.network/ws` as secondary RPC URLs for the same network. Block explorers: `https://explorer.somnia.network` (mainnet) and `https://shannon-explorer.somnia.network` (Shannon). Elwood, Hideki, and local carry no explorer. Multicall3: mainnet `0x5e44F178E8cF9B2F5409B6f18ce936aB817C5a11`, Shannon `0x841b8199E6d3Db3C6f264f6C2bd8848b3cA64223`, Hideki `0x540B091b608f54E603c5dC19F6b2d955e1d2D131`. Elwood and local carry none. ## Somnia Markets deployments | Network | Indexer GraphQL | Address constant | | ----------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------- | | Mainnet (5031) | `https://prd.smk.somnia.host/v1/graphql` | `SOMNIA_MAINNET_ADDRESSES` | | Shannon testnet (50312) | `https://dev.smk.somnia.host/v1/graphql` | `SOMNIA_TESTNET_ADDRESSES` | | Local anvil (31337) | `http://localhost:8085/v1/graphql` when started with `demo-clob.sh up` | Resolved from the local manifest through `@somnia-chain/deployments/local` | The two address constants share the protocol contracts (`binaryModule`, `binaryPoolBeacon`, `binaryPoolImpl`, `marketsCore`, `oracleHub`, `binarySettlement`, `clobFactory`, `collateralRouter`, `marketCreatorFactory`) and differ in `collateral`, `marketCreator`, and `lend`. | Field | Mainnet | Shannon | | ------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------ | | `collateral` / `testUsdc` | `0x00000022dA000002656c64D9eA6011ea952D008A` | `0x70a86D8842FB63C4Ad2b7cdddF530eBf1BB25d8E` (tUSDC, 6 decimals, has `faucet`) | | `marketCreator` | `0xfe81C4e8EfFb7df27Eb21881f80AF2BF8DCF0c39` | `0x138CfA6b80475b8c03d7E468b2442278E51e645a` | | `lend` | `SOMNIA_MAINNET_LEND` | `SOMNIA_TESTNET_LEND` | Addresses change with deployments. The constants in the installed SDK version are the source of truth; the values above are the ones current at the time of writing. ## Testnet tokens | Token | Address on Shannon | Decimals | Role | How to obtain | | ----- | -------------------------------------------- | -------- | --------------------------------------------------- | --------------------------------------------------------------------- | | STT | native | 18 | Gas, and the base of `SOMI/USDso` | Faucets listed in [Get testnet funds](../how-to/get-testnet-funds.md) | | USDso | `0x9c32f3827a1a99f0cf9b213de8b53ec3d57bb171` | 18 | Quote of the spot pairs and settlement of the perps | Public `mint(address,uint256)` | | tUSDC | `0x70a86D8842FB63C4Ad2b7cdddF530eBf1BB25d8E` | 6 | Collateral of the binary markets | `exchange.trader.faucet()` | ## Price feed | Network | Endpoint | Constant | | --------------- | -------------------------------------------------------------------- | --------------------------- | | Somnia mainnet | `https://price-feed.prd.oracle.somnia.host/v1/graphql`, quote `USDC` | `SOMNIA_MAINNET_PRICE_FEED` | | Shannon testnet | `https://price-feed.dev.oracle.somnia.host/v1/graphql`, quote `USDC` | `SOMNIA_TESTNET_PRICE_FEED` | These are two separate deployments. Each one indexes the `PriceFeedScheduler` on its own chain. Use the feed that matches the chain the client runs on. A mainnet client that uses the testnet feed reads prices from chain 50312. The mainnet feed carries fewer symbols than the testnet feed. Code written for the testnet asset list can therefore fail on mainnet. Read the feed catalog to learn which bases exist. A base the feed does not carry returns no rows. It does not raise an error. ## Peer dependencies | Package | Range | Required | | -------------------------- | -------- | ----------------------------------------------- | | `viem` | `^2` | yes | | `react` | `>=18` | only for `@somnia-chain/markets-sdk/react` | | `@somnia-chain/reactivity` | `^0.2.1` | only for `@somnia-chain/markets-sdk/reactivity` | The package is published on the public npm registry from version 0.20.0. Node.js 22 or newer provides the global `WebSocket` the chain transport uses. --- # /docs/typescript/reference/symbols # Symbols This page describes the symbol grammar of the exchange API (`SomniaMarkets`). A symbol names a market; a tradable symbol names something an order can be placed on. Every method that takes a symbol also takes a raw chain reference. ## Grammar | Market kind | Market symbol | Tradable symbols | Example | | ---------------------- | --------------------------- | ----------------- | ---------------------------- | | Spot | `BASE/QUOTE` | the market symbol | `SOMI/USDso` | | Perp | `BASE/QUOTE:SETTLE` | the market symbol | `BTC/USDso:USDso` | | Binary | `ASSET-STRIKE-EXPIRY/QUOTE` | `…#YES`, `…#NO` | `BTC-95000-31DEC26/USDC#YES` | | Categorical (reserved) | `NAME/QUOTE` | `…#OUTCOME` | `US-ELECTION-28/USDC#TRUMP` | The part before `#` follows the conventions of exchange tooling such as ccxt. The `#OUTCOME` suffix is specific to this SDK. `UnifiedMarket.type` is `"spot"`, `"swap"` (a linear perp), `"binary"`, or `"categorical"` (reserved). ## Synthesis rules The SDK synthesises symbols from the indexed market row. - Token codes are the ERC-20 `symbol()` values, stripped to `[A-Za-z0-9.]`. Case is preserved: `USDso` and `USDC.e` keep their casing. - `STRIKE` is the strike as a decimal string with trailing zeros removed. A series market with strike `0` renders `0`, for example `ETH-0-04SEP26/tUSDC`. - `EXPIRY` is `DDMONYY` in UTC, for example `31DEC26`. An expiry that is not at 00:00 UTC appends `-HHMM`, for example `03JUL26-0930`. - A collision between two markets appends `-XXXX` to the base side, where `XXXX` is the last four hexadecimal digits of the market id, upper-cased. ## Raw references Every exchange-API method accepts, in place of a symbol: | Reference | Format | Resolves to | | -------------------- | ------------------------------------- | ----------------------- | | Pool address | 40 hexadecimal digits with `0x` | The market on that pool | | Market id | 40 or 64 hexadecimal digits with `0x` | The market | | BinaryMarket address | 40 hexadecimal digits with `0x` | The binary market | A binary market addressed without an outcome resolves to outcome 0, `YES`. ## Resolution `exchange.market(ref)` returns a `Tradable`: | Field | Type | Description | | -------------- | --------------------- | ------------------------------------------------ | | `market` | `Market` | The native market row. Narrow on `marketType`. | | `marketSymbol` | `string` | The market symbol, without outcome suffix. | | `symbol` | `string` | The tradable symbol. | | `outcome` | `string \| undefined` | `"YES"` or `"NO"` on binary markets. | | `outcomeIndex` | `number \| undefined` | `0` for YES, `1` for NO. | | `pool` | `Address` | The pool that receives orders for this tradable. | `market(ref)` throws `InvalidInputError` when: - a chain reference is unknown, including before `loadMarkets()` has run: `unknown market ref … — call loadMarkets() first`; - a symbol is unknown, including before `loadMarkets()` has run: `unknown symbol … — call loadMarkets() first`; - an outcome suffix is given on a spot or perp market: `… is a SPOT market — it has no outcomes`; - the outcome does not exist: `… has no outcome "X" (has: YES, NO)`. `exchange.symbols` lists every tradable symbol. `exchange.markets` maps market symbols to `UnifiedMarket` rows. Both are populated by `loadMarkets()`. ## Prices and sides per tradable Numbers are expressed in the tradable's own terms. - Spot and perp: price is quote per base; `buy` buys the base. - Binary `#YES`: price is the YES probability in `(0, 1)`; `buy` buys YES shares. - Binary `#NO`: price is the NO probability, `1 − YES`; `buy` buys NO shares. The conversion to the pool's YES-terms book is internal. `mintSet`, `burnSet`, and `redeem` take the market symbol or either tradable; they act on the market. --- # /docs/typescript/reference/units-and-scales # Units and scales This page lists every numeric convention the SDK uses, which surface uses it, and the helpers that convert between them. The exchange API (`SomniaMarkets`) speaks in human units. The engine (`SomniaMarketsClient`, the trader) and the indexer speak in raw integers. ## Amounts and prices | Convention | Type | Used by | Example | | --------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------- | | Human units | `number` | Every `SomniaMarkets` method and struct | `10` shares, price `0.62` | | Raw token units | `bigint` on writes and chain reads; decimal `string` on indexer reads | `SomniaMarketsClient`, `Trader`, `Market` rows, every `info` payload | `620000n` for 0.62 with 6 decimals | A raw amount is scaled by the token's decimals. The scale differs per market kind: | Market kind | Quantity scale | Price scale | | ----------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | | Spot | `baseDecimals` of the pair | `quoteDecimals` of the pair (quote per one base) | | Perp | `baseDecimals` | `quoteDecimals` | | Binary | collateral decimals (`DECIMALS`, 6, on every deployed venue) | collateral decimals; the price of one YES share in collateral, which equals the YES probability | `SpotMarket.baseDecimals` and `quoteDecimals` come from the indexed row. Spot markets are not assumed to have 6 decimals: `SOMI/USDso` has 18 and 18, `WBTC/USDso` has 8 and 18. ### Grids | Field | Meaning | | ------------- | ---------------------------------------------------------------------------------------------- | | `tickSize` | Raw price step. `UnifiedMarket.precision.price` is the number of decimal places that step has. | | `lotSize` | Raw quantity step. `UnifiedMarket.precision.amount` is its decimal places. | | `minQuantity` | Raw minimum order quantity. `UnifiedMarket.limits.amount.min` is its human value. | `createOrder` aligns price and quantity to these grids before sending. A buy price rounds down, a sell price rounds up, a quantity rounds down. `priceToPrecision` and `amountToPrecision` round down for both sides. ### Conversion helpers All helpers are exported from the root entry and default `decimals` to `DECIMALS` (6). | Helper | Signature | Behaviour | | ---------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `fromHuman` | `(human: number \| string, decimals?) => bigint` | Converts a human value to raw. A `number` with more fraction digits than `decimals` is rounded half away from zero: `fromHuman(0.1234567, 6)` is `123457n`. A `string` with at most `decimals` fraction digits is parsed exactly. Throws `InvalidInputError` on a non-finite number. | | `toHuman` | `(raw: bigint \| string, decimals?) => number` | Converts raw to a `number`. Not exact past about 15 significant digits; suitable for display. | | `toHumanString` | `(raw: bigint \| string, decimals?) => string` | Converts raw to an exact decimal string. | | `probabilityToPrice` | `(p: number, decimals?) => bigint` | A YES probability in `[0, 1]` to a raw YES price. Throws `InvalidInputError` outside the range, including `NaN`. | | `priceToProbability` | `(raw: bigint \| string, decimals?) => number` | A raw YES price to a probability. | | `balanceFloor` | `(raw: bigint, decimals?) => number` | The largest human value that converts back to at most `raw` through `fromHuman`. Spending `balanceFloor(raw)` never exceeds `raw`. | | `floorRawBalance`, `ceilRawAmount` | `(raw, decimals, quantum)` | Quantum-aligned floor and ceiling. | ## Basis points | Unit | Scale | Used by | | --------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | Basis points (bps) | 1 bps = 0.01 % | Venue fees: `getMaxVenueFeeBps`, `MarketFees`, `getMaxLeverage` limits, `cexRateBps` in portfolio analytics | | Basis points × 1000 | 1,000 = 1 bps | Builder fees: `builderFeeBpsTimes1k` on order placement, `maxFeeBpsTimes1k` on `approveBuilder`, `getMaxBuilderFeeBpsTimes1k` | | Leverage in bps of 1× | 10,000 = 1.00×, 200,000 = 20× | Perp leverage: `getPerpLeverage`, `setPerpLeverage`, `getPerpMaxLeverage` | `5_000n` as `maxFeeBpsTimes1k` allows up to 5 bps. ## Fixed-point rates | Unit | Scale | Used by | | ---------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | Wad | 1e18 | SomniaLend health factor (`maxUint256` when the account has no debt); perp funding rates (`FUNDING_PRECISION`, `1_000_000_000_000_000_000n`) | | Ray | 1e27 | SomniaLend rates and indexes. `lendRayRateToApy(rateRay)` returns a `number` APY; `RAY` is `10n ** 27n`. | | Price feed | 1e18 (`PRICE_FEED_DECIMALS`) | Oracle index prices. `LivePrice.price` and `ema` are `number`; `raw` is the exact string. | A perp funding rate is a fraction per calculation window, 28,800 seconds (8 hours) on every live pool. `fundingRate8h`, `fundingRate1h`, `fundingRatePerInterval`, and `annualizedFundingRate` renormalise it. `UnifiedFundingRate.fundingRate` from `fetchFundingRate` is already per 8 hours as a `number`. ## Time | Unit | Used by | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Unix seconds, as `string` | Indexer rows: `createdAt`, `lastTradeAt`, `placedAtTimestamp`, candle `bucketStart` | | Unix milliseconds, as `number` | Every `SomniaMarkets` struct (`timestamp`), `datetime` as ISO-8601; `since` parameters of `fetchTrades`, `fetchMyTrades`, `fetchOHLCV`; reactivity schedule timestamps | | Unix milliseconds, as `bigint` | Native `SomniaBlock` consensus timestamps | | Unix nanoseconds, as `bigint` | Order expiry: `expireTimestampNs` on `placeSpotOrder`, `placePerpOrder`, and the batch requests. The SDK default is about 50 years ahead. | Candle intervals: `CANDLE_INTERVALS` is `[60, 300, 900, 3600, 14400, 86400]` seconds. `TIMEFRAMES` maps the exchange strings `1m`, `5m`, `15m`, `1h`, `4h`, `1d` to those seconds. Price-feed candles use `1m`, `1h`, `1d` on the exchange and `M1`, `H1`, `D1` on the client. `UnifiedOHLCV` rows are `[ms, open, high, low, close, volume]`. On `fetchOHLCV` the last element is base volume. On `fetchPriceOHLCV` it is the number of oracle updates in the bucket, not volume. ## Struct conventions | Struct | Convention | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `UnifiedBalance` | `free === total` and `used` is `0` for spot and binary holdings. Funds locked in a resting order live in the pool, not the wallet, and do not appear. Perp collateral is locked in the MarginBank and does not appear either; `client.getMarginAccount(marginBank, account)` reads it. | | `UnifiedOrder.type` | Present only on the order `createOrder` returns. Absent on orders read from the indexer (`fetchOrders`, `fetchOpenOrders`, `watchOrders`): the pools do not emit the order type. | | `UnifiedStopOrder.type` | Always present: the stop registry emits it. | | `UnifiedOrder.id` | The pool's order id as a decimal string; the transaction hash when nothing rested. | | `info` | Structs that wrap a native row or write result carry the raw payload under `info`. Aggregate and tuple results such as `UnifiedBalance`, `UnifiedBalances`, and `UnifiedOHLCV` do not. | ## Identifiers | Identifier | Format | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Order id | Decimal string on the exchange API (`UnifiedOrder.id`), on live-store rows, and on indexer rows; `bigint` on trader results and chain reads such as `getOwnOpenOrdersOnchain`. When nothing rested, `UnifiedOrder.id` falls back to the transaction hash. | | Fill id | `${blockNumber}_${logIndex}` | | Trade id in `MarketActivity` | `TRADE:` followed by the fill id | | ERC-6909 outcome id | `(pool << 72) \| (nonce << 8) \| outcomeIndex`; `outcomeId`, `decodeOutcomeId`, `marketKey` encode and decode it | | Market type tag | `bytes4`; `MARKET_TYPE_BINARY_V1` is `0x06c65d9f` | ## Order enumerations | Constant | Values | | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | `ORDER_TYPE` | `LIMIT: 0`, `FILL_OR_KILL: 1`, `MARKET: 2` (immediate-or-cancel), `POST_ONLY: 3` | | `SELF_MATCHING_OPTION` | `CANCEL_TAKER: 0` (SDK default), `CANCEL_MAKER: 1` | | `ORDER_KIND_SIDE` | `["BUY_YES", "SELL_YES", "BUY_NO", "SELL_NO"]`, indexed by the pool's `kind` | | `UnifiedOrderStatus` | `"open"`, `"closed"` (fully filled), `"canceled"` (explicit cancel, or an unfillable immediate-or-cancel remainder), `"expired"` | | `CreateOrderParams.timeInForce` | `"GTC"` (default), `"IOC"`, `"FOK"`, `"PO"` | --- # /docs/typescript/reference/read-tiers # Read tiers This reference lists the sources used by SDK reads, watches, and status accessors. Use it to budget startup dependencies and requests, and to decide whether a value is fresh enough for your application. [Architecture](../ARCHITECTURE.md) explains transport ownership. ## The tiers | Tier | Source and freshness | Startup requirements | Cost | | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | Market live store | Main-indexer snapshot, then applied chain events. Values reflect the last applied events, not a guarantee of the current head. | Market watches need the main indexer for hydration and chain RPC for subscriptions and backfill. A user watch hydrates indexed history; live updates require watched markets. | Synchronous selectors make no requests. Cold hydration, backfill, ongoing subscriptions, and recovery have network cost. | | Chain | Chain RPC, normally over the owner's WebSocket. Reads reflect the blocks served by the node; a group of reads need not share one block. | A chain WebSocket endpoint and any method-specific contract addresses. | One or more RPC calls, sometimes cached or batched. Parallel calls do not guarantee one round-trip. | | Main indexer | Envio/Hasura GraphQL over HTTP. Values reflect indexed state and can lag the chain. | The main indexer endpoint; aggregate reads can require privileged headers. | One or more HTTP requests, depending on pagination and composition. No fixed freshness delay is guaranteed. | | Price-feed indexer and live price store | Separate price-feed Hasura service. HTTP reads and subscription updates reflect its indexed prices, not direct chain prices. | Price-feed HTTP configuration; watches also need its Hasura WebSocket endpoint. | Fetches make HTTP requests. Watches hydrate over HTTP and open one socket per watched asset key. Store selectors are synchronous and make no requests. | Client construction currently requires `indexerUrl`, even if the caller only uses chain reads. This configuration requirement does not mean that every method requests the main indexer. The chain socket opens lazily on chain I/O. Price-feed transport and failures are separate from the market store. A result can combine tiers with different timestamps. The SDK does not generally compare indexed state with the current chain head to certify freshness. Check the method-specific inputs below before treating a derived value as current. ## Return contract - An indexer point read resolves to `null` when the row does not exist and throws `IndexerError` when the request fails. - An indexer list read resolves to `[]` when there are no rows and throws `IndexerError` when the request fails. - A chain read throws on failure. It never returns `null` in place of a failure. - A live-store read returns empty data for a market with no active watch. `getWatchStatus(pool)` is `"unwatched"` in that state. - A live price read keeps answering with its last values after the server rejects the asset's subscription. `getPriceStatus(asset)` is `"error"` in that state, and the rejection is also emitted as a `warn` event on the debug channel. ## Exchange API (`SomniaMarkets`) | Method | Tier | | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `loadMarkets`, `fetchMarkets` | Indexer, plus chain reads for perp discovery and token symbols | | `fetchOrderBook` | Chain | | `fetchTrades`, `fetchOHLCV`, `fetchOpenOrders`, `fetchOrders`, `fetchMyTrades`, `fetchOpenStopOrders`, `fetchPortfolioAnalytics`, `fetchFundingRateHistory` | Indexer | | `fetchTicker` | Cached market metadata and main-indexer candles; on perps, also best-effort chain state. `last` can fall back to cached market data. `timestamp` is response time, not source freshness. A failed perp state read leaves candle-derived data. | | `fetchBalance` | Loads market/currency metadata through `loadMarkets`, then reads chain token/native balances and main-indexer binary holdings. Cost depends on currencies and metadata discovery. | | `fetchFundingRate`, `fetchPositions` | Chain | | `fetchPrice`, `fetchPriceOHLCV` | Separate price-feed Hasura HTTP | | `market`, `priceToPrecision`, `amountToPrecision` | Local | | `watchOrderBook`, `watchTrades`, `watchOrders`, `watchMyTrades` | Live store. The first call opens the market watch. | | `watchPrice` | Live price store. The first call opens the price watch. | A `watch*` call resolves with the current value on its first call and on every later call resolves when the channel's value changes. ## Engine (`SomniaMarketsClient`) The tables in this section are the canonical Engine inventory. Names refer to `exchange.client`, not similarly named Exchange methods. The inventory guard checks membership only; source and freshness claims require source review. Configuration, cleanup, escape hatches, and capability factories are outside this read inventory. ### Live store | Group | Methods | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Market selectors and status | `getLiveMarkets`, `getLiveMarketByPool`, `getLiveMarketByAddress`, `getLiveFills`, `getLiveUserFills`, `getLiveUserOrders`, `getLiveFundingUpdates`, `getLiveBinaryOrderBook`, `getLiveBinaryOrderBookByMarket`, `getLiveSpotOrderBook`, `getLiveStatus`, `getWatchStatus`, `isTailing`, `subscribeLive` | | Price feed | `getLivePrice`, `getLivePrices`, `getLivePriceTicks`, `getLivePriceFeedInfo`, `getPriceStatus`, `subscribePrices` | | Watches | `watchMarket`, `watchMarkets`, `watchUser`, `watchPrice`, `watchPrices` | ### Chain | Group | Methods | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Books and orders | `getBinaryOrderBook`, `getSpotOrderBook`, `getOrderOnchain`, `getOwnOpenOrdersOnchain`, `getAllOpenOrdersOnchain` | | Markets and system | `getMarketOnchain`, `getContractMeta`, `getHeadBlock`, `getSystemInfo`, `getTransactionSummary`, `getPoolCreator`, `getFreePools`, `getOnchainResolutionPrice`, `getMaxVenueFeeBps`, `encodeBinaryVenueFeeParams` | | Balances and allowances | `getErc20Balance`, `getErc20Metadata`, `getErc20Allowance`, `getBalances`, `getNativeBalance`, `getOutcomeBalance`, `getVaultBalance`, `getOwnLockedBalance`, `getLockedTokenBreakdown` | | Operators and builders | `getOperatorPermissionsRegistry`, `isOperatorAuthorized`, `isGloballyApproved`, `isApprovedForPool`, `getMaxBuilderFeeBpsTimes1k`, `getBuilderApproval`, `getEffectiveBuilderApproval`, `getStopOrderSomiPayment`, `getPerpStopOrderSomiPayment`, `getPerpStopOrder`, `getUnclaimedPerpStopSomi`, `getManualVaultMode`, `getAutoPullRequirement`, `convertToQuoteAtPriceCeil` | | Perps | `getPerpState`, `getPerpFeedStatus`, `getPerpPosition`, `getMarginAccount`, `getAccountHealth`, `getLiquidationPrice`, `previewPerpLiquidationPrice`, `getPerpLeverage`, `getPerpPositionAnalytics`, `listPerpPositionAnalytics`, `getMaxPerpOrderSize`, `previewPerpOrderMargin`, `previewPerpClosePnl`, `getPerpSideHolders`, `getBankruptcyPrice`, `getPerpSystemConfig`, `getInsuranceFundState`, `getLiquidationEngineConfig`, `tryGetPerpAccountEquity`, `getPerpCollateralBasis`, `listPerpPoolStatuses`, `listTradeablePerpPools`, `isPerpPoolRegistered`, `getPerpRiskParams`, `getPerpHealthSnapshot`, `getEffectiveImfBps`, `getPerpMaxLeverage`, `getPerpLeverageImSurcharge`, `tryGetPerpLeverageImSurcharge`, `readPerpMarketFromChain`, `quotePerpFundingPayer`, `getPerpMainFunding`, `getPerpLinkedWalletRegistry`, `getPerpWalletPullCapacity`, `getPerpWalletLinkage`, `listPerpLinkedChildren`, `getPerpMaxLinkedChildren`, `getPerpFundingPremium`, `meetsPerpImForFill`, `quoteMeetsPerpImForOrder`, `quotePerpOrderTopUp` | | Oracle hub | `getSchedulingCost`, `earmarkedOf`, `creditOf`, `outstandingOf`, `withdrawableOf`, `payerCreditOf`, `payerOf`, `resolveReserve`, `quoteCreateMarketValue` | | SomniaLend | `client.lend.listReserves`, `client.lend.getAccount` | ### Indexer | Group | Methods | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Markets | `listMarkets`, `listRegistryMarkets`, `listRegistryMarketsChecked`, `countMarkets`, `countMarketsBounded`, `getMarket`, `getMarketByPool`, `listMarketsByPool`, `listBinaryMarkets`, `listLiveBinaryMarkets`, `listPastBinaryMarkets`, `getBinaryMarket`, `getBinaryMarketByAddress`, `listBinaryVenueIds`, `listBinaryAssets`, `countBinaryMarkets`, `countBinaryMarketsBounded`, `listSpotMarkets`, `getSpotMarket`, `listPerpMarkets`, `getPerpMarket`, `getMarketFees`, `getMarketStatusHistory` | | History | `getCandles`, `getFills`, `getFill`, `getUserFills`, `countUserFills`, `getOrderFills`, `getOrder`, `getOrders`, `getOpenOrders`, `countOrders`, `listSweepableOrders`, `getMarketActivity`, `getTradeContext`, `getRouterActions`, `getUserFillsPage`, `getLatestActiveBlock` | | Portfolios | `getPortfolio`, `getSpotPortfolio`, `getPerpPortfolio`, `getOutcomeBalances`, `getSpotStopOrders`, `listPerpStopOrders`, `listPerpOrderHistory`, `listPerpPositions` | | Resolution | `getMarketResolution`, `getOpeningPrices`, `getResolutionPrices`, `getBookTops` | | Fees and perps history | `listProtocolFees`, `listBuilderFees`, `listSettlementFees`, `listBuilderApprovals`, `getVaultPayoutFallbacks`, `getFundingPayments`, `getMarginEvents`, `listLiquidations`, `getLiquidations`, `listFundingRateHistory`, `listFundingRateCandles`, `listPerpFees`, `getOpenInterestHistory`, `getFundingRateHistory`, `listPerpOrderRejections`, `listPerpInsuranceFundEvents`, `listPerpWalletLinkEvents`, `listPerpMarginPulls`, `listPerpMainFundingEvents` | | Control plane | `listOperators`, `getOperator`, `countOperators`, `listVenues`, `getVenue`, `countVenues`, `listMarketCreators`, `getMarketCreator`, `listOracleAdapters`, `getOracleAdapter`, `listSeries`, `getSeries`, `getOracleQuestion`, `listOracleQuestions`, `getOperatorHubAccount`, `listOperatorHubAccounts`, `listOracleBinds`, `listOracleCallbacks`, `getSyncStatus`, `getPool`, `getPoolBindings` | ### Price-feed HTTP reads | Group | Methods | | -------------------------------- | ------------------------------------------------------------------- | | Current prices and feed metadata | `fetchPrice`, `fetchPrices`, `fetchPriceFeedInfo`, `listPriceFeeds` | | Price history | `fetchPriceHistory`, `fetchPriceCandles` | ### Mixed and derived reads | Inputs and behavior | Methods | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | | Main indexer plus a mandatory chain block timestamp lookup. The timestamp anchors indexed activity; it does not make indexed rows current. | `getBlockActivity`, `getAdjacentActiveBlocks` | | Main-indexer activity. Without a caller-supplied anchor, tries a chain receipt and block lookup first. Failure to obtain that anchor leaves the indexer-only path available. | `getTransactionActivity` | | Synchronous live binary book and stored market decimals. Needs a hydrated market watch for useful depth. | `quoteBinaryOrder` | | Live binary book plus cached chain tick/lot grid. A market-id target can add an indexer lookup when the store cannot resolve its pool. An empty live book is not replaced by an indexer book. | `quoteBinaryStake`, `quoteBinarySell` | | Chain grid read cached per pool for the client lifetime. Later administrative grid changes do not invalidate this cache. | `getBinaryBookParams` | | Chain closing-price view, including its capture state. | `getClosingPrice` | | Main-indexer candles; a market-id target also resolves its pool through the main indexer. | `getMarketStats24h` | | Main-indexer market metadata, fills, router actions, and outcome balances, plus chain book top for the mark clamp. Without configured chain access, uses indexed last price alone; an operational chain failure propagates. | `getBinaryPositionPnL` | | Main-indexer positions and market metadata, fills, router actions, and indexed book tops. All inputs can lag; this does not use the live book or a chain book. | `getOpenPositionsWithPnL` | | Main-indexer positions and resolution data, plus indexed settlement fees for winning markets. This estimates claimable amounts from indexed state. | `getClaimable` | | Independent RPC head, then main-indexer metadata plus processed-block time. Raw measurements, no SDK stale threshold. | `getIndexerFreshness` | | One independent head for response-associated reads, using the same owner. | `createObservedReads` | | Per-asset price watch lifecycle, without I/O. | `getPriceHealth`, `listPriceHealth` | ### Watch startup and updates Engine watches return a handle with `stop()`. Repeated handles for the same scope share its work. The scope normally remains for about 30 seconds after the last handle stops, so a quick remount can reuse it. After teardown, a new watch hydrates again. Market watches hydrate a main-indexer snapshot before chain backfill and live updates. `watchUser` hydrates the account's indexed order/fill history. It opens no subscription of its own. Subsequent account updates come only from market scopes watched by this client; it is not an account-wide chain subscription. Price watches hydrate metadata and recent prices from the separate price-feed HTTP service. Each asset key owns a Hasura socket for its price and tick subscriptions. A resolved watch means its snapshot landed, not that the socket has connected. Check `getPriceStatus` for state. Rejected subscriptions report `error`, while synchronous price reads retain stale values. These failures do not change market-watch status. ## React hooks | Hook family | Tier | | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | | `useLive*`, `useWatchMarket`, `useWatchUser`, `useLiveStatus`, `useIsTailing` | Live store. The pool-keyed hooks open the market watch while mounted. | | `useLivePrice`, `useLivePriceTicks`, `useLivePriceFeedInfo`, `useWatchPrice` | Live price store | | `usePortfolio`, `useMarkets`, `useCandles`, `useFundingRateSeries`, `useMarketFees`, `useOperators`, `useMarketCreators`, `useOracleAdapters` | Indexer | | `useLendReserves`, `useLendAccount` | Chain | `useIndexerQuery` runs the supplied callback on mount, owner or dependency changes, and explicit `refetch`. It does not poll or automatically refresh on live events. The callback determines its source and freshness. The hook passes an abort signal and fences superseded responses; cancellation reaches the request only if the callback forwards that signal to an operation that supports it. Automatic hooks preserve background acquisition semantics: failures use the configured debug/console warning channel and do not throw during render. This includes `useFundingRateSeries`; its `state.error` still contains history query failures. Opt into `useWatchMarketResult`, `useWatchUserResult`, or `useWatchPriceResult` for a typed acquisition error, which a component may explicitly throw into an ErrorBoundary. Missing-provider validation still throws `InvalidInputError`. ## Response-associated indexer observations `client.createObservedReads()` observes one independent RPC head. Its `read` and `batch` methods accept the operations in `ObservedReadOperation`. The roster includes every ordinary main-indexer domain read, including mixed-tier derived reads. `getSyncStatus` and `getIndexerFreshness` are source diagnostics, not row reads. Live-store reads, chain-only reads, write capabilities and the separate price service are excluded. The envelope keeps the domain value in `data`. `observation.latestProcessedBlock` is the minimum metadata watermark across successful contributing responses. Missing metadata in any response leaves it null. `startedAt`, `completedAt` and `responseCount` describe the observation span. The metadata is selected beside the rows in the same GraphQL request, without a separate metadata request. A rejected privileged aggregate attempt does not contribute; its successful fallback does. Observed portfolio reads refresh their scope inside the logical read so a cached pool set cannot hide an older contributing response. These are indexing watermarks. They do not claim each entity changed at that block, that the RPC itself is current, or that separate requests share an atomic historical snapshot. Keep an envelope with its value; later reads cannot update its observation. Create a new observed capability to refresh the shared head. Closing the owner cancels pending observations; a stopped capability cannot reopen transports. `fetchStatus()` remains a local-only three-field chain-tail snapshot. Opt into `fetchDataStatus()` to read RPC and the main indexer once. Its top-level `status` retains chain-tail meaning; `indexer` contains independent measurements and `prices` lists precise per-asset `health`. API-only monitors keep using `client.getSyncStatus(chainId)` with no RPC dependency. The concrete `exchange.client` exposes the additive `SomniaMarketsClientWithObservations` contract. The original `SomniaMarketsClient` interface and existing providers require no extra members. Ordinary reads retain their original document selections and role permissions. Only observed reads select the response watermark. `stopLive()` invalidates observed capabilities without aborting ordinary pending indexer reads; caller cancellation still reaches those reads. ### Consumer example Use the configured exchange in dreamDEX or another consumer. The downstream dreamDEX hook edit remains outside this repository. ```ts const observed = await exchange.client.createObservedReads(); const [markets, count] = await observed.batch([ { operation: "listMarkets", args: [{ limit: 20 }] }, { operation: "countMarkets", args: [] }, ]); console.log(markets.data, markets.observation.latestProcessedBlock); console.log(count.data, count.observation.independentHead.blockNumber); const freshness = await exchange.client.getIndexerFreshness(exchange.client.config.chain.id); console.log(freshness?.lagBlocks, freshness?.lagSeconds); ``` For a local end-to-end observation, start `./demo-clob.sh up`, construct the exchange with the local chain and deployment configuration used by the explorer, and run this example against `http://127.0.0.1:8085/v1/graphql` and `ws://127.0.0.1:8545`. Use chain id 31337. No production configuration or transaction is required. --- # /docs/typescript/reference/errors # Errors This page lists the error classes the SDK throws, the fields each carries, and the contract error names the SDK decodes into `ContractRevertError`. For the decision logic that goes with them, see [Handle errors and reverts](../how-to/handle-errors.md). Every SDK error extends `SomniaMarketsError`, sets `name` to its class name, prefixes its message with `@somnia-chain/markets-sdk: `, and carries the underlying failure in `cause` when it wraps one. ## Classes All classes are exported from the root entry. | Class | Fields | Meaning | Retrying the same call | | --------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | `SomniaMarketsError` | none | Base class. | depends on the subclass | | `InvalidInputError` | none | The call cannot proceed: unknown symbol or reference, unknown timeframe, a method used on the wrong market kind, an amount below one lot, a limit order without a price, a market order against an empty opposite side, a probability outside `[0, 1]`, or a non-finite amount. Most cases are local validation. The empty-book market-order case follows a chain book read and depends on current liquidity. | fails again, except an empty-book market order may succeed after liquidity appears | | `NotConfiguredError` | `what: string` | The client lacks a URL or address the feature needs: `wsRpcUrl`, `priceFeed`, or an entry of `addresses`. Thrown at the first call that needs it, not at construction. The one exception is an empty `indexerUrl`, which the constructor rejects. | fails again | | `SignerRequiredError` | `operation: string` | An authenticated method was called without a `privateKey`, `account`, or `walletClient`. Authenticated methods include `fetchBalance`, `fetchOpenOrders`, `fetchOrders`, `fetchMyTrades`, `fetchPositions`, `watchOrders`, `watchMyTrades`, `exchange.trader`, and every write. | fails again | | `IndexerError` | `operation: string` | An indexer request did not complete: endpoint down, bad URL, HTTP error, GraphQL error, or the 30-second request timeout. Never means "no such row". | may succeed | | `RpcError` | `operation: string` | A JSON-RPC or WebSocket request did not complete: connection refused, 4-second request timeout, dropped subscription, unsupported method. The request never produced a chain answer. | may succeed | | `ContractRevertError` | `errorName?`, `args?`, `reason?`, `data?`, `address?`, `functionName?` | The chain rejected the call. Thrown on send-time rejection, pre-send simulation, a mined receipt with failed status, and `eth_call` reads. | fails again unless state changes | Errors from code the SDK calls but does not own can surface unchanged. This includes a `walletClient` supplied by the app and the client returned by `getViemClient()`. Debug sink failures are different: the SDK contains them so diagnostic code cannot break an operation. An `InvariantError` exists for contradictions in the SDK's own reasoning. It is not exported and indicates an SDK defect. ### `ContractRevertError` fields | Field | Type | Present when | | -------------- | -------------------- | -------------------------------------------------------------- | | `errorName` | `string` | The revert data matched a custom error in `contractErrorsAbi`. | | `args` | `readonly unknown[]` | `errorName` is set. Positional decoded arguments. | | `reason` | `string` | The revert carried a `require` or `revert` string. | | `data` | `string` | The node returned revert data. | | `address` | `string` | The reverting contract is known. | | `functionName` | `string` | The called function is known. | A mined transaction with `status: "reverted"` carries no revert data. The SDK replays the call as `eth_call` at the receipt's block to recover `errorName` or `reason`. When the replay yields nothing, the error is still a `ContractRevertError` and its message ends with `(no revert data recoverable)`. `decodeRevert(caught)` is exported for callers who send transactions themselves. It walks the `cause` chain, decodes the first revert data it finds against `contractErrorsAbi`, and always returns a `ContractRevertError`. It does not check that the input is a revert: a transport error passed to it returns a `ContractRevertError` without `errorName`. ## Absence versus failure | Outcome | Indexer point read (`get*`) | Indexer list read (`list*`) | Chain read | Live-store read | | -------------- | --------------------------- | --------------------------- | ------------------------------------------------------------------ | ------------------------------ | | Row exists | the row | the rows | the value | the value | | No such row | `null` | `[]` | throws `ContractRevertError` or returns the contract's empty value | `[]`, `null`, or an empty book | | Request failed | throws `IndexerError` | throws `IndexerError` | throws `RpcError` or `ContractRevertError` | not applicable | ## Contract error names `contractErrorsAbi`, exported from the root entry, is the generated ABI of every custom error the protocol contracts declare. `ContractRevertError.errorName` is one of its names. The names the exchange API and the trader raise most often: | Area | Error names | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Order validation | `InvalidPrice`, `InvalidQuantity`, `PriceNotAlignedToTickSize`, `QuantityNotAlignedToLotSize`, `QuantityBelowMinimum`, `PriceOutOfBounds`, `PriceTooLarge`, `TooManyRestingOrders` | | Market state | `TradingNotActive`, `UseBinaryPlacement`, `MarketRestricted`, `MarketNotSettled`, `NotFinalized`, `StaleMarketId` | | Order lifecycle | `OrderDoesNotExist`, `IncorrectSender` (a cancel of an order the caller does not own, including an order already cancelled), `OrderAlreadyExpired`, `ExpiredOrderMustBeCancelled`, `NotExpired`, `OrderExpiryBeyondMarket` | | Time in force | `PostOnlyWouldCross`, `FillOrKillNotFillable`, `ImmediateOrCancelNoFill`, `SelfMatchCancelTaker` | | Amend and batch | `AmendOldOrderGone`, `AmendReplacementRejected`, `EmptyOrderBatch`, `BatchTooLarge`, `LengthMismatch` | | Funds | `InsufficientBalance`, `InsufficientVaultBalance`, `ExceedsWithdrawableBalance`, `ERC20InsufficientAllowance`, `ERC20InsufficientBalance`, `InvalidMsgValue`, `NativeAmountMismatch` | | Builder fees | `BuilderNotApproved`, `BuilderFeeExceedsApproval`, `BuilderFeeExceedsCap`, `InvalidBuilder` | | Binary settlement | `NothingToClaim`, `AlreadyClaimed`, `NothingOwed`, `AlreadyFinalized`, `OracleNotAnswered`, `QuestionNotFinal` | | Perps | `NoOpenPosition`, `InsufficientMargin`, `InsufficientMarginForOrder`, `InsufficientMarginAfterWithdrawal`, `MaxPositionSizeExceeded`, `OpenInterestCapExceeded`, `InvalidLeverage`, `MarkPriceUnavailable`, `OraclePriceStale`, `NotLiquidatable`, `PerpPoolNotRegistered` | | Stop orders | `InvalidTriggerPrice`, `LimitPriceIncompatibleWithTrigger`, `InsufficientSomiPayment`, `TriggerTooCloseToEma`, `RefundFailed` | | Operators and venues | `OperatorDisabled`, `OperatorNotActive`, `UnknownOperator`, `UnknownVenue`, `VenuePolicyDenied`, `InsufficientPermission`, `Unauthorized`, `NotOwner` | | Test collateral | `FaucetCapExceeded` | The full list is longer and changes with the contracts. Read it from `contractErrorsAbi` in the installed version. --- # /docs/typescript/explanation/about-the-exchange-instance # About the exchange instance This page discusses why the SDK has one constructible object, `SomniaMarkets`, and what that decision buys and costs. It covers ownership of connections, state, and signers. It does not cover the internals of the live watches; those are in [Architecture](../ARCHITECTURE.md). ## One root, no globals Many chain SDKs expose a set of free functions and a global configuration step: set the RPC once, then call anything from anywhere. This SDK does not. `new SomniaMarkets(config)` creates an instance, and every capability hangs off it: the exchange verbs, the engine at `exchange.client`, the trader at `exchange.trader`, the SomniaLend namespace at `exchange.client.lend`. Nothing that needs a connection is reachable without an instance. The root entry exports only the class, types, pure helpers, constants, and ABIs. The reason is isolation. An instance owns its configuration, its WebSocket, its live store, its watches, its approval cache, its signer, and its local-send queue. Two instances share none of those execution resources. Viem's nonce manager is process-wide and keyed by account and chain, but serialization runs per trader: code that writes concurrently as one account should share one long-lived exchange instead of relying on separate roots to coordinate broadcast acceptance. A bot that trades on two chains constructs two exchanges. A server reuses one long-lived exchange per chain. An indexer-only request may use a short-lived instance because it never opens a socket. A test suite runs cases in parallel with one exchange each. With module-level state, each of those needs a workaround. The cost is one line of plumbing. A React app constructs the exchange once at module scope and passes `exchange.client` to the provider. A script constructs it at the top. There is no `configure()` call to forget and no hidden singleton to reason about. ## Sockets opened late Every instance can talk to the indexer over HTTP and the chain over one WebSocket. A configured price feed is a third, independent backend: its fetches use the feed's GraphQL HTTP endpoint, and `watchPrice` opens a separate GraphQL WebSocket. The chain WebSocket carries log and head subscriptions for market watches, `eth_call` reads, and transaction sends. There is no HTTP RPC path and no polling. Concurrent chain reads pipeline on that socket, so a `Promise.all` of ten reads costs about one round-trip. The chain socket opens on the first chain touch, not at construction, and the price-feed socket opens on the first price watch. `close()` stops active price-feed sockets but leaves the viem chain transport open. An instance that only lists markets or reads candles opens neither socket. This is deliberate: server-side code that renders a page from indexer data pays nothing for transports it does not use, and a misconfigured `wsRpcUrl` surfaces at the first chain call as `NotConfiguredError` rather than as a failed construction. You can think of the instance as a small local node for the markets you care about. It hydrates a snapshot of a market from the indexer once, then follows the chain itself. After that the indexer is only asked for history. ## The signer belongs to the instance A signer is part of the configuration: `privateKey`, `account`, or `walletClient`. The instance derives `walletAddress` from it and uses it for every authenticated verb, read or write. `fetchBalance` and `watchOrders` are authenticated reads: they answer for the signer's address without taking an address parameter. That mirrors how exchange APIs behave, and it is why `SignerRequiredError` is thrown by reads as well as writes. Browser apps rarely have a signer at boot. `setSigner()` exists for them: construct the exchange for public reads, bind the wallet when the user connects, and pass `{}` on disconnect. Watches and market data are unaffected by a signer change; only the trader is rebuilt. An alternative would have been per-call signers, as in `createOrder(symbol, …, { signer })`. That design keeps the instance stateless but pushes the approval cache to the caller, and the cache needs to be per-signer to be correct. Holding the signer in the instance keeps it correct by construction. The trade-off is that one instance trades as one account; an app that trades as several accounts constructs several instances or calls `setSigner` between them. ## Lifecycle `close()` releases the watches, the streaming channels, and every socket and timer the instance opened, including the WebSocket to the node. A Node script that has touched the chain exits on its own once `close()` returns. The instance stays usable afterwards: a later read reopens a connection, and a later `close()` releases that one too. Two instances configured with the same WebSocket URL share one underlying socket, because the underlying viem transport caches sockets per URL and offers no way to opt out; closing one instance therefore leaves the other's socket up until it closes too. That sharing extends to your own application: a socket your code already had open on that URL through viem is not the SDK's to close, so `close()` leaves it alone. Still prefer a long-lived instance over one per server request, because each instance also carries its own market cache and local order-book state. ## Where the design shows through - `exchange.client` is the engine, not a second client. It shares the store and the socket with the exchange, so a live book read through a hook and through `watchOrderBook` are the same data. - `exchange.client.getViemClient()` returns the underlying viem client for anything the SDK does not cover. It is deliberately undecorated: errors from it are viem's, not the SDK's, and it opens the socket if it is not open yet. --- # /docs/typescript/explanation/about-symbols-and-human-units # About symbols and human units This page discusses two choices in the exchange API: markets are addressed by symbols such as `SOMI/USDso`, and quantities are decimal numbers rather than integers scaled by token decimals. Both choices trade exactness for familiarity, and the SDK keeps the exact values within reach. The grammar itself is in the [Symbols reference](../reference/symbols.md) and the scales in [Units and scales](../reference/units-and-scales.md). ## Why symbols The protocol addresses a market by its pool address, and a binary market additionally by a market id and a `BinaryMarket` contract address. Those identifiers are exact and stable, and they mean nothing to a human reading a log line or a config file. Exchange tooling answered this question years ago: a market is `BASE/QUOTE`, a derivative carries its settlement currency after a colon, and a bot's configuration lists symbols. The exchange API adopts that grammar so that code written against ccxt-style venues transfers with little change. The design intent is that the verbs never change again: a new market kind is new data (a `type`, an `outcomes` list), not a new API. Binary markets have no precedent in that grammar. Each market has two things you can trade, YES and NO, and each needs its own price and its own side of the book. The SDK's answer is the `#OUTCOME` suffix: `BTC-95000-31DEC26/USDC#YES` and `…#NO` are two tradables on one market. A market symbol without a suffix resolves to YES, so callers who only think in YES terms can ignore the suffix entirely. The cost of synthesised symbols is that they are derived, not stored. Two markets can render the same symbol, for example two series markets with the same asset and expiry. The SDK breaks the tie deterministically with a four-hex-digit suffix from the market id. That keeps the mapping one-to-one, but it means a symbol can carry a suffix a human did not expect. For that reason every method also accepts the raw pool address or market id in place of a symbol. ## Why human units On chain, a quantity is an integer scaled by the token's decimals, and a binary price of 0.62 is `620000` when the collateral has six decimals. Correct code must carry the decimals with every number, and most bugs in trading code are decimals bugs. The exchange API takes and returns JavaScript numbers in the tradable's own terms: 10 shares at 0.62, 1 SOMI at 0.5 USDso. The SDK converts at the boundary using the decimals it already knows from the market row. The caller never sees a raw integer unless they ask for one. A NO price is the NO probability. The pool keeps a single book in YES terms, and a NO bid at 0.38 is a YES ask at 0.62 on chain. The SDK presents each outcome's own view (prices, sides, and candles are outcome-relative) and performs the complement internally. A caller who buys NO at 0.38 reasons about NO at 0.38. ## What it costs, and how the SDK pays A JavaScript number holds about 15 significant digits. An 18-decimal token amount does not fit. The conversion helper used for display, `toHuman`, is documented as lossy for that reason, and `toHumanString` exists for exact rendering. On the way in, `fromHuman` rounds a value with too many fraction digits rather than throwing. We judged that a computed mid price almost always has too many digits and that rejecting it would hurt more than rounding. A caller who needs exactness passes a string. The exchange structs that wrap a native row or result carry that payload under `info`. An order's `info` is the placement result with the receipt and the decoded fills in bigint. A market's `info` is the indexed row with `tickSize`, `lotSize`, and the token addresses. Aggregate and tuple results such as `UnifiedBalance`, `UnifiedBalances`, and `UnifiedOHLCV` do not have `info`. The engine at `exchange.client` preserves each backend's exact representation: chain reads and writes use bigint, while indexer and live-store numeric fields such as prices and quantities are decimal strings. The SDK aligns prices and quantities to the venue's tick and lot grids before it sends an order, and never against the caller. A buy price rounds down, a sell price rounds up, a quantity rounds down. The returned order echoes the aligned values. This is where the human-unit design most visibly diverges from what the caller typed. It is why the reference says to read `price` and `amount` back from the result rather than assuming the inputs. ## The alternative we did not take A `bigint`-only exchange API would be exact and would match the engine's chain boundary. We judged that it would also reproduce the decimals bugs it exists to remove: every caller would carry `baseDecimals` and `quoteDecimals` through their own code, and the ccxt idiom the API borrows would be lost. A decimal library would be exact and readable, but it would make the SDK impose a number type on every consumer. The chosen design keeps the surface familiar and keeps exactness one property access away. ## Where the protocol shows through Two conventions in the structs are protocol facts that the human-unit layer cannot hide, and the [Units and scales reference](../reference/units-and-scales.md#struct-conventions) records them. Wallet balances report `free === total`, because locked funds sit in the pool rather than the wallet. Orders read back from the indexer have no `type`, because the pools do not emit it. In both cases the SDK reports what it knows rather than guessing. --- # /docs/contracts/raw-integration # Raw Smart-Contract Integration Somnia Markets runs three market families on one on-chain order-book engine: **spot** pairs (`SpotPool`), **binary markets** (`BinaryPool`), and **perps** (`PerpPool`). All three extend the same shared `OrderBook` core, so the placement surface, the order-lifecycle events, and the book-materialization technique are identical across every book; what differs per family is discovery, funding/escrow, and settlement. This guide is how to trade with nothing but an RPC node and the contract ABIs — any language, any stack. It covers the shared core first, then each family in turn, then [materializing a live local order book](#materialize-the-order-book-from-events) from the event stream. Pair it with [Market Making](./MarketMakingTips.md) if you are building a quoting system. (Building a JS/TypeScript app instead? The [SDK](../packages/sdk/README.md) wraps everything here.) What you need to start: contract addresses and signatures. Protocol contracts (the `BinaryMarketsModule` market registry, the `MarketsCore` control plane, the `OutcomeToken6909` singleton) are listed live per network on this explorer's [System page](/system); spot pairs and live binary markets are listed on the [markets page](/); per-market binary addresses are read from the module's registry on-chain ([below](#binary-markets)). The complete Solidity interfaces — everything needed to generate ABIs — are in the [interface reference](#interface-reference) at the end of this guide. ## The shared order-book core Every book — spot, binary, perp — exposes the same placement entrypoint, covering all order types (GTC / `NormalOrder`, `FillOrKill`, `ImmediateOrCancel`, `PostOnly`): ```solidity function placeOrder( bool isBid, uint64 userData, uint256 price, uint256 quantity, uint64 expireTimestampNs, OrderType orderType, SelfMatchingOption selfMatchingOption, address builder, uint96 builderFeeBpsTimes1k ) external payable returns (bool success, OrderId id); ``` - **`expireTimestampNs` is mandatory and nanoseconds** — a future unix-ns timestamp (`now_seconds * 1e9 + lifetime_ns`); zero or past values are rejected. There is no "no expiry" sentinel. - **`success == false` without a revert is a normal outcome** — a `PostOnly` that would cross, a `FillOrKill` that can't fully fill, an IOC that fills nothing. Always branch on it. - **Quantize in integers.** `getOrderBookParameters()` returns `tickSize`, `lotSize`, and `minQuantity` in raw token units; off-grid values revert `InvalidPrice` / `InvalidQuantity`. - **`builder` / `builderFeeBpsTimes1k`** attribute the order to a routing/builder frontend and pay it a per-order fee (basis-points × 1000). Pass `(address(0), 0)` for none. A non-zero fee requires the order owner to have opted the builder in first — `approveBuilder(builder, maxFeeBpsTimes1k)` on the pool (0 revokes) — and is capped by the pool's `getMaxBuilderFeeBpsTimes1k()`; charges emit `BuilderFeeCharged`. Spot, binary and perp pools all accept builder values; an unapproved non-zero fee reverts `BuilderNotApproved` (spot), `BuilderFeeExceedsCap` (binary) or `BuilderFeeExceedsApproval` (perp). - `cancelOrder(id)` / `reduceOrder(id, newQty)` manage resting orders; both revert (rather than no-op) on already-terminal orders — check your local book or `getOrder(id)` first. `cancelExpiredOrders(ids)` and `sweepExpiredAtLevel(isBid, price, maxCount)` are permissionless cleanup — the SDK's `client.listSweepableOrders({ pool?, marketType? })` is the work-list for both, returning `orderId` / `isBid` / `price` per row. Note it is **not** `status: "Expired"`: that status means the order was already swept, whereas a keeper wants orders still `Open` whose expiry has passed. - `OrderId`s are unique **per pool** — always key by `(pool, orderId)`. Reading any book on demand, via `eth_call`: | View | Returns | |---|---| | `getBookLevels(isBid, numLevels)` | Aggregated `(price, quantity)` levels, best first | | `getAllOpenOrdersOffChain(isBid, maxCount, startCursor)` | Full `Order` structs, paginated (`msg.sender` must be `address(0)` — the `eth_call` default) | | `getOrder(orderId)` / `getOwnOpenOrders()` | Single order / caller's open ids | Polling these is fine for a dashboard; a trading system should take one snapshot and apply event deltas — see [materialization](#materialize-the-order-book-from-events). ## Spot markets Each trading pair is its own `SpotPool` — live pairs are listed on the [markets page](/). `getPoolParams()` returns everything static in one call: `(baseToken, quoteToken, makerFeeBpsTimes1k, takerFeeBpsTimes1k, tickSize, minQuantity, lotSize)`. A native-token side is reported as a sentinel token address (not `address(0)`) — resolve it from `getPoolParams` rather than assuming. Spot semantics are the conventional ones: `isBid = true` buys base with quote, a fill is a base ↔ quote swap at the **maker's** resting price, and `userData` is a free 64-bit tag echoed back on the order struct and its `OrderPlaced` event — use it for strategy/generation ids (this is *not* true on the binary books — see below). **Funding.** By default the pool **auto-pulls** the required input from your wallet at placement (ERC-20 `transferFrom` after a one-time approval, or `msg.value` on native pools) and **auto-delivers** proceeds back on fill, cancel, or expiry. Size the pull with `getAutoPullRequirement(owner, isBid, price, quantity, builderFeeBpsTimes1k)`. High-churn integrations should opt out with `setManualVaultMode(true)`: `deposit` once, quote against the vault balance with no per-order token transfers, `withdraw` when rebalancing — for a loop that places and cancels constantly the gas savings compound. **Mark price.** Spot pools push `MarkPriceUpdated(asset, markPrice, rawMidpoint)` whenever the book midpoint advances — an EMA-smoothed midpoint plus the raw `(bestBid + bestAsk) / 2`, an on-chain fair-price feed with no extra infrastructure. ## Binary markets ### Discover markets `BinaryMarketsModule` is the market registry (the `MarketsCore` control plane holds only operators, venues, and module bindings — no markets). Each market is a `MarketRecord` (read via `module.markets(marketId)`): | Field | Use | |---|---| | `pool` | The `BinaryPool` — the order book you trade on | | `market` | The `BinaryMarket` — lifecycle + resolution state | | `collateral` | The ERC-20 quoted against (one per market) | | `originOperatorId` / `originVenueId` | Origin attribution: the uint32 operator id + opaque bytes32 venue id the market was created under | | `yesId` / `noId` | ERC-6909 ids of the outcome positions on the shared `OutcomeToken6909` singleton | | `tradingStart` / `expiry` | Trading window (unix seconds) | Watch the module's `MarketCreated` event to discover new markets — **every** market fires it, whether created directly via `createMarket` or rolled by a venue's `MarketCreator` (venues run rolling series — hourly up/down and similar — that create markets continuously), and it is the only creation event carrying the `(operatorId, venueId)` origin. `marketId` is a module-scoped counter (`bytes32(++marketSeq)`) that doubles as the CREATE2 salt — unique by construction, not precomputable before the create tx. `module.marketIdByAddress(addr)` is the reverse lookup. Every market carries an immutable kind tag, `IMarket.marketType()`. This section describes **`BINARY_SINGLE_BOOK`** — the only kind live today. Future kinds (dual-book, multi-outcome) will carry different tags and different book semantics: branch on the tag, never on assumptions. Lifecycle: `Listed → Trading → Locked → (Settling) → Resolved | Voided` (`BinaryMarket.StatusChanged`, plus `Resolved` / `Voided`). Orders are only accepted while the market reports Trading — placement reverts `TradingNotActive` otherwise. Cancellation stays open through `Locked`; `redeem` opens at `Resolved` / `Voided`. ### One book, two outcomes — the (isBid, userData) encoding Each `BinaryPool` runs a **single** order book. Unlike spot, `userData` is **not** a tag field — it selects the book half, and the four order kinds are encoded in the `(isBid, userData)` pair: | `userData` | `isBid = true` | `isBid = false` | |---|---|---| | `0` (YES book) | `BUY_YES` | `SELL_YES` | | `1` (NO book) | `SELL_NO` | `BUY_NO` | Any other `userData` value reverts `InvalidUserData`. The NO book is price-inverted so the base matcher can cross the two books without knowing about outcomes: a NO order is submitted at the YES-side complement, `price = oneCollateral − noPrice`, where `oneCollateral = 10 ** collateral.decimals()`. All prices must satisfy `0 < price < oneCollateral` (`PriceOutOfBounds`) — a share can never be worth more than one collateral unit. ### Escrow and funding Placement escrows worst-case value up front: - **BUY orders** (`BUY_YES`, `BUY_NO`) lock collateral (ceil-rounded `price × quantity` in the order's own frame). The pull is **vault-first**: free vault balance is consumed before `transferFrom` on your wallet — so `collateral.approve(pool, …)` once per pool. (There is no auto-pull/manual-vault toggle here; this is the only mode.) - **SELL orders** (`SELL_YES`, `SELL_NO`) lock the outcome tokens themselves, pulled from your ERC-6909 balance on the singleton — call `outcomeToken.setOperator(pool, true)` once; it covers every market, since ids are namespaced by pool. Money flows back through two channels worth knowing: - **Refunds land in your vault balance** — taker surplus (you locked at your limit price, filled at a better maker price) and cancel/reduce/expiry refunds credit the pool vault, not your wallet. Because placement is vault-first, a quoting loop recycles these automatically; `withdraw(collateral, amount)` only when rebalancing. Read it with `getWithdrawableBalance(owner, collateral)`. - **Fill proceeds deliver wallet-first with vault fallback** — if the wallet transfer fails the pool credits the vault and emits `PayoutFallbackToVault`. Inventory comes from complete sets: `module.mintCompleteSet(operatorId, venueId, marketId, amount)` turns `amount` collateral into `amount` YES + `amount` NO (`setOperator(module, true)` once for the merge/redeem directions; `operatorId`/`venueId` are routing attribution only — pass `0` / `bytes32(0)` for none); `mergeCompleteSet(operatorId, venueId, marketId, amount)` is the inverse; `redeem(operatorId, venueId, marketId, outcomeIdx, amount)` burns the winning side 1:1 after resolution (or either side at 1/2 on void). You can also call the pool's `mintSet` / `burnSet` / `redeem` directly. Note you often need **no inventory at all** to quote — see the fill paths below. On a **resolved** market (never a voided one), the pool skims the venue's frozen `settlementFeeBpsTimes1k` ONCE from the whole winning backing when the first winning redeem lands (emitting `SettlementFeeCharged(feeRecipient, winningBacking, fee)`); every winner then redeems for `1 − fee` per token. Per-fill maker/taker fees (`ProtocolFeeCharged`) and the per-order builder fee (`BuilderFeeCharged`) are the other two fee rails — all rates are frozen into the pool at creation from the origin venue's config and readable via `getBinaryPoolParams()`. ### The four fill paths Two opposite-kind orders crossing settle by one of four paths (dispatched on the unordered pair of order kinds): | Crossing pair | Path | Settlement | |---|---|---| | `BUY_YES × SELL_YES` | DIRECT_YES | YES ↔ collateral swap | | `SELL_NO × BUY_NO` | DIRECT_NO | NO ↔ collateral swap | | `BUY_YES × BUY_NO` | MINT_A_PAIR | Both pay collateral; pool mints a fresh pair, one side each (emits `SetMinted`) | | `SELL_YES × SELL_NO` | BURN_A_PAIR | Both escrows burned as a pair; each seller paid their share (emits `SetBurned`) | The fill price on `OrderFilled` is always the **maker's** resting price, in the YES frame; the NO-side display price is `oneCollateral − fillPrice`. There is no on-chain "fill kind" field — consumers derive it from the two orders' kinds — the SDK exports [`sideOfKind`](/docs/typescript/api/index/functions/sideOfKind) (the YES/NO side of a resting order, from the pool's `BinaryOrderPlaced(orderId, kind)` event) and [`fillKind`](/docs/typescript/api/index/functions/fillKind) for exactly this derivation. `getOrderInfo(orderId)` exposes the binary-side escrow state per order (`lockedCollateral` / `lockedOutcome`, kind). ## Perps `PerpPool` extends the same `OrderBook` core, so everything in [the shared core](#the-shared-order-book-core) and [materialization](#materialize-the-order-book-from-events) carries over unchanged. On top it adds margin accounting, funding, and liquidations — with `FundingUpdated` / `OpenInterestUpdated` events, and a dedicated `MakerOrderCancelledExceedsPosition` removal event (a maker order erased pre-fill because it would breach the owner's position limit — treat it as a removal in a book reducer). BTC and ETH perps are live on testnet — see [Perps](../packages/sdk/docs/PERPS.md). ## Materialize the order book from events Every book mutation emits an event, so one pinned snapshot plus the log stream reproduces the full book — for **any** of the three families. This is exactly how the protocol's own indexer and the SDK's live watches work — the reducer below is the same one they run (see [Architecture](../packages/sdk/docs/ARCHITECTURE.md) for the SDK's implementation of it). ### Snapshot, then stream 1. Pin a block `N` (`eth_blockNumber`). 2. Snapshot both sides with `getAllOpenOrdersOffChain` **at block `N`** (pass the block tag explicitly so pagination pages are mutually consistent). Drop orders whose `expireTimestampNs` has already passed. 3. Stream the pool's logs from `N + 1` (`eth_subscribe("logs")` over WSS, or an `eth_getLogs` loop) and apply them strictly in `(blockNumber, logIndex)` order. ### The event reducer Keep a map `orderId → Order` plus per-side level aggregates: | Event | Action | |---|---| | `OrderPlaced(orderId, placedOrder)` | Cache the struct; do **not** insert. Fires for every accepted order — `placedOrder.quantityRemaining` is already the **post-match residual** (the matcher runs before the event), so zero remaining means it fully filled on entry. | | `OrderRested(orderId)` | Insert the cached order into the book. This is the **only** insert signal. | | `OrderFilled(takerId, makerId, qty, takerRem, makerRem, fillPrice)` | Patch the **maker**: remaining = `makerRem`, remove at zero. Ignore the taker leg — its state arrives on its own `OrderPlaced`/`OrderRested` later in the same tx. | | `OrderReduced(orderId, newQuantity)` | Set remaining = `newQuantity` (not a fill). | | `OrderCancelled(orderId)` / `OrderExpired(orderId)` | Remove (idempotently). | | `OrderCancelledSelfMatch(orderId)` | Remove — a same-owner resting maker erased by a `CancelMaker` self-match. | | `OrderCancelledPreFill(orderId)` | Remove — a resting maker pulled by a pre-fill guard before it could fill. The matching loop emits it for **every** pre-fill removal, so handling it covers every present and future guard. | Family extras, none of which mutate book state: spot pools also emit `MarkPriceUpdated` (fair-price telemetry); binary pools emit `SetMinted` / `SetBurned` / `Redeemed` / `SettlementFeeCharged` (outcome-supply / settlement telemetry — mint-a-pair and burn-a-pair fills emit the first two alongside `OrderFilled`) and `BinaryMarket.StatusChanged` (leaves Trading → no new fills, only cancels from here); perp pools add `MakerOrderCancelledExceedsPosition`, `MakerOrderCancelledNegativeEquity` and `MakerOrderCancelledStaleMark`, which **do** mutate the book — treat all three as removals. They are reason tags emitted alongside the base `OrderCancelledPreFill`, so a reducer that handles the base event alone already removes the order. Ordering inside a placement tx: settlement hooks and one `OrderFilled` per matched maker fire **first**, then the taker's `OrderPlaced` (already residual-adjusted), then `OrderRested` iff the residual rested. A reducer that only inserts on `OrderRested` handles this for free. ### The sharp edges - **Self-match removals have their own event.** With `SelfMatchingOption.CancelMaker`, the matcher erases the same-owner resting maker and emits `OrderCancelledSelfMatch(orderId)` (on every book — spot, binary, perp). Handle it as a removal or your reducer carries a phantom order whenever *any* trader self-crosses with `CancelMaker`. With `CancelTaker` the incoming order is rejected instead (`success == false`). - **Expiry is lazy.** Matching walks past expired makers without cleanup; `OrderExpired` only fires later (owner's next placement, or the permissionless sweeps). Prune locally the moment `expireTimestampNs` passes — an expired order can never fill — and treat the eventual event as a no-op. - **Make removals idempotent.** Between local pruning and the several removal paths, "remove an already-absent order" must be a no-op. - **Stream gaps.** On WSS reconnect, backfill the missed range with `eth_getLogs` before resuming. Somnia blocks have instant BFT finality, so a delivered log is final and no reorg handling is needed; the SDK's own live tail does none. If you still want a guard, treat a parent-hash discontinuity as a reason to re-snapshot rather than to unwind. ## Track your own orders and fills Both order-id parameters on `OrderFilled` are indexed topics, so you can filter your fills by the ids your `placeOrder` calls returned (or `getOwnOpenOrders()` after a restart). Alert on `PayoutFallbackToVault` — a delivery to your wallet failed and the proceeds are parked in your vault balance. Reconcile funds with `getWithdrawableBalance(owner, token)` and, on binary markets, `outcomeToken.balanceOf(owner, yesId | noId)` for positions. ## Interface reference ABI-faithful excerpts of every function and event used in this guide, taken from the deployed contracts. Admin/venue-governance entrypoints are omitted; external interface types (`IERC20`, adapters) are shown as `address` — the ABI encoding is identical. ### Shared order-book core (every pool) ```solidity type OrderId is uint128; enum OrderType { NormalOrder, FillOrKill, ImmediateOrCancel, PostOnly } enum SelfMatchingOption { CancelTaker, CancelMaker } struct Order { OrderId orderId; bool isBid; address owner; uint64 userData; uint256 price; uint256 fullQuantity; uint256 quantityRemaining; uint64 expireTimestampNs; } struct OrderBookLevel { uint256 price; uint256 quantity; } struct OrderBookParameters { uint256 tickSize; // min price increment, raw quote/collateral units uint256 minQuantity; // min order quantity, raw base units uint256 lotSize; // min quantity increment, raw base units } interface IOrderBook { event OrderPlaced(OrderId indexed orderId, Order placedOrder); event OrderRested(OrderId indexed orderId); event OrderFilled( OrderId indexed takerOrderId, OrderId indexed makerOrderId, uint256 quantityFilled, uint256 takerRemainingQuantity, uint256 makerRemainingQuantity, uint256 fillPrice ); event OrderCancelled(OrderId indexed orderId); event OrderCancelledSelfMatch(OrderId indexed orderId); event OrderExpired(OrderId indexed orderId); event OrderReduced(OrderId indexed orderId, uint256 newQuantity); event OrderBookParametersUpdated(OrderBookParameters newParameters); function placeOrder( bool isBid, uint64 userData, uint256 price, uint256 quantity, uint64 expireTimestampNs, OrderType orderType, SelfMatchingOption selfMatchingOption, address builder, uint96 builderFeeBpsTimes1k ) external payable returns (bool success, OrderId id); function cancelOrder(OrderId orderId) external; function reduceOrder(OrderId orderId, uint256 newQuantityRemaining) external; function cancelExpiredOrders(OrderId[] calldata orderIds) external; function sweepExpiredAtLevel(bool isBid, uint256 price, uint256 maxCount) external returns (uint256 cleaned); function getOrder(OrderId orderId) external view returns (Order memory); function getOwnOpenOrders() external view returns (OrderId[] memory); function getBookLevels(bool isBid, uint64 numLevels) external view returns (OrderBookLevel[] memory); function getOrderBookParameters() external view returns (OrderBookParameters memory); // eth_call only — msg.sender must be address(0) function getAllOpenOrdersOffChain(bool isBid, uint256 maxCount, uint64 startCursor) external view returns (Order[] memory orders, bool hasMoreOrders, uint64 nextCursor); } // The per-user vault, inherited by every pool. interface IVault { function deposit(address token, uint256 amount) external; function depositNative() external payable; function withdraw(address token, uint256 amount) external; function getWithdrawableBalance(address owner, address token) external view returns (uint256); } ``` ### SpotPool additions ```solidity interface ISpotPool /* is IOrderBook, IVault */ { event MarkPriceUpdated(address indexed asset, uint256 markPrice, uint256 rawMidpoint); event ManualVaultModeUpdated(address indexed user, bool enabled); event PayoutFallbackToVault(address indexed owner, address indexed token, uint256 amount); function setManualVaultMode(bool enabled) external; function getPoolParams() external view returns ( address baseToken, address quoteToken, uint256 makerFeeBpsTimes1k, uint256 takerFeeBpsTimes1k, uint256 tickSize, uint256 minQuantity, uint256 lotSize ); function getManualVaultMode(address user) external view returns (bool enabled); function getAutoPullRequirement( address owner, bool isBid, uint256 price, uint256 quantity, uint96 builderFeeBpsTimes1k ) external view returns (address inputToken, uint256 requiredAmount, uint256 delta); function getMidpointEmaState() external view returns (uint256 emaValue, uint64 lastUpdateNs); } ``` ### BinaryPool additions ```solidity struct BinaryPoolOrderInfo { OrderId orderId; uint256 lockedCollateral; // BUY escrow (mutually exclusive with lockedOutcome) uint256 lockedOutcome; // SELL escrow uint8 outcomeIdx; // 0 = YES, 1 = NO bool isBuy; address builder; uint96 builderFeeBpsTimes1k; } struct BinaryPoolInfo { address collateralToken; address market; address outcomeToken; uint256 yesId; uint256 noId; uint256 oneCollateral; // 10 ** collateral.decimals() uint256 setBacking; address feeRecipient; uint256 makerFeeBpsTimes1k; uint256 takerFeeBpsTimes1k; uint256 maxBuilderFeeBpsTimes1k; uint256 settlementFeeBpsTimes1k; } interface IBinaryPool /* is IOrderBook, IVault */ { event SetMinted(address indexed payer, address indexed yesTo, address indexed noTo, uint256 amount); event SetBurned(address indexed holder, uint256 amount); event Redeemed( address indexed holder, address indexed to, uint8 outcomeIdx, uint256 amountBurned, uint256 collateralOut ); // Fee rail: per-fill protocol fees, per-order builder fees (opt-in via // approveBuilder), and the one-time settlement fee on the winning backing. event ProtocolFeeCharged( OrderId indexed orderId, address indexed recipient, address indexed token, uint256 amount, bool isTakerSide ); event BuilderApproved(address indexed user, address indexed builder, uint256 maxFeeBpsTimes1k); event BuilderFeeCharged(OrderId indexed orderId, address indexed builder, address indexed token, uint256 amount); event SettlementFeeCharged(address indexed feeRecipient, uint256 winningBacking, uint256 fee); event PayoutFallbackToVault(address indexed owner, address indexed token, uint256 amount); function approveBuilder(address builder, uint256 maxFeeBpsTimes1k) external; function getMaxBuilderFeeBpsTimes1k() external view returns (uint256 maxFeeBpsTimes1k); function getBuilderApproval(address user, address builder) external view returns (uint256 maxFeeBpsTimes1k); function getEffectiveBuilderApproval(address user, address builder) external view returns (uint256 maxFeeBpsTimes1k); function mintSet(address yesTo, address noTo, uint256 amount) external; function burnSet(uint256 amount) external; function redeem(uint256 amount, uint8 outcomeIdx, address to) external returns (uint256 collateralOut); function collateralToken() external view returns (address); function outcomeToken() external view returns (address); function outcomeId(uint8 outcomeIdx) external view returns (uint256); function market() external view returns (address); function setBacking() external view returns (uint256); function getBinaryPoolParams() external view returns (BinaryPoolInfo memory info); function getOrderInfo(OrderId orderId) external view returns (BinaryPoolOrderInfo memory info); } ``` ### BinaryMarketsModule (the market registry) ```solidity enum VoidPolicy { UNIFORM, AMM_SNAPSHOT } // AMM_SNAPSHOT is a dead legacy slot enum MarketType { BINARY_SINGLE_BOOK, BINARY_DUAL_BOOK, NATIVE_MULTI } interface IBinaryMarketsModule { event MarketCreated( bytes32 indexed marketId, address indexed market, address indexed pool, uint256 oracleQuestionId, uint32 operatorId, bytes32 venueId, address creator, address collateral, uint256 yesId, uint256 noId, uint8 outcomeSlotCount, MarketType marketType, uint64 tradingStart, uint64 expiry, VoidPolicy voidPolicy, string asset, uint256 strike, // 0 for reference-mode markets (no fixed strike) string question, bytes context ); function markets(bytes32 marketId) external view returns ( uint256 oracleQuestionId, uint8 outcomeSlotCount, VoidPolicy voidPolicy, address collateral, uint32 originOperatorId, bytes32 originVenueId, address oracleAdapter, address creator, address market, address pool, uint256 yesId, uint256 noId, uint64 tradingStart, uint64 expiry ); function marketIdByAddress(address market) external view returns (bytes32 marketId); // operatorId / venueId are routing attribution only (0 / bytes32(0) = none). function mintCompleteSet(uint32 operatorId, bytes32 venueId, bytes32 marketId, uint256 amount) external; function mergeCompleteSet(uint32 operatorId, bytes32 venueId, bytes32 marketId, uint256 amount) external; function redeem(uint32 operatorId, bytes32 venueId, bytes32 marketId, uint8 outcomeIdx, uint256 amount) external; } ``` ### BinaryMarket (lifecycle) and the outcome-token singleton ```solidity enum MarketStatus { Listed, Trading, Locked, Settling, Resolved, Voided } interface IBinaryMarket { event StatusChanged(MarketStatus indexed oldStatus, MarketStatus indexed newStatus); event Resolved(uint8 indexed winningOutcome); event Voided(); function marketType() external view returns (MarketType); function tradingActive() external view returns (bool); function isResolved() external view returns (bool); function isVoided() external view returns (bool); function winningOutcome() external view returns (uint8); } // ERC-6909 subset. One singleton for all markets; id = (uint160(pool) << 8) | outcomeIdx. interface IOutcomeToken6909 { event Transfer( address caller, address indexed sender, address indexed receiver, uint256 indexed id, uint256 amount ); function setOperator(address spender, bool approved) external returns (bool); function transferFrom(address from, address to, uint256 id, uint256 amount) external returns (bool); function balanceOf(address owner, uint256 id) external view returns (uint256); } ``` --- # /docs/contracts/market-making # Market Making on Somnia Markets What is different about quoting this venue. Somnia Markets runs **spot** order books, **binary** information markets, and **perps**, all on the same on-chain order-book engine; this guide covers quoting the **binary markets**. It assumes you already run market-making systems and skips the generalities — only the mechanics that will surprise you or cost you money if learned in production. Everything below is specific to binary markets (`marketType() == BINARY_SINGLE_BOOK`), which is every binary market live today; future kinds (multi-outcome, dual-book) carry a different `marketType()` and will not share these semantics — branch on the tag, never assume. Full contract mechanics are in [Raw Integration](./RawIntegration.md); the SDK (`@somnia-chain/markets-sdk`) wraps all of it if you're in a JS runtime. ## One book per binary market; `userData` selects the side, and NO is price-inverted Each binary market runs a **single** order book crossing all four order kinds. `userData` is not a client tag field — it selects the book half (`0` = YES, `1` = NO; anything else reverts `InvalidUserData`), so tag quote generations off `orderId` (unique per pool) instead. NO orders are submitted at the YES complement: `price = oneCollateral − noPrice`, with `oneCollateral = 10 ** collateral.decimals()`. All prices must sit strictly inside `(0, oneCollateral)`, tick/lot/min from `getOrderBookParameters()` at runtime. The kind matrix — note the inversion means `isBid` does **not** mean "buy" on the NO book: | `userData` | `isBid = true` | `isBid = false` | |---|---|---| | `0` | BUY_YES | SELL_YES | | `1` | SELL_NO | BUY_NO | ## You can quote two-sided with zero inventory A resting BUY_YES at *p* and BUY_NO at *1 − p* is a full two-sided quote: when either crosses an incoming opposite buyer the pool **mints a fresh pair** (`MINT_A_PAIR`) — collateral in, one side to each buyer, no inventory required. `SELL_YES × SELL_NO` burns a pair symmetrically. This changes the standard outcome-market bootstrap: you never need to pre-mint outcome tokens to open a market, and your quoting book can stay entirely collateral-denominated. Deliberate inventory moves go through `mintCompleteSet` / `mergeCompleteSet` (1 collateral ⇄ 1 YES + 1 NO, always), and `redeem` pays the winning side 1:1 at resolution, less the venue's frozen settlement fee if it configured one (0.5 each on void, never fee'd). Price the venue's fees into your spread: maker/taker rates are **per-venue** and frozen into the pool at market creation — read them once per market from `getBinaryPoolParams()` (`makerFeeBpsTimes1k` / `takerFeeBpsTimes1k` / `settlementFeeBpsTimes1k`; basis-points × 1000). The per-order builder fee only applies if you opt a builder in with `approveBuilder` — as an MM placing your own orders you simply pass `(address(0), 0)` and never pay it. ## Escrow: BUYs lock collateral, SELLs lock tokens, refunds recycle via the vault Placement escrows worst-case value up front: BUYs lock collateral (vault-balance-first, then wallet `transferFrom` — one approval per pool), SELLs lock the ERC-6909 outcome tokens themselves (one `setOperator(pool, true)` on the singleton covers every market). Two flows matter for float accounting: - **Taker surplus and cancel/reduce refunds credit your pool vault balance**, not your wallet — and since placement is vault-first, a quoting loop recycles them automatically. `withdraw` only when rebalancing across pools. - **Fill proceeds deliver wallet-first with vault fallback.** Alert on `PayoutFallbackToVault` or your reconciliation will drift. ## Expiry is mandatory — make it your dead man's switch Every order carries `expireTimestampNs` (future unix-ns; there is no "no expiry" sentinel). Set it just past your requote interval rather than far-future: a crashed or partitioned quoter's ladder then ages off the book on its own. Note expired orders are unfillable **immediately**, but the `OrderExpired` event is lazy (fires on later cleanup, not at expiry) — prune your own book model on the timestamp, not the event. ## Self-match: pick your side, and handle `OrderCancelledSelfMatch` With `SelfMatchingOption.CancelMaker`, the matcher erases your same-owner resting maker and emits `OrderCancelledSelfMatch(orderId)` — an event-materialized book (yours, and every other participant's) must treat it as a removal or it carries a phantom order afterward. With `CancelTaker` the incoming order is rejected instead (`success == false`, no revert). Details in [the sharp edges](./RawIntegration.md#the-sharp-edges). The protocol pulls your makers on other paths too. A pre-fill guard emits `OrderCancelledPreFill(orderId)` for every maker it removes before a fill. On a perp pool a reason tag rides alongside it — one of `MakerOrderCancelledExceedsPosition`, `MakerOrderCancelledNegativeEquity` or `MakerOrderCancelledStaleMark`. Treat all four as removals. Handling the base `OrderCancelledPreFill` alone covers every guard, present and future. ## Rejections return `(false, 0)` — they don't revert A PostOnly that would cross, a FillOrKill that can't fill fully, and an IOC that fills nothing all return `success == false` from a *successful* transaction. A loop that only handles reverts will silently under-quote. Conversely `cancelOrder` / `reduceOrder` **do** revert on already-terminal orders — check state before cancelling or you're burning a tx slot in your re-center path. ## Markets die on schedule — and respawn Every market has a hard `expiry`; venue rolling series (e.g. hourly up/down) spawn a successor each interval. Placement reverts `TradingNotActive` the moment the market leaves Trading; cancels keep working through `Locked`. Anything resting at lock is free option value to whoever knows the outcome first — pull quotes ahead of expiry, sweep after resolution (`redeem` winners — note a resolved market's winning payout is net of the venue's frozen settlement fee, if any — `mergeCompleteSet` balanced pairs), and watch `BinaryMarketsModule`'s `MarketCreated` to be resting in the successor the moment it opens. ## Infrastructure and latency The public Somnia RPC nodes — `https://api.infra.mainnet.somnia.network/` (mainnet) and `https://api.infra.testnet.somnia.network/` (testnet) — are hosted in **GCP `europe-west4` (Netherlands)** and have **no rate limit**: host your quoting infrastructure in or near that region and submit transactions / read state as fast as your strategy requires. There is no separate market-data service to rate-limit you on this venue — market data *is* the chain, materialized from the event stream ([Raw Integration](./RawIntegration.md#materialize-the-order-book-from-events)). A 24/7 operation should keep backup RPCs configured (the authoritative provider list, including WSS endpoints, is at [Somnia network-info](https://docs.somnia.network/developer/network-info)), fail over on repeated errors, and backfill any missed log range before trusting its book model again. ## No session keys — atomicity comes from owning a contract `BinaryPool` has no per-user operator approvals (the `*For` entrypoints are admin-allowlist only), so the operator/fund key split you may run elsewhere doesn't apply. The equivalent isolation *and* atomic multi-order operations come from making your own contract the order owner: it places a full ladder or cancel-and-replaces both sides in one all-or-nothing transaction, and the book never sees a half-updated ladder. --- # /docs/typescript/api **@somnia-chain/markets-sdk** *** # @somnia-chain/markets-sdk ## Modules - [chains](chains/README.md) - [index](index/README.md) - [native](native/README.md) - [react](react/README.md) - [reactivity](reactivity/README.md) --- # /docs/typescript/api/chains [**@somnia-chain/markets-sdk**](../README.md) *** [@somnia-chain/markets-sdk](../README.md) / chains # chains ## bridging - [warpRouterAbi](variables/warpRouterAbi.md) - [SOMNIA\_BRIDGE](variables/SOMNIA_BRIDGE.md) - [getBridgeToken](functions/getBridgeToken.md) - [listBridgeTokens](functions/listBridgeTokens.md) - [getBridgeNetwork](functions/getBridgeNetwork.md) - [listBridgeNetworks](functions/listBridgeNetworks.md) - [isBridgeNetwork](functions/isBridgeNetwork.md) - [getBridgeRoute](functions/getBridgeRoute.md) - [getBridgeRouter](functions/getBridgeRouter.md) - [SendBridgeStepOptions](interfaces/SendBridgeStepOptions.md) - [sendBridgeStep](functions/sendBridgeStep.md) - [CreateBridgeTransferParams](interfaces/CreateBridgeTransferParams.md) - [createBridgeTransfer](functions/createBridgeTransfer.md) - [toEip1193Transaction](functions/toEip1193Transaction.md) - [BridgeToken](variables/BridgeToken.md) - [BridgeToken](type-aliases/BridgeToken.md) - [BridgeTokenModel](type-aliases/BridgeTokenModel.md) - [BridgeTokenDetails](interfaces/BridgeTokenDetails.md) - [BridgeNetworkDetails](interfaces/BridgeNetworkDetails.md) - [BridgeRoute](interfaces/BridgeRoute.md) - [BridgeDetails](interfaces/BridgeDetails.md) - [BridgeTransaction](interfaces/BridgeTransaction.md) - [BridgeTransfer](interfaces/BridgeTransfer.md) ## networks - [ChainId](variables/ChainId.md) - [ChainId](type-aliases/ChainId.md) - [hidekiTestnet](variables/hidekiTestnet.md) - [somniaElwood](variables/somniaElwood.md) - [somniaLocal](variables/somniaLocal.md) - [somniaMainnet](variables/somniaMainnet.md) - [somniaShannon](variables/somniaShannon.md) - [somniaChains](variables/somniaChains.md) - [getSomniaChain](functions/getSomniaChain.md) - [isSomniaChainId](functions/isSomniaChainId.md) --- # /docs/typescript/api/chains/functions/createBridgeTransfer [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / createBridgeTransfer # Function: createBridgeTransfer() > **createBridgeTransfer**(`params`): [`BridgeTransfer`](../interfaces/BridgeTransfer.md) Defined in: packages/sdk/src/chains/bridge/transfer.ts:115 Build the unsigned transactions that bridge `amount` of `token` from one Somnia network to another. Returns a plan rather than a single transaction, because what it takes depends on the route: a **collateral** leg needs an ERC-20 `approve` before `transferRemote`, while **native** and **synthetic** legs need only the bridge call. `approveStep` is absent when there is nothing to approve — branch on it and it narrows, no non-null assertion needed: **Details** - `params`: Token, direction, amount, recipient, and the optional gas/approval knobs. - Returns: The transfer: `bridgeStep` (the `transferRemote` call), `approveStep` (the ERC-20 approval on a collateral route, absent otherwise), and both sides' token details. **Gotchas** - Throws If the amount is not positive, the recipient isn't an address, the two chains are the same, or that token has no route between them. The message names what IS supported. **Example** (Planning a bridge transfer) ```ts import { BridgeToken, ChainId, createBridgeTransfer } from "@somnia-chain/markets-sdk/chains"; const plan = createBridgeTransfer({ token: BridgeToken.WBTC, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: 100_000_000n, // 1 WBTC — 8 decimals, not 18 recipient: account.address, }); if (plan.approveStep) { const hash = await walletClient.sendTransaction({ ...plan.approveStep, account }); await publicClient.waitForTransactionReceipt({ hash }); // the approval must LAND first } const hash = await walletClient.sendTransaction({ ...plan.bridgeStep, account }); await publicClient.waitForTransactionReceipt({ hash }); ``` On a Somnia node, [sendBridgeStep](sendBridgeStep.md) does the same in one round-trip per transaction via `realtime_sendRawTransaction`. Delivery is asynchronous: `transferRemote` only escrows and dispatches. The relayer delivers on the far side seconds later, and this bridge does not meter that gas — see [SOMNIA\_BRIDGE](../variables/SOMNIA_BRIDGE.md). ## Parameters ### params [`CreateBridgeTransferParams`](../interfaces/CreateBridgeTransferParams.md) ## Returns [`BridgeTransfer`](../interfaces/BridgeTransfer.md) --- # /docs/typescript/api/chains/functions/getBridgeNetwork [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / getBridgeNetwork # Function: getBridgeNetwork() > **getBridgeNetwork**(`chainId`): [`BridgeNetworkDetails`](../interfaces/BridgeNetworkDetails.md) \| `null` Defined in: packages/sdk/src/chains/bridge/registry.ts:315 The Hyperlane core deployment on one network — mailbox, ISM, hooks — plus the tokens it carries. **Details** - `chainId`: Chain id to look up. - Returns: The network's bridge deployment, or `null` if it isn't bridged. **Example** (Resolving a bridge network) ```ts import { ChainId, getBridgeNetwork } from "@somnia-chain/markets-sdk/chains"; getBridgeNetwork(ChainId.hidekiTestnet)?.mailbox; getBridgeNetwork(ChainId.somniaMainnet); // null — not bridged yet ``` ## Parameters ### chainId `number` ## Returns [`BridgeNetworkDetails`](../interfaces/BridgeNetworkDetails.md) \| `null` --- # /docs/typescript/api/chains/functions/getBridgeRoute [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / getBridgeRoute # Function: getBridgeRoute() > **getBridgeRoute**(`token`, `chainIdA`, `chainIdB`): [`BridgeRoute`](../interfaces/BridgeRoute.md) \| `null` Defined in: packages/sdk/src/chains/bridge/registry.ts:356 The route carrying one token between two networks, in either order. Bridging is **not transitive** — a chain must be a member of the token's route. **Details** - `token`: Token symbol. - `chainIdA`: One end of the lane. - `chainIdB`: The other end. - Returns: The route, or `null` if that token doesn't connect those two networks. ## Parameters ### token [`BridgeToken`](../type-aliases/BridgeToken.md) ### chainIdA `number` ### chainIdB `number` ## Returns [`BridgeRoute`](../interfaces/BridgeRoute.md) \| `null` --- # /docs/typescript/api/chains/functions/getBridgeRouter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / getBridgeRouter # Function: getBridgeRouter() > **getBridgeRouter**(`token`, `chainId`): `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/chains/bridge/registry.ts:370 The warp router that moves `token` on `chainId`, or `null`. ## Parameters ### token [`BridgeToken`](../type-aliases/BridgeToken.md) ### chainId `number` ## Returns `` `0x${string}` `` \| `null` --- # /docs/typescript/api/chains/functions/getBridgeToken [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / getBridgeToken # Function: getBridgeToken() > **getBridgeToken**(`token`, `chainId`): [`BridgeTokenDetails`](../interfaces/BridgeTokenDetails.md) \| `null` Defined in: packages/sdk/src/chains/bridge/registry.ts:277 Token details for one token on one network — the router to call, what the sender holds, its decimals, and where it can go. **Details** - `token`: Token symbol. - `chainId`: Chain id of the network (also the Hyperlane domain id). - Returns: The details, or `null` when that token has no route on that network. **Example** (Resolving a bridged token) ```ts import { BridgeToken, ChainId, getBridgeToken } from "@somnia-chain/markets-sdk/chains"; const wbtc = getBridgeToken(BridgeToken.WBTC, ChainId.somniaShannon); wbtc?.model; // "collateral" — approve `wbtc.address` to `wbtc.router` first wbtc?.decimals; // 8, NOT 18 ``` ## Parameters ### token [`BridgeToken`](../type-aliases/BridgeToken.md) ### chainId `number` ## Returns [`BridgeTokenDetails`](../interfaces/BridgeTokenDetails.md) \| `null` --- # /docs/typescript/api/chains/functions/getSomniaChain [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / getSomniaChain # Function: getSomniaChain() > **getSomniaChain**(`chainId`): `Chain` \| `null` Defined in: packages/sdk/src/chains/index.ts:117 Resolve a chain id to its definition, or `null` when it isn't a Somnia network we ship. The `chainId` a deployment manifest carries is a plain `number`, so this is the bridge from "the env told me 50312" to a viem `Chain`. **Details** - `chainId`: Chain id to look up (e.g. `50312`). - Returns: The matching viem `Chain`, or `null` if it isn't one of ours. **Example** (Resolving a deployment chain) ```ts import { getSomniaChain, defineChain } from "@somnia-chain/markets-sdk/chains"; const chain = getSomniaChain(deployment.chainId) ?? defineChain({ id: deployment.chainId, name: "Somnia", nativeCurrency: { name: "STT", symbol: "STT", decimals: 18 }, rpcUrls: { default: { http: [rpcUrl] } }, }); ``` ## Parameters ### chainId `number` ## Returns `Chain` \| `null` --- # /docs/typescript/api/chains/functions/isBridgeNetwork [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / isBridgeNetwork # Function: isBridgeNetwork() > **isBridgeNetwork**(`chainId`): `boolean` Defined in: packages/sdk/src/chains/bridge/registry.ts:338 Is this chain id part of the bridge? A `true` here is what makes [getBridgeNetwork](getBridgeNetwork.md) non-null. **Details** - `chainId`: Chain id to test. ## Parameters ### chainId `number` ## Returns `boolean` --- # /docs/typescript/api/chains/functions/isSomniaChainId [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / isSomniaChainId # Function: isSomniaChainId() > **isSomniaChainId**(`chainId`): `chainId is ChainId` Defined in: packages/sdk/src/chains/index.ts:132 Type guard: is this chain id one of the Somnia networks in [somniaChains](../variables/somniaChains.md)? Narrows a plain `number` to [ChainId](../variables/ChainId.md), so it can index `somniaChains` without a cast. **Details** - `chainId`: Chain id to test. ## Parameters ### chainId `number` ## Returns `chainId is ChainId` --- # /docs/typescript/api/chains/functions/listBridgeNetworks [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / listBridgeNetworks # Function: listBridgeNetworks() > **listBridgeNetworks**(): [`BridgeNetworkDetails`](../interfaces/BridgeNetworkDetails.md)[] Defined in: packages/sdk/src/chains/bridge/registry.ts:324 Every network with a bridge deployment. ## Returns [`BridgeNetworkDetails`](../interfaces/BridgeNetworkDetails.md)[] --- # /docs/typescript/api/chains/functions/listBridgeTokens [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / listBridgeTokens # Function: listBridgeTokens() > **listBridgeTokens**(`chainId?`): [`BridgeTokenDetails`](../interfaces/BridgeTokenDetails.md)[] Defined in: packages/sdk/src/chains/bridge/registry.ts:291 Every bridgeable token, optionally narrowed to one network. **Details** - `chainId`: Only tokens with a route on this network. Omit for all of them. - Returns: Matching token details; `[]` when the network isn't bridged. ## Parameters ### chainId? `number` ## Returns [`BridgeTokenDetails`](../interfaces/BridgeTokenDetails.md)[] --- # /docs/typescript/api/chains/functions/sendBridgeStep [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / sendBridgeStep # Function: sendBridgeStep() > **sendBridgeStep**(`client`, `step`, `options`): `Promise`\<`TransactionReceipt`\> Defined in: packages/sdk/src/chains/bridge/send.ts:94 Sign one planner transaction locally and send it via Somnia's **`realtime_sendRawTransaction`** — the node blocks until the transaction is executed and answers with the receipt, so send + confirm is a single round-trip. On a node without the method (anvil, stock geth) it falls back to `eth_sendRawTransaction` + a receipt wait, so the same code runs against `somniaLocal`. **Details** - `client`: A public client for the transaction's chain (its `request` is the wire). - `step`: The planner transaction — `plan.approveStep` / `plan.bridgeStep`. - `options`: The local signer, plus optional gas/fee overrides. - Returns: The mined receipt, status `"success"`. **Gotchas** - Throws If the client is on a different chain than the step, if the node rejects the transaction, or if the receipt says `"reverted"` — the message names the step's `description`. **Example** (Sending a bridge transfer) ```ts import { BridgeToken, ChainId, createBridgeTransfer, sendBridgeStep } from "@somnia-chain/markets-sdk/chains"; const plan = createBridgeTransfer({ token: BridgeToken.WBTC, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: 100_000_000n, // 1 WBTC — 8 decimals, not 18 recipient: account.address, }); if (plan.approveStep) await sendBridgeStep(client, plan.approveStep, { account }); const receipt = await sendBridgeStep(client, plan.bridgeStep, { account }); receipt.status; // "success" — a reverted receipt throws instead ``` Each call resolves only once its transaction is CONFIRMED, so the approve-then-bridge ordering above is safe by construction. Fees and gas are fixed, never estimated — the same doctrine as the SDK's trading writes. ## Parameters ### client ### step [`BridgeTransaction`](../interfaces/BridgeTransaction.md) ### options [`SendBridgeStepOptions`](../interfaces/SendBridgeStepOptions.md) ## Returns `Promise`\<`TransactionReceipt`\> --- # /docs/typescript/api/chains/functions/toEip1193Transaction [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / toEip1193Transaction # Function: toEip1193Transaction() > **toEip1193Transaction**(`step`, `options?`): `RpcTransactionRequest` Defined in: packages/sdk/src/chains/bridge/transfer.ts:216 A [BridgeTransaction](../interfaces/BridgeTransaction.md) as the JSON-safe object a browser wallet's `eth_sendTransaction` takes — typed as viem's own `RpcTransactionRequest` (hex quantities throughout), with only `from`/`to`/`data`/`value` set. Every field is a hex string, so the result survives `JSON.stringify`, a server → browser boundary, or a `postMessage` — which a raw [BridgeTransaction](../interfaces/BridgeTransaction.md) does not: its `value` is a `bigint`, and `JSON.stringify` throws on bigints. What it deliberately DROPS is as important as what it converts: - **`chainId`** — `eth_sendTransaction` has no chain field; an EIP-1193 wallet signs on its **active** chain. Switch first with `wallet_switchEthereumChain` (using the transaction's `chainId`) or it goes out on whatever network the wallet happens to be on. - `description` — a UI label, not a transaction field; some wallets reject requests carrying unknown keys. No `gas`, no nonce, no fees, same as the input: the wallet estimates and fills those. Callers on viem don't need this at all — `walletClient.sendTransaction({ ...plan.bridgeStep, account })` takes it as-is; this exists for the raw `provider.request(...)` path and for moving a server-built plan across a JSON boundary. **Details** - `step`: The planner transaction (or anything with `to`/`data`/`value`) to convert. - `options`: `from` — the sender to pin; omit to let the wallet choose. - Returns: The `eth_sendTransaction` params object, JSON-safe by construction. **Example** (Preparing an EIP-1193 transaction) ```ts import { BridgeToken, ChainId, createBridgeTransfer, toEip1193Transaction } from "@somnia-chain/markets-sdk/chains"; import { numberToHex } from "viem"; const plan = createBridgeTransfer({ token: BridgeToken.STT, from: ChainId.somniaShannon, to: ChainId.hidekiTestnet, amount: 1_000_000_000_000_000_000n, // 1 STT recipient, }); const tx = toEip1193Transaction(plan.bridgeStep, { from: sender }); tx.value; // "0xde0b6b3a7640000" — hex wei, not a bigint JSON.stringify(tx); // safe: every field is a string // The wallet signs on its ACTIVE chain — put it on the step's chain first. await provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: numberToHex(plan.bridgeStep.chainId) }], }); await provider.request({ method: "eth_sendTransaction", params: [tx] }); ``` ## Parameters ### step `Pick`\<[`BridgeTransaction`](../interfaces/BridgeTransaction.md), `"to"` \| `"data"` \| `"value"`\> ### options? #### from? `` `0x${string}` `` ## Returns `RpcTransactionRequest` --- # /docs/typescript/api/chains/interfaces/BridgeDetails [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeDetails # Interface: BridgeDetails Defined in: packages/sdk/src/chains/bridge/types.ts:157 The bridge as a whole: what it connects, what it carries, and how far to trust it. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:159 Lane id, e.g. `"somniatestnet-hidekitestnet"`. *** ### displayName > **displayName**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:161 Human name of the lane. *** ### chainIds > **chainIds**: `number`[] Defined in: packages/sdk/src/chains/bridge/types.ts:163 Chain ids the bridge connects. *** ### tokens > **tokens**: [`BridgeToken`](../type-aliases/BridgeToken.md)[] Defined in: packages/sdk/src/chains/bridge/types.ts:165 Tokens with at least one route. *** ### routes > **routes**: [`BridgeRoute`](BridgeRoute.md)[] Defined in: packages/sdk/src/chains/bridge/types.ts:167 Every token route on the lane. *** ### status > **status**: `"dev-test"` Defined in: packages/sdk/src/chains/bridge/types.ts:172 `"dev-test"` — a single validator, a threshold-1 ISM and EOA owners. One key is the entire bridge. **Do not put real funds behind it.** *** ### security > **security**: `object` Defined in: packages/sdk/src/chains/bridge/types.ts:174 Validators in the multisig ISM, and how many signatures it requires. #### validators > **validators**: `` `0x${string}` ``[] #### threshold > **threshold**: `number` *** ### relayerPaysDestinationGas > **relayerPaysDestinationGas**: `boolean` Defined in: packages/sdk/src/chains/bridge/types.ts:179 True when the relayer pays destination gas unmetered — so a sender attaches nothing for delivery, and delivery depends on the relayer staying funded. *** ### docs > **docs**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:181 Where the deployment record lives. --- # /docs/typescript/api/chains/interfaces/BridgeNetworkDetails [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeNetworkDetails # Interface: BridgeNetworkDetails Defined in: packages/sdk/src/chains/bridge/types.ts:108 The Hyperlane core deployment on one network, plus what it carries. ## Properties ### chainId > **chainId**: `number` Defined in: packages/sdk/src/chains/bridge/types.ts:110 Chain id. *** ### domainId > **domainId**: `number` Defined in: packages/sdk/src/chains/bridge/types.ts:112 Hyperlane domain id — equal to the chain id on this bridge. *** ### network > **network**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:114 Hyperlane registry name, e.g. `"hidekitestnet"`. *** ### displayName > **displayName**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:116 Human name, e.g. `"Hideki Testnet"`. *** ### mailbox > **mailbox**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:118 Dispatches and delivers interchain messages. *** ### interchainSecurityModule > **interchainSecurityModule**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:120 The default ISM messages are verified against (1-of-1 multisig on this lane). *** ### merkleTreeHook > **merkleTreeHook**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:122 Accumulates dispatched message ids into the tree validators sign. *** ### validatorAnnounce > **validatorAnnounce**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:124 Where validators announce their checkpoint storage. *** ### interchainAccountRouter > **interchainAccountRouter**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:126 Interchain account router (not used by token transfers). *** ### proxyAdmin > **proxyAdmin**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:128 Proxy admin owning the core proxies. *** ### interchainGasPaymaster > **interchainGasPaymaster**: `null` Defined in: packages/sdk/src/chains/bridge/types.ts:133 `null` — no InterchainGasPaymaster is deployed on this bridge, which is why `quoteGasPayment` is 0 and the relayer absorbs delivery gas. *** ### tokens > **tokens**: [`BridgeToken`](../type-aliases/BridgeToken.md)[] Defined in: packages/sdk/src/chains/bridge/types.ts:135 Tokens with a route on this network. --- # /docs/typescript/api/chains/interfaces/BridgeRoute [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeRoute # Interface: BridgeRoute Defined in: packages/sdk/src/chains/bridge/types.ts:143 A token route between exactly two networks. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:145 Hyperlane route id, e.g. `"WBTC/somniatestnet-hidekitestnet"`. *** ### token > **token**: [`BridgeToken`](../type-aliases/BridgeToken.md) Defined in: packages/sdk/src/chains/bridge/types.ts:147 The token this route carries. *** ### chainIds > **chainIds**: \[`number`, `number`\] Defined in: packages/sdk/src/chains/bridge/types.ts:149 The two chain ids it connects. Bridging is NOT transitive. --- # /docs/typescript/api/chains/interfaces/BridgeTokenDetails [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeTokenDetails # Interface: BridgeTokenDetails Defined in: packages/sdk/src/chains/bridge/types.ts:72 One token on one network: which router moves it, what the sender actually holds, and where it can go. ## Properties ### token > **token**: [`BridgeToken`](../type-aliases/BridgeToken.md) Defined in: packages/sdk/src/chains/bridge/types.ts:74 The token symbol. *** ### chainId > **chainId**: `number` Defined in: packages/sdk/src/chains/bridge/types.ts:76 Chain id of the network these details describe (also the Hyperlane domain id). *** ### network > **network**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:78 Hyperlane registry name of that network, e.g. `"somniatestnet"`. *** ### model > **model**: [`BridgeTokenModel`](../type-aliases/BridgeTokenModel.md) Defined in: packages/sdk/src/chains/bridge/types.ts:80 How this side holds value — decides approvals and `msg.value`. *** ### router > **router**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:82 The warp router to call `transferRemote` on. *** ### address > **address**: `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/chains/bridge/types.ts:88 The ERC-20 the sender holds on this chain: the canonical token for `collateral`, the router itself for `synthetic` (a HypERC20 *is* its token), and `null` for `native` — where the balance is the chain's gas coin. *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/chains/bridge/types.ts:90 Decimals on this side. Amounts are base units of THIS number. *** ### name > **name**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:92 Human name of the token, e.g. `"Wrapped Bitcoin"`. *** ### destinations > **destinations**: `number`[] Defined in: packages/sdk/src/chains/bridge/types.ts:94 Chain ids this token can be bridged to from here. *** ### requiresDestinationLiquidity > **requiresDestinationLiquidity**: `boolean` Defined in: packages/sdk/src/chains/bridge/types.ts:100 True when delivery is paid out of the destination router's own balance rather than by minting — the `native` model. Such a route can stall if the destination router is drained, so check its balance before sending. --- # /docs/typescript/api/chains/interfaces/BridgeTransaction [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeTransaction # Interface: BridgeTransaction Defined in: packages/sdk/src/chains/bridge/types.ts:197 One unsigned transaction of a bridge transfer, ready for any signer: spread into viem's `sendTransaction`, hand to [sendBridgeStep](../functions/sendBridgeStep.md) for Somnia's one-round-trip realtime path, or convert with [toEip1193Transaction](../functions/toEip1193Transaction.md) for a browser wallet. Its ROLE is the field it hangs off — `approveStep` or `bridgeStep` — so it carries no tag; `description` is the human label. Deliberately minimal and chain-tagged: no nonce, no fees, no gas — the signer's job. (No viem type requires exactly these fields, which is why this one exists; it is assignable to viem's `TransactionRequest`.) ## Properties ### chainId > **chainId**: `number` Defined in: packages/sdk/src/chains/bridge/types.ts:199 Chain this must be sent on — always the ORIGIN chain. *** ### to > **to**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:201 Contract to call. *** ### data > **data**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:203 ABI-encoded calldata. *** ### value > **value**: `bigint` Defined in: packages/sdk/src/chains/bridge/types.ts:205 Native value to attach, in wei. `0n` unless the route is native. *** ### description > **description**: `string` Defined in: packages/sdk/src/chains/bridge/types.ts:207 What this transaction does, for a UI to label a confirmation with. --- # /docs/typescript/api/chains/interfaces/BridgeTransfer [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeTransfer # Interface: BridgeTransfer Defined in: packages/sdk/src/chains/bridge/types.ts:233 A bridge transfer, expanded into the transactions it actually takes. Two or one: a `collateral` transfer needs an ERC-20 `approve` before the bridge call; `native` and `synthetic` transfers do not. `approveStep` is simply absent when there is nothing to approve — branching on it narrows: **Example** (Sending an approval before a transfer) ```ts if (plan.approveStep) { await sendBridgeStep(client, plan.approveStep, { account }); // confirmed before the next line } await sendBridgeStep(client, plan.bridgeStep, { account }); ``` Everything protocol-derived lives on the transactions themselves or on `origin`/`destination` — e.g. a native route's destination-liquidity caveat is [BridgeTokenDetails.requiresDestinationLiquidity](BridgeTokenDetails.md#requiresdestinationliquidity) on `destination`, and an interchain gas payment is already folded into `bridgeStep.value`. ## Properties ### origin > **origin**: [`BridgeTokenDetails`](BridgeTokenDetails.md) Defined in: packages/sdk/src/chains/bridge/types.ts:235 The origin-side token being sent. *** ### destination > **destination**: [`BridgeTokenDetails`](BridgeTokenDetails.md) Defined in: packages/sdk/src/chains/bridge/types.ts:237 The destination-side token that will be received. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/chains/bridge/types.ts:239 Amount in base units of `origin.decimals`. *** ### recipient > **recipient**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/types.ts:241 Who receives it on the destination chain. *** ### approveStep? > `optional` **approveStep?**: [`BridgeTransaction`](BridgeTransaction.md) Defined in: packages/sdk/src/chains/bridge/types.ts:247 The ERC-20 approval a **collateral** route needs first — absent on native and synthetic routes. Confirm it before sending `bridgeStep`, which spends the allowance. *** ### bridgeStep > **bridgeStep**: [`BridgeTransaction`](BridgeTransaction.md) Defined in: packages/sdk/src/chains/bridge/types.ts:254 The `transferRemote` call on the origin router — the transaction that bridges. Always present, always sent last: it escrows or burns on the origin and dispatches the interchain message. Its `value` carries the amount on a native route (plus any `gasPayment` passed in), `0n` otherwise. --- # /docs/typescript/api/chains/interfaces/CreateBridgeTransferParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / CreateBridgeTransferParams # Interface: CreateBridgeTransferParams Defined in: packages/sdk/src/chains/bridge/transfer.ts:37 Parameters for [createBridgeTransfer](../functions/createBridgeTransfer.md). ## Properties ### token > **token**: [`BridgeToken`](../type-aliases/BridgeToken.md) Defined in: packages/sdk/src/chains/bridge/transfer.ts:39 Token to bridge. *** ### from > **from**: `number` Defined in: packages/sdk/src/chains/bridge/transfer.ts:41 Chain id to send FROM. *** ### to > **to**: `number` Defined in: packages/sdk/src/chains/bridge/transfer.ts:43 Chain id to send TO. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/chains/bridge/transfer.ts:48 Amount in **base units of the origin side's decimals** — read them off [BridgeTokenDetails.decimals](BridgeTokenDetails.md#decimals) rather than assuming 18 (WBTC is 8). *** ### recipient > **recipient**: `` `0x${string}` `` Defined in: packages/sdk/src/chains/bridge/transfer.ts:50 Who receives the tokens on the destination chain. *** ### gasPayment? > `optional` **gasPayment?**: `bigint` Defined in: packages/sdk/src/chains/bridge/transfer.ts:57 Interchain gas payment to attach, added to the transfer's `value`. Defaults to `0n`, which is correct for this bridge — it has no InterchainGasPaymaster and every router quotes 0. Pass the result of `quoteGasPayment(destinationDomain)` if that ever changes. *** ### approveAmount? > `optional` **approveAmount?**: `bigint` Defined in: packages/sdk/src/chains/bridge/transfer.ts:63 Amount to approve on a `collateral` route. Defaults to `amount` (exact approval). Pass a larger value to approve once for several transfers, or `0n` to skip the approval step entirely when an allowance is already in place. --- # /docs/typescript/api/chains/interfaces/SendBridgeStepOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / SendBridgeStepOptions # Interface: SendBridgeStepOptions Defined in: packages/sdk/src/chains/bridge/send.ts:30 Options for [sendBridgeStep](../functions/sendBridgeStep.md). ## Properties ### account > **account**: `object` Defined in: packages/sdk/src/chains/bridge/send.ts:43 The signer. Must be a LOCAL account (viem's `privateKeyToAccount`, a derived session account, a mnemonic account…) — raw-transaction sending needs `signTransaction`, which injected browser wallets do not expose. Its balance must cover the full FEE ENVELOPE — `gas × maxFeePerGas`, 0.6 STT at the defaults — on top of the transaction's `value`: Somnia's mempool admits a transaction only when the ceiling is funded, even though unused gas is never charged (measured live: a 0.05 STT account is rejected "insufficient balance"). Fund small accounts accordingly, or lower `gas`. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/chains/bridge/send.ts:45 Gas ceiling (default 10,000,000 — the SDK-wide fixed ceiling). Never estimated. *** ### maxFeePerGas? > `optional` **maxFeePerGas?**: `bigint` Defined in: packages/sdk/src/chains/bridge/send.ts:47 Fixed fees (default the SDK-wide `DEFAULT_FEES`: 60 gwei max, 0 priority). *** ### maxPriorityFeePerGas? > `optional` **maxPriorityFeePerGas?**: `bigint` Defined in: packages/sdk/src/chains/bridge/send.ts:48 --- # /docs/typescript/api/chains/type-aliases/BridgeToken [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeToken # Type Alias: BridgeToken > **BridgeToken** = *typeof* [`BridgeToken`](../variables/BridgeToken.md)\[keyof *typeof* [`BridgeToken`](../variables/BridgeToken.md)\] Defined in: packages/sdk/src/chains/bridge/types.ts:31 One of the [BridgeToken](../variables/BridgeToken.md) symbols. --- # /docs/typescript/api/chains/type-aliases/BridgeTokenModel [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeTokenModel # Type Alias: BridgeTokenModel > **BridgeTokenModel** = `"native"` \| `"collateral"` \| `"synthetic"` Defined in: packages/sdk/src/chains/bridge/types.ts:64 How a warp route holds value on one side. - `native` — the router escrows the chain's own gas coin and delivery pays out of the destination router's balance. No wrapped token exists. Needs seeded liquidity on each side (see [BridgeTokenDetails.requiresDestinationLiquidity](../interfaces/BridgeTokenDetails.md#requiresdestinationliquidity)). - `collateral` — the token's home chain: the router escrows the canonical ERC-20, which the sender must `approve` first. - `synthetic` — the router *is* an ERC-20 it mints and burns 1:1 against the collateral held on the home chain. No approval needed to send back. --- # /docs/typescript/api/chains/type-aliases/ChainId [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / ChainId # Type Alias: ChainId > **ChainId** = *typeof* [`ChainId`](../variables/ChainId.md)\[keyof *typeof* [`ChainId`](../variables/ChainId.md)\] Defined in: packages/sdk/src/chains/chainId.ts:39 Chain id of one of the Somnia networks — the union behind `somniaChains`. --- # /docs/typescript/api/chains/variables/BridgeToken [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / BridgeToken # Variable: BridgeToken > `const` **BridgeToken**: `object` Defined in: packages/sdk/src/chains/bridge/types.ts:31 The tokens with a live warp route, by symbol. `BridgeToken.WBTC` is the value; `BridgeToken` is also the type of every such value. Adding a token is a registry change, not a code change. **Example** (Naming a bridge token) ```ts import { BridgeToken } from "@somnia-chain/markets-sdk/chains"; const symbol: BridgeToken = BridgeToken.WBTC; // "WBTC" ``` ## Type Declaration ### STT > `readonly` **STT**: `"STT"` = `"STT"` Native gas coin of every Somnia network. Native on BOTH sides of its route. ### USDso > `readonly` **USDso**: `"USDso"` = `"USDso"` Somnia USD test stable, 18 decimals. ### WBTC > `readonly` **WBTC**: `"WBTC"` = `"WBTC"` Wrapped Bitcoin — **8 decimals**, on the canonical token AND the synthetic. ### WETH > `readonly` **WETH**: `"WETH"` = `"WETH"` Wrapped ETH, 18 decimals. ### HBTT > `readonly` **HBTT**: `"HBTT"` = `"HBTT"` Hyperlane Bridge Test Token — a throwaway used to verify the lane. --- # /docs/typescript/api/chains/variables/ChainId [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / ChainId # Variable: ChainId > `const` **ChainId**: `object` Defined in: packages/sdk/src/chains/chainId.ts:39 Every Somnia network's chain id, keyed by its chain definition's export name — `ChainId.somniaShannon === somniaShannon.id` by construction, so the constant and the definition can never disagree. The id is the value because that is what wallets, deployment manifests and viem all speak — and on the bridge the Hyperlane **domain id equals the chain id**, so one number identifies a network everywhere. A `const` object with a matching type, not a TS `enum` — the pattern this package uses everywhere (`BridgeToken`, `BinarySide`, …): `ChainId.somniaShannon` is the value, `ChainId` is also the type of every such value, and plain number literals still assign. Not every network is bridged — `listBridgeNetworks()` is the live set. **Example** (Indexing a chain definition) ```ts import { ChainId, somniaChains } from "@somnia-chain/markets-sdk/chains"; somniaChains[ChainId.hidekiTestnet].name; // "Hideki Testnet" ``` ## Type Declaration ### somniaMainnet > `readonly` **somniaMainnet**: `5031` = `somniaMainnet.id` Somnia mainnet (`5031`). Not bridged yet. ### somniaShannon > `readonly` **somniaShannon**: `50312` = `somniaShannon.id` Somnia Testnet — Shannon (`50312`), the general-purpose testnet. Bridged. ### somniaElwood > `readonly` **somniaElwood**: `50313` = `somniaElwood.id` Somnia Testnet — Elwood (`50313`), the testnet regenesis. Not bridged yet. ### hidekiTestnet > `readonly` **hidekiTestnet**: `50383` = `hidekiTestnet.id` Hideki Testnet (`50383`) — the low-latency Tokyo network. Bridged. ### somniaLocal > `readonly` **somniaLocal**: `31337` = `somniaLocal.id` The local anvil stack (`31337`). Never bridged. --- # /docs/typescript/api/chains/variables/SOMNIA_BRIDGE [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / SOMNIA\_BRIDGE # Variable: SOMNIA\_BRIDGE > `const` **SOMNIA\_BRIDGE**: [`BridgeDetails`](../interfaces/BridgeDetails.md) Defined in: packages/sdk/src/chains/bridge/registry.ts:243 The Somnia token bridge: one Hyperlane lane, **Somnia Testnet ↔ Hideki Testnet**, carrying five token routes. > ⚠️ **`status: "dev-test"`.** A single validator, a threshold-1 ISM and EOA > owners — one key is the entire bridge. Do not put real funds behind it. Delivery gas is paid by the relayer, unmetered ([BridgeDetails.relayerPaysDestinationGas](../interfaces/BridgeDetails.md#relayerpaysdestinationgas)): a sender attaches nothing for it, and a drained relayer means transfers are accepted on the origin but not delivered until it is refunded — escrowed, not lost. **Example** (Inspecting the registry) ```ts import { SOMNIA_BRIDGE } from "@somnia-chain/markets-sdk/chains"; SOMNIA_BRIDGE.tokens; // ["STT", "USDso", "WBTC", "WETH", "HBTT"] SOMNIA_BRIDGE.chainIds; // [50312, 50383] ``` --- # /docs/typescript/api/chains/variables/hidekiTestnet [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / hidekiTestnet # Variable: hidekiTestnet > `const` **hidekiTestnet**: `object` Defined in: packages/sdk/src/chains/definitions/hidekiTestnet.ts:32 **Hideki** testnet (chain id `50383`) — the low-latency Tokyo network. Validators sit in one region to keep validator-to-validator latency low, so blocks land every **10 ms** (~100 blocks/s) instead of Shannon's 100 ms. Native token is **STT**. One live-verified oddity, so nobody "fixes" it: Hideki's **network id is not its chain id**. `eth_chainId` answers `0xc4cf` (50383) — the value here, the one wallets and signatures use — while `net_version` answers `50000258` (`0x2faf182`). Shannon's and mainnet's two ids are equal; Hideki's are not. The 10 ms cadence is what makes this the interesting target for latency work: a `blockTime` of 10 is what viem uses to size its own polling/waiting heuristics, and the SDK's live tail sees ~10x the block rate of Shannon. Multicall3 lives at a NON-canonical address (deployed 2026-08-10 by the bridge infra, byte-identical to the canonical runtime). The canonical `0xcA11bde0…` route is permanently unreachable here: Somnia chains charge ~4,928 gas per deployed byte, so the presigned "Nick's method" transaction (fixed 500k gas limit) cannot deploy Multicall3's 3,808-byte runtime, and the presigned deployers' nonce-0 transactions have already been burned on these networks. The same address holds the same bytes on Shannon — one deployer key at the same nonce on both chains — but Shannon's definition keeps its earlier deployment for parity with viem's `somniaTestnet`. No public block explorer is known for Hideki, so that field stays unset. ## Type Declaration ### blockTime > **blockTime**: `10` Block time in milliseconds. ### contracts > **contracts**: `object` Collection of contracts #### contracts.multicall3 > `readonly` **multicall3**: `object` #### contracts.multicall3.address > `readonly` **address**: `"0x540B091b608f54E603c5dC19F6b2d955e1d2D131"` = `"0x540B091b608f54E603c5dC19F6b2d955e1d2D131"` #### contracts.multicall3.blockCreated > `readonly` **blockCreated**: `265712387` = `265712387` ### id > **id**: `50383` ID in number form ### name > **name**: `"Hideki Testnet"` Human-readable name ### nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` ### rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### rpcUrls.default > `readonly` **default**: `object` #### rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.hideki.infra.testnet.somnia.network"`\] #### rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.hideki.infra.testnet.somnia.network/ws"`\] ### testnet > **testnet**: `true` Flag for test networks --- # /docs/typescript/api/chains/variables/somniaChains [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / somniaChains # Variable: somniaChains > `const` **somniaChains**: `object` Defined in: packages/sdk/src/chains/index.ts:82 Every Somnia network this module ships, keyed by chain id — the lookup table behind [getSomniaChain](../functions/getSomniaChain.md). Iterate it to build a network switcher; index it when you already know the id is one of ours. ## Type Declaration ### 5031 > `readonly` **5031**: `object` = `somniaMainnet` #### 5031.blockExplorers > **blockExplorers**: `object` Collection of block explorers #### 5031.blockExplorers.default > `readonly` **default**: `object` #### 5031.blockExplorers.default.name > `readonly` **name**: `"Somnia Explorer"` = `"Somnia Explorer"` #### 5031.blockExplorers.default.url > `readonly` **url**: `"https://explorer.somnia.network"` = `"https://explorer.somnia.network"` #### 5031.blockExplorers.default.apiUrl > `readonly` **apiUrl**: `"https://explorer.somnia.network/api"` = `"https://explorer.somnia.network/api"` #### 5031.blockTime > **blockTime**: `100` Block time in milliseconds. #### 5031.contracts > **contracts**: `object` Collection of contracts #### 5031.contracts.multicall3 > `readonly` **multicall3**: `object` #### 5031.contracts.multicall3.address > `readonly` **address**: `"0x5e44F178E8cF9B2F5409B6f18ce936aB817C5a11"` = `"0x5e44F178E8cF9B2F5409B6f18ce936aB817C5a11"` #### 5031.contracts.multicall3.blockCreated > `readonly` **blockCreated**: `38516341` = `38516341` #### 5031.id > **id**: `5031` ID in number form #### 5031.name > **name**: `"Somnia"` Human-readable name #### 5031.nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### 5031.nativeCurrency.name > `readonly` **name**: `"Somnia"` = `"Somnia"` #### 5031.nativeCurrency.symbol > `readonly` **symbol**: `"SOMI"` = `"SOMI"` #### 5031.nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` #### 5031.rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### 5031.rpcUrls.default > `readonly` **default**: `object` #### 5031.rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.infra.mainnet.somnia.network"`\] #### 5031.rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.infra.mainnet.somnia.network/ws"`\] #### 5031.testnet > **testnet**: `false` Flag for test networks ### 50312 > `readonly` **50312**: `object` = `somniaShannon` #### 50312.blockExplorers > **blockExplorers**: `object` Collection of block explorers #### 50312.blockExplorers.default > `readonly` **default**: `object` #### 50312.blockExplorers.default.name > `readonly` **name**: `"Somnia Testnet Explorer"` = `"Somnia Testnet Explorer"` #### 50312.blockExplorers.default.url > `readonly` **url**: `"https://shannon-explorer.somnia.network"` = `"https://shannon-explorer.somnia.network"` #### 50312.blockExplorers.default.apiUrl > `readonly` **apiUrl**: `"https://shannon-explorer.somnia.network/api"` = `"https://shannon-explorer.somnia.network/api"` #### 50312.blockTime > **blockTime**: `100` Block time in milliseconds. #### 50312.contracts > **contracts**: `object` Collection of contracts #### 50312.contracts.multicall3 > `readonly` **multicall3**: `object` #### 50312.contracts.multicall3.address > `readonly` **address**: `"0x841b8199E6d3Db3C6f264f6C2bd8848b3cA64223"` = `"0x841b8199E6d3Db3C6f264f6C2bd8848b3cA64223"` #### 50312.contracts.multicall3.blockCreated > `readonly` **blockCreated**: `71314235` = `71314235` #### 50312.id > **id**: `50312` ID in number form #### 50312.name > **name**: `"Somnia Testnet"` Human-readable name #### 50312.nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### 50312.nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### 50312.nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### 50312.nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` #### 50312.rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### 50312.rpcUrls.default > `readonly` **default**: `object` #### 50312.rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.infra.testnet.somnia.network"`, `"https://dream-rpc.somnia.network"`\] #### 50312.rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.infra.testnet.somnia.network/ws"`, `"wss://dream-rpc.somnia.network/ws"`\] #### 50312.testnet > **testnet**: `true` Flag for test networks ### 50313 > `readonly` **50313**: `object` = `somniaElwood` #### 50313.blockTime > **blockTime**: `100` Block time in milliseconds. #### 50313.id > **id**: `50313` ID in number form #### 50313.name > **name**: `"Somnia Elwood Testnet"` Human-readable name #### 50313.nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### 50313.nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### 50313.nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### 50313.nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` #### 50313.rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### 50313.rpcUrls.default > `readonly` **default**: `object` #### 50313.rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.elwood.infra.testnet.somnia.network"`\] #### 50313.rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.elwood.infra.testnet.somnia.network/ws"`\] #### 50313.testnet > **testnet**: `true` Flag for test networks ### 50383 > `readonly` **50383**: `object` = `hidekiTestnet` #### 50383.blockTime > **blockTime**: `10` Block time in milliseconds. #### 50383.contracts > **contracts**: `object` Collection of contracts #### 50383.contracts.multicall3 > `readonly` **multicall3**: `object` #### 50383.contracts.multicall3.address > `readonly` **address**: `"0x540B091b608f54E603c5dC19F6b2d955e1d2D131"` = `"0x540B091b608f54E603c5dC19F6b2d955e1d2D131"` #### 50383.contracts.multicall3.blockCreated > `readonly` **blockCreated**: `265712387` = `265712387` #### 50383.id > **id**: `50383` ID in number form #### 50383.name > **name**: `"Hideki Testnet"` Human-readable name #### 50383.nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### 50383.nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### 50383.nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### 50383.nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` #### 50383.rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### 50383.rpcUrls.default > `readonly` **default**: `object` #### 50383.rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.hideki.infra.testnet.somnia.network"`\] #### 50383.rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.hideki.infra.testnet.somnia.network/ws"`\] #### 50383.testnet > **testnet**: `true` Flag for test networks ### 31337 > `readonly` **31337**: `object` = `somniaLocal` #### 31337.id > **id**: `31337` ID in number form #### 31337.name > **name**: `"Somnia Local"` Human-readable name #### 31337.nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### 31337.nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### 31337.nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### 31337.nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` #### 31337.rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### 31337.rpcUrls.default > `readonly` **default**: `object` #### 31337.rpcUrls.default.http > `readonly` **http**: readonly \[`"http://127.0.0.1:8545"`\] #### 31337.rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"ws://127.0.0.1:8545"`\] #### 31337.testnet > **testnet**: `true` Flag for test networks --- # /docs/typescript/api/chains/variables/somniaElwood [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / somniaElwood # Variable: somniaElwood > `const` **somniaElwood**: `object` Defined in: packages/sdk/src/chains/definitions/somniaElwood.ts:14 Somnia testnet — **Elwood** (chain id `50313`, network id `50313`), the regenesis of the public testnet. Its own cluster, DNS zone and genesis; 100 ms blocks and **STT** as the native token, same as Shannon. No public block explorer and no Multicall3 deployment are known for Elwood, so neither field is set — a `multicall: true` read against this chain falls back to individual `eth_call`s instead of pointing at an address that has no code. ## Type Declaration ### blockTime > **blockTime**: `100` Block time in milliseconds. ### id > **id**: `50313` ID in number form ### name > **name**: `"Somnia Elwood Testnet"` Human-readable name ### nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` ### rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### rpcUrls.default > `readonly` **default**: `object` #### rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.elwood.infra.testnet.somnia.network"`\] #### rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.elwood.infra.testnet.somnia.network/ws"`\] ### testnet > **testnet**: `true` Flag for test networks --- # /docs/typescript/api/chains/variables/somniaLocal [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / somniaLocal # Variable: somniaLocal > `const` **somniaLocal**: `object` Defined in: packages/sdk/src/chains/definitions/somniaLocal.ts:21 The local Somnia dev chain (chain id `31337`) — an Anvil node, as brought up by `demo-clob.sh up` / `DEPLOY_ENV=local`. Anvil is a first-class environment for this protocol: the deploy scripts, the indexer, the deployments hub and the explorer all run against it, so it gets a definition here instead of borrowing viem's `foundry`. Deliberately presented as **Somnia** with **STT** rather than "Foundry"/"Ether": the agent-facing docs read the chain name and native symbol straight out of this object, and a local stack should still read as Somnia there. Two things a local chain does *not* have: the Somnia reactivity precompile at `0x…0100` (`isLocalPrecompileUnavailable` returns true here — anything that pings it, such as `enableReactivity` or `triggerRoll`, is testnet/mainnet only) and a Multicall3 deployment, unless you deployed one yourself. ## Type Declaration ### id > **id**: `31337` ID in number form ### name > **name**: `"Somnia Local"` Human-readable name ### nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` ### rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### rpcUrls.default > `readonly` **default**: `object` #### rpcUrls.default.http > `readonly` **http**: readonly \[`"http://127.0.0.1:8545"`\] #### rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"ws://127.0.0.1:8545"`\] ### testnet > **testnet**: `true` Flag for test networks --- # /docs/typescript/api/chains/variables/somniaMainnet [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / somniaMainnet # Variable: somniaMainnet > `const` **somniaMainnet**: `object` Defined in: packages/sdk/src/chains/definitions/somniaMainnet.ts:11 Somnia mainnet (chain id `5031`) — the production network. Native token is **SOMI**; blocks land roughly every 100 ms. Same content as viem's `somnia`, under the name the runbooks use. ## Type Declaration ### blockExplorers > **blockExplorers**: `object` Collection of block explorers #### blockExplorers.default > `readonly` **default**: `object` #### blockExplorers.default.name > `readonly` **name**: `"Somnia Explorer"` = `"Somnia Explorer"` #### blockExplorers.default.url > `readonly` **url**: `"https://explorer.somnia.network"` = `"https://explorer.somnia.network"` #### blockExplorers.default.apiUrl > `readonly` **apiUrl**: `"https://explorer.somnia.network/api"` = `"https://explorer.somnia.network/api"` ### blockTime > **blockTime**: `100` Block time in milliseconds. ### contracts > **contracts**: `object` Collection of contracts #### contracts.multicall3 > `readonly` **multicall3**: `object` #### contracts.multicall3.address > `readonly` **address**: `"0x5e44F178E8cF9B2F5409B6f18ce936aB817C5a11"` = `"0x5e44F178E8cF9B2F5409B6f18ce936aB817C5a11"` #### contracts.multicall3.blockCreated > `readonly` **blockCreated**: `38516341` = `38516341` ### id > **id**: `5031` ID in number form ### name > **name**: `"Somnia"` Human-readable name ### nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### nativeCurrency.name > `readonly` **name**: `"Somnia"` = `"Somnia"` #### nativeCurrency.symbol > `readonly` **symbol**: `"SOMI"` = `"SOMI"` #### nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` ### rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### rpcUrls.default > `readonly` **default**: `object` #### rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.infra.mainnet.somnia.network"`\] #### rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.infra.mainnet.somnia.network/ws"`\] ### testnet > **testnet**: `false` Flag for test networks --- # /docs/typescript/api/chains/variables/somniaShannon [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / somniaShannon # Variable: somniaShannon > `const` **somniaShannon**: `object` Defined in: packages/sdk/src/chains/definitions/somniaShannon.ts:13 Somnia testnet — **Shannon** (chain id `50312`), the public testnet and the default target for Somnia Markets development. Native token is **STT**; blocks land roughly every 100 ms. `https://dream-rpc.somnia.network` is a public alias for the same network and is listed as a secondary HTTP/WebSocket endpoint. ## Type Declaration ### blockExplorers > **blockExplorers**: `object` Collection of block explorers #### blockExplorers.default > `readonly` **default**: `object` #### blockExplorers.default.name > `readonly` **name**: `"Somnia Testnet Explorer"` = `"Somnia Testnet Explorer"` #### blockExplorers.default.url > `readonly` **url**: `"https://shannon-explorer.somnia.network"` = `"https://shannon-explorer.somnia.network"` #### blockExplorers.default.apiUrl > `readonly` **apiUrl**: `"https://shannon-explorer.somnia.network/api"` = `"https://shannon-explorer.somnia.network/api"` ### blockTime > **blockTime**: `100` Block time in milliseconds. ### contracts > **contracts**: `object` Collection of contracts #### contracts.multicall3 > `readonly` **multicall3**: `object` #### contracts.multicall3.address > `readonly` **address**: `"0x841b8199E6d3Db3C6f264f6C2bd8848b3cA64223"` = `"0x841b8199E6d3Db3C6f264f6C2bd8848b3cA64223"` #### contracts.multicall3.blockCreated > `readonly` **blockCreated**: `71314235` = `71314235` ### id > **id**: `50312` ID in number form ### name > **name**: `"Somnia Testnet"` Human-readable name ### nativeCurrency > **nativeCurrency**: `object` Currency used by chain #### nativeCurrency.name > `readonly` **name**: `"STT"` = `"STT"` #### nativeCurrency.symbol > `readonly` **symbol**: `"STT"` = `"STT"` #### nativeCurrency.decimals > `readonly` **decimals**: `18` = `18` ### rpcUrls > **rpcUrls**: `object` Collection of RPC endpoints #### rpcUrls.default > `readonly` **default**: `object` #### rpcUrls.default.http > `readonly` **http**: readonly \[`"https://api.infra.testnet.somnia.network"`, `"https://dream-rpc.somnia.network"`\] #### rpcUrls.default.webSocket > `readonly` **webSocket**: readonly \[`"wss://api.infra.testnet.somnia.network/ws"`, `"wss://dream-rpc.somnia.network/ws"`\] ### testnet > **testnet**: `true` Flag for test networks --- # /docs/typescript/api/chains/variables/warpRouterAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [chains](../README.md) / warpRouterAbi # Variable: warpRouterAbi > `const` **warpRouterAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/chains/bridge/abi.ts:28 The Warp Route router surface used to bridge and to preflight a bridge. `transferRemote` is the one write: selector `0x81b4e8b4`, payable, returns the dispatched message id. On a **native** route the amount rides in `msg.value`; on a **collateral** route the router pulls a pre-approved ERC-20 and `msg.value` carries only the (currently zero) interchain gas payment; on a **synthetic** route the router burns the sender's balance, no approval needed. --- # /docs/typescript/api/index [**@somnia-chain/markets-sdk**](../README.md) *** [@somnia-chain/markets-sdk](../README.md) / index # index ## ABIs - [orderBookEventsAbi](variables/orderBookEventsAbi.md) - [marginBankEventsAbi](variables/marginBankEventsAbi.md) - [liquidationEngineEventsAbi](variables/liquidationEngineEventsAbi.md) - [oracleHubAbi](variables/oracleHubAbi.md) - [oracleHubEventsAbi](variables/oracleHubEventsAbi.md) - [binaryModuleWriteAbi](variables/binaryModuleWriteAbi.md) - [binaryModuleReadAbi](variables/binaryModuleReadAbi.md) - [binarySettlementAbi](variables/binarySettlementAbi.md) - [erc6909Abi](variables/erc6909Abi.md) - [binaryPoolWriteAbi](variables/binaryPoolWriteAbi.md) - [spotPoolWriteAbi](variables/spotPoolWriteAbi.md) - [perpPoolWriteAbi](variables/perpPoolWriteAbi.md) ## activity - [byNewestFirst](functions/byNewestFirst.md) ## administration ### GovernanceAdminConfig Renames and re-exports [OracleHubAdminConfig](interfaces/OracleHubAdminConfig.md) *** ### MarketCreatorAdminConfig Renames and re-exports [OracleHubAdminConfig](interfaces/OracleHubAdminConfig.md) ## analytics - [BinaryOrderQuote](interfaces/BinaryOrderQuote.md) - [quoteBinaryOrderOverBook](functions/quoteBinaryOrderOverBook.md) - [MarketStats24h](interfaces/MarketStats24h.md) - [marketStats24hFromCandles](functions/marketStats24hFromCandles.md) - [BinaryOutcomePositionPnL](interfaces/BinaryOutcomePositionPnL.md) - [BinaryPositionPnL](interfaces/BinaryPositionPnL.md) - [PnLEvent](interfaces/PnLEvent.md) - [pnlEventsFor](functions/pnlEventsFor.md) - [computePositionPnL](functions/computePositionPnL.md) - [ClaimablePosition](interfaces/ClaimablePosition.md) - [ClaimableInput](interfaces/ClaimableInput.md) - [estPayoutFor](functions/estPayoutFor.md) - [claimableFrom](functions/claimableFrom.md) - [DEFAULT\_SLIPPAGE\_BPS](variables/DEFAULT_SLIPPAGE_BPS.md) - [DEFAULT\_SLIPPAGE\_MIN\_TICKS](variables/DEFAULT_SLIPPAGE_MIN_TICKS.md) - [BinaryCrossingParams](interfaces/BinaryCrossingParams.md) - [slippageForCrossing](functions/slippageForCrossing.md) - [BinaryBuySide](type-aliases/BinaryBuySide.md) - [BinarySellSide](type-aliases/BinarySellSide.md) - [BinaryStakeQuote](interfaces/BinaryStakeQuote.md) - [quoteBinaryStakeOverBook](functions/quoteBinaryStakeOverBook.md) - [BinarySellQuote](interfaces/BinarySellQuote.md) - [quoteBinarySellOverBook](functions/quoteBinarySellOverBook.md) - [midYesPrice](functions/midYesPrice.md) - [EntryTrade](interfaces/EntryTrade.md) - [averageEntryPrice](functions/averageEntryPrice.md) - [outcomeMarkPrice](functions/outcomeMarkPrice.md) - [OutcomePositionMark](interfaces/OutcomePositionMark.md) - [markOutcomePosition](functions/markOutcomePosition.md) - [PositionMarkState](type-aliases/PositionMarkState.md) - [positionMarkState](functions/positionMarkState.md) - [PortfolioTimeframe](type-aliases/PortfolioTimeframe.md) - [PortfolioTradeEvent](interfaces/PortfolioTradeEvent.md) - [PortfolioFundingEvent](interfaces/PortfolioFundingEvent.md) - [PortfolioFlowEvent](type-aliases/PortfolioFlowEvent.md) - [MarkSeries](type-aliases/MarkSeries.md) - [MarkSources](interfaces/MarkSources.md) - [EquityPoint](interfaces/EquityPoint.md) - [HoldingsPoint](interfaces/HoldingsPoint.md) - [PnlBucket](interfaces/PnlBucket.md) - [PortfolioAnalytics](interfaces/PortfolioAnalytics.md) - [DEFAULT\_CEX\_RATE\_BPS](variables/DEFAULT_CEX_RATE_BPS.md) - [PortfolioAnalyticsOptions](interfaces/PortfolioAnalyticsOptions.md) - [ComputePortfolioAnalyticsError](type-aliases/ComputePortfolioAnalyticsError.md) - [computePortfolioAnalytics](functions/computePortfolioAnalytics.md) ## balances - [Erc20Metadata](interfaces/Erc20Metadata.md) - [BalanceQuery](interfaces/BalanceQuery.md) ## binary markets - [binaryMarketTypePlugin](variables/binaryMarketTypePlugin.md) - [OutcomeBalances](type-aliases/OutcomeBalances.md) - [PortfolioMarket](type-aliases/PortfolioMarket.md) - [PortfolioPosition](type-aliases/PortfolioPosition.md) - [OpenPositionPnL](type-aliases/OpenPositionPnL.md) - [PortfolioOrder](type-aliases/PortfolioOrder.md) - [PortfolioTrade](type-aliases/PortfolioTrade.md) - [Portfolio](type-aliases/Portfolio.md) - [PortfolioOptions](type-aliases/PortfolioOptions.md) - [GetVaultBalanceParams](interfaces/GetVaultBalanceParams.md) - [GetOutcomeBalanceParams](interfaces/GetOutcomeBalanceParams.md) - [VaultPayoutFallback](type-aliases/VaultPayoutFallback.md) - [MarketResolutionEvent](type-aliases/MarketResolutionEvent.md) - [MarketReferenceLink](type-aliases/MarketReferenceLink.md) - [OracleAnswer](type-aliases/OracleAnswer.md) ## caching - [QUERY\_KEY\_SCOPE](variables/QUERY_KEY_SCOPE.md) - [QueryKeyElement](type-aliases/QueryKeyElement.md) - [ClientQueryKey](type-aliases/ClientQueryKey.md) - [marketsKey](functions/marketsKey.md) - [portfolioKey](functions/portfolioKey.md) - [candlesKey](functions/candlesKey.md) - [marketActivityKey](functions/marketActivityKey.md) - [tradeContextKey](functions/tradeContextKey.md) - [transactionActivityKey](functions/transactionActivityKey.md) - [blockActivityKey](functions/blockActivityKey.md) - [marketFeesKey](functions/marketFeesKey.md) - [operatorsKey](functions/operatorsKey.md) - [marketCreatorsKey](functions/marketCreatorsKey.md) - [oracleAdaptersKey](functions/oracleAdaptersKey.md) - [syncStatusKey](functions/syncStatusKey.md) - [maxVenueFeeBpsKey](functions/maxVenueFeeBpsKey.md) - [marketOnchainKey](functions/marketOnchainKey.md) ## clients - [SomniaMarketsClient](interfaces/SomniaMarketsClient.md) - [SomniaMarketsConfig](type-aliases/SomniaMarketsConfig.md) - [FetchOrderBookOptions](interfaces/FetchOrderBookOptions.md) - [SomniaMarketsGetOrdersPageOptions](type-aliases/SomniaMarketsGetOrdersPageOptions.md) - [SomniaMarketsGetOrderHistoryPageOptions](type-aliases/SomniaMarketsGetOrderHistoryPageOptions.md) - [CreateOrderParams](interfaces/CreateOrderParams.md) - [RedeemOptions](interfaces/RedeemOptions.md) ## configuration - [SOMNIA\_TESTNET\_ADDRESSES](variables/SOMNIA_TESTNET_ADDRESSES.md) - [SOMNIA\_MAINNET\_ADDRESSES](variables/SOMNIA_MAINNET_ADDRESSES.md) - [SomniaMarketsAddresses](interfaces/SomniaMarketsAddresses.md) - [PriceFeedConfig](interfaces/PriceFeedConfig.md) - [SOMNIA\_TESTNET\_PRICE\_FEED](variables/SOMNIA_TESTNET_PRICE_FEED.md) - [SOMNIA\_MAINNET\_PRICE\_FEED](variables/SOMNIA_MAINNET_PRICE_FEED.md) - [FixedFees](interfaces/FixedFees.md) - [DEFAULT\_FEES](variables/DEFAULT_FEES.md) - [ClientConfig](interfaces/ClientConfig.md) - [TailReconciliationConfig](interfaces/TailReconciliationConfig.md) ## converting - [IntervalSource](type-aliases/IntervalSource.md) - [resolveIntervalSec](functions/resolveIntervalSec.md) - [snapIntervalSec](functions/snapIntervalSec.md) - [CADENCE\_LADDER\_SEC](variables/CADENCE_LADDER_SEC.md) - [CADENCE\_TOLERANCE\_SEC](variables/CADENCE_TOLERANCE_SEC.md) - [snapToCadence](functions/snapToCadence.md) - [cadenceBandSec](functions/cadenceBandSec.md) - [formatIntervalLabel](functions/formatIntervalLabel.md) - [marketIntervalLabel](functions/marketIntervalLabel.md) - [toHuman](functions/toHuman.md) - [toHumanString](functions/toHumanString.md) - [fromHuman](functions/fromHuman.md) - [priceToProbability](functions/priceToProbability.md) - [probabilityToPrice](functions/probabilityToPrice.md) - [YesBookTop](interfaces/YesBookTop.md) - [markYesPrice](functions/markYesPrice.md) - [BinaryOutcomePnl](interfaces/BinaryOutcomePnl.md) - [BinaryPnl](interfaces/BinaryPnl.md) - [BinaryPnlFill](interfaces/BinaryPnlFill.md) - [binaryFillsFor](functions/binaryFillsFor.md) - [binaryFillsFromPortfolio](functions/binaryFillsFromPortfolio.md) - [computeBinaryPnl](functions/computeBinaryPnl.md) - [balanceFloor](functions/balanceFloor.md) - [floorRawBalance](functions/floorRawBalance.md) - [ceilRawAmount](functions/ceilRawAmount.md) - [snapRawToGrid](functions/snapRawToGrid.md) - [roundPriceToTick](functions/roundPriceToTick.md) - [upProbability](functions/upProbability.md) - [upPercent](functions/upPercent.md) ## encoding - [OutcomeIdx](type-aliases/OutcomeIdx.md) - [outcomeId](functions/outcomeId.md) - [DecodedOutcomeId](interfaces/DecodedOutcomeId.md) - [decodeOutcomeId](functions/decodeOutcomeId.md) - [marketKey](functions/marketKey.md) ## errors - [SomniaMarketsError](classes/SomniaMarketsError.md) - [InvalidInputError](classes/InvalidInputError.md) - [NotConfiguredError](classes/NotConfiguredError.md) - [SignerRequiredError](classes/SignerRequiredError.md) - [IndexerError](classes/IndexerError.md) - [RpcError](classes/RpcError.md) - [ContractRevertError](classes/ContractRevertError.md) - [SomniaMarketsClientGetBinaryOrderBookError](type-aliases/SomniaMarketsClientGetBinaryOrderBookError.md) - [SomniaMarketsClientGetSpotOrderBookError](type-aliases/SomniaMarketsClientGetSpotOrderBookError.md) - [SomniaMarketsClientGetOrderOnchainError](type-aliases/SomniaMarketsClientGetOrderOnchainError.md) - [SomniaMarketsFetchOrderBookError](type-aliases/SomniaMarketsFetchOrderBookError.md) - [SomniaMarketsConstructorError](type-aliases/SomniaMarketsConstructorError.md) - [SomniaMarketsFetchTradesError](type-aliases/SomniaMarketsFetchTradesError.md) - [SomniaMarketsFetchMyTradesError](type-aliases/SomniaMarketsFetchMyTradesError.md) - [SomniaMarketsWatchTradesError](type-aliases/SomniaMarketsWatchTradesError.md) - [SomniaMarketsWatchMyTradesError](type-aliases/SomniaMarketsWatchMyTradesError.md) - [SomniaMarketsWatchOrderBookError](type-aliases/SomniaMarketsWatchOrderBookError.md) - [SomniaMarketsGetOrdersPageError](type-aliases/SomniaMarketsGetOrdersPageError.md) - [SomniaMarketsGetOrderHistoryPageError](type-aliases/SomniaMarketsGetOrderHistoryPageError.md) ## fees - [ProtocolFeeRecord](type-aliases/ProtocolFeeRecord.md) - [BuilderFeeRecord](type-aliases/BuilderFeeRecord.md) - [SettlementFeeRecord](type-aliases/SettlementFeeRecord.md) - [BuilderApproval](type-aliases/BuilderApproval.md) - [BuilderApprovalRef](interfaces/BuilderApprovalRef.md) ## fills - [FillsOptions](type-aliases/FillsOptions.md) - [FillsScope](type-aliases/FillsScope.md) - [FillRow](type-aliases/FillRow.md) ## funding - [FUNDING\_PRECISION](variables/FUNDING_PRECISION.md) - [EIGHT\_HOURS\_SEC](variables/EIGHT_HOURS_SEC.md) - [ONE\_HOUR\_SEC](variables/ONE_HOUR_SEC.md) - [ONE\_YEAR\_SEC](variables/ONE_YEAR_SEC.md) - [normalizeFundingRate](functions/normalizeFundingRate.md) - [fundingRate8h](functions/fundingRate8h.md) - [fundingRate1h](functions/fundingRate1h.md) - [fundingRatePerInterval](functions/fundingRatePerInterval.md) - [annualizedFundingRate](functions/annualizedFundingRate.md) - [intervalsPerWindow](functions/intervalsPerWindow.md) - [realizedFundingPerBase](functions/realizedFundingPerBase.md) - [isFundingStale](functions/isFundingStale.md) - [FundingBucketLike](interfaces/FundingBucketLike.md) - [densifyFundingBuckets](functions/densifyFundingBuckets.md) - [FundingSeriesBucket](type-aliases/FundingSeriesBucket.md) - [FundingRateSeries](type-aliases/FundingRateSeries.md) - [buildFundingRateSeries](functions/buildFundingRateSeries.md) - [NATIVE\_TOKEN\_SENTINEL](variables/NATIVE_TOKEN_SENTINEL.md) ## indexing - [CountResult](type-aliases/CountResult.md) - [IndexerSyncStatus](type-aliases/IndexerSyncStatus.md) ## lending - [SomniaLendClient](interfaces/SomniaLendClient.md) - [SOMNIA\_MAINNET\_LEND](variables/SOMNIA_MAINNET_LEND.md) - [SOMNIA\_TESTNET\_LEND](variables/SOMNIA_TESTNET_LEND.md) - [lendPoolAbi](variables/lendPoolAbi.md) - [lendUiPoolDataProviderAbi](variables/lendUiPoolDataProviderAbi.md) - [lendGatewayAbi](variables/lendGatewayAbi.md) - [lendDebtTokenAbi](variables/lendDebtTokenAbi.md) - [LenderConfig](type-aliases/LenderConfig.md) - [LendWriteOptions](interfaces/LendWriteOptions.md) - [LendSupplyOptions](interfaces/LendSupplyOptions.md) - [LendWithdrawOptions](interfaces/LendWithdrawOptions.md) - [LendRepayOptions](interfaces/LendRepayOptions.md) - [Lender](interfaces/Lender.md) - [RAY](variables/RAY.md) - [rayMul](functions/rayMul.md) - [accrueLinear](functions/accrueLinear.md) - [accrueCompounded](functions/accrueCompounded.md) - [lendRayRateToApy](functions/lendRayRateToApy.md) - [LendAddresses](interfaces/LendAddresses.md) - [LendReserve](interfaces/LendReserve.md) - [LendPosition](interfaces/LendPosition.md) - [LendAccount](interfaces/LendAccount.md) ## live data - [WatchHandle](interfaces/WatchHandle.md) - [WatchStatus](type-aliases/WatchStatus.md) - [TailMode](type-aliases/TailMode.md) - [BinarySide](type-aliases/BinarySide.md) - [BinaryFillKind](type-aliases/BinaryFillKind.md) - [OrderStatus](type-aliases/OrderStatus.md) - [BinaryMarketStatus](type-aliases/BinaryMarketStatus.md) - [TailStatus](interfaces/TailStatus.md) - [TailFailure](interfaces/TailFailure.md) - [TailDivergence](interfaces/TailDivergence.md) - [LiveMarket](type-aliases/LiveMarket.md) - [LiveFundingUpdate](interfaces/LiveFundingUpdate.md) - [LiveFill](interfaces/LiveFill.md) - [LiveOrder](interfaces/LiveOrder.md) - [BookLevel](interfaces/BookLevel.md) - [DECIMALS](variables/DECIMALS.md) - [ORDER\_KIND\_SIDE](variables/ORDER_KIND_SIDE.md) - [sideOfKind](functions/sideOfKind.md) - [fillKind](functions/fillKind.md) ## logging - [DebugEvent](type-aliases/DebugEvent.md) - [Span](interfaces/Span.md) - [consoleDebugSink](functions/consoleDebugSink.md) - [DebugCollector](interfaces/DebugCollector.md) - [debugCollector](functions/debugCollector.md) ## market types - [MARKET\_TYPE\_PLUGINS](variables/MARKET_TYPE_PLUGINS.md) - [getMarketTypePlugin](functions/getMarketTypePlugin.md) - [listMarketTypePlugins](functions/listMarketTypePlugins.md) - [MachineryStep](interfaces/MachineryStep.md) - [MarketTypePlugin](interfaces/MarketTypePlugin.md) ## markets - [MarketType](type-aliases/MarketType.md) - [BaseMarket](type-aliases/BaseMarket.md) - [SpotMarket](type-aliases/SpotMarket.md) - [PerpMarket](type-aliases/PerpMarket.md) - [BinaryMarket](type-aliases/BinaryMarket.md) - [Market](type-aliases/Market.md) - [isBinaryMarket](functions/isBinaryMarket.md) - [isSpotMarket](functions/isSpotMarket.md) - [isPerpMarket](functions/isPerpMarket.md) - [BinaryResolutionMode](type-aliases/BinaryResolutionMode.md) - [binaryResolutionMode](functions/binaryResolutionMode.md) - [BinaryMarketFilter](type-aliases/BinaryMarketFilter.md) - [BinaryMarketOrderBy](type-aliases/BinaryMarketOrderBy.md) - [RegistrySweep](interfaces/RegistrySweep.md) - [MarketFees](type-aliases/MarketFees.md) - [SpotMarketFilter](type-aliases/SpotMarketFilter.md) - [MarketStatusUpdate](type-aliases/MarketStatusUpdate.md) - [PerpMarketFilter](type-aliases/PerpMarketFilter.md) - [LiveBinaryMarketsFilter](type-aliases/LiveBinaryMarketsFilter.md) - [PastBinaryMarketsOptions](type-aliases/PastBinaryMarketsOptions.md) - [boundaryPrice](functions/boundaryPrice.md) - [MarketOnchain](interfaces/MarketOnchain.md) - [OnchainResolutionPrice](interfaces/OnchainResolutionPrice.md) - [MarketOnchainSources](interfaces/MarketOnchainSources.md) - [ContractMeta](interfaces/ContractMeta.md) ## models - [Candle](type-aliases/Candle.md) - [CANDLE\_INTERVALS](variables/CANDLE_INTERVALS.md) - [OracleHubAdminConfig](interfaces/OracleHubAdminConfig.md) - [UnifiedOrderIdentity](type-aliases/UnifiedOrderIdentity.md) - [UnifiedOrderPageItem](type-aliases/UnifiedOrderPageItem.md) - [UnifiedOrdersPage](type-aliases/UnifiedOrdersPage.md) - [UnifiedMarketType](type-aliases/UnifiedMarketType.md) - [UnifiedMarket](interfaces/UnifiedMarket.md) - [UnifiedOrderBook](interfaces/UnifiedOrderBook.md) - [UnifiedTrade](interfaces/UnifiedTrade.md) - [UnifiedOrderStatus](type-aliases/UnifiedOrderStatus.md) - [UnifiedOrder](interfaces/UnifiedOrder.md) - [UnifiedStopOrderStatus](type-aliases/UnifiedStopOrderStatus.md) - [UnifiedStopOrder](interfaces/UnifiedStopOrder.md) - [UnifiedBalance](interfaces/UnifiedBalance.md) - [UnifiedBalances](interfaces/UnifiedBalances.md) - [UnifiedOHLCV](type-aliases/UnifiedOHLCV.md) - [UnifiedTicker](interfaces/UnifiedTicker.md) - [UnifiedFundingRate](interfaces/UnifiedFundingRate.md) - [UnifiedPosition](interfaces/UnifiedPosition.md) - [UnifiedPrice](interfaces/UnifiedPrice.md) - [TIMEFRAMES](variables/TIMEFRAMES.md) - [Tradable](interfaces/Tradable.md) ## oracles - [QUESTION\_SOURCE\_TYPE](variables/QUESTION_SOURCE_TYPE.md) - [ANSWER\_TYPE](variables/ANSWER_TYPE.md) - [QuestionSourceInput](interfaces/QuestionSourceInput.md) - [QuestionIntervalInput](interfaces/QuestionIntervalInput.md) - [ValidAnswersInput](interfaces/ValidAnswersInput.md) - [QuestionDefinitionInput](interfaces/QuestionDefinitionInput.md) - [HubQuestionState](interfaces/HubQuestionState.md) - [HubStatus](interfaces/HubStatus.md) - [ScheduleQuestionParams](interfaces/ScheduleQuestionParams.md) - [ScheduleQuestionResult](interfaces/ScheduleQuestionResult.md) - [WithdrawParams](interfaces/WithdrawParams.md) - [WithdrawMyCreditParams](interfaces/WithdrawMyCreditParams.md) - [FundHubParams](interfaces/FundHubParams.md) - [SetHubGasParams](interfaces/SetHubGasParams.md) - [SetHubDrainParams](interfaces/SetHubDrainParams.md) - [EnableHubReactivityParams](interfaces/EnableHubReactivityParams.md) - [OracleHubAdmin](interfaces/OracleHubAdmin.md) - [OracleQuestionRecord](type-aliases/OracleQuestionRecord.md) - [OperatorHubAccountRecord](type-aliases/OperatorHubAccountRecord.md) - [OracleBindRecord](type-aliases/OracleBindRecord.md) - [OracleCallbackRecord](type-aliases/OracleCallbackRecord.md) ## orders - [OrderMarket](type-aliases/OrderMarket.md) - [OpenOrder](type-aliases/OpenOrder.md) - [OrdersOptions](type-aliases/OrdersOptions.md) - [OrderRow](type-aliases/OrderRow.md) - [BookTop](type-aliases/BookTop.md) - [BinaryOrderBook](interfaces/BinaryOrderBook.md) - [BinaryBookParams](interfaces/BinaryBookParams.md) - [ClosingPriceState](interfaces/ClosingPriceState.md) - [OnchainOrder](interfaces/OnchainOrder.md) - [GetOrderOnchainOptions](interfaces/GetOrderOnchainOptions.md) - [GetBinaryOrderBookOptions](interfaces/GetBinaryOrderBookOptions.md) - [GetSpotOrderBookOptions](interfaces/GetSpotOrderBookOptions.md) - [SpotOrderBook](interfaces/SpotOrderBook.md) - [SweepableOrder](type-aliases/SweepableOrder.md) ## Other - [MarketActivityKind](type-aliases/MarketActivityKind.md) - [MarketActivityBase](type-aliases/MarketActivityBase.md) - [MarketTradeActivity](type-aliases/MarketTradeActivity.md) - [MarketSupplyActivity](type-aliases/MarketSupplyActivity.md) - [MarketResolutionActivity](type-aliases/MarketResolutionActivity.md) - [MarketStatusActivity](type-aliases/MarketStatusActivity.md) - [MarketActivity](type-aliases/MarketActivity.md) - [MarketActivityOptions](type-aliases/MarketActivityOptions.md) - [TransactionOrder](type-aliases/TransactionOrder.md) - [TransactionActivity](type-aliases/TransactionActivity.md) - [TransactionActivityOptions](type-aliases/TransactionActivityOptions.md) - [BlockTimestampResolver](type-aliases/BlockTimestampResolver.md) - [BlockOrderTouch](type-aliases/BlockOrderTouch.md) - [BlockOrder](type-aliases/BlockOrder.md) - [BlockMarketActivity](type-aliases/BlockMarketActivity.md) - [BlockActivity](type-aliases/BlockActivity.md) - [BlockActivityOptions](type-aliases/BlockActivityOptions.md) - [contractErrorsAbi](variables/contractErrorsAbi.md) - [ComputePositionPnLError](type-aliases/ComputePositionPnLError.md) - [EstPayoutForError](type-aliases/EstPayoutForError.md) - [ClaimableFromError](type-aliases/ClaimableFromError.md) - [perpPoolEventsAbi](variables/perpPoolEventsAbi.md) - [GetUserFillsPageOptions](type-aliases/GetUserFillsPageOptions.md) - [UserFillsPage](type-aliases/UserFillsPage.md) - [OrderFillRow](type-aliases/OrderFillRow.md) - [MarketRef](type-aliases/MarketRef.md) - [FillDetail](type-aliases/FillDetail.md) - [FillOrder](type-aliases/FillOrder.md) - [TradeContext](type-aliases/TradeContext.md) - [NetworkTapeOptions](interfaces/NetworkTapeOptions.md) - [TapeOrder](interfaces/TapeOrder.md) - [TapeFill](interfaces/TapeFill.md) - [NetworkTapeStatus](interfaces/NetworkTapeStatus.md) - [NetworkTape](classes/NetworkTape.md) - [ObservedReadOperation](type-aliases/ObservedReadOperation.md) - [ObservedReadMethods](type-aliases/ObservedReadMethods.md) - [ObservedReadRequest](type-aliases/ObservedReadRequest.md) - [IndexerObservation](interfaces/IndexerObservation.md) - [ObservedReadResult](interfaces/ObservedReadResult.md) - [ObservedReadsReadError](type-aliases/ObservedReadsReadError.md) - [ObservedReadsBatchError](type-aliases/ObservedReadsBatchError.md) - [SomniaMarketsClientCreateObservedReadsError](type-aliases/SomniaMarketsClientCreateObservedReadsError.md) - [SomniaMarketsClientGetIndexerFreshnessError](type-aliases/SomniaMarketsClientGetIndexerFreshnessError.md) - [SomniaMarketsClientGetSyncStatusError](type-aliases/SomniaMarketsClientGetSyncStatusError.md) - [ObservedReads](interfaces/ObservedReads.md) - [OrderDetail](type-aliases/OrderDetail.md) - [~~GetLiquidationsOptions~~](type-aliases/GetLiquidationsOptions.md) - [InvariantError](classes/InvariantError.md) - [spotPoolOperatorRegistryReadAbi](variables/spotPoolOperatorRegistryReadAbi.md) - [RevertContext](interfaces/RevertContext.md) - [decodeRevert](functions/decodeRevert.md) - [SomniaMarketsClientGetOpenPositionsWithPnLError](type-aliases/SomniaMarketsClientGetOpenPositionsWithPnLError.md) - [SomniaMarketsClientGetClaimableError](type-aliases/SomniaMarketsClientGetClaimableError.md) - [SomniaMarketsClientGetUserFillsPageError](type-aliases/SomniaMarketsClientGetUserFillsPageError.md) - [SomniaMarketsClientListLiquidationsError](type-aliases/SomniaMarketsClientListLiquidationsError.md) - [~~SomniaMarketsClientGetLiquidationsError~~](type-aliases/SomniaMarketsClientGetLiquidationsError.md) - [SomniaMarketsClientListRegistryMarketsCheckedError](type-aliases/SomniaMarketsClientListRegistryMarketsCheckedError.md) - [SomniaMarketsClientGetPerpFeedStatusError](type-aliases/SomniaMarketsClientGetPerpFeedStatusError.md) - [SomniaMarketsClientWithObservations](interfaces/SomniaMarketsClientWithObservations.md) - [IndependentHead](interfaces/IndependentHead.md) - [IndexerFreshness](type-aliases/IndexerFreshness.md) - [TransactionSummary](interfaces/TransactionSummary.md) - [erc20WriteAbi](variables/erc20WriteAbi.md) - [orderBookBatchWriteAbi](variables/orderBookBatchWriteAbi.md) - [marginBankWriteAbi](variables/marginBankWriteAbi.md) - [erc20VaultWriteAbi](variables/erc20VaultWriteAbi.md) - [spotStopRegistryWriteAbi](variables/spotStopRegistryWriteAbi.md) - [spotStopRegistryEventsAbi](variables/spotStopRegistryEventsAbi.md) - [operatorRegistryWriteAbi](variables/operatorRegistryWriteAbi.md) - [ExchangeStatus](interfaces/ExchangeStatus.md) - [ExchangeDataStatus](interfaces/ExchangeDataStatus.md) - [SomniaMarketsFetchDataStatusError](type-aliases/SomniaMarketsFetchDataStatusError.md) - [SomniaMarketsRedeemError](type-aliases/SomniaMarketsRedeemError.md) - [SomniaMarkets](classes/SomniaMarkets.md) - [ComputeBinaryPnlError](type-aliases/ComputeBinaryPnlError.md) - [RawGridDirection](type-aliases/RawGridDirection.md) ## perpetual markets - [FundingPayment](type-aliases/FundingPayment.md) - [MarginEvent](type-aliases/MarginEvent.md) - [LIQUIDATION\_KIND](variables/LIQUIDATION_KIND.md) - [LiquidationKind](type-aliases/LiquidationKind.md) - [isLiquidationKind](functions/isLiquidationKind.md) - [LiquidationEvent](type-aliases/LiquidationEvent.md) - [FundingRateUpdate](type-aliases/FundingRateUpdate.md) - [FundingRateCandle](type-aliases/FundingRateCandle.md) - [PerpFeeRecord](type-aliases/PerpFeeRecord.md) - [OpenInterestSnapshot](type-aliases/OpenInterestSnapshot.md) - [ListLiquidationsOptions](interfaces/ListLiquidationsOptions.md) - [PERP\_ORDER\_REJECTION\_REASON](variables/PERP_ORDER_REJECTION_REASON.md) - [PerpOrderRejectionReason](type-aliases/PerpOrderRejectionReason.md) - [PerpOrderRejection](type-aliases/PerpOrderRejection.md) - [PerpFundingPayer](type-aliases/PerpFundingPayer.md) - [PerpMainFunding](interfaces/PerpMainFunding.md) - [PerpWalletLinkage](interfaces/PerpWalletLinkage.md) - [PerpWalletLinkEvent](type-aliases/PerpWalletLinkEvent.md) - [PerpMarginPull](type-aliases/PerpMarginPull.md) - [PerpMainFundingEvent](type-aliases/PerpMainFundingEvent.md) - [MarginStatus](type-aliases/MarginStatus.md) - [MARGIN\_STATUS](variables/MARGIN_STATUS.md) - [MarginAccount](interfaces/MarginAccount.md) - [AccountHealth](interfaces/AccountHealth.md) - [PerpRiskParams](interfaces/PerpRiskParams.md) - [PerpHealthSnapshot](type-aliases/PerpHealthSnapshot.md) - [PerpLiquidationPriceInputs](interfaces/PerpLiquidationPriceInputs.md) - [perpLiquidationPrice](functions/perpLiquidationPrice.md) - [PerpLeverage](interfaces/PerpLeverage.md) - [PerpPositionAnalyticsInputs](interfaces/PerpPositionAnalyticsInputs.md) - [PerpPositionMetrics](interfaces/PerpPositionMetrics.md) - [perpPositionAnalytics](functions/perpPositionAnalytics.md) - [PerpPositionAnalytics](type-aliases/PerpPositionAnalytics.md) - [PerpSideHoldersRef](interfaces/PerpSideHoldersRef.md) - [GetPerpSideHoldersOptions](interfaces/GetPerpSideHoldersOptions.md) - [PerpSideHolders](interfaces/PerpSideHolders.md) - [GetBankruptcyPriceOptions](interfaces/GetBankruptcyPriceOptions.md) - [UnsignedMarginDeposit](interfaces/UnsignedMarginDeposit.md) - [PerpOrderMarginPreview](type-aliases/PerpOrderMarginPreview.md) - [PerpOrderMarginQuoteInputs](interfaces/PerpOrderMarginQuoteInputs.md) - [PerpOrderMarginQuote](interfaces/PerpOrderMarginQuote.md) - [perpOrderMarginQuote](functions/perpOrderMarginQuote.md) - [PerpMaxOrderSizeLimit](type-aliases/PerpMaxOrderSizeLimit.md) - [PerpMaxOrderSize](type-aliases/PerpMaxOrderSize.md) - [GetPerpMaxLeverageOptions](interfaces/GetPerpMaxLeverageOptions.md) - [PerpLiquidationPreview](type-aliases/PerpLiquidationPreview.md) - [PerpClosePreview](type-aliases/PerpClosePreview.md) - [PerpPortfolioMarket](type-aliases/PerpPortfolioMarket.md) - [PerpPortfolioOrder](type-aliases/PerpPortfolioOrder.md) - [PerpPortfolioTrade](type-aliases/PerpPortfolioTrade.md) - [PerpPortfolio](type-aliases/PerpPortfolio.md) - [TerminalOrderStatus](type-aliases/TerminalOrderStatus.md) - [PerpOrderHistoryRow](type-aliases/PerpOrderHistoryRow.md) - [PERP\_POOL\_FACTORY\_MARKET\_STATUS\_INTERFACE\_ID](variables/PERP_POOL_FACTORY_MARKET_STATUS_INTERFACE_ID.md) - [PerpPoolStatus](type-aliases/PerpPoolStatus.md) - [PerpStateOnchain](interfaces/PerpStateOnchain.md) - [perpMarkForPnl](functions/perpMarkForPnl.md) - [PerpFeedStatus](interfaces/PerpFeedStatus.md) - [PerpFundingPremium](interfaces/PerpFundingPremium.md) - [PerpPosition](interfaces/PerpPosition.md) - [PerpPositionRef](interfaces/PerpPositionRef.md) - [IndexedPerpPosition](type-aliases/IndexedPerpPosition.md) - [PERP\_STOP\_DROP\_REASON](variables/PERP_STOP_DROP_REASON.md) - [PerpStopDropReason](type-aliases/PerpStopDropReason.md) - [PerpStopOrderMarket](type-aliases/PerpStopOrderMarket.md) - [PerpStopOrder](type-aliases/PerpStopOrder.md) - [PerpStopOrderOnChain](type-aliases/PerpStopOrderOnChain.md) - [decodePerpStopOrderIds](functions/decodePerpStopOrderIds.md) - [UnsignedPerpStopOrder](interfaces/UnsignedPerpStopOrder.md) - [PerpSystemConfig](interfaces/PerpSystemConfig.md) - [InsuranceFundTier](interfaces/InsuranceFundTier.md) - [InsuranceFundState](interfaces/InsuranceFundState.md) - [LiquidationEngineConfig](interfaces/LiquidationEngineConfig.md) - [PerpInsuranceFundEvent](type-aliases/PerpInsuranceFundEvent.md) ## pools - [PoolBindingRecord](interfaces/PoolBindingRecord.md) - [IndexedPool](interfaces/IndexedPool.md) ## price feeds - [PriceWatchHandle](interfaces/PriceWatchHandle.md) - [PRICE\_FEED\_DECIMALS](variables/PRICE_FEED_DECIMALS.md) - [PriceCandleResolution](type-aliases/PriceCandleResolution.md) - [PRICE\_RESOLUTION\_SECONDS](variables/PRICE_RESOLUTION_SECONDS.md) - [LivePrice](interfaces/LivePrice.md) - [PricePoint](interfaces/PricePoint.md) - [PriceCandle](interfaces/PriceCandle.md) - [PriceFeedInfo](interfaces/PriceFeedInfo.md) - [PriceFeedStatus](type-aliases/PriceFeedStatus.md) - [PriceFeedHealth](type-aliases/PriceFeedHealth.md) ## quoting - [UnifiedBookLevels](type-aliases/UnifiedBookLevels.md) - [QuoteDenomination](type-aliases/QuoteDenomination.md) - [MarketOrderEstimate](interfaces/MarketOrderEstimate.md) - [estimateMarketOrder](functions/estimateMarketOrder.md) - [bookMidPrice](functions/bookMidPrice.md) - [fillsWithinSlippage](functions/fillsWithinSlippage.md) ## routing - [RouterActionKind](type-aliases/RouterActionKind.md) - [RouterActionRecord](type-aliases/RouterActionRecord.md) - [RouterActionsOptions](type-aliases/RouterActionsOptions.md) ## spot markets - [PLACE\_ORDER\_FOR\_SELECTOR](variables/PLACE_ORDER_FOR_SELECTOR.md) - [CANCEL\_ORDER\_FOR\_SELECTOR](variables/CANCEL_ORDER_FOR_SELECTOR.md) - [IsGloballyApprovedParams](interfaces/IsGloballyApprovedParams.md) - [IsApprovedForPoolParams](interfaces/IsApprovedForPoolParams.md) - [GetAutoPullRequirementParams](interfaces/GetAutoPullRequirementParams.md) - [AutoPullRequirement](interfaces/AutoPullRequirement.md) - [IsOperatorAuthorizedParams](interfaces/IsOperatorAuthorizedParams.md) - [LockedBalance](interfaces/LockedBalance.md) - [TokenLockBreakdown](interfaces/TokenLockBreakdown.md) - [LockedTokenBreakdown](interfaces/LockedTokenBreakdown.md) - [SpotPortfolioMarket](type-aliases/SpotPortfolioMarket.md) - [SpotPortfolioOrder](type-aliases/SpotPortfolioOrder.md) - [SpotPortfolioTrade](type-aliases/SpotPortfolioTrade.md) - [SpotPortfolio](type-aliases/SpotPortfolio.md) - [StopOrderStatus](type-aliases/StopOrderStatus.md) - [SpotStopOrder](type-aliases/SpotStopOrder.md) - [GetManualVaultModeParams](interfaces/GetManualVaultModeParams.md) ## system - [MarketCreatorInfo](interfaces/MarketCreatorInfo.md) - [SystemInfo](interfaces/SystemInfo.md) ## trading - [TraderConfig](interfaces/TraderConfig.md) - [TxResult](interfaces/TxResult.md) - [OrderFill](interfaces/OrderFill.md) - [PlaceStopOrderResult](interfaces/PlaceStopOrderResult.md) - [PlacePerpStopOrderResult](interfaces/PlacePerpStopOrderResult.md) - [PlaceOrderResult](interfaces/PlaceOrderResult.md) - [PlaceOrderParams](interfaces/PlaceOrderParams.md) - [ApproveBuilderParams](interfaces/ApproveBuilderParams.md) - [CancelOrderParams](interfaces/CancelOrderParams.md) - [ReduceOrderParams](interfaces/ReduceOrderParams.md) - [CancelExpiredOrdersParams](interfaces/CancelExpiredOrdersParams.md) - [SweepExpiredAtLevelParams](interfaces/SweepExpiredAtLevelParams.md) - [CaptureCloseParams](interfaces/CaptureCloseParams.md) - [ORDER\_TYPE](variables/ORDER_TYPE.md) - [PlaceSpotOrderParams](interfaces/PlaceSpotOrderParams.md) - [SpotOrderRequest](interfaces/SpotOrderRequest.md) - [PlaceSpotOrdersParams](interfaces/PlaceSpotOrdersParams.md) - [BatchPlaceOutcome](interfaces/BatchPlaceOutcome.md) - [PlaceSpotOrdersResult](interfaces/PlaceSpotOrdersResult.md) - [CancelOrdersParams](interfaces/CancelOrdersParams.md) - [BatchCancelOutcome](interfaces/BatchCancelOutcome.md) - [CancelOrdersResult](interfaces/CancelOrdersResult.md) - [ReduceOrderRequest](interfaces/ReduceOrderRequest.md) - [ReduceOrdersParams](interfaces/ReduceOrdersParams.md) - [PlacePerpOrderParams](interfaces/PlacePerpOrderParams.md) - [SELF\_MATCHING\_OPTION](variables/SELF_MATCHING_OPTION.md) - [BatchOrderRequest](interfaces/BatchOrderRequest.md) - [AmendOrdersParams](interfaces/AmendOrdersParams.md) - [AmendOrdersResult](interfaces/AmendOrdersResult.md) - [AmendOrderParams](interfaces/AmendOrderParams.md) - [AmendOrderResult](interfaces/AmendOrderResult.md) - [DepositMarginParams](interfaces/DepositMarginParams.md) - [WithdrawMarginParams](interfaces/WithdrawMarginParams.md) - [PerpWalletLinkTarget](interfaces/PerpWalletLinkTarget.md) - [ProposePerpWalletLinkParams](interfaces/ProposePerpWalletLinkParams.md) - [AcceptPerpWalletLinkParams](interfaces/AcceptPerpWalletLinkParams.md) - [CancelPerpWalletLinkProposalParams](interfaces/CancelPerpWalletLinkProposalParams.md) - [UnlinkPerpWalletParams](interfaces/UnlinkPerpWalletParams.md) - [RepayPerpMainFundingParams](interfaces/RepayPerpMainFundingParams.md) - [RecallPerpMainFundingParams](interfaces/RecallPerpMainFundingParams.md) - [WithdrawVaultParams](interfaces/WithdrawVaultParams.md) - [DepositVaultParams](interfaces/DepositVaultParams.md) - [DepositVaultNativeParams](interfaces/DepositVaultNativeParams.md) - [SetManualVaultModeParams](interfaces/SetManualVaultModeParams.md) - [SetOperatorApprovalGlobalParams](interfaces/SetOperatorApprovalGlobalParams.md) - [SetOperatorApprovalForPoolParams](interfaces/SetOperatorApprovalForPoolParams.md) - [SetPerpLeverageParams](interfaces/SetPerpLeverageParams.md) - [PlaceSpotStopOrderParams](interfaces/PlaceSpotStopOrderParams.md) - [CancelStopOrderParams](interfaces/CancelStopOrderParams.md) - [ClaimPerpStopSomiParams](interfaces/ClaimPerpStopSomiParams.md) - [PerpStopIntent](type-aliases/PerpStopIntent.md) - [PerpStopOrderLeg](interfaces/PerpStopOrderLeg.md) - [PlacePerpStopOrderParams](interfaces/PlacePerpStopOrderParams.md) - [LinkPerpStopOrdersParams](interfaces/LinkPerpStopOrdersParams.md) - [CancelPerpStopOrdersParams](interfaces/CancelPerpStopOrdersParams.md) - [MintSetParams](interfaces/MintSetParams.md) - [BurnSetParams](interfaces/BurnSetParams.md) - [RedeemParams](interfaces/RedeemParams.md) - [RedeemManyParams](interfaces/RedeemManyParams.md) - [RedeemAuthorization](interfaces/RedeemAuthorization.md) - [SignRedeemAuthParams](interfaces/SignRedeemAuthParams.md) - [RedeemForParams](interfaces/RedeemForParams.md) - [RedeemDirectParams](interfaces/RedeemDirectParams.md) - [ClaimOwedParams](interfaces/ClaimOwedParams.md) - [FinalizeMarketParams](interfaces/FinalizeMarketParams.md) - [SyncSettlementParams](interfaces/SyncSettlementParams.md) - [ReleasePoolParams](interfaces/ReleasePoolParams.md) - [PokeOracleParams](interfaces/PokeOracleParams.md) - [VoidExpiredParams](interfaces/VoidExpiredParams.md) - [SettlementRecord](interfaces/SettlementRecord.md) - [Permit2TransferFrom](interfaces/Permit2TransferFrom.md) - [RouterMintBase](interfaces/RouterMintBase.md) - [MintSetNativeParams](interfaces/MintSetNativeParams.md) - [MintSetPermit2Params](interfaces/MintSetPermit2Params.md) - [RedeemNativeParams](interfaces/RedeemNativeParams.md) - [FaucetParams](interfaces/FaucetParams.md) - [ResolveParams](interfaces/ResolveParams.md) - [VoidMarketParams](interfaces/VoidMarketParams.md) - [TraderBuildPlaceSpotOrderError](type-aliases/TraderBuildPlaceSpotOrderError.md) - [Trader](interfaces/Trader.md) - [ORDER\_KIND](variables/ORDER_KIND.md) - [UnsignedCall](interfaces/UnsignedCall.md) - [UnsignedOrder](interfaces/UnsignedOrder.md) ## validation - [PreflightResult](interfaces/PreflightResult.md) - [ZERO\_ADDRESS](variables/ZERO_ADDRESS.md) - [HUB\_MIN\_FREE\_BALANCE\_WEI](variables/HUB_MIN_FREE_BALANCE_WEI.md) - [MIN\_SERIES\_INTERVAL\_SEC](variables/MIN_SERIES_INTERVAL_SEC.md) - [OperatorPreflightInput](interfaces/OperatorPreflightInput.md) - [preflightOperator](functions/preflightOperator.md) - [VenuePreflightInput](interfaces/VenuePreflightInput.md) - [preflightVenue](functions/preflightVenue.md) - [HubPreflightInput](interfaces/HubPreflightInput.md) - [preflightHub](functions/preflightHub.md) - [CreateQuotePreflightInput](interfaces/CreateQuotePreflightInput.md) - [preflightCreateQuote](functions/preflightCreateQuote.md) - [MarketCreatorPreflightInput](interfaces/MarketCreatorPreflightInput.md) - [preflightMarketCreator](functions/preflightMarketCreator.md) - [SeriesPreflightInput](interfaces/SeriesPreflightInput.md) - [preflightSeries](functions/preflightSeries.md) - [RollPreflightInput](interfaces/RollPreflightInput.md) - [preflightRoll](functions/preflightRoll.md) - [preflightChain](functions/preflightChain.md) - [isLocalPrecompileUnavailable](functions/isLocalPrecompileUnavailable.md) --- # /docs/typescript/api/index/classes/ContractRevertError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ContractRevertError # Class: ContractRevertError Defined in: packages/sdk/src/errors.ts:280 A contract rejected the call — the SDK decodes the revert against the protocol's custom-error ABIs so the failure reads as its Solidity name. **Details** `errorName` is the contract's own error (e.g. `"InsufficientBalance"`, `"MarketNotSettled"`, `"ExpiredOrderMustBeCancelled"`) and `args` its decoded parameters — that pair is what a caller branches on to decide whether to cancel-then-retry, top up collateral, or give up. Thrown on every revert path: send-time rejection, pre-send simulation, a mined receipt with failed status, and `eth_call` reads. **Gotchas** `errorName` is not always populated. When the revert data doesn't match any known error (a bare `require` string, an unknown selector, or no data at all) it is `undefined` and `reason`/`data` carry whatever the node returned — so branch with a fallback arm rather than assuming a name. The error is still this class either way, so callers never face a raw viem error. **Example** (Handling a decoded revert) ```ts import { ContractRevertError } from "@somnia-chain/markets-sdk"; try { await trader.placeOrder(params); } catch (e) { if (e instanceof ContractRevertError && e.errorName === "ExpiredOrderMustBeCancelled") { await trader.cancelExpiredOrders({ pool, orderIds: [orderId] }); } else throw e; } ``` ## Extends - [`SomniaMarketsError`](SomniaMarketsError.md) ## Constructors ### Constructor > **new ContractRevertError**(`fields`, `options?`): `ContractRevertError` Defined in: packages/sdk/src/errors.ts:294 #### Parameters ##### fields ###### errorName? `string` ###### args? readonly `unknown`[] ###### reason? `string` ###### data? `string` ###### address? `string` ###### functionName? `string` ##### options? `ErrorOptions` #### Returns `ContractRevertError` #### Overrides [`SomniaMarketsError`](SomniaMarketsError.md).[`constructor`](SomniaMarketsError.md#constructor) ## Properties ### errorName? > `readonly` `optional` **errorName?**: `string` Defined in: packages/sdk/src/errors.ts:282 The decoded Solidity error name, or `undefined` when the revert didn't match a known error. *** ### args? > `readonly` `optional` **args?**: readonly `unknown`[] Defined in: packages/sdk/src/errors.ts:284 Decoded arguments of the custom error, positionally, when `errorName` is set. *** ### reason? > `readonly` `optional` **reason?**: `string` Defined in: packages/sdk/src/errors.ts:286 A plain `require`/`revert` string reason, when the revert carried one instead of a custom error. *** ### data? > `readonly` `optional` **data?**: `string` Defined in: packages/sdk/src/errors.ts:288 Raw revert data as returned by the node, when present. *** ### address? > `readonly` `optional` **address?**: `string` Defined in: packages/sdk/src/errors.ts:290 The contract that reverted, when known. *** ### functionName? > `readonly` `optional` **functionName?**: `string` Defined in: packages/sdk/src/errors.ts:292 The function that was called, when known. --- # /docs/typescript/api/index/classes/IndexerError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexerError # Class: IndexerError Defined in: packages/sdk/src/errors.ts:186 An indexer (Hasura/Envio GraphQL) request did not complete. **When to use** Use when opting into graceful degradation — this is the error to catch to serve stale or empty UI instead of failing a page. It is safe to treat as transient-or-misconfigured: endpoint down, bad URL, schema drift, timeout. **Gotchas** This ALWAYS means "the read didn't happen" — never "there is no such row". A point read that finds nothing resolves to `null` and a list read to `[]`; both are successful reads. Treating this as "not found" will hide an outage behind an empty state. **Example** (Falling back after an indexer failure) ```ts import { IndexerError } from "@somnia-chain/markets-sdk"; const markets = await exchange.client .listBinaryMarkets() .catch((e) => { if (e instanceof IndexerError) return []; throw e; }); ``` ## Extends - [`SomniaMarketsError`](SomniaMarketsError.md) ## Constructors ### Constructor > **new IndexerError**(`operation`, `detail`, `options?`): `IndexerError` Defined in: packages/sdk/src/errors.ts:196 Creates an indexer error with operation context and an optional cause. **Details** - `operation`: GraphQL operation name that failed (e.g. `"listBinaryMarkets"`). - `detail`: Why it failed (HTTP status, GraphQL error message, "empty response"). - `options`: Standard `cause` passthrough — the underlying fetch/GraphQL failure. #### Parameters ##### operation `string` ##### detail `string` ##### options? `ErrorOptions` #### Returns `IndexerError` #### Overrides [`SomniaMarketsError`](SomniaMarketsError.md).[`constructor`](SomniaMarketsError.md#constructor) ## Properties ### operation > `readonly` **operation**: `string` Defined in: packages/sdk/src/errors.ts:197 --- # /docs/typescript/api/index/classes/InvalidInputError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / InvalidInputError # Class: InvalidInputError Defined in: packages/sdk/src/errors.ts:82 The call itself was wrong — a bad argument, an unknown symbol, or a method used against the wrong kind of market. Thrown *before* any network round-trip. **Details** This says the *caller* is at fault, in contrast to [NotConfiguredError](NotConfiguredError.md) (the client is missing a config value) and [ContractRevertError](ContractRevertError.md) (the call was well-formed but the chain rejected it). **Gotchas** Never retry this. The arguments are wrong, so the same call fails the same way forever — fix the input instead of backing off. ## Extends - [`SomniaMarketsError`](SomniaMarketsError.md) ## Constructors ### Constructor > **new InvalidInputError**(`message`, `options?`): `InvalidInputError` Defined in: packages/sdk/src/errors.ts:91 Creates an invalid-input error with an optional underlying cause. **Details** - `message`: What was wrong with the input. - `options`: Standard `cause` passthrough. #### Parameters ##### message `string` ##### options? `ErrorOptions` #### Returns `InvalidInputError` #### Overrides [`SomniaMarketsError`](SomniaMarketsError.md).[`constructor`](SomniaMarketsError.md#constructor) --- # /docs/typescript/api/index/classes/InvariantError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / InvariantError # Class: InvariantError Defined in: packages/sdk/src/raise.ts:29 Thrown when an invariant the code had already established turns out false. **Details** Seeing this in a log means the SDK's own reasoning was wrong — not that a caller did anything invalid. That distinction is why it is its own class. **Gotchas** It should never be caught to control flow, only reported as a bug. ## Extends - [`SomniaMarketsError`](SomniaMarketsError.md) ## Constructors ### Constructor > **new InvariantError**(`message`): `InvariantError` Defined in: packages/sdk/src/raise.ts:30 #### Parameters ##### message `string` #### Returns `InvariantError` #### Overrides [`SomniaMarketsError`](SomniaMarketsError.md).[`constructor`](SomniaMarketsError.md#constructor) --- # /docs/typescript/api/index/classes/NetworkTape [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / NetworkTape # Class: NetworkTape Defined in: packages/sdk/src/networkTape.ts:126 The live network-wide order-flow tape. Construct via [SomniaMarketsClient.createNetworkTape](../interfaces/SomniaMarketsClient.md#createnetworktape); nothing connects until the first [subscribe](#subscribe), and the socket closes when the last listener unsubscribes. Rows are read synchronously off [bids](#bids) / [fills](#fills) / [asks](#asks) after a listener fires. ## Properties ### bids > **bids**: [`TapeOrder`](../interfaces/TapeOrder.md)[] = `[]` Defined in: packages/sdk/src/networkTape.ts:128 Newest-first ring buffer of bid placements (capped at `maxRows`). *** ### fills > **fills**: [`TapeFill`](../interfaces/TapeFill.md)[] = `[]` Defined in: packages/sdk/src/networkTape.ts:130 Newest-first ring buffer of fills. *** ### asks > **asks**: [`TapeOrder`](../interfaces/TapeOrder.md)[] = `[]` Defined in: packages/sdk/src/networkTape.ts:132 Newest-first ring buffer of ask placements. ## Methods ### subscribe() > **subscribe**(`listener`): () => `void` Defined in: packages/sdk/src/networkTape.ts:172 Register a listener (fired, microtask-coalesced, after each applied batch — read the row buffers in it). The FIRST subscription opens the socket; the returned unsubscribe closes it again when it releases the last one. #### Parameters ##### listener () => `void` #### Returns () => `void` *** ### getStatus() > **getStatus**(): [`NetworkTapeStatus`](../interfaces/NetworkTapeStatus.md) Defined in: packages/sdk/src/networkTape.ts:181 #### Returns [`NetworkTapeStatus`](../interfaces/NetworkTapeStatus.md) --- # /docs/typescript/api/index/classes/NotConfiguredError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / NotConfiguredError # Class: NotConfiguredError Defined in: packages/sdk/src/errors.ts:115 The feature needs a contract address (or URL) that this client wasn't given. **Details** The SDK degrades by feature rather than refusing to construct: most [SomniaMarketsAddresses](../interfaces/SomniaMarketsAddresses.md) entries are optional, and the methods that need one throw this when it's absent. **Gotchas** Because construction succeeds, a missing address surfaces at the first call that needs it rather than at `new SomniaMarkets(…)` — so a feature can look wired up until it's exercised. The fix is always config-side (pass the address, or the method's own override param), never a retry. ## Extends - [`SomniaMarketsError`](SomniaMarketsError.md) ## Constructors ### Constructor > **new NotConfiguredError**(`what`, `detail`): `NotConfiguredError` Defined in: packages/sdk/src/errors.ts:124 Creates a missing-configuration error for one operation. **Details** - `what`: The config key or contract the operation needs (e.g. `"addresses.oracleHub"`). - `detail`: What was being attempted, and how to supply it. #### Parameters ##### what `string` ##### detail `string` #### Returns `NotConfiguredError` #### Overrides [`SomniaMarketsError`](SomniaMarketsError.md).[`constructor`](SomniaMarketsError.md#constructor) ## Properties ### what > `readonly` **what**: `string` Defined in: packages/sdk/src/errors.ts:125 --- # /docs/typescript/api/index/classes/RpcError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RpcError # Class: RpcError Defined in: packages/sdk/src/errors.ts:222 A JSON-RPC / WebSocket request to the node did not complete. **Details** Transport-level only — the request never produced a chain answer (connection refused, timeout, unsupported method, subscription dropped). **Gotchas** A call that *did* reach the chain and was rejected by a contract is a [ContractRevertError](ContractRevertError.md) instead. Check for that first when branching: both are plausible for the same write, but only this one is worth retrying. ## Extends - [`SomniaMarketsError`](SomniaMarketsError.md) ## Constructors ### Constructor > **new RpcError**(`operation`, `detail`, `options?`): `RpcError` Defined in: packages/sdk/src/errors.ts:232 Creates an RPC error with operation context and an optional cause. **Details** - `operation`: What was attempted (e.g. `"eth_sendRawTransaction"`, `"watchBook"`). - `detail`: Why it failed. - `options`: Standard `cause` passthrough — the underlying viem/transport error. #### Parameters ##### operation `string` ##### detail `string` ##### options? `ErrorOptions` #### Returns `RpcError` #### Overrides [`SomniaMarketsError`](SomniaMarketsError.md).[`constructor`](SomniaMarketsError.md#constructor) ## Properties ### operation > `readonly` **operation**: `string` Defined in: packages/sdk/src/errors.ts:233 --- # /docs/typescript/api/index/classes/SignerRequiredError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SignerRequiredError # Class: SignerRequiredError Defined in: packages/sdk/src/errors.ts:144 An authenticated (writing) method was called on a read-only client. **Details** Construct the exchange with a `privateKey`, an `account`, or a `walletClient` to unlock writes. Distinct from [NotConfiguredError](NotConfiguredError.md): nothing is missing from the *addresses*, the client simply has no signer. ## Extends - [`SomniaMarketsError`](SomniaMarketsError.md) ## Constructors ### Constructor > **new SignerRequiredError**(`operation`): `SignerRequiredError` Defined in: packages/sdk/src/errors.ts:152 Creates a signer-required error for one authenticated operation. **Details** - `operation`: The method that needs a signer (e.g. `"createOrder"`). #### Parameters ##### operation `string` #### Returns `SignerRequiredError` #### Overrides [`SomniaMarketsError`](SomniaMarketsError.md).[`constructor`](SomniaMarketsError.md#constructor) ## Properties ### operation > `readonly` **operation**: `string` Defined in: packages/sdk/src/errors.ts:152 --- # /docs/typescript/api/index/classes/SomniaMarkets [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarkets # Class: SomniaMarkets Defined in: packages/sdk/src/unified/exchange.ts:325 ## Constructors ### Constructor > **new SomniaMarkets**(`config`): `SomniaMarkets` Defined in: packages/sdk/src/unified/exchange.ts:430 Create one owner for Markets reads, watches, and optional signing. Reconciliation is off unless its positive block interval and bounded depth are supplied. #### Parameters ##### config [`SomniaMarketsConfig`](../type-aliases/SomniaMarketsConfig.md) #### Returns `SomniaMarkets` #### Throws [InvalidInputError](InvalidInputError.md) If reconciliation bounds are invalid. #### Throws [NotConfiguredError](NotConfiguredError.md) If the indexer endpoint is absent. ## Properties ### client > `readonly` **client**: [`SomniaMarketsClientWithObservations`](../interfaces/SomniaMarketsClientWithObservations.md) Defined in: packages/sdk/src/unified/exchange.ts:327 The native engine — bigint-exact, address-keyed. The escape hatch. *** ### markets > **markets**: `Record`\<`string`, [`UnifiedMarket`](../interfaces/UnifiedMarket.md)\> = `{}` Defined in: packages/sdk/src/unified/exchange.ts:329 Unified markets keyed by MARKET symbol (populated by loadMarkets). *** ### symbols > **symbols**: `string`[] = `[]` Defined in: packages/sdk/src/unified/exchange.ts:331 All market symbols (populated by loadMarkets). *** ### has > `readonly` **has**: `object` Defined in: packages/sdk/src/unified/exchange.ts:338 Capability map — which unified verbs this venue supports (the ccxt `exchange.has` convention, for capability-probing bot code). Every listed verb is implemented here, so every flag is `true`. #### fetchMarkets > `readonly` **fetchMarkets**: `true` = `true` [SomniaMarkets.fetchMarkets](#fetchmarkets) #### fetchOrderBook > `readonly` **fetchOrderBook**: `true` = `true` [SomniaMarkets.fetchOrderBook](#fetchorderbook) #### fetchTrades > `readonly` **fetchTrades**: `true` = `true` [SomniaMarkets.fetchTrades](#fetchtrades) #### fetchOHLCV > `readonly` **fetchOHLCV**: `true` = `true` [SomniaMarkets.fetchOHLCV](#fetchohlcv) #### fetchBalance > `readonly` **fetchBalance**: `true` = `true` [SomniaMarkets.fetchBalance](#fetchbalance) #### fetchOpenOrders > `readonly` **fetchOpenOrders**: `true` = `true` [SomniaMarkets.fetchOpenOrders](#fetchopenorders) #### getOrderHistoryPage > `readonly` **getOrderHistoryPage**: `true` = `true` [SomniaMarkets.getOrderHistoryPage](#getorderhistorypage) #### getOrdersPage > `readonly` **getOrdersPage**: `true` = `true` [SomniaMarkets.getOrdersPage](#getorderspage) #### fetchMyTrades > `readonly` **fetchMyTrades**: `true` = `true` [SomniaMarkets.fetchMyTrades](#fetchmytrades) #### fetchStatus > `readonly` **fetchStatus**: `true` = `true` [SomniaMarkets.fetchStatus](#fetchstatus) #### createOrder > `readonly` **createOrder**: `true` = `true` [SomniaMarkets.createOrder](#createorder) #### cancelOrder > `readonly` **cancelOrder**: `true` = `true` [SomniaMarkets.cancelOrder](#cancelorder) #### watchOrderBook > `readonly` **watchOrderBook**: `true` = `true` [SomniaMarkets.watchOrderBook](#watchorderbook) #### watchTrades > `readonly` **watchTrades**: `true` = `true` [SomniaMarkets.watchTrades](#watchtrades) #### watchOrders > `readonly` **watchOrders**: `true` = `true` [SomniaMarkets.watchOrders](#watchorders) #### watchMyTrades > `readonly` **watchMyTrades**: `true` = `true` [SomniaMarkets.watchMyTrades](#watchmytrades) #### fetchPositions > `readonly` **fetchPositions**: `true` = `true` [SomniaMarkets.fetchPositions](#fetchpositions) #### fetchFundingRate > `readonly` **fetchFundingRate**: `true` = `true` [SomniaMarkets.fetchFundingRate](#fetchfundingrate) #### fetchFundingRateHistory > `readonly` **fetchFundingRateHistory**: `true` = `true` [SomniaMarkets.fetchFundingRateHistory](#fetchfundingratehistory) — the key did not previously exist in this map, so it had to be ADDED rather than flipped. #### watchPrice > `readonly` **watchPrice**: `true` = `true` [SomniaMarkets.watchPrice](#watchprice) #### fetchPrice > `readonly` **fetchPrice**: `true` = `true` [SomniaMarkets.fetchPrice](#fetchprice) #### fetchPriceOHLCV > `readonly` **fetchPriceOHLCV**: `true` = `true` [SomniaMarkets.fetchPriceOHLCV](#fetchpriceohlcv) ## Accessors ### trader #### Get Signature > **get** **trader**(): [`Trader`](../interfaces/Trader.md) Defined in: packages/sdk/src/unified/exchange.ts:448 The raw write tier bound to this exchange's signer — bigint-exact `placeOrder`/`mintSet`/`faucet`/… for anything the unified verbs don't cover. **Gotchas** Built lazily; throws if no signer was configured. ##### Returns [`Trader`](../interfaces/Trader.md) *** ### walletAddress #### Get Signature > **get** **walletAddress**(): `` `0x${string}` `` \| `undefined` Defined in: packages/sdk/src/unified/exchange.ts:471 The authenticated wallet address, if a signer was configured. ##### Returns `` `0x${string}` `` \| `undefined` *** ### perpDiscoveryError #### Get Signature > **get** **perpDiscoveryError**(): [`SomniaMarketsError`](SomniaMarketsError.md) \| `null` Defined in: packages/sdk/src/unified/exchange.ts:535 Why chain-tier perp discovery did not run on the last [loadMarkets](#loadmarkets), or `null` when it ran (or was never applicable). `loadMarkets()` contains a discovery failure rather than throwing, because it is the implicit prerequisite of nearly every symbol-based verb and a chain failure must not take the SPOT and OUTCOME market lists down with it. This is where that contained failure is reported, with the underlying error preserved in `cause`. **When to use** Check it after `loadMarkets()` whenever a SHORT perp list would be worse than an error — a market page, an order router, anything that would otherwise present "this market does not exist". Then either tell the user the list is incomplete, or retry with **`loadMarkets(true)`**: a bare `loadMarkets()` early-returns once any market is cached, so it never re-runs discovery and this value would stay stale. **Gotchas** - Do NOT infer this from `perpStatus` being absent. That works only when the indexer already carries a perp row to inspect; with a configured factory and an indexer carrying none, a failed discovery yields an EMPTY perp list with no market to check. This accessor answers in both cases. - `null` does not mean the venue has perps. A chain with no perps plane deployed (local anvil) never attempts discovery and reports `null` too. **Example** (Refusing to show a possibly-short perp list) ```ts await exchange.loadMarkets(); if (exchange.perpDiscoveryError) { // A bare loadMarkets() would early-return the cached registry and never retry. await exchange.loadMarkets(true); } if (exchange.perpDiscoveryError) { const partial = exchange.perpDiscoveryPartialFailure; throw new Error( partial ? `perp list incomplete: ${partial.failed} of ${partial.total} markets unread` : "perp discovery failed; the perp list may be short", ); } ``` ##### Returns [`SomniaMarketsError`](SomniaMarketsError.md) \| `null` *** ### perpDiscoveryPartialFailure #### Get Signature > **get** **perpDiscoveryPartialFailure**(): \{ `failed`: `number`; `total`: `number`; \} \| `null` Defined in: packages/sdk/src/unified/exchange.ts:548 How much of the chain-only perp set was lost when discovery PARTIALLY failed, or `null` when it did not. Typed counts rather than prose in a message, so a consumer can decide on them — `{ failed: 1, total: 4 }` reads as "three of four chain-only markets are listed". Always `null` when [perpDiscoveryError](#perpdiscoveryerror) is null, and also null when discovery failed outright rather than partly (nothing was read, so there is no ratio). ##### Returns \{ `failed`: `number`; `total`: `number`; \} \| `null` ## Methods ### setSigner() > **setSigner**(`signer`): `void` Defined in: packages/sdk/src/unified/exchange.ts:461 Bind (or replace) the exchange's signer after construction. Browser apps construct the exchange at boot for public reads, then call this when the user's wallet connects — and again with `{}` on disconnect, which returns the exchange to unauthenticated reads. Replaces the trader every authenticated verb and `walletAddress` resolve against; live watches and market data are unaffected. #### Parameters ##### signer `Pick`\<[`TraderConfig`](../interfaces/TraderConfig.md), `"privateKey"` \| `"account"` \| `"walletClient"`\> #### Returns `void` *** ### loadMarkets() > **loadMarkets**(`reload?`): `Promise`\<`Record`\<`string`, [`UnifiedMarket`](../interfaces/UnifiedMarket.md)\>\> Defined in: packages/sdk/src/unified/exchange.ts:579 Load (or reload) the market registry: every market as a unified, symbol-keyed market object. Call once before anything symbol-based. **Perp markets come from two sources.** The indexer's rows are unioned with the PerpPoolFactory's, because the indexer's perp set is a curated manifest and a pool deployed after it was written is live on chain and absent there. A market only the chain knows carries [UnifiedMarket.indexed](../interfaces/UnifiedMarket.md#indexed) `false`; read that field's docs before touching anything history-derived on it. **A chain failure is contained, not thrown.** This method is the implicit prerequisite of nearly every symbol-based verb, so letting a discovery failure out would take the SPOT and OUTCOME lists down with it — lists that need no chain read at all. The indexer read still throws: its failure means there is no registry to return. A contained discovery failure is reported by [perpDiscoveryError](#perpdiscoveryerror), and that includes the PARTIAL case where some chain-only markets were read and others were not. **Gotchas** - Early-returns the cached registry unless `reload` is true, so a retry after a discovery failure must pass `true`. - Concurrent cold reads share discovery. Each explicit reload waits for prior discovery, then re-reads independently. **Details** - `reload`: Re-read everything, including the live tradeability gates and the binary pools' grids. #### Parameters ##### reload? `boolean` = `false` #### Returns `Promise`\<`Record`\<`string`, [`UnifiedMarket`](../interfaces/UnifiedMarket.md)\>\> *** ### market() > **market**(`ref`): [`Tradable`](../interfaces/Tradable.md) Defined in: packages/sdk/src/unified/exchange.ts:960 Resolve any handle (symbol, tradable symbol, pool/market address, market id) to its tradable. Requires loadMarkets(). #### Parameters ##### ref `string` #### Returns [`Tradable`](../interfaces/Tradable.md) *** ### priceToPrecision() > **priceToPrecision**(`ref`, `price`): `number` Defined in: packages/sdk/src/unified/exchange.ts:980 Snap a price to the market's tick grid (rounds down; binary prices are also clamped inside (0, 1)). **When to use** Use before createOrder with computed prices. Spot/perp ticks come from the market row; binary ticks come from the pool, read once by [loadMarkets](#loadmarkets) — so a pool recycled mid-session keeps the grid captured at load time until `loadMarkets(true)` refreshes it. **Gotchas** - Throws [InvalidInputError](InvalidInputError.md) if the market is binary and its pool's parameters could not be read — quantizing against a guessed grid is what produced off-tick rejections, so this fails loudly instead. #### Parameters ##### ref `string` ##### price `number` #### Returns `number` *** ### amountToPrecision() > **amountToPrecision**(`ref`, `amount`): `number` Defined in: packages/sdk/src/unified/exchange.ts:1001 Snap an amount to the market's lot grid (rounds down). Spot/perp lots come from the market row; binary lots come from the pool, read once by [loadMarkets](#loadmarkets) — so a pool recycled mid-session keeps the grid captured at load time until `loadMarkets(true)` refreshes it. **Gotchas** - Throws [InvalidInputError](InvalidInputError.md) if the market is binary and its pool's parameters could not be read. Previously such a market fell back to a one-whole-token lot, silently flooring every sub-token amount to 0. #### Parameters ##### ref `string` ##### amount `number` #### Returns `number` *** ### fetchMarkets() > **fetchMarkets**(): `Promise`\<[`UnifiedMarket`](../interfaces/UnifiedMarket.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:1018 Every market as an array — [loadMarkets](#loadmarkets) (called if needed), minus the symbol keying. **When to use** Use as the ccxt-shaped sibling for list-style consumers. #### Returns `Promise`\<[`UnifiedMarket`](../interfaces/UnifiedMarket.md)[]\> *** ### fetchOrderBook() > **fetchOrderBook**(`ref`, `options?`): `Promise`\<[`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md)\> Defined in: packages/sdk/src/unified/exchange.ts:1158 One-shot book read from the contract (head-fresh; no watch needed). **When to use** Use when one book snapshot is enough. For a continuously-current zero-round-trip book, use [watchOrderBook](#watchorderbook). Both sides use one selected head, or `options.blockNumber`. Empty books keep that pin. A numeric second argument remains the level limit. #### Parameters ##### ref `string` ##### options? `number` \| [`FetchOrderBookOptions`](../interfaces/FetchOrderBookOptions.md) #### Returns `Promise`\<[`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md)\> #### Throws [InvalidInputError](InvalidInputError.md) If the symbol, depth, or pin is invalid. #### Throws [NotConfiguredError](NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [RpcError](RpcError.md) If the head selection or either read fails. #### Throws [ContractRevertError](ContractRevertError.md) If the contract rejects a read. *** ### fetchTrades() > **fetchTrades**(`ref`, `since?`, `limit?`): `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:1184 Recent public trades with authoritative block and log positions (indexer, newest first). #### Parameters ##### ref `string` ##### since? `number` ##### limit? `number` = `50` #### Returns `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> #### Throws [InvalidInputError](InvalidInputError.md) If the symbol or source position is invalid. #### Throws [IndexerError](IndexerError.md) If the indexer read fails. *** ### fetchOHLCV() > **fetchOHLCV**(`ref`, `timeframe?`, `since?`, `limit?`): `Promise`\<[`UnifiedOHLCV`](../type-aliases/UnifiedOHLCV.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:1230 OHLCV candles (indexer), oldest first as [ms,o,h,l,c,vol] rows. Timeframes: 1m 5m 15m 1h 4h 1d. **Example** (Reading candles) The last 24 hourly candles, destructured per row. ```ts const candles = await exchange.fetchOHLCV("SOMI/USDC", "1h", undefined, 24); for (const [ts, open, high, low, close, volume] of candles) { console.log(new Date(ts).toISOString(), open, high, low, close, volume); } ``` #### Parameters ##### ref `string` ##### timeframe? `string` = `"5m"` ##### since? `number` ##### limit? `number` = `500` #### Returns `Promise`\<[`UnifiedOHLCV`](../type-aliases/UnifiedOHLCV.md)[]\> *** ### fetchTicker() > **fetchTicker**(`ref`): `Promise`\<[`UnifiedTicker`](../interfaces/UnifiedTicker.md)\> Defined in: packages/sdk/src/unified/exchange.ts:1262 Rolling 24h ticker (indexer): OHLC + base/quote volume folded from the hourly candles, `last` from the freshest fill. NO-outcome tradables view prices through the 1−p lens like every other read. **Example** (Reading a ticker) Drive a price strip off one call. ```ts const tk = await exchange.fetchTicker("SOMI/USDC"); console.log(tk.last, tk.percentage, tk.baseVolume); ``` #### Parameters ##### ref `string` #### Returns `Promise`\<[`UnifiedTicker`](../interfaces/UnifiedTicker.md)\> *** ### fetchBalance() > **fetchBalance**(): `Promise`\<[`UnifiedBalances`](../interfaces/UnifiedBalances.md)\> Defined in: packages/sdk/src/unified/exchange.ts:1369 Wallet balances for every currency the loaded markets use (+ native). **Gotchas** `free === total`: funds escrowed in resting orders live in the pools, not the wallet, so they simply don't appear here. - Throws [SignerRequiredError](SignerRequiredError.md) - balances are per-account, so this needs a signer (or an `account`) even though it only reads. - Throws [IndexerError](IndexerError.md) - `loadMarkets()` or the outcome-holdings read needed the indexer and it was unreachable. Distinct from an empty result: no balances is `{}`, not a throw. - Throws [RpcError](RpcError.md) - a chain balance read did not complete. A failed read is never reported as a zero balance or a missing key. - Throws [ContractRevertError](ContractRevertError.md) - a token's `balanceOf` reverted. **Example** (Reading balances) ERC-20s key by currency code; binary outcome holdings key by TRADABLE symbol. ```ts const bal = await exchange.fetchBalance(); console.log(bal.USDC?.total); // collateral in the wallet console.log(bal["BTC-95000-31DEC26/USDC#YES"]?.total); // YES shares held ``` #### Returns `Promise`\<[`UnifiedBalances`](../interfaces/UnifiedBalances.md)\> *** ### fetchOpenOrders() > **fetchOpenOrders**(`ref?`, `limit?`): `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:1433 Open orders (indexer view). **When to use** Use for an occasional snapshot; a trading loop should prefer [watchOrders](#watchorders). **Details** `limit` is applied BY THE QUERY, per venue — not to the merged result. An unscoped call reads all three venues, so it can return up to 3 × `limit` rows; a `ref`-scoped call reads only that venue. The default is 200 per venue. - `ref`: Restrict to one tradable (symbol or address). Omit for all. - `limit`: Max orders PER VENUE the query returns (default 200). **Gotchas** The indexer view lags the chain slightly. On SPOT the same limit also bounds the PENDING STOP ORDERS the underlying portfolio read returns — one query variable caps both sets. That list is not part of this verb's result, so the coupling is invisible here, but a caller reading `client.getSpotPortfolio` directly with a small `ordersLimit` will see a correspondingly short `pendingStopOrders`. #### Parameters ##### ref? `string` ##### limit? `number` #### Returns `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)[]\> *** ### fetchOrders() > **fetchOrders**(`ref?`, `since?`, `limit?`, `params?`): `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:1470 The wallet's orders across every lifecycle status (indexer), newest first — the history counterpart to [fetchOpenOrders](#fetchopenorders). Scope to one tradable with `ref`; page with `limit`/`params.offset`, both forwarded to the query as a true offset window over one ordered set. (Its siblings page differently: [fetchMyTrades](#fetchmytrades) pages a fill tape to satisfy `limit`, and [fetchOpenOrders](#fetchopenorders) applies its limit per venue.) **Example** (Reading order history) The last 50 orders on one book, whatever became of them. ```ts const orders = await exchange.fetchOrders("SOMI/USDC", undefined, 50); for (const o of orders) console.log(o.status, o.side, o.amount, o.txHash); ``` #### Parameters ##### ref? `string` ##### since? `number` ##### limit? `number` = `100` ##### params? ###### offset? `number` #### Returns `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)[]\> *** ### getOrderHistoryPage() > **getOrderHistoryPage**(`options?`): `Promise`\<[`UnifiedOrdersPage`](../type-aliases/UnifiedOrdersPage.md)\> Defined in: packages/sdk/src/unified/exchange.ts:1528 Read one raw-row page of the authenticated owner's indexed order history. Use this method to traverse indexed order records with immutable order identities. The records and offset window are mutable. They are not an immutable lifecycle log or a current Open Orders snapshot. The default `limit` is 100 and the default `offset` is 0. Continuation depends on raw rows, so a full page can have no display orders and still continue. The result is partial because changes can make pages skip or repeat rows. Exhaustion does not prove complete account state. The `status` option is an indexed history filter. In particular, `status: "Open"` cannot establish completeness, removals, continuity, or action freshness. Use a separately supported current-state flow when the caller needs the SDK's current open-order view. **Example** (Following order-history page offsets) ```ts let offset = 0; while (true) { const page = await exchange.getOrderHistoryPage({ limit: 100, offset }); for (const order of page.orders) console.log(order.identity, order.status); if (page.nextOffset === null) break; offset = page.nextOffset; } ``` #### Parameters ##### options? [`SomniaMarketsGetOrdersPageOptions`](../type-aliases/SomniaMarketsGetOrdersPageOptions.md) = `{}` #### Returns `Promise`\<[`UnifiedOrdersPage`](../type-aliases/UnifiedOrdersPage.md)\> #### Throws [InvalidInputError](InvalidInputError.md) If the ref, status, limit, or offset is invalid. #### Throws [SignerRequiredError](SignerRequiredError.md) If no account is configured. #### Throws [IndexerError](IndexerError.md) If the indexer read or producer-row conversion fails. *** ### getOrdersPage() > **getOrdersPage**(`options?`): `Promise`\<[`UnifiedOrdersPage`](../type-aliases/UnifiedOrdersPage.md)\> Defined in: packages/sdk/src/unified/exchange.ts:1542 Read one raw-row page of the authenticated owner's indexed order history. This compatibility name has the same result, pagination, and errors as [SomniaMarkets.getOrderHistoryPage](#getorderhistorypage). #### Parameters ##### options? [`SomniaMarketsGetOrdersPageOptions`](../type-aliases/SomniaMarketsGetOrdersPageOptions.md) = `{}` #### Returns `Promise`\<[`UnifiedOrdersPage`](../type-aliases/UnifiedOrdersPage.md)\> #### Throws [InvalidInputError](InvalidInputError.md) If the ref, status, limit, or offset is invalid. #### Throws [SignerRequiredError](SignerRequiredError.md) If no account is configured. #### Throws [IndexerError](IndexerError.md) If the indexer read or producer-row conversion fails. *** ### fetchPortfolioAnalytics() > **fetchPortfolioAnalytics**(`timeframe`, `params?`): `Promise`\<[`PortfolioAnalytics`](../interfaces/PortfolioAnalytics.md)\> Defined in: packages/sdk/src/unified/exchange.ts:1744 The wallet's portfolio metrics plane over a timeframe: a holdings curve, an equity curve, per-bucket PnL, money-weighted return, volume, and fees saved versus a comparison taker rate. Computed client-side from the wallet's indexed fills (avg-cost basis) marked to candle closes — no server aggregate involved. The two curves measure different things. `holdings` is what the traded book is worth at each sample, so it is a level. `equity` is the window's cumulative realized and unrealized PnL, so it is a change. Neither counts a token that arrived without a fill: read balances from the chain for what the wallet itself holds. Read `HoldingsPoint` before presenting the level — it states where its sign and its completeness end. SPOT-scoped today: binary outcomes settle rather than mark, and the perp account plane (funding, margin) joins the fold as new event kinds when perp analytics land. Fills are paged to exhaustion — truncating would drop the OLDEST fills and silently corrupt the carried-in cost basis, not just undercount volume. Fills whose taker direction the indexer has not resolved (`takerIsBid` null), or where the wallet's role (maker vs taker) is unknowable, are skipped rather than guessed. The money-weighted return needs to know what capital the wallet put in. Fills alone cannot say — capital that never passed through a trade is invisible to them — so without `funding` the capital base is a trades-only proxy that overstates the return for a wallet trading a small part of its balance. Pass `funding` to measure against real external capital, and read `mwrr.capitalBasis` to see which definition applied. **Example** (Measuring portfolio performance) ```ts const p = await exchange.fetchPortfolioAnalytics("7d"); console.log(p.pnl.totalUsd, p.mwrr.return, p.equity.length); ``` #### Parameters ##### timeframe [`PortfolioTimeframe`](../type-aliases/PortfolioTimeframe.md) ##### params? ###### sessionSince? `number` ###### cexRateBps? `number` ###### funding? readonly [`PortfolioFundingEvent`](../interfaces/PortfolioFundingEvent.md)[] External capital movements (deposits/withdrawals) for the wallet, USD valued at event time. When any of them bears on the window they define the MWRR capital base (`mwrr.capitalBasis: "funding"`) in place of the trades-only proxy. They never affect PnL or volume. Venue fills are not funding — see `PortfolioFundingEvent` for the sourcing rules. #### Returns `Promise`\<[`PortfolioAnalytics`](../interfaces/PortfolioAnalytics.md)\> *** ### fetchMyTrades() > **fetchMyTrades**(`ref?`, `since?`, `limit?`): `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:1883 My historical trades, newest-first across every venue. **Details** Reads the unified fill tape (`getUserFills`), so the scope, the window and the limit are applied by the INDEXER rather than to an already-truncated page. This is what makes a narrow question answerable: a `ref`-scoped call returns that market's fills however old they are, where a per-venue read would have capped at its newest 50 across all markets first and left nothing to filter. `limit` counts rows YOU receive. Fills whose pool is not in the loaded registry are unresolvable and are skipped, so the read pages until it has `limit` resolvable rows or the tape runs out — asking the query for exactly `limit` would under-deliver by however many it then dropped. - `ref`: Restrict to one tradable (symbol or address). Omit for all. - `since`: Lower time bound, **milliseconds** — same clock as [UnifiedTrade.timestamp](../interfaces/UnifiedTrade.md#timestamp), so a value read off a previous row can be passed straight back. Converted to the indexer's unix seconds internally. - `limit`: Max rows to return (default 50). #### Parameters ##### ref? `string` ##### since? `number` ##### limit? `number` = `50` #### Returns `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> #### Throws [InvalidInputError](InvalidInputError.md) If the symbol or source position is invalid. #### Throws [IndexerError](IndexerError.md) If the indexer read fails. #### Throws [SignerRequiredError](SignerRequiredError.md) If no account is configured. *** ### fetchStatus() > **fetchStatus**(): `Promise`\<[`ExchangeStatus`](../interfaces/ExchangeStatus.md)\> Defined in: packages/sdk/src/unified/exchange.ts:1981 Read the local chain-tail status without network requests. "ok" means no watches are held or the tail is connected. "connecting" means a watch is awaiting its first head. "error" means a previously live socket was lost or the tail retains an operational failure. #### Returns `Promise`\<[`ExchangeStatus`](../interfaces/ExchangeStatus.md)\> *** ### fetchDataStatus() > **fetchDataStatus**(): `Promise`\<[`ExchangeDataStatus`](../interfaces/ExchangeDataStatus.md)\> Defined in: packages/sdk/src/unified/exchange.ts:2001 Observe independent indexer freshness and per-asset price health once. No polling starts. The top-level verdict describes only the local chain tail. Use fetchStatus for a local-only snapshot. #### Returns `Promise`\<[`ExchangeDataStatus`](../interfaces/ExchangeDataStatus.md)\> #### Throws Configured chain or metadata arguments are invalid. #### Throws Indexer metadata could not be read. #### Throws The owner has no chain transport. #### Throws Independent chain measurement failed. *** ### watchOrderBook() > **watchOrderBook**(`ref`, `limit?`): `Promise`\<[`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md)\> Defined in: packages/sdk/src/unified/exchange.ts:2097 Streaming book off the local store: zero round-trips, current to the last block; each await resolves on the next book change. **Example** (Watching the order book) A quoting loop: wake on every book change, read the touch. ```ts while (true) { const book = await exchange.watchOrderBook("SOMI/USDC", 5); const [bestBid] = book.bids[0] ?? []; const [bestAsk] = book.asks[0] ?? []; console.log(`bid ${bestBid} / ask ${bestAsk}`); } ``` Block provenance comes from the native owner. Background failures appear in tail status. #### Parameters ##### ref `string` ##### limit? `number` = `10` #### Returns `Promise`\<[`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md)\> #### Throws [InvalidInputError](InvalidInputError.md) If the symbol or source position is invalid. #### Throws [NotConfiguredError](NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [IndexerError](IndexerError.md) If snapshot initialization fails. #### Throws [RpcError](RpcError.md) If chain catch-up fails. #### Throws [ContractRevertError](ContractRevertError.md) If a required contract read reverts. *** ### watchTrades() > **watchTrades**(`ref`, `limit?`): `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:2136 Streaming public trades (the live tape), newest first. **Example** (Watching trades) Print each fill as it lands (`[0]` is always the latest). ```ts while (true) { const [latest] = await exchange.watchTrades("SOMI/USDC", 1); if (latest) console.log(`${latest.side ?? "?"} ${latest.amount} @ ${latest.price}`); } ``` Block provenance comes from the native owner. Background failures appear in tail status. #### Parameters ##### ref `string` ##### limit? `number` = `50` #### Returns `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> #### Throws [InvalidInputError](InvalidInputError.md) If the symbol or source position is invalid. #### Throws [NotConfiguredError](NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [IndexerError](IndexerError.md) If snapshot initialization fails. #### Throws [RpcError](RpcError.md) If chain catch-up fails. #### Throws [ContractRevertError](ContractRevertError.md) If a required contract read reverts. *** ### watchOrders() > **watchOrders**(`ref`, `limit?`): `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:2191 Streaming view of MY orders on this tradable (authenticated). **When to use** Use to learn that a resting order filled: its status flips to "closed". **Example** (Waiting for an order) Place a limit order, then block until it fully fills (or dies). ```ts const placed = await exchange.createOrder(symbol, "limit", "buy", 10, 0.62); while (placed.status === "open") { const orders = await exchange.watchOrders(symbol); // resolves on the next change const mine = orders.find((o) => o.id === placed.id); if (!mine || mine.status !== "open") break; // filled, canceled, or expired } ``` #### Parameters ##### ref `string` ##### limit? `number` = `100` #### Returns `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)[]\> *** ### watchMyTrades() > **watchMyTrades**(`ref`, `limit?`): `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:2239 Streaming view of MY fills on this tradable (authenticated). Block provenance comes from the native owner. Background failures appear in tail status. #### Parameters ##### ref `string` ##### limit? `number` = `50` #### Returns `Promise`\<[`UnifiedTrade`](../interfaces/UnifiedTrade.md)[]\> #### Throws [InvalidInputError](InvalidInputError.md) If the symbol or source position is invalid. #### Throws [NotConfiguredError](NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [IndexerError](IndexerError.md) If snapshot initialization fails. #### Throws [RpcError](RpcError.md) If chain catch-up fails. #### Throws [ContractRevertError](ContractRevertError.md) If a required contract read reverts. #### Throws [SignerRequiredError](SignerRequiredError.md) If no account is configured. *** ### watchPrice() > **watchPrice**(`asset`): `Promise`\<[`UnifiedPrice`](../interfaces/UnifiedPrice.md)\> Defined in: packages/sdk/src/unified/exchange.ts:2306 Streaming price off the local price store: zero round-trips, current to the last pushed tick; each await resolves on the next price change. **Details** First call hydrates the ref-counted feed watch. **Gotchas** Requires `config.priceFeed` to be set. #### Parameters ##### asset `string` #### Returns `Promise`\<[`UnifiedPrice`](../interfaces/UnifiedPrice.md)\> *** ### fetchPrice() > **fetchPrice**(`asset`): `Promise`\<[`UnifiedPrice`](../interfaces/UnifiedPrice.md) \| `null`\> Defined in: packages/sdk/src/unified/exchange.ts:2328 One-shot current price (indexer HTTP read; no watch needed), or null if the feed has no observations yet. #### Parameters ##### asset `string` #### Returns `Promise`\<[`UnifiedPrice`](../interfaces/UnifiedPrice.md) \| `null`\> *** ### fetchPriceOHLCV() > **fetchPriceOHLCV**(`asset`, `timeframe?`, `since?`, `limit?`): `Promise`\<[`UnifiedOHLCV`](../type-aliases/UnifiedOHLCV.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:2344 OHLC price candles (EMA oracle), oldest first as [ms,o,h,l,c,vol] rows. **Details** Timeframes: 1m 1h 1d (aliases for the feed's M1/H1/D1). **Gotchas** `vol` is the oracle update count for the bucket (NOT trade volume). #### Parameters ##### asset `string` ##### timeframe? `string` = `"1m"` ##### since? `number` ##### limit? `number` = `500` #### Returns `Promise`\<[`UnifiedOHLCV`](../type-aliases/UnifiedOHLCV.md)[]\> *** ### createOrder() > **createOrder**(`ref`, `type`, `side`, `amount`, `price?`, `params?`): `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)\> Defined in: packages/sdk/src/unified/exchange.ts:2411 Place an order. **Details** Works identically for every market kind: the tradable symbol carries the outcome, `side` is plain buy/sell, prices and amounts are human units in the tradable's own terms. `type: "market"` computes a crossing limit from the best opposite level ± `params.slippage` (default 1%) and sends it IOC. Resolves once mined, with fills decoded from the same round-trip. **Gotchas** A NO price is the NO probability — the YES-terms complement is handled internally. The price and quantity are ALIGNED to the market's tick and lot grids before they are sent, because the pool rejects an off-grid value outright. Alignment never moves a value against you: a buy price rounds down, a sell price rounds up, and a quantity always rounds down, so the order is never larger or worse priced than you asked for. The returned [UnifiedOrder](../interfaces/UnifiedOrder.md) carries what was actually placed, which may differ from the arguments by up to one tick or lot — read `price` and `amount` back from it rather than assuming your inputs. Pre-aligning with [priceToPrecision](#pricetoprecision) / [amountToPrecision](#amounttoprecision) makes this a no-op, since aligning an aligned value changes nothing. Note [priceToPrecision](#pricetoprecision) always rounds DOWN, for either side; this path is side-aware instead, so for a sell the two can differ by one tick. A quantity below one whole lot throws [InvalidInputError](InvalidInputError.md) rather than silently placing a zero-quantity order. - Throws [SignerRequiredError](SignerRequiredError.md) - the exchange was built without a `privateKey` / `account` / `walletClient`. - Throws [InvalidInputError](InvalidInputError.md) - unknown symbol (call `loadMarkets()` first), a `"limit"` order with no price, or a `"market"` order whose opposite book side is empty so no crossing price exists. - Throws [ContractRevertError](ContractRevertError.md) - the chain rejected the order. Branch on `errorName` for the protocol's own reason (e.g. `InsufficientBalance`, `ExpiredOrderMustBeCancelled`). - Throws [RpcError](RpcError.md) - the send never got an answer from the node. - Throws [IndexerError](IndexerError.md) - a symbol lookup needed the indexer and it was unreachable. **Example** (Placing binary orders) Rest a bid at 62% on YES, then take the NO book at market. ```ts const rested = await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 25, 0.62); console.log(rested.status, rested.filled); // "open" 0 — or "closed" if it crossed const taken = await exchange.createOrder("BTC-95000-31DEC26/USDC#NO", "market", "sell", 10, undefined, { slippage: 0.02, // accept up to 2% past the best bid }); ``` #### Parameters ##### ref `string` ##### type `"limit"` \| `"market"` ##### side `"buy"` \| `"sell"` ##### amount `number` ##### price? `number` ##### params? [`CreateOrderParams`](../interfaces/CreateOrderParams.md) = `{}` #### Returns `Promise`\<[`UnifiedOrder`](../interfaces/UnifiedOrder.md)\> *** ### cancelOrder() > **cancelOrder**(`id`, `ref`): `Promise`\<\{ `id`: `string`; `symbol`: `string`; `status`: `"canceled"`; `info`: `unknown`; \}\> Defined in: packages/sdk/src/unified/exchange.ts:2600 Cancel a resting order by id (from createOrder / watchOrders). **Gotchas** - Throws [SignerRequiredError](SignerRequiredError.md) - no signer on this exchange. - Throws [InvalidInputError](InvalidInputError.md) - unknown symbol. - Throws [ContractRevertError](ContractRevertError.md) - the cancel did not land; `errorName` says why (an already-filled or already-canceled order reverts). - Throws [RpcError](RpcError.md) - the send never got an answer from the node. **Example** (Cancelling an open order) ```ts const placed = await exchange.createOrder("SOMI/USDC", "limit", "buy", 10, 0.55); if (placed.status === "open") await exchange.cancelOrder(placed.id, "SOMI/USDC"); ``` #### Parameters ##### id `string` ##### ref `string` #### Returns `Promise`\<\{ `id`: `string`; `symbol`: `string`; `status`: `"canceled"`; `info`: `unknown`; \}\> *** ### createStopOrder() > **createStopOrder**(`ref`, `type`, `side`, `amount`, `triggerPrice`, `price?`, `params?`): `Promise`\<[`UnifiedStopOrder`](../interfaces/UnifiedStopOrder.md)\> Defined in: packages/sdk/src/unified/exchange.ts:2671 Place a stop / take-profit order: rests OFF the book on the market's stop registry and fires as a market or limit order when the pool's mark price crosses `triggerPrice`. The trigger direction is inferred from which side of the current mark the trigger sits on; pass `params.triggerDirection` to pin it explicitly. **Gotchas** The trigger, limit price and quantity are aligned to the market's grids, and the trigger aligns AWAY from the mark so it cannot land on it (a trigger equal to the mark fires the instant it is armed). The limit price aligns like any order price — a buy down, a sell up — so it never becomes worse than stated. Those two rules are independent, so a limit set exactly EQUAL to the trigger can end up one tick inside it: a buy stop at trigger `0.5004`, limit `0.5004` on a `0.001` grid arms at `0.501` and rests a `0.500` bid, which may not fill. That is deliberate — pulling the limit up to meet the trigger would make you pay more than you asked. Set the limit a tick or two past the trigger when you want the triggered order to cross. - Throws [SignerRequiredError](SignerRequiredError.md) - the exchange was built without a `privateKey` / `account` / `walletClient`. - Throws [InvalidInputError](InvalidInputError.md) - unknown symbol, a non-spot market, a market with no stop registry, a `"limit"` stop with no price, a sub-lot quantity, or no mark yet to infer the trigger direction from (pass `params.triggerDirection`). - Throws [IndexerError](IndexerError.md) - the pool's mark was needed (to infer the trigger direction, or to price a market stop's protective limit) and the indexer read did not complete. A limit stop with `params.triggerDirection` set needs no mark. - Throws [ContractRevertError](ContractRevertError.md) - the registry or the pool rejected the placement (or the operator grant / escrow approval that precedes it). Branch on `errorName`. - Throws [RpcError](RpcError.md) - a send or a pre-placement chain read did not complete. **Example** (Placing a stop order) A stop-loss: sell 5 if the mark drops to 1.10. ```ts const stop = await exchange.createStopOrder("SOMI/USDC", "market", "sell", 5, 1.10); // …later: await exchange.cancelStopOrder(stop.id, "SOMI/USDC"); ``` #### Parameters ##### ref `string` ##### type `"limit"` \| `"market"` ##### side `"buy"` \| `"sell"` ##### amount `number` ##### triggerPrice `number` ##### price? `number` ##### params? ###### triggerDirection? `"above"` \| `"below"` #### Returns `Promise`\<[`UnifiedStopOrder`](../interfaces/UnifiedStopOrder.md)\> *** ### fetchOpenStopOrders() > **fetchOpenStopOrders**(`ref?`): `Promise`\<[`UnifiedStopOrder`](../interfaces/UnifiedStopOrder.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:2788 The wallet's pending (armed, untriggered) stop orders, newest first. Scope to one tradable with `ref`. #### Parameters ##### ref? `string` #### Returns `Promise`\<[`UnifiedStopOrder`](../interfaces/UnifiedStopOrder.md)[]\> *** ### cancelStopOrder() > **cancelStopOrder**(`id`, `ref`): `Promise`\<\{ `id`: `string`; `symbol`: `string`; `status`: `"canceled"`; `info`: `unknown`; \}\> Defined in: packages/sdk/src/unified/exchange.ts:2824 Cancel a pending stop order on its registry (refunds the keeper payment). `id` comes from [fetchOpenStopOrders](#fetchopenstoporders). #### Parameters ##### id `string` ##### ref `string` #### Returns `Promise`\<\{ `id`: `string`; `symbol`: `string`; `status`: `"canceled"`; `info`: `unknown`; \}\> *** ### fetchFundingRate() > **fetchFundingRate**(`ref`): `Promise`\<[`UnifiedFundingRate`](../interfaces/UnifiedFundingRate.md)\> Defined in: packages/sdk/src/unified/exchange.ts:2845 Live funding-rate + mark/index snapshot for a perp market (chain read). #### Parameters ##### ref `string` #### Returns `Promise`\<[`UnifiedFundingRate`](../interfaces/UnifiedFundingRate.md)\> *** ### fetchFundingRateHistory() > **fetchFundingRateHistory**(`ref`, `since?`, `limit?`): `Promise`\<[`UnifiedFundingRate`](../interfaces/UnifiedFundingRate.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:2915 Historical funding rates for a perp market, oldest first (ccxt-standard shape). Reads the INDEXED series rather than the chain: only one funding value is readable on chain at a time. Positional `(symbol, since, limit)` follows the ccxt convention set by `fetchOHLCV`, unlike the object-options readers on the client. `fundingRate` is normalized to a per-8h fraction using each row's own `fundingWindowSec`, so the series stays consistent across a parameter change. The raw indexed row is on `info` for anything more specific — including `spanStart` / `spanEnd`, which matter because a row's accrual reaches BACKWARDS from its timestamp and a lazily-settled one can cover hours. `since` is a CURSOR, not just a window bound: passing it walks FORWARD from that point, so the ccxt pagination idiom terminates. **Details** - `ref`: market symbol or pool address - `since`: unix MILLISECONDS (ccxt convention), inclusive; acts as a forward cursor - `limit`: max rows (default 100) **Example** (Paging through funding history) ```ts let since = startOfHistory; for (;;) { const page = await exchange.fetchFundingRateHistory("BTC/USDSO:USDSO", since, 100); if (page.length === 0) break; consume(page); since = page[page.length - 1].timestamp + 1; // advances } ``` Without the forward ordering this loop spins: the underlying read pages newest-first, so narrowing the window from below still returns the newest N and `since` never gets past the tail. Omitting `since` keeps the newest-first behaviour, which is what a "latest funding" read wants — `fetchOHLCV` has the same split. #### Parameters ##### ref `string` ##### since? `number` ##### limit? `number` #### Returns `Promise`\<[`UnifiedFundingRate`](../interfaces/UnifiedFundingRate.md)[]\> *** ### fetchPositions() > **fetchPositions**(`refs?`): `Promise`\<[`UnifiedPosition`](../interfaces/UnifiedPosition.md)[]\> Defined in: packages/sdk/src/unified/exchange.ts:2946 Open perp positions (authenticated; on-chain MarginBank reads). Pass symbols to scope; defaults to every loaded perp market. #### Parameters ##### refs? `string`[] #### Returns `Promise`\<[`UnifiedPosition`](../interfaces/UnifiedPosition.md)[]\> *** ### depositMargin() > **depositMargin**(`ref`, `amount`): `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> Defined in: packages/sdk/src/unified/exchange.ts:3011 Deposit collateral into the perp MarginBank (human quote units, e.g. USDso). One cross-margin balance covers every perp market. #### Parameters ##### ref `string` ##### amount `number` #### Returns `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> *** ### withdrawMargin() > **withdrawMargin**(`ref`, `amount`): `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> Defined in: packages/sdk/src/unified/exchange.ts:3030 Withdraw free collateral from the perp MarginBank (human quote units). #### Parameters ##### ref `string` ##### amount `number` #### Returns `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> *** ### mintSet() > **mintSet**(`ref`, `amount`): `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> Defined in: packages/sdk/src/unified/exchange.ts:3070 Mint complete sets: `amount` collateral → `amount` of EVERY outcome. **Example** (Minting complete sets) Mint 100 sets (100 USDC → 100 YES + 100 NO), then sell the side you don't want. ```ts await exchange.mintSet("BTC-95000-31DEC26/USDC", 100); await exchange.createOrder("BTC-95000-31DEC26/USDC#NO", "limit", "sell", 100, 0.38); ``` #### Parameters ##### ref `string` ##### amount `number` #### Returns `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> *** ### burnSet() > **burnSet**(`ref`, `amount`): `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> Defined in: packages/sdk/src/unified/exchange.ts:3085 Burn complete sets back to collateral. #### Parameters ##### ref `string` ##### amount `number` #### Returns `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> *** ### redeem() > **redeem**(`ref`, `amount`, `options?`): `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> Defined in: packages/sdk/src/unified/exchange.ts:3141 Redeem outcome tokens for collateral after settlement. Settlement- extraction v2 routes by `marketId`. When the caller omits the leg, the SDK verifies the BinaryMarket state and reads its winner on-chain. **Example** (Redeeming a winning position) After resolution, redeem the winning side found in the balance map. ```ts const bal = await exchange.fetchBalance(); const winning = bal["BTC-95000-31DEC26/USDC#YES"]?.total ?? 0; if (winning > 0) await exchange.redeem("BTC-95000-31DEC26/USDC", winning); ``` **Gotchas** A VOIDED market has no winning outcome — both legs pay — so the auto-lookup cannot pick one and `redeem` throws. Pass `{ outcomeIdx }` for the leg you hold, and call once per leg to claim both. An unresolved market also throws instead of guessing from an unfinalized payout vector. **Errors** - Throws [InvalidInputError](InvalidInputError.md) for an unknown or non-binary market, an invalid amount, or an omitted leg when the on-chain market is unresolved, voided, or does not store an exact one-hot resolved payout vector. - Throws [NotConfiguredError](NotConfiguredError.md) when the binary module address is not configured. - Throws [SignerRequiredError](SignerRequiredError.md) when the exchange has no usable signer. - Throws [RpcError](RpcError.md) when a market, approval, submission, or receipt request does not complete. - Throws [ContractRevertError](ContractRevertError.md) when a market read, operator approval, or redemption transaction is rejected by a contract. #### Parameters ##### ref `string` Market symbol or id. ##### amount `number` Outcome-token amount to burn, in display units. ##### options? [`RedeemOptions`](../interfaces/RedeemOptions.md) Optional leg selection. Omit it on a resolved market to verify the terminal state and read the winner on-chain. A voided market requires `options.outcomeIdx` because both legs are redeemable and only the caller knows which one they hold. #### Returns `Promise`\<\{ `hash`: `string`; `info`: `unknown`; \}\> *** ### close() > **close**(): `Promise`\<`void`\> Defined in: packages/sdk/src/unified/exchange.ts:3192 Release every watch, channel, socket, and timer this exchange holds and stop the client's live machinery. **Details** This includes the chain WebSocket, so a Node process that has touched the chain exits on its own once this resolves. The instance stays usable for one-shot fetch calls: a later read reopens a connection, and a later `close()` releases that one too. **Gotchas** Exchanges configured with the same `wsRpcUrl` share one chain socket — the underlying viem transport caches sockets per URL and offers no way to opt out — so it closes only when the last of them closes. #### Returns `Promise`\<`void`\> --- # /docs/typescript/api/index/classes/SomniaMarketsError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsError # Class: SomniaMarketsError Defined in: packages/sdk/src/errors.ts:58 Base class for every error the SDK raises. **When to use** Use when you want "anything the SDK itself rejected" without enumerating subclasses — typically an application's top-level boundary. To branch on *what went wrong*, catch (or `instanceof`-test) the subclass instead; each one documents the action it implies. **Gotchas** Catching this is not the same as catching everything. Errors from a `walletClient` supplied by the app can surface as-is, so keep an `else throw e` arm. Debug sink failures are contained and do not escape. **Example** (Branching on SDK errors) ```ts import { SomniaMarketsError, ContractRevertError } from "@somnia-chain/markets-sdk"; try { await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 10, 0.62); } catch (e) { if (e instanceof ContractRevertError) console.error("chain rejected:", e.errorName); else if (e instanceof SomniaMarketsError) console.error("sdk:", e.message); else throw e; } ``` ## Extends - `Error` ## Extended by - [`InvalidInputError`](InvalidInputError.md) - [`NotConfiguredError`](NotConfiguredError.md) - [`SignerRequiredError`](SignerRequiredError.md) - [`IndexerError`](IndexerError.md) - [`RpcError`](RpcError.md) - [`ContractRevertError`](ContractRevertError.md) - [`InvariantError`](InvariantError.md) ## Constructors ### Constructor > **new SomniaMarketsError**(`message`, `options?`): `SomniaMarketsError` Defined in: packages/sdk/src/errors.ts:59 #### Parameters ##### message `string` ##### options? `ErrorOptions` #### Returns `SomniaMarketsError` #### Overrides `Error.constructor` --- # /docs/typescript/api/index/functions/accrueCompounded [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / accrueCompounded # Function: accrueCompounded() > **accrueCompounded**(`indexRay`, `rateRay`, `lastUpdateTimestamp`, `nowSec`): `bigint` Defined in: packages/sdk/src/lend/math.ts:45 Grow a borrow-side index compounded from `lastUpdateTimestamp` to `nowSec` at `rateRay`, using Aave's three-term binomial expansion of (1+r/s)^dt (MathUtils .calculateCompoundedInterest). Returns the ray index current to `nowSec`. ## Parameters ### indexRay `bigint` ### rateRay `bigint` ### lastUpdateTimestamp `number` ### nowSec `number` ## Returns `bigint` --- # /docs/typescript/api/index/functions/accrueLinear [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / accrueLinear # Function: accrueLinear() > **accrueLinear**(`indexRay`, `rateRay`, `lastUpdateTimestamp`, `nowSec`): `bigint` Defined in: packages/sdk/src/lend/math.ts:31 Grow a supply-side index linearly from `lastUpdateTimestamp` to `nowSec` at `rateRay` (Aave accrues deposit interest linearly between updates). Returns the ray index current to `nowSec`. ## Parameters ### indexRay `bigint` ### rateRay `bigint` ### lastUpdateTimestamp `number` ### nowSec `number` ## Returns `bigint` --- # /docs/typescript/api/index/functions/annualizedFundingRate [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / annualizedFundingRate # Function: annualizedFundingRate() > **annualizedFundingRate**(`rate`, `fundingWindowSec`): `number` Defined in: packages/sdk/src/funding.ts:119 Annualized funding rate as a JS number fraction (0.01 = 1% APR). Returns a `number` deliberately, unlike its siblings: APR is a display quantity, and at an 8h window this is roughly `rate x 1095`, so the 1e18 scale carries far more precision than any axis label needs. Never round-trip a settlement amount through it. ## Parameters ### rate `bigint` ### fundingWindowSec `number` ## Returns `number` --- # /docs/typescript/api/index/functions/averageEntryPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / averageEntryPrice # Function: averageEntryPrice() > **averageEntryPrice**(`input`): `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:1154 Average entry price for a YES/NO position, in the outcome's OWN terms (raw), derived from the wallet's BUY fills on that outcome. A binary fill's `fillPrice` is always YES-terms, so the NO leg enters at the complement. Only buys are averaged — this is the cost basis an unrealized-PnL display compares the live mark against. Returns `null` when there are no matching buys (show a dash, not a bogus 0 that reads as +100%). NOTE: complete-set mints don't appear in fills; positions built by mint+sell carry a fills-only basis here, same as [computePositionPnL](computePositionPnL.md) without router actions. ## Parameters ### input #### trades readonly [`EntryTrade`](../interfaces/EntryTrade.md)[] #### outcomeIndex `number` 0 = YES, 1 = NO. #### oneShare `bigint` `10 ** decimals` — one whole outcome share in raw terms. ## Returns `bigint` \| `null` --- # /docs/typescript/api/index/functions/balanceFloor [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / balanceFloor # Function: balanceFloor() > **balanceFloor**(`raw`, `decimals?`): `number` Defined in: packages/sdk/src/units.ts:521 Convert a raw balance to the largest JS number that does not exceed it — full token precision, no lot/display quantum. `Number(formatUnits(raw))` rounds to nearest, so on high-precision balances it can land a ULP above the true value; this nudges the result down until it round-trips back to ≤ `raw`. Size "max" orders against this, never against a nearest-rounded conversion — a max that exceeds the wallet by one ULP is an on-chain "insufficient balance" revert. The round-trip is verified through the same number-to-raw conversion the write path applies, so the guarantee holds for the value `createOrder` will actually send rather than for a differently-rounded stand-in. ## Parameters ### raw `bigint` ### decimals? `number` = `Store.DECIMALS` ## Returns `number` --- # /docs/typescript/api/index/functions/binaryFillsFor [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binaryFillsFor # Function: binaryFillsFor() > **binaryFillsFor**(`account`, `fills`, `decimals?`): [`BinaryPnlFill`](../interfaces/BinaryPnlFill.md)[] Defined in: packages/sdk/src/units.ts:321 Derive per-account [BinaryPnlFill](../interfaces/BinaryPnlFill.md)s from the raw [FillRow](../type-aliases/FillRow.md)s the indexer returns (as from `getUserFills`), from `account`'s perspective. Skips fills whose side/kind the indexer hasn't fully bridged (unknown side), and re-expresses the fill's price into the outcome the account traded (the book is YES-terms; a NO trade prices at `1 − yesPrice`). SCOPE IS THE CALLER'S JOB: no market filter is applied here, so pass ONE market's fills when the result feeds cost basis, selected by [FillRow.market](../type-aliases/FillRow.md#market) (never by `pool` — see there). ## Parameters ### account `string` ### fills [`FillRow`](../type-aliases/FillRow.md)[] ### decimals? `number` = `Store.DECIMALS` ## Returns [`BinaryPnlFill`](../interfaces/BinaryPnlFill.md)[] --- # /docs/typescript/api/index/functions/binaryFillsFromPortfolio [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binaryFillsFromPortfolio # Function: binaryFillsFromPortfolio() > **binaryFillsFromPortfolio**(`trades`, `decimals?`): [`BinaryPnlFill`](../interfaces/BinaryPnlFill.md)[] Defined in: packages/sdk/src/units.ts:367 Derive [BinaryPnlFill](../interfaces/BinaryPnlFill.md)s from one market's slice of a portfolio's trades (as from `getPortfolio`). The portfolio view already resolves the account's own side per fill, so this only re-expresses the YES-terms `fillPrice` into the traded outcome (a NO trade prices at `1 − yesPrice`) and skips fills whose side the indexer hasn't bridged yet. **Gotchas** The portfolio reads cut `trades` two ways, and BOTH have to be checked before a total derived from them means anything — this function reports no warning of its own. They cap the page (default 50) and page newest-first: `tradesTruncated` says whether that cap was hit. They also WINDOW the leg — by default to the last seven days — and `tradesSince` is the bound that was applied. A wallet whose fills predate the window comes back with `tradesTruncated: false` and an incomplete `trades`, so the flag alone is not enough. For a whole-history PnL ask for the history first: `since: 0` (with a `tradesLimit` to match), then check `tradesTruncated`. ## Parameters ### trades [`PortfolioTrade`](../type-aliases/PortfolioTrade.md)[] ### decimals? `number` = `Store.DECIMALS` ## Returns [`BinaryPnlFill`](../interfaces/BinaryPnlFill.md)[] --- # /docs/typescript/api/index/functions/binaryResolutionMode [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binaryResolutionMode # Function: binaryResolutionMode() > **binaryResolutionMode**(`strike`): [`BinaryResolutionMode`](../type-aliases/BinaryResolutionMode.md) Defined in: packages/sdk/src/markets.ts:784 Read a binary market's [BinaryResolutionMode](../type-aliases/BinaryResolutionMode.md) off its `strike` — the ONE place that reading happens. Strike 0 is reference mode DECLARING "no fixed strike": a sentinel, never a $0 threshold. `_strikeLabel` treats 0 as "no strike fragment" and reference resolution compares two numeric answers instead of reading a strike at all, so every market the current creator mints holds to it — but nothing in `_validateCreate` cross-checks it against `referenceQuestionId`, so it is convention rather than an enforced invariant. Centralized here so the day that changes is a one-line change. Takes either encoding: the indexer serves `strike` as a decimal string, the contract event as a `uint256`. ## Parameters ### strike `string` \| `bigint` \| `null` \| `undefined` ## Returns [`BinaryResolutionMode`](../type-aliases/BinaryResolutionMode.md) --- # /docs/typescript/api/index/functions/blockActivityKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / blockActivityKey # Function: blockActivityKey() > **blockActivityKey**(`blockNumber`, `opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:183 Key for `client.getBlockActivity(blockNumber, opts)`. The block alone identifies the question — the client resolves the anchoring timestamp itself, so there is no second argument that could disagree with it. ## Parameters ### blockNumber `bigint` \| `null` \| `undefined` ### opts? [`BlockActivityOptions`](../type-aliases/BlockActivityOptions.md) ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/bookMidPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / bookMidPrice # Function: bookMidPrice() > **bookMidPrice**(`book`): `number` \| `null` Defined in: packages/sdk/src/unified/quotes.ts:139 Midpoint of the book's best bid/ask, or null when either side is empty. ## Parameters ### book [`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md) ## Returns `number` \| `null` --- # /docs/typescript/api/index/functions/boundaryPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / boundaryPrice # Function: boundaryPrice() > **boundaryPrice**(`m`, `openingPrices`): \{ `raw`: `string`; `posted`: `boolean`; \} \| `null` Defined in: packages/sdk/src/markets.ts:1381 The level a binary market's outcome is measured against, in the oracle's price scale — the one answer to that question, for every surface that asks. Which source supplies it is exactly [BinaryMarket.mode](../type-aliases/BinaryMarket.md): - `"reference"` — the posted answer to the market's reference question, from the `openingPrices` map that `client.getOpeningPrices` returns. `null` until the oracle posts it, which is a real and temporary state. - `"fixed"` — the market's own `strike`, known from creation. `posted` says WHICH, because it decides what a caller may CLAIM about the number: only a posted answer has an "answered at" instant, so only it may be labelled as one. Returning it here rather than letting callers re-test the map keeps the label and the value derived from one decision. Lives here rather than in a UI because it is protocol knowledge, not presentation: which of two mechanisms a venue chose. Scale is the caller's to apply, as with any raw oracle value. ## Parameters ### m `Pick`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md), `"id"` \| `"strike"` \| `"mode"`\> ### openingPrices `Record`\<`string`, `string` \| `null`\> ## Returns \{ `raw`: `string`; `posted`: `boolean`; \} \| `null` --- # /docs/typescript/api/index/functions/buildFundingRateSeries [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / buildFundingRateSeries # Function: buildFundingRateSeries() > **buildFundingRateSeries**\<`T`\>(`rows`, `intervalSeconds`, `from`, `to`, `limit`): [`FundingRateSeries`](../type-aliases/FundingRateSeries.md)\<`T`\> Defined in: packages/sdk/src/funding.ts:353 Densify a page of rollup rows into a chart-ready series, and report whether the page was truncated. Split out of the React hook on purpose: the truncation rule is the part that misleads if it is wrong, and it is worth asserting without a DOM. `truncated` is `rows.length >= limit` — `listFundingRateCandles` pages newest-first, so a FULL page means older buckets were dropped, NOT that funding stopped. A caller that renders a truncated window without saying so shows missing history as a funding pause; the densifier declines to invent those older slots, which is why the returned window can be shorter than `[from, to)` and why `firstBucketStart` is reported rather than assumed to equal `from`. **Details** - `rows`: a page from `listFundingRateCandles`, any order - `intervalSeconds`: the grid resolution the rows were queried at - `from`: window start, unix seconds (snapped down to the grid) - `to`: window end, unix seconds (exclusive) - `limit`: the `limit` the page was requested with, for the truncation test ## Type Parameters ### T `T` *extends* [`FundingBucketLike`](../interfaces/FundingBucketLike.md) ## Parameters ### rows readonly `T`[] ### intervalSeconds `number` ### from `number` \| `bigint` ### to `number` \| `bigint` ### limit `number` ## Returns [`FundingRateSeries`](../type-aliases/FundingRateSeries.md)\<`T`\> --- # /docs/typescript/api/index/functions/byNewestFirst [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / byNewestFirst # Function: byNewestFirst() > **byNewestFirst**(`a`, `b`): `number` Defined in: packages/sdk/src/activity.ts:1000 Newest first, breaking a shared timestamp on block then log position. EXPORTED because it is the order `getMarketActivity` pages by: a caller merging its own rows into that page (the live tail, say) must sort by the same rule, and a hand-copied comparator is free to drift from the paging contract with nothing to catch it. ## Parameters ### a [`MarketActivity`](../type-aliases/MarketActivity.md) ### b [`MarketActivity`](../type-aliases/MarketActivity.md) ## Returns `number` --- # /docs/typescript/api/index/functions/cadenceBandSec [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / cadenceBandSec # Function: cadenceBandSec() > **cadenceBandSec**(`cadenceSec`): `object` Defined in: packages/sdk/src/interval.ts:167 The inclusive window of raw `intervalSec` values that count as `cadenceSec` — `cadenceSec ± ` [CADENCE\_TOLERANCE\_SEC](../variables/CADENCE_TOLERANCE_SEC.md). This is what turns a cadence filter into a range predicate server-side, so "15m" returns the 898s and 899s markets of the same series rather than only the exact-900s ones. Rungs are far enough apart that the bands never overlap. THROWS on a non-finite or non-positive cadence rather than banding it. The other helpers here answer 0/null for junk because their callers render the result; this one's output becomes a Hasura predicate, where `NaN` would go on the wire as the string `"NaN"` and a `<= 0` cadence would quietly select a 1–5s band that matches nothing. A filter that silently matches nothing is the worst of the three outcomes: it looks like an empty result set rather than the caller error it is. **Gotchas** - Throws RangeError when `cadenceSec` is not a positive finite number. ## Parameters ### cadenceSec `number` ## Returns `object` ### minSec > **minSec**: `number` ### maxSec > **maxSec**: `number` --- # /docs/typescript/api/index/functions/candlesKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / candlesKey # Function: candlesKey() > **candlesKey**(`pool`, `intervalSeconds`, `opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:104 Key for `client.getCandles(pool, intervalSeconds, opts)`. ## Parameters ### pool `string` \| `null` \| `undefined` ### intervalSeconds `number` ### opts? #### limit? `number` Max candles. #### from? `number` Range start (unix seconds). #### to? `number` Range end (unix seconds). ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/ceilRawAmount [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ceilRawAmount # Function: ceilRawAmount() > **ceilRawAmount**(`raw`, `decimals`, `quantum`): `bigint` Defined in: packages/sdk/src/units.ts:598 Ceil a raw on-chain amount UP to a whole multiple of `quantum` (a human decimal string — the market's lot size for base amounts, or a display precision like "0.01" for quote). The mirror of [floorRawBalance](floorRawBalance.md), for sizing a **minimum**: a minimum rounded DOWN falls below what the pool requires and the order is rejected as under the minimum — the exact mirror of the max-order revert the floors prevent. An amount below one quantum rises to one whole quantum rather than collapsing to `0` the way the floor does. Returns a `bigint`, unlike the floors, which return `number`. A minimum is checked against the lot boundary exactly, and no `double` can hold one: the nearest `double` to `0.1` at 18 decimals sits tens of wei off, which puts it below the minimum itself. Convert at the edge if you need a number — `Number(formatUnits(result, decimals))`. ## Parameters ### raw `bigint` ### decimals `number` ### quantum `string` ## Returns `bigint` --- # /docs/typescript/api/index/functions/claimableFrom [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / claimableFrom # Function: claimableFrom() > **claimableFrom**(`inputs`): [`ClaimablePosition`](../interfaces/ClaimablePosition.md)[] Defined in: packages/sdk/src/derivedReads.ts:737 Filter and shape settled positions into [ClaimablePosition](../interfaces/ClaimablePosition.md)s. A position is claimable when the market is voided or when it holds the winning outcome. A void pays against the stored vector. Loser-side and still-trading positions are omitted. **Errors** Throws [InvalidInputError](../classes/InvalidInputError.md) when a void has a present but invalid payout vector. A legacy row with both vector fields absent keeps the documented half-payout fallback. ## Parameters ### inputs [`ClaimableInput`](../interfaces/ClaimableInput.md)[] ## Returns [`ClaimablePosition`](../interfaces/ClaimablePosition.md)[] --- # /docs/typescript/api/index/functions/computeBinaryPnl [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / computeBinaryPnl # Function: computeBinaryPnl() > **computeBinaryPnl**(`fills`, `balances`, `market`, `opts?`): [`BinaryPnl`](../interfaces/BinaryPnl.md) Defined in: packages/sdk/src/units.ts:409 Realized + unrealized binary PnL for one account, avg-cost basis — a PURE helper (no indexer/chain dependency). `fills` are the account's own trades (from [binaryFillsFor](binaryFillsFor.md)); `balances` its current YES/NO holdings (from `getOutcomeBalances`); `market` supplies decimals + resolution state. Realized PnL accrues on sells (proceeds − avg cost of the tokens sold). Unrealized marks the remaining position: to the book-clamped last price while trading (see [markYesPrice](markYesPrice.md); pass `opts.bookTop` so a live quote beyond a stale print corrects the mark), and to the settlement payout once resolved: 1 for the winning outcome, 0 for the loser, and on a void each leg's share of the market's stored payout vector — a half per side under the `UNIFORM` void policy, `[p, D−p]` at the closing YES price on a `CLOB_SNAPSHOT` void that captured a two-sided close. An unresolved market that has never traded has no mark. When `market.lastPrice` is null and `opts.bookTop` supplies no quote, `mark`, `value` and `unrealized` are `null` on both legs, as are the combined `unrealized` and `total`. `realized` and `avgCost` stay exact, because neither depends on a mark. **Errors** Throws [InvalidInputError](../classes/InvalidInputError.md) when a void has a present but invalid payout vector. A missing legacy vector keeps the documented half-payout fallback. ## Parameters ### fills [`BinaryPnlFill`](../interfaces/BinaryPnlFill.md)[] ### balances [`OutcomeBalances`](../type-aliases/OutcomeBalances.md) ### market `Pick`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md), `"quoteDecimals"` \| `"lastPrice"` \| `"winningOutcome"` \| `"voided"` \| `"payoutNumerators"` \| `"payoutDenominator"`\> ### opts? #### bookTop? [`YesBookTop`](../interfaces/YesBookTop.md) Top of the YES book — clamps the mark to live quotes (see [markYesPrice](markYesPrice.md)). ## Returns [`BinaryPnl`](../interfaces/BinaryPnl.md) --- # /docs/typescript/api/index/functions/computePortfolioAnalytics [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / computePortfolioAnalytics # Function: computePortfolioAnalytics() > **computePortfolioAnalytics**(`events`, `opts`): [`PortfolioAnalytics`](../interfaces/PortfolioAnalytics.md) Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:397 Fold portfolio flow events into the metrics plane. PURE — every input is explicit, so it runs identically in apps, bots, and tests. `events` may arrive in any order; they are sorted oldest-first internally. Events before the window establish the carried-in cost basis; events inside it drive the equity curve. Supply [PortfolioFundingEvent](../interfaces/PortfolioFundingEvent.md)s to measure the return against real external capital. Without them the capital base falls back to a trades-only proxy that overstates the return for an account trading a small part of its balance; `mwrr.capitalBasis` reports which definition applied. **Gotchas** - Throws [InvalidInputError](../classes/InvalidInputError.md) — a sampling bound is not a finite number: `asOf`, any event's `timestamp`, or the window start they derive. The equity series is sampled from those bounds, so a non-finite one leaves the loop's exit comparison false forever and the process allocates until it dies. The offending field is named in the message. Nothing is substituted and no event is dropped — an invalid time is the caller's to fix, and guessing one would silently misplace money on the curve. ## Parameters ### events readonly [`PortfolioFlowEvent`](../type-aliases/PortfolioFlowEvent.md)[] ### opts [`PortfolioAnalyticsOptions`](../interfaces/PortfolioAnalyticsOptions.md) ## Returns [`PortfolioAnalytics`](../interfaces/PortfolioAnalytics.md) --- # /docs/typescript/api/index/functions/computePositionPnL [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / computePositionPnL # Function: computePositionPnL() > **computePositionPnL**(`events`, `balances`, `market`, `oneCollateral`, `opts?`): [`BinaryPositionPnL`](../interfaces/BinaryPositionPnL.md) Defined in: packages/sdk/src/derivedReads.ts:431 Fold a [PnLEvent](../interfaces/PnLEvent.md) stream (oldest-first) + current balances into a [BinaryPositionPnL](../interfaces/BinaryPositionPnL.md), avg-cost basis, RAW units. `oneCollateral = 10^quoteDecimals`. Prices arrive in YES terms; a NO event is re-expressed to NO terms (`oneCollateral − yesPrice`) here so the two books stay separate. An unresolved market that has never traded has no mark price. When `market.lastPrice` is null and `opts.bookTop` supplies no quote, `markPrice`, `markValue` and `unrealizedPnl` are `null` on both legs and on the total. `balance`, `costBasis`, `avgCost` and `realizedPnl` stay exact, because none of them depends on a mark. **Errors** Throws [InvalidInputError](../classes/InvalidInputError.md) when a void has a present but invalid payout vector. A legacy row with both vector fields absent keeps the documented half-payout fallback. ## Parameters ### events [`PnLEvent`](../interfaces/PnLEvent.md)[] ### balances #### balanceYes `bigint` #### balanceNo `bigint` ### market `Pick`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md), `"quoteDecimals"` \| `"lastPrice"` \| `"winningOutcome"` \| `"voided"` \| `"payoutNumerators"` \| `"payoutDenominator"`\> ### oneCollateral `bigint` ### opts? #### bookTop? [`YesBookTop`](../interfaces/YesBookTop.md) Top of the YES book — clamps the mark to live quotes (see [markYesPrice](markYesPrice.md)). ## Returns [`BinaryPositionPnL`](../interfaces/BinaryPositionPnL.md) --- # /docs/typescript/api/index/functions/consoleDebugSink [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / consoleDebugSink # Function: consoleDebugSink() > **consoleDebugSink**(`opts?`): (`e`) => `void` Defined in: packages/sdk/src/debug.ts:347 Ready-made console renderer for [ClientConfig.debug](../interfaces/ClientConfig.md#debug) — prints the event stream as an indented span tree, the zero-setup way to watch what a client is doing. Output shape — `▶` opens a span, `◀` closes it with its duration, `·` is a mid-span annotation, and log events print flat with their scope: ```text [sdk] ▶ trader.placeOrder { params: { pool: "0x…", side: "BUY_YES" } } [sdk] ▶ trade.execute { functionName: "placeBinaryOrder", … } [sdk] liveTail applying logs { received: 3, … } [sdk] · trade.execute { hash: "0x…" } [sdk] ◀ trade.execute 38.2ms [sdk] ◀ trader.placeOrder 41.0ms ``` **Details** Indentation is reconstructed from `parentId`, so trees stay correct when concurrent operations interleave. `warn`-level logs and failed spans route to `console.warn`; everything else goes to `console.debug` (in browser devtools, enable the *Verbose* level to see it). - `opts`: `prefix` replaces the leading `[sdk]` tag on every line — useful to tell two clients apart in one console. - Returns: A sink to pass as [ClientConfig.debug](../interfaces/ClientConfig.md#debug). **Gotchas** The sink keeps per-span depth state, so build one per client rather than sharing an instance. ## Parameters ### opts? #### prefix? `string` ## Returns (`e`) => `void` ## See [debugCollector](debugCollector.md) for capturing events in tests instead of printing. **Example** (Enabling console logs) Opt in from devtools without redeploying — `localStorage.setItem("sdk-debug", "1")` and reload: ```ts const exchange = new SomniaMarkets({ ...config, debug: localStorage.getItem("sdk-debug") ? consoleDebugSink() : undefined, }); ``` --- # /docs/typescript/api/index/functions/debugCollector [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / debugCollector # Function: debugCollector() > **debugCollector**(): [`DebugCollector`](../interfaces/DebugCollector.md) Defined in: packages/sdk/src/debug.ts:422 Build a fresh event collector — the test-side counterpart of [consoleDebugSink](consoleDebugSink.md), for asserting that an operation produced the spans/logs you expect (or for ad-hoc capture in a REPL). **Details** - Returns: An independent [DebugCollector](../interfaces/DebugCollector.md); nothing is shared between calls, so parallel tests can each have their own. **Example** (Collecting test traces) Assert a trader write went through the execute pipeline exactly once: ```ts const collector = debugCollector(); const exchange = new SomniaMarkets({ ...config, debug: collector.sink }); await exchange.trader.placeOrder(params); expect(collector.starts("trade.execute")).toHaveLength(1); expect(collector.ends("trade.execute")[0].error).toBeUndefined(); ``` ## Returns [`DebugCollector`](../interfaces/DebugCollector.md) --- # /docs/typescript/api/index/functions/decodeBinaryVenueFeeParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / decodeBinaryVenueFeeParams # Function: decodeBinaryVenueFeeParams() > **decodeBinaryVenueFeeParams**(`feeParams`): \{ `version`: `number`; `params`: [`BinaryVenueParams`](../interfaces/BinaryVenueParams.md); \} \| `null` Defined in: packages/sdk/src/operatorReads.ts:146 Decode a BINARY_V1 venue's `feeParams` bytes back into (version, rates) for display — pure/local, mirrors BinaryMarketsModule's own dual decoder: 192 bytes ⇒ legacy v2 (policy implied `UNIFORM`), 224 bytes ⇒ v3 (policy word). Returns null for anything else (empty / non-BINARY_V1 venue, wrong version-for-shape, or an on-chain-unreachable policy value). ## Parameters ### feeParams `` `0x${string}` `` ## Returns ### Type Literal \{ `version`: `number`; `params`: [`BinaryVenueParams`](../interfaces/BinaryVenueParams.md); \} #### version > **version**: `number` The payload's schema version tag (2 legacy, 3 current). #### params > **params**: [`BinaryVenueParams`](../interfaces/BinaryVenueParams.md) The decoded plain-bps venue fee rates (+ resolved `voidPolicy`). *** `null` --- # /docs/typescript/api/index/functions/decodeOutcomeId [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / decodeOutcomeId # Function: decodeOutcomeId() > **decodeOutcomeId**(`id`): [`DecodedOutcomeId`](../interfaces/DecodedOutcomeId.md) Defined in: packages/sdk/src/ids.ts:70 Split an outcome id back into `{ pool, nonce, idx }` — the inverse of [outcomeId](outcomeId.md). ## Parameters ### id `bigint` ## Returns [`DecodedOutcomeId`](../interfaces/DecodedOutcomeId.md) --- # /docs/typescript/api/index/functions/decodePerpStopOrderIds [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / decodePerpStopOrderIds # Function: decodePerpStopOrderIds() > **decodePerpStopOrderIds**(`logs`, `registry`): `bigint`[] Defined in: packages/sdk/src/perp/stops.ts:643 Registry order ids from a receipt's logs, in the registry's own (GTE, LTE) order. The ids only surface through `PendingOrderCreated` — the create functions' return value is unreadable from a receipt — so this is the only way to learn what a placement created. `trader.placePerpStopOrder` calls it for you; it is exported for the build path, where the caller sends the transaction and so holds the only copy of the receipt. Filters to `registry`'s own logs: another contract could emit a matching signature, and in a batched UserOp several contracts' logs share one receipt. **Details** - `logs`: The receipt's logs. - `registry`: The PerpStopOrderRegistry the placement targeted. - Returns: The created ids, oldest first; empty if the receipt created none. **Example** (Decoding submitted stop IDs) ```ts const { stopOrder } = await trader.buildPlacePerpStopOrder({ registry, pool, isBid: false, quantity: 10_000_000n, triggerPrice: 90_000_000_000_000_000_000n, triggerOperator: 1, stopOrderType: 1, skipOperatorApproval: true, }); const receipt = await myBatcher.send([stopOrder]); const [stopOrderId] = decodePerpStopOrderIds(receipt.logs, registry); ``` ## Parameters ### logs readonly `object`[] ### registry `` `0x${string}` `` ## Returns `bigint`[] --- # /docs/typescript/api/index/functions/decodeRevert [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / decodeRevert # Function: decodeRevert() > **decodeRevert**(`caught`, `context?`): [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/revert.ts:204 Decodes a caught contract failure into a [ContractRevertError](../classes/ContractRevertError.md). **Details** Never throws and never returns undefined: an undecodable revert still produces the typed error, because "the chain rejected this" is useful even when the bytes are a mystery. - `caught`: The value thrown by viem / the transport. - `context`: Which contract and function were called, for the message. - Returns: A ContractRevertError — with `errorName` + `args` when the revert data matched one of the protocol's custom errors, else `reason` (a require string) or `data` (unrecognized bytes) preserved, and `caught` in `cause`. **Gotchas** Decodes unconditionally: it does not first check whether the failure IS a revert, so a transport error (timeout, disconnect) passed here comes back as a ContractRevertError with no `errorName`. Callers inside the SDK use the internal `isRevert` / `toSdkError` pair to make that distinction; neither is exported, so a consumer should pass values it already knows to be revert data — which is the usual case when decoding a failed call's own error. ## Parameters ### caught `unknown` ### context? [`RevertContext`](../interfaces/RevertContext.md) = `{}` ## Returns [`ContractRevertError`](../classes/ContractRevertError.md) --- # /docs/typescript/api/index/functions/densifyFundingBuckets [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / densifyFundingBuckets # Function: densifyFundingBuckets() > **densifyFundingBuckets**\<`T`\>(`candles`, `intervalSeconds`, `from`, `to`): (`T` \| \{ `bucketStart`: `string`; `intervalSeconds`: `number`; `avgFundingRate8h`: `"0"`; `coverage`: `"0"`; `filled`: `true`; \})[] Defined in: packages/sdk/src/funding.ts:237 Fill the bucket-grid slots a candle query did not return, over `[from, to)`. Rollup candles are **sparse by construction**: a window touched by no settlement's covered span produces no row, because nothing triggered a write. A chart that plots the rows as-is silently closes those gaps and draws funding that never accrued. This is the ONLY densification the presentation tier should do, and the constraint is as much about what it must not do: - Missing slots are emitted as **zero** rate with **zero coverage** — never as a carry-forward of the previous rate. Carrying forward is the specific error the protocol docs call out: gaps are genuinely zero-funding intervals, and carrying the last rate through the 22h outage these pools actually had would fabricate ~2.6% of funding out of nothing. - It is not interpolation. Nothing is smoothed, and no real value is altered. - `coverage: "0"` is what lets a chart hatch or grey the slot rather than draw a zero that looks like a measurement. A filled slot and a genuinely-zero measured slot are different facts, and only `coverage` distinguishes them. - **It never fills slots older than the oldest row it was given.** This is the truncation guard, and it matters because `listFundingRateCandles` pages newest-first: 30 days of hourly buckets is 720 rows against a default `limit` of 500, so a caller who asks for a month gets the newest 500 and no indication that anything was dropped. Filling the 220 missing older slots would render nine days as a funding pause that never happened — reintroducing exactly the ambiguity `coverage` exists to remove, one layer up. Refusing to invent them means the window can come back SHORTER than `[from, to)`: read the first element's `bucketStart` rather than assuming it equals `from`, and page with `offset` if you need the rest. Returned oldest-first, which is chart order — note that `listFundingRateCandles` serves newest-first. **Details** - `candles`: rows from [client.listFundingRateCandles](../interfaces/SomniaMarketsClient.md#listfundingratecandles), any order - `intervalSeconds`: the grid resolution the rows were queried at - `from`: window start, unix seconds (snapped down to the grid) - `to`: window end, unix seconds (exclusive) ## Type Parameters ### T `T` *extends* [`FundingBucketLike`](../interfaces/FundingBucketLike.md) ## Parameters ### candles readonly `T`[] ### intervalSeconds `number` ### from `number` \| `bigint` ### to `number` \| `bigint` ## Returns (`T` \| \{ `bucketStart`: `string`; `intervalSeconds`: `number`; `avgFundingRate8h`: `"0"`; `coverage`: `"0"`; `filled`: `true`; \})[] --- # /docs/typescript/api/index/functions/estPayoutFor [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / estPayoutFor # Function: estPayoutFor() > **estPayoutFor**(`input`): `bigint` Defined in: packages/sdk/src/derivedReads.ts:653 Compute the estimated payout for one settled position (raw collateral). Winner: `amount × (10_000 − feeBps) / 10_000`; voided: `amount × payoutNumerators[outcomeIdx] / payoutDenominator`; loser: 0. A void pays its stored vector, which is a half per side under the `UNIFORM` policy and `[p, D−p]` on a `CLOB_SNAPSHOT` void that captured a two-sided close. When the vector is absent the estimate falls back to the half, which is what this returned for every void before the vector existed. A void is never fee-charged, so no settlement fee applies on this branch — the raw vector and the fee-scaled one are identical for a void. **Errors** Throws [InvalidInputError](../classes/InvalidInputError.md) when a void has a present but invalid payout vector. A legacy row with both vector fields absent keeps the documented half-payout fallback. ## Parameters ### input [`ClaimableInput`](../interfaces/ClaimableInput.md) ## Returns `bigint` --- # /docs/typescript/api/index/functions/estimateMarketOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / estimateMarketOrder # Function: estimateMarketOrder() > **estimateMarketOrder**(`book`, `side`, `amount`, `denomination?`): [`MarketOrderEstimate`](../interfaces/MarketOrderEstimate.md) \| `null` Defined in: packages/sdk/src/unified/quotes.ts:112 Estimate a market order's execution by walking one side of the book: buys walk the asks, sells walk the bids, consuming `amount` in either the base or the quote denomination. The four combinations: - buy + quote — spend a quote budget, learn the base received. - buy + base — target a base size, learn the quote cost. - sell + base — deliver a base size, learn the quote received. - sell + quote — target quote proceeds, learn the base sold. Returns `null` when the relevant side is empty or `amount` is non-positive. A partial walk (book thinner than the order) returns what WOULD fill — compare `baseFilled`/`quoteFilled` against the request to detect it. ## Parameters ### book [`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md) ### side `"buy"` \| `"sell"` ### amount `number` ### denomination? [`QuoteDenomination`](../type-aliases/QuoteDenomination.md) = `"base"` ## Returns [`MarketOrderEstimate`](../interfaces/MarketOrderEstimate.md) \| `null` --- # /docs/typescript/api/index/functions/fillKind [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / fillKind # Function: fillKind() > **fillKind**(`takerSide`, `makerSide`): [`BinaryFillKind`](../type-aliases/BinaryFillKind.md) Defined in: packages/sdk/src/store.ts:393 Classify a binary fill from its two sides: opposite trades on ONE outcome are direct (`DIRECT_YES`/`DIRECT_NO`); two buys mint a YES+NO pair from collateral, two sells burn one back. Mirror of the indexer's `fillKind` (BinaryPool._isPair matrix — keep in lockstep). **Details** - `takerSide`: The taker's [BinarySide](../type-aliases/BinarySide.md). - `makerSide`: The maker's [BinarySide](../type-aliases/BinarySide.md). ## Parameters ### takerSide [`BinarySide`](../type-aliases/BinarySide.md) ### makerSide [`BinarySide`](../type-aliases/BinarySide.md) ## Returns [`BinaryFillKind`](../type-aliases/BinaryFillKind.md) --- # /docs/typescript/api/index/functions/fillsWithinSlippage [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / fillsWithinSlippage # Function: fillsWithinSlippage() > **fillsWithinSlippage**(`book`, `side`, `amount`, `slippage`, `denomination?`): `boolean` Defined in: packages/sdk/src/unified/quotes.ts:156 Whether a market order of `amount` (in `denomination`) fills COMPLETELY within `slippage` of the mid price: buys spend against asks at or below `mid·(1+slippage)`, sells deliver into bids at or above `mid·(1−slippage)`. Levels are sorted best-first, so the first level outside the band ends the walk. False when the book is empty, the mid is unknown, or the in-band liquidity can't cover the size — the caller should refuse the order rather than fill deep. ## Parameters ### book [`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md) ### side `"buy"` \| `"sell"` ### amount `number` ### slippage `number` ### denomination? [`QuoteDenomination`](../type-aliases/QuoteDenomination.md) = `"base"` ## Returns `boolean` --- # /docs/typescript/api/index/functions/floorRawBalance [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / floorRawBalance # Function: floorRawBalance() > **floorRawBalance**(`raw`, `decimals`, `quantum`): `number` Defined in: packages/sdk/src/units.ts:565 Floor a raw on-chain balance to a whole multiple of `quantum` (a human decimal string — the market's lot size for base amounts, or a display precision like "0.01" for quote) and return it as a JS number that is provably ≤ the true balance. Flooring happens in raw (bigint) space, so float rounding can never push a "max" order above the wallet. ## Parameters ### raw `bigint` ### decimals `number` ### quantum `string` ## Returns `number` --- # /docs/typescript/api/index/functions/formatIntervalLabel [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / formatIntervalLabel # Function: formatIntervalLabel() > **formatIntervalLabel**(`sec`): `string` \| `null` Defined in: packages/sdk/src/interval.ts:187 Compact human label for a cadence in SECONDS, in the largest unit up to hours that divides it cleanly: `600 → "10m"`, `900 → "15m"`, `3600 → "1h"`, `14400 → "4h"`, `86400 → "24h"`, `172800 → "48h"`, `90 → "90s"`. Returns `null` on non-finite/non-positive input (callers pick their own placeholder). Does NOT snap — pass a snapped value, or use [marketIntervalLabel](marketIntervalLabel.md), to first shed off-by-one-second noise. ## Parameters ### sec `number` ## Returns `string` \| `null` --- # /docs/typescript/api/index/functions/fromHuman [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / fromHuman # Function: fromHuman() > **fromHuman**(`human`, `decimals?`): `bigint` Defined in: packages/sdk/src/units.ts:52 Human amount (number or decimal string) → raw bigint at `decimals`, for the write API (`placeOrder` price/quantity, `mintSet` amount, …). Accepts a string to avoid float rounding (`fromHuman("0.1")`), or a number for convenience. **Gotchas** A number carrying more fraction digits than `decimals` is ROUNDED to scale (half-away-from-zero, via `toFixed`): `fromHuman(0.1234567, 6)` is `123457n`. That is a deliberate, long-standing choice — the alternative (throwing) would reject ordinary computed values like a mid price. Pass a string when you need the exact value preserved or rejected instead. ## Parameters ### human `string` \| `number` ### decimals? `number` = `Store.DECIMALS` ## Returns `bigint` --- # /docs/typescript/api/index/functions/fundingRate1h [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / fundingRate1h # Function: fundingRate1h() > **fundingRate1h**(`rate`, `fundingWindowSec`): `bigint` Defined in: packages/sdk/src/funding.ts:96 The rate per hour. ## Parameters ### rate `bigint` ### fundingWindowSec `number` ## Returns `bigint` --- # /docs/typescript/api/index/functions/fundingRate8h [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / fundingRate8h # Function: fundingRate8h() > **fundingRate8h**(`rate`, `fundingWindowSec`): `bigint` Defined in: packages/sdk/src/funding.ts:87 The rate per 8 hours — the primary presentation axis, matching the convention used by Hyperliquid and Binance. A no-op while `fundingWindowSec` is 28800, which it is on every live pool. Use it anyway: it is what keeps a chart correct across a window change. ## Parameters ### rate `bigint` ### fundingWindowSec `number` ## Returns `bigint` --- # /docs/typescript/api/index/functions/fundingRatePerInterval [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / fundingRatePerInterval # Function: fundingRatePerInterval() > **fundingRatePerInterval**(`rate`, `fundingWindowSec`, `fundingIntervalSec`): `bigint` Defined in: packages/sdk/src/funding.ts:106 The rate that accrues per settlement interval — what an account actually pays or receives at each settlement. ## Parameters ### rate `bigint` ### fundingWindowSec `number` ### fundingIntervalSec `number` ## Returns `bigint` --- # /docs/typescript/api/index/functions/getMarketTypePlugin [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / getMarketTypePlugin # Function: getMarketTypePlugin() > **getMarketTypePlugin**(`marketType`): [`MarketTypePlugin`](../interfaces/MarketTypePlugin.md)\<`unknown`\> \| `undefined` Defined in: packages/sdk/src/marketTypes/index.ts:29 Resolve a market-type plugin by its bytes4 id (case-insensitive), or undefined if unregistered. ## Parameters ### marketType `` `0x${string}` `` ## Returns [`MarketTypePlugin`](../interfaces/MarketTypePlugin.md)\<`unknown`\> \| `undefined` --- # /docs/typescript/api/index/functions/intervalsPerWindow [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / intervalsPerWindow # Function: intervalsPerWindow() > **intervalsPerWindow**(`fundingWindowSec`, `fundingIntervalSec`): `number` Defined in: packages/sdk/src/funding.ts:137 Intervals per calculation window — `n`. The per-interval divisor: each settlement accrues `rate / n` of the emitted per-window rate. **It is not a cap on what a lazily-settled emit accrues, and never treat it as one.** The contract's catch-up horizon is ONE interval, so a settlement charges at most `rate / n` however long the gap was, and the excess is forgiven rather than deferred. Read `FundingRateUpdate.intervalsAccrued` for what a given settlement actually accrued; deriving it as `min(intervalsSettled, n)` is the specific error the protocol interface warns against, and it renders funding across intervals that were forgiven. ## Parameters ### fundingWindowSec `number` ### fundingIntervalSec `number` ## Returns `number` --- # /docs/typescript/api/index/functions/isBinaryMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / isBinaryMarket # Function: isBinaryMarket() > **isBinaryMarket**(`m`): `m is BinaryMarket` Defined in: packages/sdk/src/markets.ts:427 Narrow a [Market](../type-aliases/Market.md) to its binary variant. ## Parameters ### m [`Market`](../type-aliases/Market.md) ## Returns `m is BinaryMarket` --- # /docs/typescript/api/index/functions/isFundingStale [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / isFundingStale # Function: isFundingStale() > **isFundingStale**(`lastFundingUpdateAt`, `fundingIntervalSec`, `nowSec`, `staleAfterIntervals?`): `boolean` Defined in: packages/sdk/src/funding.ts:177 Whether a pool's funding has gone stale — no settlement for `staleAfterIntervals` worth of time. Settlement is permissionless and LAZY, so a due settlement simply may not have happened. One missed interval is routine; a sustained gap means funding is not accruing, and on the zero-open-interest branch it is being forgiven with no event at all. Two intervals is a deliberately forgiving default. ## Parameters ### lastFundingUpdateAt `bigint` ### fundingIntervalSec `number` ### nowSec `bigint` ### staleAfterIntervals? `number` = `2` ## Returns `boolean` --- # /docs/typescript/api/index/functions/isLiquidationKind [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / isLiquidationKind # Function: isLiquidationKind() > **isLiquidationKind**(`kind`): kind is "AutoDeleveraged" \| "CloseOutMarginSettled" \| "BadDebtAbsorbed" \| "PositionTransferred" \| "AccountLiquidated" \| "PositionLiquidated" \| "PositionTakenOver" \| "ResidualBadDebt" \| "ResidualBackedByOpenPnl" \| "AdlCapacityShortfall" \| "AdlPriceCapacityExhausted" \| "AdlSessionDiscarded" \| "PositionSkipped" \| "Throttled" \| "KeeperReward" \| "OrderPanicked" \| "CoverageDeclined" Defined in: packages/sdk/src/perp/history.ts:135 Whether a wire `kind` is one this SDK version knows, narrowing it to [LiquidationKind](../type-aliases/LiquidationKind.md). This is the seam between the open rows and the closed filter, and it exists because the two really are different: [LiquidationEvent.kind](../type-aliases/LiquidationEvent.md#kind) is whatever the DEPLOYED indexer wrote, which can outrun a pinned SDK, while [ListLiquidationsOptions.kind](../interfaces/ListLiquidationsOptions.md#kind) is a value the caller chooses and must not be able to misspell. Narrow a row's kind to switch on it exhaustively, or to pass it back into the filter; the false branch is the honest "a kind this version does not know" rather than a cast over it. ## Parameters ### kind `string` ## Returns kind is "AutoDeleveraged" \| "CloseOutMarginSettled" \| "BadDebtAbsorbed" \| "PositionTransferred" \| "AccountLiquidated" \| "PositionLiquidated" \| "PositionTakenOver" \| "ResidualBadDebt" \| "ResidualBackedByOpenPnl" \| "AdlCapacityShortfall" \| "AdlPriceCapacityExhausted" \| "AdlSessionDiscarded" \| "PositionSkipped" \| "Throttled" \| "KeeperReward" \| "OrderPanicked" \| "CoverageDeclined" --- # /docs/typescript/api/index/functions/isLocalPrecompileUnavailable [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / isLocalPrecompileUnavailable # Function: isLocalPrecompileUnavailable() > **isLocalPrecompileUnavailable**(`chainId`): `boolean` Defined in: packages/sdk/src/preflight.ts:413 True when a chain id belongs to a network WITHOUT the Somnia reactivity precompile — i.e. a local anvil/hardhat dev chain (31337 / 1337), where `enableReactivity` / `triggerRoll` cannot work. Somnia testnet/mainnet return false. Use to fill the `precompileAvailable` flag the validators take. ## Parameters ### chainId `number` ## Returns `boolean` --- # /docs/typescript/api/index/functions/isPerpMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / isPerpMarket # Function: isPerpMarket() > **isPerpMarket**(`m`): `m is PerpMarket` Defined in: packages/sdk/src/markets.ts:445 Narrow a [Market](../type-aliases/Market.md) to its perp variant. ## Parameters ### m [`Market`](../type-aliases/Market.md) ## Returns `m is PerpMarket` --- # /docs/typescript/api/index/functions/isSpotMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / isSpotMarket # Function: isSpotMarket() > **isSpotMarket**(`m`): `m is SpotMarket` Defined in: packages/sdk/src/markets.ts:436 Narrow a [Market](../type-aliases/Market.md) to its spot variant. ## Parameters ### m [`Market`](../type-aliases/Market.md) ## Returns `m is SpotMarket` --- # /docs/typescript/api/index/functions/lendRayRateToApy [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / lendRayRateToApy # Function: lendRayRateToApy() > **lendRayRateToApy**(`rateRay`): `number` Defined in: packages/sdk/src/lend/math.ts:95 Convert a ray annual rate (a reserve's `liquidityRateRay` / `variableBorrowRateRay`) to the per-second-compounded APY fraction Aave UIs display (0.05 = 5%). **When to use** Use to display a rate — this exists so apps don't each re-derive `(1 + r/s)^s - 1` from the ray rate. Position math stays in bigint ray space ([rayMul](rayMul.md), [accrueCompounded](accrueCompounded.md)). **Details** - `rateRay`: Annual rate in ray (1e27) units, as returned in [LendReserve](../interfaces/LendReserve.md). - Returns: The compounded annual yield as a plain fraction (`0.031` ⇒ 3.1% APY). **Gotchas** Display-only — the one place the lend surface hands back a `number`. **Example** (Converting a ray rate) ```ts const reserves = await lend.listReserves(); const usdso = reserves.find((r) => r.symbol === "USDso"); if (usdso) console.log(`supply APY ${(lendRayRateToApy(usdso.liquidityRateRay) * 100).toFixed(2)}%`); ``` ## Parameters ### rateRay `bigint` ## Returns `number` --- # /docs/typescript/api/index/functions/listMarketTypePlugins [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / listMarketTypePlugins # Function: listMarketTypePlugins() > **listMarketTypePlugins**(): [`MarketTypePlugin`](../interfaces/MarketTypePlugin.md)\<`unknown`\>[] Defined in: packages/sdk/src/marketTypes/index.ts:39 All registered market-type plugins (e.g. to render a "pick a market type" list in a venue-creation wizard). ## Returns [`MarketTypePlugin`](../interfaces/MarketTypePlugin.md)\<`unknown`\>[] --- # /docs/typescript/api/index/functions/markOutcomePosition [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / markOutcomePosition # Function: markOutcomePosition() > **markOutcomePosition**(`input`): [`OutcomePositionMark`](../interfaces/OutcomePositionMark.md) Defined in: packages/sdk/src/derivedReads.ts:1225 Mark an outcome position: `value = balance × mark`, `upnl = balance × (mark − avgEntry)`. When `avgEntry` is unknown (no buys indexed yet) only `value` is computed and the PnL fields stay `null` — a dash beats an invented zero basis. ## Parameters ### input #### balance `bigint` Outcome-token balance held (raw units). #### markPrice `bigint` Live mark price in the outcome's own terms (raw). #### avgEntry `bigint` \| `null` Average entry price in the outcome's own terms (raw), or `null`. #### oneShare `bigint` ## Returns [`OutcomePositionMark`](../interfaces/OutcomePositionMark.md) --- # /docs/typescript/api/index/functions/markYesPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / markYesPrice # Function: markYesPrice() > **markYesPrice**(`top`, `lastPrice`): `bigint` \| `null` Defined in: packages/sdk/src/units.ts:153 Mark-to-market YES price (raw): the book mid when two-sided, otherwise the last trade clamped into the surviving side's bound. The clamp reconciles the two failure modes of a one-sided book: marking to the lone quote outright flashes the full bid-ask spread as a loss right after a taker clears the top of the book, while marking to the last trade alone freezes the mark at a stale print when the market genuinely runs away — a resting quote BEYOND the last print is live, executable information and supersedes it. With no last trade the lone side is all there is; `null` only when the book is empty and nothing has traded. ## Parameters ### top [`YesBookTop`](../interfaces/YesBookTop.md) ### lastPrice `string` \| `bigint` \| `null` \| `undefined` ## Returns `bigint` \| `null` --- # /docs/typescript/api/index/functions/marketActivityKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketActivityKey # Function: marketActivityKey() > **marketActivityKey**(`market`, `opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:133 Key for `client.getMarketActivity(market, opts)`. `kinds` is sorted and joined, so two callers that ask for the same kinds in a different order share one cache entry — the read does not depend on the order. ## Parameters ### market `string` \| `null` \| `undefined` ### opts? [`MarketActivityOptions`](../type-aliases/MarketActivityOptions.md) ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/marketCreatorsKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketCreatorsKey # Function: marketCreatorsKey() > **marketCreatorsKey**(`opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:233 Key for `client.listMarketCreators(opts)`. ## Parameters ### opts? [`MarketCreatorFilter`](../type-aliases/MarketCreatorFilter.md) & `object` ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/marketFeesKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketFeesKey # Function: marketFeesKey() > **marketFeesKey**(`marketId`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:199 Key for `client.getMarketFees(marketId)`. ## Parameters ### marketId `string` \| `null` \| `undefined` ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/marketIntervalLabel [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketIntervalLabel # Function: marketIntervalLabel() > **marketIntervalLabel**(`m`): `string` \| `null` Defined in: packages/sdk/src/interval.ts:212 The served timeframe label for a binary market: resolve the cadence ([resolveIntervalSec](resolveIntervalSec.md)), snap it to its ladder rung ([snapToCadence](snapToCadence.md)), then label it ([formatIntervalLabel](formatIntervalLabel.md)) — so a market reads as `"1m"` / `"5m"` / `"15m"` / `"1h"` / `"4h"` / `"24h"` whether or not its roll spilled. A window matching no rung (a series' bootstrap partial, a non-ladder cadence) keeps its own short window. Returns `null` when the market has no determinable cadence (SPOT/PERP). This is what the SDK stamps onto `BinaryMarket.interval` and trade-history rows. Snapping to the LADDER rather than to the nearest minute/hour is what stops a row's own badge contradicting the group it was filed under: a 1m member that rolled 4s late is indexed at 56s, which the plain unit snap has no rung to reach for and labels `"56s"`. ## Parameters ### m [`IntervalSource`](../type-aliases/IntervalSource.md) ## Returns `string` \| `null` --- # /docs/typescript/api/index/functions/marketKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketKey # Function: marketKey() > **marketKey**(`outcomeId`): `bigint` Defined in: packages/sdk/src/ids.ts:88 The settlement `marketKey` for any outcome id of a market: `id >> 8`. Both the YES id and the NO id of the same market map to the SAME key (they differ only in the low 8 idx bits), so this keys the per-market `BinarySettlement` record regardless of which side's id you pass. Named `marketKey(yesId)` for the canonical YES-id caller, but any outcome id of the market works. ## Parameters ### outcomeId `bigint` ## Returns `bigint` --- # /docs/typescript/api/index/functions/marketOnchainKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketOnchainKey # Function: marketOnchainKey() > **marketOnchainKey**(`marketId`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:304 Key for `client.getMarketOnchain(marketId)`. ## Parameters ### marketId `string` \| `null` \| `undefined` ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/marketStats24hFromCandles [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketStats24hFromCandles # Function: marketStats24hFromCandles() > **marketStats24hFromCandles**(`candles`, `nowSec`): [`MarketStats24h`](../interfaces/MarketStats24h.md) Defined in: packages/sdk/src/derivedReads.ts:181 Fold candle buckets whose `bucketStart >= nowSec − 86400` into a [MarketStats24h](../interfaces/MarketStats24h.md). `candles` are oldest-first (as `getCandles` returns). Pure — the wiring in createClient just fetches the candles first. ## Parameters ### candles [`Candle`](../type-aliases/Candle.md)[] ### nowSec `number` ## Returns [`MarketStats24h`](../interfaces/MarketStats24h.md) --- # /docs/typescript/api/index/functions/marketsKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marketsKey # Function: marketsKey() > **marketsKey**(`opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:70 Key for `client.listMarkets(opts)`. ## Parameters ### opts? #### marketType? [`MarketType`](../type-aliases/MarketType.md) Restrict to one market kind. #### limit? `number` Page size. #### offset? `number` Page offset. ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/maxVenueFeeBpsKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / maxVenueFeeBpsKey # Function: maxVenueFeeBpsKey() > **maxVenueFeeBpsKey**(): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:295 Key for `client.getMaxVenueFeeBps()`. ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/midYesPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / midYesPrice # Function: midYesPrice() > **midYesPrice**(`bestYesBid`, `bestYesAsk`): `bigint` \| `undefined` Defined in: packages/sdk/src/derivedReads.ts:1116 The mid YES price (raw) from the best book levels — `(bid + ask) / 2` when both sides are quoted, otherwise whichever single side exists. `undefined` when the book is empty. For an ODDS display; positions should mark with [markYesPrice](markYesPrice.md) instead (a lone bid/ask is not a fair mark). ## Parameters ### bestYesBid `bigint` \| `undefined` ### bestYesAsk `bigint` \| `undefined` ## Returns `bigint` \| `undefined` --- # /docs/typescript/api/index/functions/normalizeFundingRate [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / normalizeFundingRate # Function: normalizeFundingRate() > **normalizeFundingRate**(`rate`, `fundingWindowSec`, `targetSec`): `bigint` Defined in: packages/sdk/src/funding.ts:73 Re-express a per-window funding rate on a different denominator. `rate_target = rate * targetSec / fundingWindowSec`, in 1e18 fixed point. Truncates toward zero, matching the contract's integer arithmetic; sign is preserved. **Details** - `rate`: the rate as stored/emitted: per `fundingWindowSec`, 1e18-scaled, signed - `fundingWindowSec`: the rate's denominator, from the same row or state read - `targetSec`: the denominator to convert to **Example** (Normalizing an interval rate) ```ts const perInterval = normalizeFundingRate(st.fundingRate, st.fundingWindowSec, st.fundingIntervalSec); ``` ## Parameters ### rate `bigint` ### fundingWindowSec `number` ### targetSec `number` ## Returns `bigint` --- # /docs/typescript/api/index/functions/operatorsKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / operatorsKey # Function: operatorsKey() > **operatorsKey**(`opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:208 Key for `client.listOperators(opts)`. ## Parameters ### opts? [`OperatorFilter`](../type-aliases/OperatorFilter.md) & `object` ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/oracleAdaptersKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / oracleAdaptersKey # Function: oracleAdaptersKey() > **oracleAdaptersKey**(`opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:259 Key for `client.listOracleAdapters(opts)`. ## Parameters ### opts? #### owner? `string` Restrict to adapters owned by this address. #### approved? `boolean` Restrict to approved (true) / unapproved (false) adapters. #### limit? `number` Page size. #### offset? `number` Page offset. ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/outcomeId [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / outcomeId # Function: outcomeId() > **outcomeId**(`pool`, `nonce`, `idx`): `bigint` Defined in: packages/sdk/src/ids.ts:46 The ERC-6909 outcome id for `pool`'s market at `nonce`, outcome `idx`. `id = (uint160(pool) << 72) | (nonce << 8) | idx`. Pool is a 0x-address; nonce is the pool's `marketNonce` for the target market (1 on a fresh pool, ++ on each recycle); idx is 0 (YES) or 1 (NO). ## Parameters ### pool `string` ### nonce `number` \| `bigint` ### idx [`OutcomeIdx`](../type-aliases/OutcomeIdx.md) ## Returns `bigint` --- # /docs/typescript/api/index/functions/outcomeMarkPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / outcomeMarkPrice # Function: outcomeMarkPrice() > **outcomeMarkPrice**(`input`): `bigint` \| `undefined` Defined in: packages/sdk/src/derivedReads.ts:1192 Live mark price for one outcome in its own terms (raw): YES marks at the YES mid, NO at the complement. `undefined` when there's no mid to mark to. ## Parameters ### input #### outcomeIndex `number` #### yesMid `bigint` \| `undefined` YES mark (raw), e.g. from [markYesPrice](markYesPrice.md). #### oneShare `bigint` ## Returns `bigint` \| `undefined` --- # /docs/typescript/api/index/functions/perpLiquidationPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / perpLiquidationPrice # Function: perpLiquidationPrice() > **perpLiquidationPrice**(`p`): `bigint` \| `null` Defined in: packages/sdk/src/perp/margin.ts:438 Solve for the mark price at which one market's position trips maintenance margin — the shared kernel behind `client.getLiquidationPrice` and `client.previewPerpLiquidationPrice`, which is why a current and a projected price cannot disagree on identical inputs. Pure: no client, no block, no I/O. Feed it a consistent snapshot and it is exact arithmetic. **Both sides of the inequality move with the price.** Liquidation begins where `equity == mmReq` — `MarginBank._classify` returns `PartialLiquidation` the moment `equity < mmReq`. Equity moves with the mark through unrealized PnL, at `size / oneBase` per unit of price. But `mmReq` moves too, because `_marketHealthFromSnapshot` recomputes it as `ceil(|size| × mark × mmBps / (oneBase × 10000))` against the CURRENT mark. Solving `equity(p) == mmReq(p)` therefore carries a factor a fixed-`mmReq` estimate drops: ```text long p = mark − (equity − mmReq) × oneBase × 10000 / (|size| × (10000 − mmBps)) short p = mark + (equity − mmReq) × oneBase × 10000 / (|size| × (10000 + mmBps)) ``` Dropping that factor errs conservative on a long and **optimistic on a short** — reporting the liquidation further away than it is, on the side whose loss is unbounded. At a 250 bps maintenance threshold it misplaces a short's liquidation by ~2.5% of the distance to it. **A single-market solve, deliberately.** Only this market's mark is varied; every other market's contribution stays at the value baked into `equity` and `mmReq`. So the answer is "the price at which THIS market's move alone trips maintenance", which is what a per-position liquidation price means under cross margin. A correlated move across several markets liquidates sooner, and nothing here claims otherwise. Also held constant: pending funding (already netted into `equity`), the mark's own EMA lag, and any fill landing between the read and the move. **Details** - Returns: The liquidation price in raw quote units per whole base, floored at 0 (a price cannot go negative) — or `null` when the position is flat, or when `mmBps` is exactly 10000 on a long, where price cancels out of the inequality entirely and no price triggers liquidation. That last case is unreachable on a real pool: `PerpPool._validatePerpPoolParameters` enforces `initialMarginBps ≤ 10000` and `maintenanceMarginBps < initialMarginBps`, so `mmBps < 10000` on every market. ## Parameters ### p [`PerpLiquidationPriceInputs`](../interfaces/PerpLiquidationPriceInputs.md) ## Returns `bigint` \| `null` --- # /docs/typescript/api/index/functions/perpMarkForPnl [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / perpMarkForPnl # Function: perpMarkForPnl() > **perpMarkForPnl**(`state`): `object` Defined in: packages/sdk/src/perp/state.ts:117 The price to mark a perp position at, and whether it came from the mark feed. Extracted and tested rather than written inline at the call site, because the inline version is a one-line regression waiting to happen. `getPerpState` reads the mark via `tryGetMarkPrice`, which REPORTS staleness rather than reverting on it — so the naive `markPrice - entryPrice` takes the meaningless 0 price word from a stale feed and produces a 100% loss on every open position. An earlier `getMarkPrice()` read reverted instead, which failed loudly; making the read more robust made the derived number silently worse until this guard. The index price is the fallback rather than "no value": it is a separate oracle the pool already trusts for funding, and dropping positions out of a portfolio view is its own kind of wrong. Callers that want a MARK READING (rather than something to mark against) should report undefined on staleness instead — see `fetchFundingRate`. ## Parameters ### state `Pick`\<[`PerpStateOnchain`](../interfaces/PerpStateOnchain.md), `"markPrice"` \| `"markPriceOk"` \| `"indexPrice"`\> ## Returns `object` ### price > **price**: `bigint` ### fromIndex > **fromIndex**: `boolean` --- # /docs/typescript/api/index/functions/perpOrderMarginQuote [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / perpOrderMarginQuote # Function: perpOrderMarginQuote() > **perpOrderMarginQuote**(`p`): [`PerpOrderMarginQuote`](../interfaces/PerpOrderMarginQuote.md) Defined in: packages/sdk/src/perp/margin.ts:2008 The pool's placement arithmetic — pure, no client, no block. Split out of [SomniaMarketsClient.previewPerpOrderMargin](../interfaces/SomniaMarketsClient.md#previewperpordermargin) so the FORWARD question ("what does this order cost") and the INVERSE one (`client.getMaxPerpOrderSize`, "what is the largest order I can place") are answered by the same code rather than by two ports of the same contract. They cannot drift, which matters more here than usual: a max size computed by a second, subtly different rule reverts on placement, and the term such a rule most often drops is [PerpOrderMarginQuote.adverseGapPortion](../interfaces/PerpOrderMarginQuote.md#adversegapportion). **Auto-pull (T70) is modelled iff [PerpOrderMarginQuoteInputs.wallet](../interfaces/PerpOrderMarginQuoteInputs.md#wallet) is supplied**, and supplying it is a statement about the SENDER, not about the account: `PerpPool._autoPullMargin` fires only when `msg.sender == order.owner`. Given a wallet, the gates below describe the balance the pool will have topped up to before it locks; without one they describe the in-bank balance alone, which is what an operator- or registry-routed placement actually faces. The no-wallet path is arithmetically identical to the pre-T70 one. ## Parameters ### p [`PerpOrderMarginQuoteInputs`](../interfaces/PerpOrderMarginQuoteInputs.md) ## Returns [`PerpOrderMarginQuote`](../interfaces/PerpOrderMarginQuote.md) --- # /docs/typescript/api/index/functions/perpPositionAnalytics [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / perpPositionAnalytics # Function: perpPositionAnalytics() > **perpPositionAnalytics**(`p`): [`PerpPositionMetrics`](../interfaces/PerpPositionMetrics.md) Defined in: packages/sdk/src/perp/margin.ts:903 Split one position into PnL, funding, notional and its three margin requirements — pure, no client, no block. A direct port of `MarginBank._computePositionMetrics` and `_marketHealthFromSnapshot`. Exported so a caller can re-run it against a live store, a hypothetical mark, or a position it is about to open, without a round-trip — and so a table and a detail view cannot disagree on identical inputs. ## Parameters ### p [`PerpPositionAnalyticsInputs`](../interfaces/PerpPositionAnalyticsInputs.md) ## Returns [`PerpPositionMetrics`](../interfaces/PerpPositionMetrics.md) --- # /docs/typescript/api/index/functions/pnlEventsFor [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / pnlEventsFor # Function: pnlEventsFor() > **pnlEventsFor**(`account`, `fills`, `routerActions`): [`PnLEvent`](../interfaces/PnLEvent.md)[] Defined in: packages/sdk/src/derivedReads.ts:372 Derive the [PnLEvent](../interfaces/PnLEvent.md) stream for `account` from raw [FillRow](../type-aliases/FillRow.md)s (order-book fills) + [RouterActionRecord](../type-aliases/RouterActionRecord.md)s (mint/merge complete sets), merged into ONE oldest-first timeline by timestamp (so the avg-cost roll sees mints and fills in the order they happened). Fills whose side isn't bridged yet are skipped (can't attribute an outcome). Mint/merge use the record's `amount` (each outcome's set size). Redeem actions are ignored (they settle the position at payout, they don't change cost basis of a still-open book). SCOPE IS THE CALLER'S JOB: no market filter is applied here, so pass ONE market's fills, selected by `FillRow.market` (never by `pool` — see there). ## Parameters ### account `string` ### fills [`FillRow`](../type-aliases/FillRow.md)[] ### routerActions [`RouterActionRecord`](../type-aliases/RouterActionRecord.md)[] ## Returns [`PnLEvent`](../interfaces/PnLEvent.md)[] --- # /docs/typescript/api/index/functions/portfolioKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / portfolioKey # Function: portfolioKey() > **portfolioKey**(`account`, `opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:90 Key for `client.getPortfolio(account, opts)`. ## Parameters ### account `string` \| `null` \| `undefined` ### opts? [`PortfolioOptions`](../type-aliases/PortfolioOptions.md) ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/positionMarkState [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / positionMarkState # Function: positionMarkState() > **positionMarkState**(`input`): [`PositionMarkState`](../type-aliases/PositionMarkState.md) Defined in: packages/sdk/src/derivedReads.ts:1276 Classify how a position marks from its market's status/resolution: a resolved market pays its winning outcome, a voided one refunds, a still-trading one marks live, and anything expired-but-unresolved is settling (marking to a stale book there flashes phantom PnL). ## Parameters ### input #### status `string` BinaryMarketStatus string from the market row. #### voided `boolean` #### winningOutcome `number` \| `null` \| `undefined` Winning outcome index (0 = YES, 1 = NO), or null until resolved. #### outcomeIndex `number` #### expirySec `number` Market expiry (unix seconds). #### nowSec `number` Reference "now" (unix seconds). ## Returns [`PositionMarkState`](../type-aliases/PositionMarkState.md) --- # /docs/typescript/api/index/functions/preflightChain [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightChain # Function: preflightChain() > **preflightChain**(`connectedChainId`, `expectedChainId`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:397 Validate the wallet is on the expected chain (a machinery write on the wrong chain either reverts or lands on the wrong deployment). A standalone gate the wizard runs before any step. ## Parameters ### connectedChainId `number` ### expectedChainId `number` ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/preflightCreateQuote [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightCreateQuote # Function: preflightCreateQuote() > **preflightCreateQuote**(`q`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:249 Validate a create-market call can proceed under §8e: the payer's balance covers the FULL create value `getSchedulingCost(def) + resolveReserve()` — the reserve is attached to the create and earmarked at onBind (excess is refunded in-tx). No separate prepaid-balance gate. ## Parameters ### q [`CreateQuotePreflightInput`](../interfaces/CreateQuotePreflightInput.md) ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/preflightHub [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightHub # Function: preflightHub() > **preflightHub**(`h`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:191 Validate the OracleHub is live: approved on the module, its balance above the reactivity-bond floor, and its subscription armed (where the precompile exists). Protocol-admin view — an operator can't fix these, but a panel surfaces them so a dead hub isn't debugged at the create-market step. ## Parameters ### h [`HubPreflightInput`](../interfaces/HubPreflightInput.md) ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/preflightMarketCreator [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightMarketCreator # Function: preflightMarketCreator() > **preflightMarketCreator**(`c`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:288 Validate a MarketCreator is funded enough to roll (a warning, not a hard blocker — a creator with a series but no balance still exists, it just can't roll until funded). For the exact per-roll amount, run [preflightCreateQuote](preflightCreateQuote.md) with the live hub quote. ## Parameters ### c [`MarketCreatorPreflightInput`](../interfaces/MarketCreatorPreflightInput.md) ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/preflightOperator [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightOperator # Function: preflightOperator() > **preflightOperator**(`op`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:104 Validate that an operator is a sound base for machinery: the caller owns it, it is enabled, and it has a non-zero fee recipient. ## Parameters ### op [`OperatorPreflightInput`](../interfaces/OperatorPreflightInput.md) ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/preflightRoll [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightRoll # Function: preflightRoll() > **preflightRoll**(`r`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:373 Validate the preconditions for `triggerRoll`: the series is registered, the chain has the precompile, and the creator holds native to pay the roll. ## Parameters ### r [`RollPreflightInput`](../interfaces/RollPreflightInput.md) ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/preflightSeries [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightSeries # Function: preflightSeries() > **preflightSeries**(`s`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:329 Validate a series config matches the module's constraints: non-zero `seriesId`, non-empty `asset`, `intervalSec >= 60`, non-zero collateral. ## Parameters ### s [`SeriesPreflightInput`](../interfaces/SeriesPreflightInput.md) ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/preflightVenue [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / preflightVenue # Function: preflightVenue() > **preflightVenue**(`v`): [`PreflightResult`](../interfaces/PreflightResult.md) Defined in: packages/sdk/src/preflight.ts:146 Validate a venue is ready to host a market: the caller owns its operator, its creation flag is on, and its market type is bound to a module. ## Parameters ### v [`VenuePreflightInput`](../interfaces/VenuePreflightInput.md) ## Returns [`PreflightResult`](../interfaces/PreflightResult.md) --- # /docs/typescript/api/index/functions/priceToProbability [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / priceToProbability # Function: priceToProbability() > **priceToProbability**(`rawPrice`, `decimals?`): `number` Defined in: packages/sdk/src/units.ts:106 Raw YES price → YES probability in [0, 1]. ## Parameters ### rawPrice `string` \| `bigint` ### decimals? `number` = `Store.DECIMALS` ## Returns `number` --- # /docs/typescript/api/index/functions/probabilityToPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / probabilityToPrice # Function: probabilityToPrice() > **probabilityToPrice**(`probability`, `decimals?`): `bigint` Defined in: packages/sdk/src/units.ts:115 YES probability in [0, 1] → raw YES price (the `price` field of placeOrder). ## Parameters ### probability `number` ### decimals? `number` = `Store.DECIMALS` ## Returns `bigint` --- # /docs/typescript/api/index/functions/quoteBinaryOrderOverBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / quoteBinaryOrderOverBook # Function: quoteBinaryOrderOverBook() > **quoteBinaryOrderOverBook**(`book`, `side`, `quantity`, `oneCollateral`): [`BinaryOrderQuote`](../interfaces/BinaryOrderQuote.md) Defined in: packages/sdk/src/derivedReads.ts:105 Walk the live book crossing the opposite side for a market order of `quantity` on `side` — the pure kernel behind `client.quoteBinaryOrder`. `oneCollateral = 10^quoteDecimals` (full collateral = a share worth 1). ## Parameters ### book [`BinaryOrderBook`](../interfaces/BinaryOrderBook.md) ### side [`BinarySide`](../type-aliases/BinarySide.md) ### quantity `bigint` ### oneCollateral `bigint` ## Returns [`BinaryOrderQuote`](../interfaces/BinaryOrderQuote.md) --- # /docs/typescript/api/index/functions/quoteBinarySellOverBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / quoteBinarySellOverBook # Function: quoteBinarySellOverBook() > **quoteBinarySellOverBook**(`book`, `side`, `quantity`, `oneCollateral`, `params`): [`BinarySellQuote`](../interfaces/BinarySellQuote.md) \| `null` Defined in: packages/sdk/src/derivedReads.ts:1053 Build a market SELL that unwinds `quantity` of an outcome by crossing the resting bids, with a slippage cushion below the best bid — the sell-side sibling of [quoteBinaryStakeOverBook](quoteBinaryStakeOverBook.md). Pinning the protective limit to the exact best bid means any tick of book churn between the quote and on-chain execution leaves the IOC uncrossable — a sell into a busy book fills nothing. The limit instead sits a cushion below the best bid, aligned DOWN to the tick grid (never below one tick): the order still fills each resting bid at its own price, best-first. Unlike the buy side, `quantity` is NOT sized to the book — it's the caller's position, lot-aligned. The quote walks the crossable bids and reports `fillableQuantity`/`estProceeds` so a thin book surfaces as a partial unwind up front rather than a silent IOC cancel. Returns `null` when there's nothing to sell (including a position below the pool's `minQuantity`) or no bid to cross — disable the Sell control rather than sending a doomed order. **Details** - `book`: The live four-sided book (NO sides pre-inverted). - `side`: "SELL_YES" (Up position) or "SELL_NO" (Down position). - `quantity`: Outcome-token quantity to sell, raw units (snapped down to the lot grid). - `oneCollateral`: `10^quoteDecimals` — one whole outcome share. - `params`: The pool's tick/lot grid + slippage policy. ## Parameters ### book [`BinaryOrderBook`](../interfaces/BinaryOrderBook.md) ### side [`BinarySellSide`](../type-aliases/BinarySellSide.md) ### quantity `bigint` ### oneCollateral `bigint` ### params [`BinaryCrossingParams`](../interfaces/BinaryCrossingParams.md) ## Returns [`BinarySellQuote`](../interfaces/BinarySellQuote.md) \| `null` --- # /docs/typescript/api/index/functions/quoteBinaryStakeOverBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / quoteBinaryStakeOverBook # Function: quoteBinaryStakeOverBook() > **quoteBinaryStakeOverBook**(`book`, `side`, `stake`, `oneCollateral`, `params`): [`BinaryStakeQuote`](../interfaces/BinaryStakeQuote.md) \| `null` Defined in: packages/sdk/src/derivedReads.ts:917 Convert a collateral stake into a market BUY by walking the live book — so the quoted shares and payout match what the order will actually fill, not an optimistic top-of-book estimate. The inverse of [quoteBinaryOrderOverBook](quoteBinaryOrderOverBook.md): that sizes cost from a quantity; this sizes quantity from a collateral budget. The sweep buys down the asks cheapest-first, accumulating shares while the escrow at the running protective price (the worst level touched) stays within the stake — the max loss never exceeds it. A pricier level lowers that ceiling, so the sweep naturally stops once the next level can't fit. The protective limit is then padded with a slippage cushion (so the IOC still crosses if the book ticks up before it lands), aligned UP to the tick grid, capped a tick below one collateral; the quantity is re-fit to the stake at the padded price and snapped DOWN to a whole lot, so the escrow can never exceed the stake. Returns `null` when nothing is fillable — empty book, a stake too small to buy a single lot (or the pool's `minQuantity`), or degenerate grid params (`tickSize`/`lotSize`/`oneCollateral`/`stake` ≤ 0). **Details** - `book`: The live four-sided book (NO sides pre-inverted). - `side`: "BUY_YES" (Up) or "BUY_NO" (Down). - `stake`: Collateral budget, raw units. - `oneCollateral`: `10^quoteDecimals` — one whole outcome share. - `params`: The pool's tick/lot grid + slippage policy. ## Parameters ### book [`BinaryOrderBook`](../interfaces/BinaryOrderBook.md) ### side [`BinaryBuySide`](../type-aliases/BinaryBuySide.md) ### stake `bigint` ### oneCollateral `bigint` ### params [`BinaryCrossingParams`](../interfaces/BinaryCrossingParams.md) ## Returns [`BinaryStakeQuote`](../interfaces/BinaryStakeQuote.md) \| `null` --- # /docs/typescript/api/index/functions/rayMul [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / rayMul # Function: rayMul() > **rayMul**(`a`, `b`): `bigint` Defined in: packages/sdk/src/lend/math.ts:20 Ray-multiply two ray fixed-point numbers, rounding half-up (Aave WadRayMath.rayMul). ## Parameters ### a `bigint` ### b `bigint` ## Returns `bigint` --- # /docs/typescript/api/index/functions/realizedFundingPerBase [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / realizedFundingPerBase # Function: realizedFundingPerBase() > **realizedFundingPerBase**(`cumulativeStart`, `cumulativeEnd`): `bigint` Defined in: packages/sdk/src/funding.ts:162 Realized funding over a range, in raw quote units per WHOLE base unit. Takes the two cumulative-index samples rather than a rate, because the cumulative index is the ground truth for accrual: the difference is exact over any range, with no interpolation, no zero-fill reasoning and no cap arithmetic. A rate-based estimate is not equivalent — it cannot see forgiven intervals or index-price movement. The result is in RAW quote units (atoms). To show it as a token amount, divide by `10 ** quoteDecimals` — and note the collateral is 18dp on the live deployment, so a human figure is `(end - start) / 1e18 / 1e18`. Treating the returned value as whole tokens overstates it by the quote scale. Signed: positive means longs paid shorts over the range. ## Parameters ### cumulativeStart `bigint` ### cumulativeEnd `bigint` ## Returns `bigint` --- # /docs/typescript/api/index/functions/resolveIntervalSec [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / resolveIntervalSec # Function: resolveIntervalSec() > **resolveIntervalSec**(`m`): `number` \| `null` Defined in: packages/sdk/src/interval.ts:46 Resolve a binary market's series cadence in SECONDS: prefer the indexer-derived `intervalSec`, else fall back to `expiry − tradingStart`. Returns `null` when neither yields a positive number (SPOT/PERP rows, or a market missing both signals). ## Parameters ### m [`IntervalSource`](../type-aliases/IntervalSource.md) ## Returns `number` \| `null` --- # /docs/typescript/api/index/functions/roundPriceToTick [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / roundPriceToTick # Function: roundPriceToTick() > **roundPriceToTick**(`price`, `tickSize`, `direction`): `bigint` Defined in: packages/sdk/src/units.ts:728 Snap a raw price onto the venue's `tickSize`, refusing to produce a price the pool rejects outright. [snapRawToGrid](snapRawToGrid.md) with the zero guard a price needs and a quantity must not have. **Details** The pool checks `price != 0` before it checks tick alignment, so a price under one tick that floors to `0` reverts `InvalidPrice` — and reverts it for a reason the caller did not choose. A positive price below one tick therefore comes back as one whole tick, the nearest price that exists on the grid. A non-positive price is a caller mistake rather than a rounding question, so it throws instead of being nudged onto the grid. `direction` belongs to the value: a resting limit rounds toward the caller, a crossing limit rounds away so it still sweeps. See [snapRawToGrid](snapRawToGrid.md). ## Parameters ### price `bigint` ### tickSize `bigint` ### direction [`RawGridDirection`](../type-aliases/RawGridDirection.md) ## Returns `bigint` ## Example **Align a resting buy limit that may sit below one tick** ```ts import { roundPriceToTick } from "@somnia-chain/markets-sdk"; const tickSize = 1_000_000_000_000_000n; // 1e15, an 18-decimal venue roundPriceToTick(2_500_000_000_000_000n, tickSize, "down"); // 2e15, floored roundPriceToTick(2_500_000_000_000_000n, tickSize, "up"); // 3e15, ceiled roundPriceToTick(400_000_000_000_000n, tickSize, "down"); // 1e15, never 0n ``` ## Throws when `tickSize` or `price` is not positive. --- # /docs/typescript/api/index/functions/sideOfKind [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / sideOfKind # Function: sideOfKind() > **sideOfKind**(`kind`): [`BinarySide`](../type-aliases/BinarySide.md) Defined in: packages/sdk/src/store.ts:376 Map an on-chain `OrderKind` index (from `BinaryOrderPlaced.kind`) to a [BinarySide](../type-aliases/BinarySide.md). Replaces the v1 `(isBid, userData)` decode — the pool now states the kind explicitly, so the SDK/indexer join the `BinaryOrderPlaced` event (by orderId) instead of inferring the side from userData. ## Parameters ### kind `number` \| `bigint` ## Returns [`BinarySide`](../type-aliases/BinarySide.md) --- # /docs/typescript/api/index/functions/slippageForCrossing [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / slippageForCrossing # Function: slippageForCrossing() > **slippageForCrossing**(`price`, `tickSize`, `opts?`): `bigint` Defined in: packages/sdk/src/derivedReads.ts:828 Slippage cushion for a crossing `price` (raw, same units): the larger of the bps fraction and the fixed tick floor. A market IOC only crosses at or better than its protective limit, so pinning that limit to the exact crossing price means any tick of book churn between the quote and on-chain execution leaves it uncrossable — the order fills nothing. The cushion only widens how far the sweep will chase a moving book; fills still land at each resting level's own price. ## Parameters ### price `bigint` ### tickSize `bigint` ### opts? `Pick`\<[`BinaryCrossingParams`](../interfaces/BinaryCrossingParams.md), `"slippageBps"` \| `"slippageMinTicks"`\> ## Returns `bigint` --- # /docs/typescript/api/index/functions/snapIntervalSec [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / snapIntervalSec # Function: snapIntervalSec() > **snapIntervalSec**(`sec`, `toleranceSec?`): `number` Defined in: packages/sdk/src/interval.ts:70 Snap a raw cadence (seconds) to its nearest natural unit — minute (< 1h), hour (< 1d), else day — but ONLY when the raw value sits within `toleranceSec` of that unit, i.e. it is genuine off-by-a-second jitter (899 → 900, 3601 → 3600, 86399 → 86400). A value further than the tolerance from any unit is a real partial / non-standard window and is returned UNCHANGED, never bucketed up: `840 → 840` ("14m"), `870 → 870` ("14m30s" is not clean, so → "870s"), `5400 → 5400` ("90m"), `86100 → 86100` (23h55m, NOT "24h"). Because a series-registered market carries an EXACT on-chain `intervalSec`, the snap is a no-op on real cadences; the tolerance only matters on the `expiry − tradingStart` fallback path. Non-positive → 0. ## Parameters ### sec `number` ### toleranceSec? `number` = `2` ## Returns `number` --- # /docs/typescript/api/index/functions/snapRawToGrid [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / snapRawToGrid # Function: snapRawToGrid() > **snapRawToGrid**(`raw`, `step`, `direction`): `bigint` Defined in: packages/sdk/src/units.ts:680 Snap a raw on-chain value onto a raw-units grid — a venue's `tickSize` for a price, or its `lotSize` for a quantity. Both come from the pool's `getOrderBookParameters`. Returns the aligned raw value. **When to use** Reach for this on the engine path, where a caller holds `bigint` price and quantity and calls `Trader.placeOrder` directly. The unified facade snaps for you — `exchange.createOrder` aligns price and quantity before it signs — so a facade caller does not need this. The pool rejects anything off the grid: an off-tick price reverts `InvalidPrice`, an off-lot quantity reverts `InvalidQuantity`. **Details** `direction` belongs to the VALUE, not to the order side. Rounding the wrong way is a real loss rather than a formatting choice, and the side does not determine it: a RESTING buy limit rounds down to stay at or below the price the caller accepted, while a CROSSING buy limit rounds up so it still sweeps every level it was computed to reach. Both ship today, so a `side` parameter would silently invert one of them. Pass the direction you mean. **Gotchas** Rounding DOWN can return `0`, and for a PRICE that is the one value the pool always rejects (`InvalidPrice`). This helper does not hide that: a shared kernel that floored a price to one tick and a quantity to zero would be keying its behaviour on which of the two it was handed, which is exactly the guess this signature exists to avoid. Use [roundPriceToTick](roundPriceToTick.md) for a price, which refuses to produce `0`. For a quantity, `0` is the honest answer — the caller has no size left and must branch rather than submit dust. This aligns to the grid and nothing else. It does not check `minQuantity`, which the pool tests BEFORE lot alignment and reverts as `QuantityBelowMinimum`. On every venue this repository deploys `tickSize == lotSize == minQuantity`, so alignment satisfies the minimum there; on an external spot or perp book the two can differ, and a caller sizing against a minimum wants [ceilRawAmount](ceilRawAmount.md). ## Parameters ### raw `bigint` ### step `bigint` ### direction [`RawGridDirection`](../type-aliases/RawGridDirection.md) ## Returns `bigint` ## Example **Align a computed price and quantity before placing an order** ```ts const trader = client.createTrader({ privateKey }); // `tickSize` and `lotSize` are the pool's own increments. const { tickSize, lotSize } = await client.getBinaryBookParams(pool); // A crossing buy rounds the limit UP so it still sweeps every level. const price = snapRawToGrid(rawPrice, tickSize, "up"); // Size rounds DOWN so it never exceeds what the caller has. const quantity = snapRawToGrid(rawQuantity, lotSize, "down"); // A quantity that floors to nothing is a real answer — branch, don't submit. if (quantity > 0n) { await trader.placeOrder({ pool, side: "BUY_YES", price, quantity }); } ``` ## Throws when `step` is not positive. --- # /docs/typescript/api/index/functions/snapToCadence [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / snapToCadence # Function: snapToCadence() > **snapToCadence**(`sec`): `number` Defined in: packages/sdk/src/interval.ts:138 Snap a raw cadence (seconds) to the [CADENCE\_LADDER\_SEC](../variables/CADENCE_LADDER_SEC.md) rung it is within [CADENCE\_TOLERANCE\_SEC](../variables/CADENCE_TOLERANCE_SEC.md) of — `898 → 900`, `59 → 60`, `3599 → 3600` — so scheduling jitter groups and filters as the cadence it is. A window that matches no rung falls through to [snapIntervalSec](snapIntervalSec.md), which keeps a genuinely different window out of a cadence it isn't (`3163 → 3163`, `1437 → 1437`) but still applies its own ±2s unit snap, so an off-ladder cadence lands on a clean unit rather than on itself: `598 → 600` ("10m"). Non-positive → 0. ## Parameters ### sec `number` ## Returns `number` --- # /docs/typescript/api/index/functions/syncStatusKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / syncStatusKey # Function: syncStatusKey() > **syncStatusKey**(`chainId`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:286 Key for `client.getSyncStatus(chainId)`. ## Parameters ### chainId `number` ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/toHuman [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / toHuman # Function: toHuman() > **toHuman**(`raw`, `decimals?`): `number` Defined in: packages/sdk/src/units.ts:23 Raw integer (string or bigint) → human number for DISPLAY ONLY. Lossy past ~15 significant digits (it's an IEEE double) — never round-trip money through this; use it for labels/charts. `decimals` defaults to the demo's 6 (tUSDC), but pass the market's real `quoteDecimals`/`baseDecimals` when you have them. ## Parameters ### raw `string` \| `bigint` ### decimals? `number` = `Store.DECIMALS` ## Returns `number` --- # /docs/typescript/api/index/functions/toHumanString [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / toHumanString # Function: toHumanString() > **toHumanString**(`raw`, `decimals?`): `string` Defined in: packages/sdk/src/units.ts:33 Raw integer → exact human STRING (no precision loss). For display where you want the full value, or to feed another decimal library. ## Parameters ### raw `string` \| `bigint` ### decimals? `number` = `Store.DECIMALS` ## Returns `string` --- # /docs/typescript/api/index/functions/tradeContextKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / tradeContextKey # Function: tradeContextKey() > **tradeContextKey**(`id`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:156 Key for `client.getTradeContext(id)`. A fill id is `${blockNumber}_${logIndex}` — already unique and already lower-case, so it is used verbatim rather than case-folded like an address. ## Parameters ### id `string` \| `null` \| `undefined` ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/transactionActivityKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / transactionActivityKey # Function: transactionActivityKey() > **transactionActivityKey**(`txHash`, `opts?`): [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) Defined in: packages/sdk/src/queryKeys.ts:168 Key for `client.getTransactionActivity(txHash, opts)`. The hash is case-folded: a caller that pastes a checksummed hash and one that pastes it lower-cased are asking the same question. ## Parameters ### txHash `string` \| `null` \| `undefined` ### opts? [`TransactionActivityOptions`](../type-aliases/TransactionActivityOptions.md) ## Returns [`ClientQueryKey`](../type-aliases/ClientQueryKey.md) --- # /docs/typescript/api/index/functions/upPercent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / upPercent # Function: upPercent() > **upPercent**(`rawYes`, `decimals`): `number` \| `null` Defined in: packages/sdk/src/units.ts:755 The Up probability as a whole-percent integer (e.g. `0.546` → `55`). ## Parameters ### rawYes `string` \| `bigint` \| `null` \| `undefined` ### decimals `number` \| `undefined` ## Returns `number` \| `null` --- # /docs/typescript/api/index/functions/upProbability [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / upProbability # Function: upProbability() > **upProbability**(`rawYes`, `decimals`): `number` \| `null` Defined in: packages/sdk/src/units.ts:744 Market-implied **Up** probability in [0, 1] from a raw YES price, or `null` when the price is missing/unusable. One source for header stats and trade rails so they always agree — pass the book mid, falling back to last price. ## Parameters ### rawYes `string` \| `bigint` \| `null` \| `undefined` ### decimals `number` \| `undefined` ## Returns `number` \| `null` --- # /docs/typescript/api/index/interfaces/AcceptOperatorOwnershipParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AcceptOperatorOwnershipParams # Interface: AcceptOperatorOwnershipParams Defined in: packages/sdk/src/operatorAdmin.ts:172 Params for [OperatorAdmin.acceptOperatorOwnership](OperatorAdmin.md#acceptoperatorownership). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:174 The operator with a pending transfer staged to the caller. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:176 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/AcceptPerpWalletLinkParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AcceptPerpWalletLinkParams # Interface: AcceptPerpWalletLinkParams Defined in: packages/sdk/src/trade.ts:993 Inputs to [Trader.acceptPerpWalletLink](Trader.md#acceptperpwalletlink) — accept a main's standing offer. The signer is the CHILD. From here the child's position-increasing orders can draw on `main`'s wallet. ## Extends - [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md) ## Properties ### registry? > `optional` **registry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:958 The LinkedWalletRegistry. Skips resolution entirely. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`registry`](PerpWalletLinkTarget.md#registry) *** ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:960 MarginBank address — its `getLinkedWalletRegistry()` is read (never cached). #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`marginBank`](PerpWalletLinkTarget.md#marginbank) *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:962 A PerpPool — its `marginBank()` is read (and cached), then the registry. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`pool`](PerpWalletLinkTarget.md#pool) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:968 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`gas`](PerpWalletLinkTarget.md#gas) *** ### main > **main**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:995 The main whose offer to accept. It must have an offer standing for the signer. --- # /docs/typescript/api/index/interfaces/AccountHealth [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AccountHealth # Interface: AccountHealth Defined in: packages/sdk/src/perp/margin.ts:103 An account's cross-margin health, standalone (equity vs the IM/MM/CM requirements + the derived status). A lighter read than [SomniaMarketsClient.getMarginAccount](SomniaMarketsClient.md#getmarginaccount) when only health matters. ## Properties ### equity > **equity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:105 Account equity = unlockedCollateralBalance + Σ(uPnl) − Σ(fundingOwed) (signed). *** ### imReq > **imReq**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:110 Initial-margin requirement: Σ notional × initialMarginBps / 10000 across all markets (raw collateral units). *** ### mmReq > **mmReq**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:112 Maintenance-margin requirement (same basis, maintenanceMarginBps; raw). *** ### cmReq > **cmReq**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:114 Close-out-margin requirement (same basis, closeOutMarginBps; raw). *** ### marginStatus > **marginStatus**: [`MarginStatus`](../type-aliases/MarginStatus.md) Defined in: packages/sdk/src/perp/margin.ts:116 Health bucket derived from equity vs the requirements (see [MarginStatus](../type-aliases/MarginStatus.md)). --- # /docs/typescript/api/index/interfaces/AdoptFromParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AdoptFromParams # Interface: AdoptFromParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:227 Params for [MarketCreatorAdmin.adoptFrom](MarketCreatorAdmin.md#adoptfrom). ## Properties ### successor > **successor**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:232 The INCOMING (v2) creator that adopts. Caller must be its owner; it must share `old`'s operator/venue/owner and have its reactivity gas params set. *** ### old > **old**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:234 The quiesced predecessor whose series + pending qid routing are inherited. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:236 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/AmendOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AmendOrderParams # Interface: AmendOrderParams Defined in: packages/sdk/src/trade.ts:852 Inputs to [Trader.amendOrder](Trader.md#amendorder) — cancel ONE resting order and place its replacement atomically, with no gap on the book. **Gotchas** — the replacement loses queue priority (it re-enters at the back of the price-time queue for its price); use [Trader.reduceOrder](Trader.md#reduceorder) to shrink an order in place instead. The call is NON-PAYABLE: the cancel leg delivers the old order's freed native to the WALLET, which the non-payable place leg cannot reach, so a native auto-pull amend reverts — fund native replacements from a manual-vault balance. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:854 SpotPool or PerpPool address. NOT a BinaryPool — see [Trader.amendOrder](Trader.md#amendorder). *** ### oldOrderId > **oldOrderId**: `string` \| `bigint` Defined in: packages/sdk/src/trade.ts:856 The resting order being replaced (decimal string or bigint). *** ### alwaysPlace? > `optional` **alwaysPlace?**: `boolean` Defined in: packages/sdk/src/trade.ts:863 How to handle an `oldOrderId` already filled/cancelled when the tx lands. False (default) reverts `AmendOldOrderGone`; true skips the cancel leg and places the replacement anyway (opt-in upsert). It never tolerates an ownership failure — someone else's live order still reverts `IncorrectSender`. *** ### newOrder > **newOrder**: [`BatchOrderRequest`](BatchOrderRequest.md) Defined in: packages/sdk/src/trade.ts:865 The replacement order. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:871 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/AmendOrderResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AmendOrderResult # Interface: AmendOrderResult Defined in: packages/sdk/src/trade.ts:879 Result of a single amend — the id of the replacement order. ## Extends - [`TxResult`](TxResult.md) ## Properties ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) *** ### newOrderId > **newOrderId**: `bigint` Defined in: packages/sdk/src/trade.ts:890 The replacement's NEW order id — update local tracking, the old id is gone. Reconstructed from the `OrderPlaced` log, since the pool's `uint128` return is not readable from a receipt. `0n` means the id could not be reconstructed (no `OrderPlaced` in the receipt). It does NOT mean the replacement failed: a single amend reverts outright when its replacement does not rest or fill, so a successful tx always carries one. *** ### fills > **fills**: [`OrderFill`](OrderFill.md)[] Defined in: packages/sdk/src/trade.ts:892 Fills executed by the replacement order. --- # /docs/typescript/api/index/interfaces/AmendOrdersParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AmendOrdersParams # Interface: AmendOrdersParams Defined in: packages/sdk/src/trade.ts:791 Inputs to [Trader.amendOrders](Trader.md#amendorders) — cancel N orders and place their replacements atomically. The replacement loses queue priority; use `reduceOrder` to shrink one in place without re-queueing. **Gotchas** — ALL-OR-NOTHING: the first replacement the book will not honour reverts everything with `AmendReplacementRejected(requestIndex, reason)`. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:793 SpotPool or PerpPool address. NOT a BinaryPool. *** ### amendments > **amendments**: `object`[] Defined in: packages/sdk/src/trade.ts:795 The amendments to apply, in array order. Must be non-empty. #### oldOrderId > **oldOrderId**: `string` \| `bigint` The resting order being replaced (decimal string or bigint). #### alwaysPlace? > `optional` **alwaysPlace?**: `boolean` How to handle an `oldOrderId` already filled/cancelled when the tx lands. False (default) reverts `AmendOldOrderGone`; true skips the cancel leg and places the replacement anyway (opt-in upsert). It never tolerates an ownership failure — someone else's live order still reverts. #### newOrder > **newOrder**: [`BatchOrderRequest`](BatchOrderRequest.md) The replacement order. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:813 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/AmendOrdersResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AmendOrdersResult # Interface: AmendOrdersResult Defined in: packages/sdk/src/trade.ts:821 Result of a batch amend — the ids of the replacement orders. ## Extends - [`TxResult`](TxResult.md) ## Properties ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) *** ### newOrderIds > **newOrderIds**: `bigint`[] Defined in: packages/sdk/src/trade.ts:834 New order ids, index-aligned with the submitted `amendments`. Reconstructed from `OrderPlaced` logs, since the pool's `uint128[]` return is not readable from a receipt. `0n` means the id could not be reconstructed — the receipt carried fewer `OrderPlaced` events than there were amendments. It does **not** mean the replacement failed to rest: `OrderPlaced` fires for every accepted order, including one that fills completely and never reaches the book (`OrderRested` is the rest-only event). Amend is all-or-nothing, so in a successful tx every slot is populated. *** ### fills > **fills**: [`OrderFill`](OrderFill.md)[] Defined in: packages/sdk/src/trade.ts:836 Fills executed by the replacement orders. --- # /docs/typescript/api/index/interfaces/ApproveBuilderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ApproveBuilderParams # Interface: ApproveBuilderParams Defined in: packages/sdk/src/trade.ts:252 Opt a routing/builder frontend in to charge up to `maxFeeBpsTimes1k` (pool bps×1000 unit) per order the trader submits with that builder code. Set 0 to revoke. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:254 Pool address (binary, spot, or perp). The approval is per-pool. *** ### builder > **builder**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:256 Builder/routing frontend address. *** ### maxFeeBpsTimes1k > **maxFeeBpsTimes1k**: `bigint` Defined in: packages/sdk/src/trade.ts:258 Max per-order builder fee to allow (pool bps×1000). 0 revokes. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:264 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ArmFirstRollParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ArmFirstRollParams # Interface: ArmFirstRollParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:192 Params for [MarketCreatorAdmin.armFirstRoll](MarketCreatorAdmin.md#armfirstroll). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:194 The MarketCreator owning the series. Caller must be its owner. *** ### seriesId > **seriesId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:199 The series whose first roll is armed; refuses re-arming or an already-rolled series. *** ### firesAtSec > **firesAtSec**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:205 Future, interval-aligned Unix-seconds boundary to arm the series' first roll at (typically the outgoing creator's current-market expiry for a seamless migration). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:207 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/AutoPullRequirement [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / AutoPullRequirement # Interface: AutoPullRequirement Defined in: packages/sdk/src/spot/poolReads.ts:43 What a pool would consume for an order — see [SomniaMarketsClient.getAutoPullRequirement](SomniaMarketsClient.md#getautopullrequirement). ## Properties ### inputToken > **inputToken**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/poolReads.ts:45 Token the pool would take: quote on a buy, base on a sell. *** ### requiredAmount > **requiredAmount**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:47 WORST-CASE amount of `inputToken` the order could consume. *** ### delta > **delta**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:52 `requiredAmount` minus the owner's current vault balance of `inputToken`, or 0 when the vault already covers it. --- # /docs/typescript/api/index/interfaces/BalanceQuery [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BalanceQuery # Interface: BalanceQuery Defined in: packages/sdk/src/balances.ts:88 A token to read a balance for in a `getBalances` batch. Omit `id` for a plain ERC-20 (`balanceOf(account)`); provide `id` to read an ERC-6909 outcome position (`balanceOf(account, id)`) on the outcome-token singleton `token`. ## Properties ### token > **token**: `` `0x${string}` `` Defined in: packages/sdk/src/balances.ts:90 ERC-20 token, or the ERC-6909 outcome-token singleton when `id` is set. *** ### id? > `optional` **id?**: `bigint` Defined in: packages/sdk/src/balances.ts:92 ERC-6909 position id (`yesId`/`noId`). Absent → read `token` as a plain ERC-20. --- # /docs/typescript/api/index/interfaces/BatchCancelOutcome [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BatchCancelOutcome # Interface: BatchCancelOutcome Defined in: packages/sdk/src/trade.ts:633 One id's outcome in a [Trader.cancelOrders](Trader.md#cancelorders) batch. ## Properties ### orderId > **orderId**: `bigint` Defined in: packages/sdk/src/trade.ts:635 The order id this entry reports on. *** ### cancelled > **cancelled**: `boolean` Defined in: packages/sdk/src/trade.ts:642 True when this id was cancelled in this transaction. False means the contract SKIPPED it — already filled, already cancelled, expired-and-swept, or not owned by the signer. A skip is inferred from the absence of an event, so it does NOT distinguish a benign race from a caller-side mistake. --- # /docs/typescript/api/index/interfaces/BatchOrderRequest [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BatchOrderRequest # Interface: BatchOrderRequest Defined in: packages/sdk/src/trade.ts:760 The replacement order in an amendment. Mirrors the pool's `PlaceOrderRequest` struct; the owner is the amend caller, not a per-request field. ## Properties ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:762 True = buy/bid, false = sell/ask. *** ### price > **price**: `bigint` Defined in: packages/sdk/src/trade.ts:764 Limit price, raw quote units per whole base. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:766 Base quantity, raw base units. *** ### expireTimestampNs? > `optional` **expireTimestampNs?**: `bigint` Defined in: packages/sdk/src/trade.ts:768 Order expiry in ns. Defaults to ~50y (GTC). *** ### orderType? > `optional` **orderType?**: `number` Defined in: packages/sdk/src/trade.ts:770 0 limit (default), 1 FillOrKill, 2 market/IOC, 3 PostOnly. See [ORDER\_TYPE](../variables/ORDER_TYPE.md). *** ### selfMatchingOption? > `optional` **selfMatchingOption?**: `number` Defined in: packages/sdk/src/trade.ts:772 Self-match behaviour, default 0. See [SELF\_MATCHING\_OPTION](../variables/SELF_MATCHING_OPTION.md). *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:774 Routing/builder address to attribute this order to; omit for none. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/trade.ts:776 Per-order builder fee in the pool's bps×1000 unit. 0 = none. *** ### userData? > `optional` **userData?**: `bigint` Defined in: packages/sdk/src/trade.ts:778 Opaque market-maker bookkeeping tag, forwarded verbatim. Default 0. --- # /docs/typescript/api/index/interfaces/BatchPlaceOutcome [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BatchPlaceOutcome # Interface: BatchPlaceOutcome Defined in: packages/sdk/src/trade.ts:582 One request's outcome in a [Trader.placeSpotOrders](Trader.md#placespotorders) batch. ## Properties ### success > **success**: `boolean` Defined in: packages/sdk/src/trade.ts:588 True when this request produced an order. False for a benign non-placement — a PostOnly that would have crossed, an unfilled FillOrKill, an IOC that found no liquidity, an already-expired expiry, or a CancelTaker self-match. *** ### orderId? > `optional` **orderId?**: `bigint` Defined in: packages/sdk/src/trade.ts:590 The resting order's id, or `undefined` when `success` is false. --- # /docs/typescript/api/index/interfaces/BinaryBookParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryBookParams # Interface: BinaryBookParams Defined in: packages/sdk/src/orders.ts:522 A binary pool's order-book increments, as the pool reports them. ## Properties ### tickSize > **tickSize**: `bigint` Defined in: packages/sdk/src/orders.ts:524 Price increment, raw collateral units per whole outcome token. *** ### minQuantity > **minQuantity**: `bigint` Defined in: packages/sdk/src/orders.ts:526 Minimum order quantity, raw outcome-token units. *** ### lotSize > **lotSize**: `bigint` Defined in: packages/sdk/src/orders.ts:528 Quantity increment, raw outcome-token units. --- # /docs/typescript/api/index/interfaces/BinaryCrossingParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryCrossingParams # Interface: BinaryCrossingParams Defined in: packages/sdk/src/derivedReads.ts:793 The price/quantity grid a BinaryPool enforces on orders, plus the slippage policy the stake/sell builders pad their protective limit with. `tickSize` and `lotSize` come from the pool's on-chain order-book parameters (`client.getBinaryBookParams`) — the pool rejects any price off the tick grid and any quantity off the lot grid (`InvalidQuantity`). ## Properties ### tickSize > **tickSize**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:795 Price increment (raw collateral units) — limits must be a multiple. *** ### lotSize > **lotSize**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:797 Quantity increment (raw outcome-token units) — sizes must be a multiple. *** ### minQuantity? > `optional` **minQuantity?**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:804 Smallest order size the pool accepts (raw outcome-token units) — a lot multiple that may exceed a single lot; the pool rejects anything smaller (`QuantityBelowMinimum`). Quotes that land below it return `null`. #### Default `0n` (no floor beyond the lot grid) *** ### slippageBps? > `optional` **slippageBps?**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:809 Slippage cushion in bps of the crossing price. #### Default [DEFAULT\_SLIPPAGE\_BPS](../variables/DEFAULT_SLIPPAGE_BPS.md) (300 = 3%) *** ### slippageMinTicks? > `optional` **slippageMinTicks?**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:814 Minimum slippage cushion in ticks. #### Default [DEFAULT\_SLIPPAGE\_MIN\_TICKS](../variables/DEFAULT_SLIPPAGE_MIN_TICKS.md) (10) --- # /docs/typescript/api/index/interfaces/BinaryOrderBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryOrderBook # Interface: BinaryOrderBook Defined in: packages/sdk/src/orders.ts:486 Both books for a market, 4-sided. NO levels are the YES book inverted into NO terms (price = 1 − yesPrice), matching BinaryPool's pricing. ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/orders.ts:488 Pinned chain block or scope applied-event watermark; absent without provenance. *** ### yesBids > **yesBids**: [`BookLevel`](BookLevel.md)[] Defined in: packages/sdk/src/orders.ts:493 Resting YES bids, best (highest price) first — raw collateral units per whole outcome token. *** ### yesAsks > **yesAsks**: [`BookLevel`](BookLevel.md)[] Defined in: packages/sdk/src/orders.ts:495 Resting YES asks, best (lowest price) first. *** ### noBids > **noBids**: [`BookLevel`](BookLevel.md)[] Defined in: packages/sdk/src/orders.ts:497 NO bids derived from the YES asks (price = 1 − yesPrice), best (highest) first. *** ### noAsks > **noAsks**: [`BookLevel`](BookLevel.md)[] Defined in: packages/sdk/src/orders.ts:499 NO asks derived from the YES bids (price = 1 − yesPrice), best (lowest) first. --- # /docs/typescript/api/index/interfaces/BinaryOrderQuote [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryOrderQuote # Interface: BinaryOrderQuote Defined in: packages/sdk/src/derivedReads.ts:34 The result of quoting a market order against the live book — the "you'll pay ~$X, average Y, slippage Z" preview. All prices/amounts are RAW units in the OUTCOME's own terms (a BUY_NO quote is priced in NO terms). ## Properties ### avgPrice > **avgPrice**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:39 Volume-weighted average fill price (raw units per whole outcome token), in the quoted outcome's terms. `0n` if nothing fills. *** ### cost > **cost**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:44 Total cost for a BUY (raw collateral paid) / total proceeds for a SELL (raw collateral received) = Σ(levelQty × levelPrice) / oneCollateral. *** ### filledQuantity > **filledQuantity**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:49 How much of `quantity` actually crosses the resting book (raw outcome units). Less than `quantity` when the book is too thin to fill it all. *** ### wouldRest > **wouldRest**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:54 The unfilled remainder that would rest as a maker order (raw outcome units) — `quantity − filledQuantity`. *** ### levelsConsumed > **levelsConsumed**: `number` Defined in: packages/sdk/src/derivedReads.ts:56 Number of price levels the order consumed (partially or fully). *** ### slippageVsMid > **slippageVsMid**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:62 Signed slippage of `avgPrice` vs the book mid, in raw price units (avgPrice − mid for a buy; mid − avgPrice for a sell — positive = worse than mid). `0n` if the book has no mid (a side is empty) or nothing fills. --- # /docs/typescript/api/index/interfaces/BinaryOutcomePnl [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryOutcomePnl # Interface: BinaryOutcomePnl Defined in: packages/sdk/src/units.ts:245 One outcome leg's slice of a [BinaryPnl](BinaryPnl.md). HUMAN numbers (quote/collateral units) throughout — display-grade, like [toHuman](../functions/toHuman.md). ## Properties ### realized > **realized**: `number` Defined in: packages/sdk/src/units.ts:247 Realized on this outcome's sells: proceeds − avg cost of the tokens sold. *** ### unrealized > **unrealized**: `number` \| `null` Defined in: packages/sdk/src/units.ts:249 The remaining balance marked to `mark`, minus its avg cost. `null` when [mark](#mark) is unknown. *** ### avgCost > **avgCost**: `number` Defined in: packages/sdk/src/units.ts:251 Average cost per token of the fills-derived holding; 0 when none held. *** ### mark > **mark**: `number` \| `null` Defined in: packages/sdk/src/units.ts:265 The price this leg is valued at: the book-clamped last while trading (see [markYesPrice](../functions/markYesPrice.md); the NO leg at its complement), or the settlement payout once resolved — 1 for the winning outcome, 0 for the loser, and on a void this leg's share of the market's stored payout vector (a half under the `UNIFORM` void policy, `[p, D−p]` on a captured `CLOB_SNAPSHOT` void). `null` when the market has NO price to value against — it has never traded and no book top was supplied. Do not read that as `0`: a zero YES mark is also a full-value NO mark, which reports a fabricated total loss on one leg and a fabricated total gain on the other. [value](#value) and [unrealized](#unrealized) are `null` with it. *** ### value > **value**: `number` \| `null` Defined in: packages/sdk/src/units.ts:267 Mark value of the current balance: `balance × mark`. `null` when [mark](#mark) is unknown. --- # /docs/typescript/api/index/interfaces/BinaryOutcomePositionPnL [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryOutcomePositionPnL # Interface: BinaryOutcomePositionPnL Defined in: packages/sdk/src/derivedReads.ts:249 One outcome's half of a binary position, RAW units — the YES or NO book on its own, as the fold already computes it before summing into the market totals. **Why this exists.** Every money field on [BinaryPositionPnL](BinaryPositionPnL.md) is blended across both outcomes, which is unusable for a wallet holding BOTH. Buy 10 YES at `0.20` and 10 NO at `0.80`, mark YES at `0.40`: the legs are `+2.00` and `-2.00` and the blended `unrealizedPnl` is `0.00`. Neither position row can show that zero as its own PnL. Legs are only reachable through a position row, so the key that names one (`yes` / `no`) is also the only label it needs. Legs sum EXACTLY to the totals — `costBasis`, `markValue`, `unrealizedPnl` and `realizedPnl` are stored here first and added up, so integer division cannot make a leg disagree with the total it belongs to. `avgCost` and `markPrice` are per-token rates and do NOT sum. ## Properties ### balance > **balance**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:251 This outcome's current token balance (raw). *** ### costBasis > **costBasis**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:253 Remaining cost basis of THIS leg's balance (raw collateral). *** ### avgCost > **avgCost**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:265 Fills-derived average cost per whole token of this outcome (raw collateral per token) — the rate used to value `balance`. `0n` when the leg holds nothing. A rate, not an amount: does not sum across legs. NOT derivable from the other two. `costBasis` is `balance * avgCost / oneCollateral`, and that division is lossy: recomputing `costBasis * oneCollateral / balance` returns a different number in ~2999 of 3000 awkward-quantity cases. It is published because a consumer cannot get it back. *** ### markPrice > **markPrice**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:279 The price this leg is marked at (raw collateral per whole token): the book-clamped last price while trading, or the settlement payout once resolved. A rate: does not sum, but while trading the two legs' prices add up to one whole collateral unit. `null` when the market has NO price to mark against — it has never traded and no book top was supplied, so [markYesPrice](../functions/markYesPrice.md) returns `null`. Do not read that as `0n`: a zero YES mark is also a FULL-collateral NO mark, which reports a fabricated total loss on one leg and a fabricated total gain on the other. [markValue](#markvalue) and [unrealizedPnl](#unrealizedpnl) are `null` with it, because both are derived from this price. *** ### markValue > **markValue**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:281 Mark value of this leg's balance (raw collateral); `null` when [markPrice](#markprice) is unknown. *** ### unrealizedPnl > **unrealizedPnl**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:283 This leg's `markValue - costBasis` (raw, signed); `null` when [markPrice](#markprice) is unknown. *** ### realizedPnl > **realizedPnl**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:285 Realized PnL from this outcome's sells (raw, signed). --- # /docs/typescript/api/index/interfaces/BinaryPnl [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryPnl # Interface: BinaryPnl Defined in: packages/sdk/src/units.ts:278 Realized + unrealized PnL for one account in one binary market, computed purely from its fills + current outcome balances + the market row. Returns HUMAN numbers (quote/collateral units), keyed per outcome (YES/NO) plus a combined total — display-grade, like [toHuman](../functions/toHuman.md). ## Properties ### yes > **yes**: [`BinaryOutcomePnl`](BinaryOutcomePnl.md) Defined in: packages/sdk/src/units.ts:280 PnL attributable to the YES outcome (human quote units). *** ### no > **no**: [`BinaryOutcomePnl`](BinaryOutcomePnl.md) Defined in: packages/sdk/src/units.ts:282 PnL attributable to the NO outcome (human quote units). *** ### realized > **realized**: `number` Defined in: packages/sdk/src/units.ts:284 yes.realized + no.realized. *** ### unrealized > **unrealized**: `number` \| `null` Defined in: packages/sdk/src/units.ts:286 yes.unrealized + no.unrealized; `null` when the market has no price to mark against. *** ### total > **total**: `number` \| `null` Defined in: packages/sdk/src/units.ts:288 realized + unrealized; `null` when the market has no price to mark against. --- # /docs/typescript/api/index/interfaces/BinaryPnlFill [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryPnlFill # Interface: BinaryPnlFill Defined in: packages/sdk/src/units.ts:297 One account-perspective fill for [computeBinaryPnl](../functions/computeBinaryPnl.md): which outcome, how many tokens, at what raw YES-terms price, and whether the account BOUGHT. ## Properties ### outcomeIndex > **outcomeIndex**: `number` Defined in: packages/sdk/src/units.ts:299 0 = YES, 1 = NO. *** ### isBuy > **isBuy**: `boolean` Defined in: packages/sdk/src/units.ts:301 True = the account bought (added) this outcome; false = sold (reduced). *** ### quantity > **quantity**: `string` \| `bigint` Defined in: packages/sdk/src/units.ts:303 Fill quantity, raw outcome-token units (decimal string or bigint). *** ### price > **price**: `string` \| `bigint` Defined in: packages/sdk/src/units.ts:305 Fill price for the fill's own outcome, raw quote units (0..10^decimals). --- # /docs/typescript/api/index/interfaces/BinaryPositionPnL [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryPositionPnL # Interface: BinaryPositionPnL Defined in: packages/sdk/src/derivedReads.ts:301 An account's position + cost basis + PnL in one binary market, RAW units. ACCOUNTING ASSUMPTION: weighted-average cost. Cost basis is reconstructed from the account's order-book fills on the market (buys add cost at the fill's outcome price; sells realize against the running average) folded with mint/merge router actions (a complete-set mint adds one YES + one NO at the split cost `oneCollateral` total; a merge removes a pair at avg cost). `markValue`/`unrealizedPnl` mark the CURRENT balances to the book-clamped last price while trading (see [markYesPrice](../functions/markYesPrice.md)), or to the settlement payout once resolved. ## Properties ### balanceYes > **balanceYes**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:303 Current YES outcome-token balance (raw). *** ### balanceNo > **balanceNo**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:305 Current NO outcome-token balance (raw). *** ### costBasis > **costBasis**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:307 Total remaining cost basis across both outcomes (raw collateral). *** ### avgCost > **avgCost**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:312 Blended average cost per whole outcome token held (raw collateral per token). `0n` when nothing is held. *** ### markValue > **markValue**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:318 Mark value of the current balances (raw collateral). `null` when the market has no price to mark against — see [BinaryOutcomePositionPnL.markPrice](BinaryOutcomePositionPnL.md#markprice). *** ### unrealizedPnl > **unrealizedPnl**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:323 markValue − costBasis (raw, signed). `null` when the market has no price to mark against — see [BinaryOutcomePositionPnL.markPrice](BinaryOutcomePositionPnL.md#markprice). *** ### realizedPnl > **realizedPnl**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:328 Realized PnL from sells (proceeds − avg cost of tokens sold), raw signed. Best-effort over indexed order-book sell fills (see accounting note). *** ### outcomes > **outcomes**: `object` Defined in: packages/sdk/src/derivedReads.ts:338 The same position split into its YES and NO books — see [BinaryOutcomePositionPnL](BinaryOutcomePositionPnL.md) for why every field above is unusable to a wallet holding both outcomes. Always present, both legs, even when one holds nothing (a zero-balance leg can still carry `realizedPnl` from earlier sells). Filter on `balance > 0n` to list only open legs. #### yes > **yes**: [`BinaryOutcomePositionPnL`](BinaryOutcomePositionPnL.md) #### no > **no**: [`BinaryOutcomePositionPnL`](BinaryOutcomePositionPnL.md) --- # /docs/typescript/api/index/interfaces/BinarySellQuote [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinarySellQuote # Interface: BinarySellQuote Defined in: packages/sdk/src/derivedReads.ts:996 A market SELL that unwinds an outcome position, shaped to feed straight into `trader.placeOrder({ pool, side, price: yesPrice, quantity, orderType: ORDER_TYPE.MARKET })`. All values RAW units. See [quoteBinaryStakeOverBook](../functions/quoteBinaryStakeOverBook.md) for the family's full mental model. ## Properties ### side > **side**: [`BinarySellSide`](../type-aliases/BinarySellSide.md) Defined in: packages/sdk/src/derivedReads.ts:998 The sell side quoted ("SELL_YES" | "SELL_NO"). *** ### yesPrice > **yesPrice**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:1000 Protective floor in YES terms (raw, tick-aligned) — what `placeOrder` takes. *** ### limitPrice > **limitPrice**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:1005 The same protective floor in the sold outcome's OWN terms (raw) — the cushioned best bid. Display this. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:1007 Outcome-token quantity to sell (raw, lot-aligned) — the size submitted. *** ### fillableQuantity > **fillableQuantity**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:1014 How much of `quantity` the resting bids at or above the floor can absorb (raw, ≤ `quantity`). The IOC cancels the rest unfilled — when this is short of `quantity`, show the user a partial-unwind warning instead of implying the whole position exits. *** ### estProceeds > **estProceeds**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:1020 Collateral proceeds if `fillableQuantity` fills at the resting bids' own prices (raw, rounded down) — an estimate: bids can churn between the quote and execution. --- # /docs/typescript/api/index/interfaces/BinaryStakeQuote [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryStakeQuote # Interface: BinaryStakeQuote Defined in: packages/sdk/src/derivedReads.ts:861 A stake-sized market BUY, shaped to feed straight into `trader.placeOrder({ pool, side, price: yesPrice, quantity, orderType: ORDER_TYPE.MARKET })`. All values RAW units. ## Properties ### side > **side**: [`BinaryBuySide`](../type-aliases/BinaryBuySide.md) Defined in: packages/sdk/src/derivedReads.ts:863 The buy side quoted ("BUY_YES" | "BUY_NO"). *** ### yesPrice > **yesPrice**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:868 Protective limit in YES terms (raw, tick-aligned) — what `placeOrder` takes. The deepest level the sweep touched plus the slippage cushion. *** ### limitPrice > **limitPrice**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:873 The same protective limit in the traded outcome's OWN terms (raw) — equals `yesPrice` for BUY_YES, `oneCollateral − yesPrice` for BUY_NO. Display this. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:878 Outcome-token quantity bought (raw, lot-aligned) — the payout if this side wins. *** ### escrow > **escrow**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:883 Collateral the order escrows (raw) — `quantity × limitPrice`, rounded up. The max loss; never above the stake. --- # /docs/typescript/api/index/interfaces/BinaryVenueParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryVenueParams # Interface: BinaryVenueParams Defined in: packages/sdk/src/operatorReads.ts:64 Plain-bps fee rates for a BINARY_V1 venue (see BinaryMarketsModule.BinaryVenueParams). Each rate is capped at the module's `MAX_FEE_BPS` (currently 1_000 = 10%). ## Properties ### makerFeeBps > **makerFeeBps**: `number` Defined in: packages/sdk/src/operatorReads.ts:66 Pool protocol fee charged on maker-side fills (bps). *** ### takerFeeBps > **takerFeeBps**: `number` Defined in: packages/sdk/src/operatorReads.ts:68 Pool protocol fee charged on taker-side fills (bps). *** ### maxBuilderFeeBps > **maxBuilderFeeBps**: `number` Defined in: packages/sdk/src/operatorReads.ts:70 Per-order builder/routing fee ceiling the pool enforces at placeOrder (bps). *** ### routingFeeBps > **routingFeeBps**: `number` Defined in: packages/sdk/src/operatorReads.ts:75 Advertised default routing fee for frontends routing through this venue (bps); must be <= `maxBuilderFeeBps`. *** ### settlementFeeBps > **settlementFeeBps**: `number` Defined in: packages/sdk/src/operatorReads.ts:82 Fee skimmed from the WINNING payout on redemption of a resolved market (bps; 0 = none). Frozen into each market at creation — a later `updateVenue` only affects markets created afterward. Never charged on voided (capital-refund) redemptions. *** ### voidPolicy? > `optional` **voidPolicy?**: [`VenueVoidPolicy`](../type-aliases/VenueVoidPolicy.md) Defined in: packages/sdk/src/operatorReads.ts:89 Void payout policy for markets created under this venue (v3 field). Omitted ⇒ `UNIFORM`. Like the fee rates it freezes per market at creation (resolved against the provisioned pool's capability — an old pool without the capture surface downgrades a `CLOB_SNAPSHOT` wish to `UNIFORM`). --- # /docs/typescript/api/index/interfaces/BookLevel [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BookLevel # Interface: BookLevel Defined in: packages/sdk/src/store.ts:326 One aggregated price level of a resting book (raw units). ## Properties ### price > **price**: `bigint` Defined in: packages/sdk/src/store.ts:331 Level price — raw quote/collateral units per whole base/outcome token, in the book's native terms (YES terms for binary, quote-per-base for spot). *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/store.ts:333 Total resting size at this price — raw base/outcome units. --- # /docs/typescript/api/index/interfaces/BuilderApprovalRef [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BuilderApprovalRef # Interface: BuilderApprovalRef Defined in: packages/sdk/src/fees.ts:328 Identifies one user's approval of one builder on one pool — the triple both `getBuilderApproval` and `getEffectiveBuilderApproval` key on. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/fees.ts:330 The pool the approval lives on (binary, spot, or perp). *** ### user > **user**: `` `0x${string}` `` Defined in: packages/sdk/src/fees.ts:332 The approving user. *** ### builder > **builder**: `` `0x${string}` `` Defined in: packages/sdk/src/fees.ts:334 The approved builder. --- # /docs/typescript/api/index/interfaces/BurnSetParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BurnSetParams # Interface: BurnSetParams Defined in: packages/sdk/src/trade.ts:1507 Inputs to [Trader.burnSet](Trader.md#burnset) — surrender equal YES + NO, get collateral back. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1509 BinaryPool address — pool burns the caller's YES + NO and refunds collateral. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1511 Outcome amount to burn (same for YES + NO). *** ### outcomeToken? > `optional` **outcomeToken?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1516 Outcome-token singleton; resolved from the pool if omitted. Both YES + NO are covered by a single operator approval on it. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:1518 Ensure the pool is an operator on the outcome-token singleton (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1524 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/CancelExpiredOrdersParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CancelExpiredOrdersParams # Interface: CancelExpiredOrdersParams Defined in: packages/sdk/src/trade.ts:322 Permissionless keeper drain: clean an explicit list of EXPIRED resting orders on a pool, returning each order's locked escrow to its owner. Best-effort — non-expired or stale ids are silently skipped on-chain (no revert). ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:324 BinaryPool (or SpotPool) address whose expired orders to clean. *** ### orderIds > **orderIds**: (`string` \| `bigint`)[] Defined in: packages/sdk/src/trade.ts:326 uint128 OrderIds to attempt to clean (decimal strings or bigints). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:332 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/CancelOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CancelOrderParams # Interface: CancelOrderParams Defined in: packages/sdk/src/trade.ts:273 Inputs to [Trader.cancelOrder](Trader.md#cancelorder) — cancel one resting order, returning its remaining escrow to the owner. Works on spot AND binary pools. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:275 BinaryPool (or SpotPool) address hosting the resting order. *** ### orderId > **orderId**: `string` \| `bigint` Defined in: packages/sdk/src/trade.ts:277 uint128 OrderId (decimal string or bigint). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:283 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/CancelOrdersParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CancelOrdersParams # Interface: CancelOrdersParams Defined in: packages/sdk/src/trade.ts:615 Inputs to [Trader.cancelOrders](Trader.md#cancelorders) — pull several resting orders on ONE pool in a single transaction. Works on spot AND binary pools. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:617 SpotPool (or BinaryPool) address hosting the resting orders. *** ### orderIds > **orderIds**: (`string` \| `bigint`)[] Defined in: packages/sdk/src/trade.ts:619 uint128 OrderIds to cancel (decimal strings or bigints). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:625 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/CancelOrdersResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CancelOrdersResult # Interface: CancelOrdersResult Defined in: packages/sdk/src/trade.ts:650 Result of [Trader.cancelOrders](Trader.md#cancelorders). ## Extends - [`TxResult`](TxResult.md) ## Properties ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) *** ### outcomes > **outcomes**: [`BatchCancelOutcome`](BatchCancelOutcome.md)[] Defined in: packages/sdk/src/trade.ts:652 Per-id outcomes, index-aligned with the `orderIds` input. --- # /docs/typescript/api/index/interfaces/CancelPerpStopOrdersParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CancelPerpStopOrdersParams # Interface: CancelPerpStopOrdersParams Defined in: packages/sdk/src/trade.ts:1467 Inputs to [Trader.cancelPerpStopOrders](Trader.md#cancelperpstoporders) — cancel several of the signer's pending stops in one transaction, refunded in a single transfer. The way to tear down a linked pair: cancelling ONE leg only unlinks the other, which stays armed. Every id must be live and owned by the signer — one bad id reverts the whole batch. ## Properties ### registry > **registry**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1469 The PerpStopOrderRegistry holding the pending orders. *** ### orderIds > **orderIds**: (`string` \| `bigint`)[] Defined in: packages/sdk/src/trade.ts:1471 The pending order ids (decimal strings or bigints). Must be non-empty. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1477 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/CancelPerpWalletLinkProposalParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CancelPerpWalletLinkProposalParams # Interface: CancelPerpWalletLinkProposalParams Defined in: packages/sdk/src/trade.ts:1007 Inputs to [Trader.cancelPerpWalletLinkProposal](Trader.md#cancelperpwalletlinkproposal) — withdraw an offer the signer made and the child has not accepted. The signer is the MAIN. An accepted link is torn down with [Trader.unlinkPerpWallet](Trader.md#unlinkperpwallet) instead. ## Extends - [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md) ## Properties ### registry? > `optional` **registry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:958 The LinkedWalletRegistry. Skips resolution entirely. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`registry`](PerpWalletLinkTarget.md#registry) *** ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:960 MarginBank address — its `getLinkedWalletRegistry()` is read (never cached). #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`marginBank`](PerpWalletLinkTarget.md#marginbank) *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:962 A PerpPool — its `marginBank()` is read (and cached), then the registry. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`pool`](PerpWalletLinkTarget.md#pool) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:968 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`gas`](PerpWalletLinkTarget.md#gas) *** ### child > **child**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1009 The child whose pending offer to withdraw. --- # /docs/typescript/api/index/interfaces/CancelStopOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CancelStopOrderParams # Interface: CancelStopOrderParams Defined in: packages/sdk/src/trade.ts:1301 Inputs to [Trader.cancelStopOrder](Trader.md#cancelstoporder) and [Trader.cancelPerpStopOrder](Trader.md#cancelperpstoporder) — cancel a pending (untriggered) stop order on its registry. Shared by both venues because the cancel takes nothing venue-specific: an id and the registry that issued it. Which registry that is follows from the method you call, so pass the SpotStopOrderRegistry to the spot cancel and the PerpStopOrderRegistry to the perp one — ids are per-registry and mean nothing on the other. ## Properties ### registry > **registry**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1303 The stop-order registry holding the pending order — spot or perp, per the method. *** ### orderId > **orderId**: `string` \| `bigint` Defined in: packages/sdk/src/trade.ts:1305 The pending order's id on the registry (decimal string or bigint). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1311 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/CaptureCloseParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CaptureCloseParams # Interface: CaptureCloseParams Defined in: packages/sdk/src/trade.ts:374 Permissionless closing-price capture on a BinaryPool (capture-generation pools only). Callable by anyone once the market's expiry passes; stores the closing book's bid/ask mid and lifts the closing-book lock, letting post-expiry cancels/sweeps of alive-at-close orders proceed on a not-yet-terminal market. Self-incentivized: whoever wants the book dismantled (a maker reclaiming escrow, a keeper draining toward release) captures first. Reverts `CloseAlreadyCaptured` when already captured/terminal-latched, `CaptureTooEarly` before expiry, `CaptureStepsExhausted` when the scan budget runs out (retry with a bigger `maxSteps`). ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:376 BinaryPool address whose closing price to capture. *** ### maxSteps? > `optional` **maxSteps?**: `bigint` Defined in: packages/sdk/src/trade.ts:383 Per-side scan budget in orders visited — only stale (earlier-expired, unswept) orders above the closing book consume steps. 0 selects the pool default (256). #### Default ```ts 0n ``` *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:389 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ClaimOwedParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClaimOwedParams # Interface: ClaimOwedParams Defined in: packages/sdk/src/trade.ts:1755 Claim an accrued push-fallback balance on the settlement singleton (a payout that could not be pushed to a reverting recipient was booked to `owed`). ## Properties ### token > **token**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1757 The token to claim (the market's collateral token). *** ### settlement? > `optional` **settlement?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1759 BinarySettlement address; resolved from `config.addresses.binarySettlement` when omitted. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1765 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ClaimPerpStopSomiParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClaimPerpStopSomiParams # Interface: ClaimPerpStopSomiParams Defined in: packages/sdk/src/trade.ts:1320 Inputs to [Trader.claimPerpStopSomi](Trader.md#claimperpstopsomi) — recover the SOMI a perp stop registry owes the signer after a refund transfer failed. ## Properties ### registry > **registry**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1322 The perp stop-order registry holding the unclaimed balance. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1328 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ClaimableInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClaimableInput # Interface: ClaimableInput Defined in: packages/sdk/src/derivedReads.ts:598 A settled binary position to evaluate for claimability. ## Properties ### marketId > **marketId**: `string` Defined in: packages/sdk/src/derivedReads.ts:600 Market id (bytes32 hex), passed through to the output. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/derivedReads.ts:602 The market's pool address, passed through to the output. *** ### outcomeIdx > **outcomeIdx**: `0` \| `1` Defined in: packages/sdk/src/derivedReads.ts:604 0 = YES, 1 = NO — which outcome this position holds. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:606 Held outcome-token balance (raw). Non-positive positions are dropped. *** ### winningOutcome > **winningOutcome**: `number` \| `null` Defined in: packages/sdk/src/derivedReads.ts:608 Winning outcome (0/1) when resolved; null when voided/unresolved. *** ### voided > **voided**: `boolean` Defined in: packages/sdk/src/derivedReads.ts:615 True when the market voided. A void redeems against the market's stored payout vector ([ClaimableInput.payoutNumerators](#payoutnumerators)), which is a half per side under the `UNIFORM` void policy but `[p, D−p]` on a `CLOB_SNAPSHOT` void that captured a two-sided close. *** ### payoutNumerators? > `optional` **payoutNumerators?**: `string`[] \| `null` Defined in: packages/sdk/src/derivedReads.ts:623 Per-outcome payout numerators the market settled to (decimal strings), from `BinaryMarket.payoutNumerators`. Supply these on a voided position so the payout comes from the vector rather than an assumed half. Null/omitted on markets indexed before the vector fields existed — the estimate then falls back to the half, unchanged from pre-vector behaviour. *** ### payoutDenominator? > `optional` **payoutDenominator?**: `string` \| `null` Defined in: packages/sdk/src/derivedReads.ts:625 Denominator the numerators are scaled against (decimal string); null/omitted with them. *** ### status > **status**: `string` Defined in: packages/sdk/src/derivedReads.ts:627 Market lifecycle status ("Resolved" | "Voided" | …), passed through to the output. *** ### settlementFeeBps > **settlementFeeBps**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:629 Settlement fee in bps (1 = 0.01%); the winner payout skims this. --- # /docs/typescript/api/index/interfaces/ClaimablePosition [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClaimablePosition # Interface: ClaimablePosition Defined in: packages/sdk/src/derivedReads.ts:572 One redeemable outcome position in a settled market — shaped to feed straight into `trader.redeemMany({ entries: [...] })`. ## Properties ### marketId > **marketId**: `string` Defined in: packages/sdk/src/derivedReads.ts:574 Market id (bytes32 hex) — `entries[].marketId` for redeemMany. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/derivedReads.ts:576 The market's pool address (lowercased). *** ### outcomeIdx > **outcomeIdx**: `0` \| `1` Defined in: packages/sdk/src/derivedReads.ts:578 0 = YES, 1 = NO — `entries[].outcomeIdx` for redeemMany. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:580 Redeemable outcome-token balance (raw) — `entries[].amount` for redeemMany. *** ### estPayout > **estPayout**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:588 Estimated collateral payout net of the settlement fee (raw). Winner: amount × (1 − fee); voided: amount × the market's stored payout vector for this outcome (a half per side under the `UNIFORM` void policy, `[p, D−p]` on a captured `CLOB_SNAPSHOT` void; a void is never fee-charged). Loser side: 0. See [estPayoutFor](../functions/estPayoutFor.md). *** ### status > **status**: `string` Defined in: packages/sdk/src/derivedReads.ts:590 Market lifecycle status driving the claim ("Resolved" | "Voided" | …). --- # /docs/typescript/api/index/interfaces/ClientConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClientConfig # Interface: ClientConfig Defined in: packages/sdk/src/config.ts:289 Configuration for a [SomniaMarketsClient](SomniaMarketsClient.md). `indexerUrl` is always required. `chain` + `wsRpcUrl` power the live tail, on-chain reads, and writes — they're required by those features, but the WebSocket socket is opened lazily, so an indexer-only client (e.g. server-side GraphQL reads) that never touches the chain never opens one. ## Properties ### reconciliation? > `optional` **reconciliation?**: [`TailReconciliationConfig`](TailReconciliationConfig.md) Defined in: packages/sdk/src/config.ts:297 Optional diagnostic, off by default. At most once per interval, recover logs through one target and compare both top-N sides at that block and timestamp. Costs chunked getLogs plus one header and two book reads per watched pool. Failures and retained divergence evidence appear in getLiveStatus(). It never replaces seed orders or the event-derived store. *** ### indexerUrl > **indexerUrl**: `string` Defined in: packages/sdk/src/config.ts:299 Envio/Hasura GraphQL endpoint (HTTP). Same-origin relative paths are fine. *** ### indexerHeaders? > `optional` **indexerHeaders?**: `Record`\<`string`, `string`\> Defined in: packages/sdk/src/config.ts:307 Extra headers sent with every indexer request — e.g. a Hasura role / admin-secret for SERVER-side reads that need privileges the public role lacks (notably `_aggregate` fields, which envio hides from the public role). MUST stay server-only; never construct a browser client with a secret here. *** ### signal? > `optional` **signal?**: `AbortSignal` Defined in: packages/sdk/src/config.ts:325 Cancels this client's in-flight INDEXER reads when aborted — pass one per request on a server, or a component's controller signal in a UI, so a navigation away stops work already on the wire. **Details** Client-wide, not per-read: it is combined with the SDK's own request timeout (whichever fires first wins). An abort re-throws YOUR abort reason unwrapped rather than an [IndexerError](../classes/IndexerError.md), so `name === "AbortError"` checks keep working — a cancellation is not an indexer failure. **Gotchas** Covers indexer reads only. Chain reads go over the WebSocket transport, which is bounded by its own request timeout instead. *** ### chain > **chain**: `Chain` Defined in: packages/sdk/src/config.ts:327 viem chain the markets live on. *** ### wsRpcUrl? > `optional` **wsRpcUrl?**: `string` Defined in: packages/sdk/src/config.ts:339 Chain WebSocket RPC — the single chain transport. The live tail subscribes to logs + new heads over it, and all on-chain reads/writes use it too. There is no HTTP fallback: the SDK assumes a healthy WebSocket. Optional when `chain` carries a WebSocket endpoint — every definition in `@somnia-chain/markets-sdk/chains` does (`rpcUrls.default.webSocket`), so with those this is only an override. viem's own `somniaTestnet` lacks one, so with that chain (or any ws-less definition) it stays required and the first chain touch throws [NotConfiguredError](../classes/NotConfiguredError.md) without it. *** ### fees? > `optional` **fees?**: [`FixedFees`](FixedFees.md) Defined in: packages/sdk/src/config.ts:344 Fixed fees for SDK-signed writes (default [DEFAULT\_FEES](../variables/DEFAULT_FEES.md)). Override for a chain whose base fee can exceed the default ceiling. *** ### addresses? > `optional` **addresses?**: [`SomniaMarketsAddresses`](SomniaMarketsAddresses.md) Defined in: packages/sdk/src/config.ts:349 Protocol contract addresses — used by the write client, the live tail's factory watch, and /system reads. *** ### priceFeed? > `optional` **priceFeed?**: [`PriceFeedConfig`](PriceFeedConfig.md) Defined in: packages/sdk/src/config.ts:356 The realtime price-feed endpoint (see [PriceFeedConfig](PriceFeedConfig.md)). One endpoint serves every asset; callers filter by asset. Required only for the price-feed methods (`watchPrice`, `getLivePrice`, `fetchPrices`, …); a client that never touches prices needs none. *** ### debug? > `optional` **debug?**: (`e`) => `void` Defined in: packages/sdk/src/config.ts:389 Opt-in debug/tracing sink. Unset (the default) means the SDK emits nothing and does no debug-only work. When set, the client sends every [DebugEvent](../type-aliases/DebugEvent.md) it produces — structured log lines plus span start/annotate/end events around trader calls and live-tail hydration — and the sink decides everything else: filtering, formatting, toggling, or forwarding to a real tracer (the shape maps 1:1 onto OpenTelemetry). Two sinks ship with the package: `consoleDebugSink` (indented span tree) and `debugCollector` (test capture). The toggle mechanism belongs to the app, not the SDK: **Example** (Enabling debug output) Explorer (dev) — flip on from devtools via localStorage; a Node bot gates a JSON-lines sink on an env var instead: ```ts const devExchange = new SomniaMarkets({ ...config, debug: localStorage.getItem("sdk-debug") ? consoleDebugSink() : undefined, }); const botExchange = new SomniaMarkets({ ...config, debug: process.env.SDK_DEBUG ? (e) => console.log(JSON.stringify(e, (_, v) => (typeof v === "bigint" ? v.toString() : v))) : undefined, }); ``` #### Parameters ##### e [`DebugEvent`](../type-aliases/DebugEvent.md) #### Returns `void` --- # /docs/typescript/api/index/interfaces/ClosingPriceState [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClosingPriceState # Interface: ClosingPriceState Defined in: packages/sdk/src/orders.ts:564 A pool's closing-price capture state (see `Trader.captureClose`). `state`: - `"OPEN"`: no capture yet — post-expiry removals of alive-at-close orders revert `CloseNotCaptured` while the market is not terminal. - `"CAPTURED"`: two-sided capture stored; `closingMid` is the bid/ask mid in raw book-price units (scale `oneCollateral`). - `"CAPTURED_DEGENERATE"`: capture ran but a side had no closing order — no mid; a void falls back to uniform. - `"TERMINAL_LATCH"`: a removal observed the market already terminal; the lock lifted without a capture. ## Properties ### closingMid > **closingMid**: `bigint` Defined in: packages/sdk/src/orders.ts:566 Captured closing mid in raw book-price units (0 unless `state === "CAPTURED"`). *** ### oneCollateral > **oneCollateral**: `bigint` Defined in: packages/sdk/src/orders.ts:568 The pool's price scale (`10 ** collateralDecimals`). *** ### state > **state**: `"OPEN"` \| `"CAPTURED"` \| `"CAPTURED_DEGENERATE"` \| `"TERMINAL_LATCH"` Defined in: packages/sdk/src/orders.ts:570 Decoded close state. --- # /docs/typescript/api/index/interfaces/ContractMeta [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ContractMeta # Interface: ContractMeta Defined in: packages/sdk/src/markets.ts:1997 owner / implementation / native balance for a deployed contract — the diagnostics the /system dashboard shows. `owner` is null when the contract isn't Ownable; `impl` is read from the EIP-1967 slot only when `proxy` is true (null otherwise, or when the slot is empty). Each sub-read degrades to null/0 independently so one missing getter never fails the whole card. ## Properties ### owner > **owner**: `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/markets.ts:1999 Ownable `owner()`, or null when the contract exposes no owner getter. *** ### impl > **impl**: `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/markets.ts:2004 EIP-1967 implementation address — null unless read as a proxy with a non-empty slot. *** ### balance > **balance**: `bigint` Defined in: packages/sdk/src/markets.ts:2006 Native (SOMI) balance, raw wei (18dp); 0n when the read fails. --- # /docs/typescript/api/index/interfaces/CreateMarketCreatorParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CreateMarketCreatorParams # Interface: CreateMarketCreatorParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:47 Params for [MarketCreatorAdmin.createMarketCreator](MarketCreatorAdmin.md#createmarketcreator). ## Properties ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:49 Owner of the minted creator (can register series / trigger rolls). *** ### factory? > `optional` **factory?**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:57 Factory to mint from. Defaults to `config.addresses.marketCreatorFactory` (v1). Pass `config.addresses.marketCreatorFactoryV2` explicitly to mint an interval/bucket-mode `MarketCreatorV2` instead — the rest of this admin's surface (registerSeries / triggerRoll / armFirstRoll / …) targets either version unchanged, since v2's instance ABI is a superset of v1's here. *** ### adapter? > `optional` **adapter?**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:63 Oracle adapter the creator's markets resolve against. Defaults to the protocol's OracleHub (`config.addresses.oracleHub`) — Oracle v2's ONE approved adapter; there is nothing to mint or arm per operator. *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:65 Origin operator id the creator's markets are attributed to. *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:71 Origin venue id (within the operator). Must be a BINARY_V1 venue whose create path does NOT require a venue signature — the automated roll loop cannot produce per-create signatures. *** ### defaultBookParams > **defaultBookParams**: [`OrderBookParams`](OrderBookParams.md) Defined in: packages/sdk/src/marketCreatorAdmin.ts:73 Default order-book config stamped onto every market the creator deploys. *** ### core? > `optional` **core?**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:78 Core BinaryMarketsModule the creator binds to. Defaults to `config.addresses.binaryModule`. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:80 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/CreateMarketCreatorResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CreateMarketCreatorResult # Interface: CreateMarketCreatorResult Defined in: packages/sdk/src/marketCreatorAdmin.ts:88 Result of [MarketCreatorAdmin.createMarketCreator](MarketCreatorAdmin.md#createmarketcreator) — the two addresses the factory minted, decoded from the receipt's `MarketCreatorCreated` event. ## Extends - [`TxResult`](TxResult.md) ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:90 The minted MarketCreator address (decoded from `MarketCreatorCreated`). *** ### policy > **policy**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:92 The minted MarketCreatorPolicy address (decoded from `MarketCreatorCreated`). *** ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) --- # /docs/typescript/api/index/interfaces/CreateOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CreateOrderParams # Interface: CreateOrderParams Defined in: packages/sdk/src/unified/exchange.ts:181 The optional trailing params bag of [SomniaMarkets.createOrder](../classes/SomniaMarkets.md#createorder) — time-in-force, market-order slippage, and builder-fee attribution. Everything here has a working default. ## Properties ### timeInForce? > `optional` **timeInForce?**: `"GTC"` \| `"IOC"` \| `"FOK"` \| `"PO"` Defined in: packages/sdk/src/unified/exchange.ts:183 "IOC" | "FOK" | "PO" (post-only). Default GTC (rest). *** ### postOnly? > `optional` **postOnly?**: `boolean` Defined in: packages/sdk/src/unified/exchange.ts:185 Alias for timeInForce: "PO". *** ### slippage? > `optional` **slippage?**: `number` Defined in: packages/sdk/src/unified/exchange.ts:187 Market-order slippage bound vs the best opposite level (default 0.01 = 1%). *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/unified/exchange.ts:193 Routing/builder frontend to attribute the order to. Requires a prior `client.createTrader().approveBuilder(...)` opt-in on the pool, else a non-zero `builderFeeBpsTimes1k` reverts. Works on binary, spot and perp. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/unified/exchange.ts:198 Per-order builder/routing fee in the pool's native bps×1000 unit (must not exceed the effective approval / the pool's max builder fee). --- # /docs/typescript/api/index/interfaces/CreateQuotePreflightInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CreateQuotePreflightInput # Interface: CreateQuotePreflightInput Defined in: packages/sdk/src/preflight.ts:228 Inputs for the create-quote preflight (§8e EARMARK-AT-CREATION): what the payer (the funding wallet or MarketCreator contract) holds vs the FULL create value — `getSchedulingCost(def) + resolveReserve()`. The reserve is attached to the create and LOCKED per-market at onBind; there is no separate prepaid gate. Fetch the total with `quoteCreateMarketValue(def)`, or fetch the two legs (`getSchedulingCost(def)` + `resolveReserve()`) separately. ## Properties ### balanceWei > **balanceWei**: `bigint` Defined in: packages/sdk/src/preflight.ts:230 Native balance (wei) of whoever pays the create (EOA or MarketCreator). *** ### schedulingCostWei > **schedulingCostWei**: `bigint` Defined in: packages/sdk/src/preflight.ts:232 The hub's marginal `getSchedulingCost(def)` quote (0 = dedup reuse). *** ### resolveReserveWei > **resolveReserveWei**: `bigint` Defined in: packages/sdk/src/preflight.ts:238 The hub's `resolveReserve()` — the reserve ATTACHED to the create and locked per-market at onBind (the bind reverts `WrongReserveAttached` if the attached value is not exactly this). --- # /docs/typescript/api/index/interfaces/CreateVenueParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CreateVenueParams # Interface: CreateVenueParams Defined in: packages/sdk/src/operatorAdmin.ts:184 Params for [OperatorAdmin.createVenue](OperatorAdmin.md#createvenue). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:186 The operator the venue is created under. Caller must be its owner. *** ### marketType > **marketType**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:188 Market-type id (e.g. `MarketTypeIds.BINARY_V1`); immutable once set. *** ### config > **config**: [`VenueConfigInput`](VenueConfigInput.md) Defined in: packages/sdk/src/operatorAdmin.ts:190 The venue's initial config (fee params, recipient, policy, signer, …). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:192 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/CreateVenueResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CreateVenueResult # Interface: CreateVenueResult Defined in: packages/sdk/src/operatorAdmin.ts:200 Result of [OperatorAdmin.createVenue](OperatorAdmin.md#createvenue) — carries the venue id the contract generated, which markets reference to inherit the venue's fees. ## Extends - [`TxResult`](TxResult.md) ## Properties ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:202 The contract-generated venue id (decoded from `VenueCreated`). *** ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) --- # /docs/typescript/api/index/interfaces/DebugCollector [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DebugCollector # Interface: DebugCollector Defined in: packages/sdk/src/debug.ts:384 Captured debug-event stream with typed filters — what [debugCollector](../functions/debugCollector.md) returns. Pass [sink](#sink) as [ClientConfig.debug](ClientConfig.md#debug), run the operation under test, then assert on the filters. ## Properties ### events > **events**: [`DebugEvent`](../type-aliases/DebugEvent.md)[] Defined in: packages/sdk/src/debug.ts:386 Every event received, in emission order (spans interleaved with logs). *** ### sink > **sink**: (`e`) => `void` Defined in: packages/sdk/src/debug.ts:388 The collecting sink — pass as [ClientConfig.debug](ClientConfig.md#debug). #### Parameters ##### e [`DebugEvent`](../type-aliases/DebugEvent.md) #### Returns `void` ## Methods ### starts() > **starts**(`name?`): `object`[] Defined in: packages/sdk/src/debug.ts:390 Span start events, optionally filtered by span name (e.g. `"trade.execute"`). #### Parameters ##### name? `string` #### Returns *** ### ends() > **ends**(`name?`): `object`[] Defined in: packages/sdk/src/debug.ts:392 Span end events, optionally filtered by span name — carry `durationMs`/`error`. #### Parameters ##### name? `string` #### Returns *** ### annotations() > **annotations**(`name?`): `object`[] Defined in: packages/sdk/src/debug.ts:394 Mid-span annotate events, optionally filtered by span name. #### Parameters ##### name? `string` #### Returns *** ### logs() > **logs**(`scope?`): `object`[] Defined in: packages/sdk/src/debug.ts:396 Log events, optionally filtered by scope (e.g. `"liveTail"`). #### Parameters ##### scope? `string` #### Returns --- # /docs/typescript/api/index/interfaces/DecodedOutcomeId [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DecodedOutcomeId # Interface: DecodedOutcomeId Defined in: packages/sdk/src/ids.ts:56 The decoded components of an outcome id. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/ids.ts:58 The pool address (the encoded high 160 bits), lowercased 0x-hex. *** ### nonce > **nonce**: `bigint` Defined in: packages/sdk/src/ids.ts:60 The pool's market nonce this id belongs to. *** ### idx > **idx**: `number` Defined in: packages/sdk/src/ids.ts:62 The outcome index (0 = YES, 1 = NO). --- # /docs/typescript/api/index/interfaces/DepositMarginParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DepositMarginParams # Interface: DepositMarginParams Defined in: packages/sdk/src/trade.ts:901 Inputs to [Trader.depositMargin](Trader.md#depositmargin) — fund the signer's cross-margin MarginBank balance (one balance backs every perp pool on that bank). ## Properties ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:903 MarginBank address (from the PerpMarket row), or pass `pool` to resolve it. *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:905 A PerpPool — its `marginBank()` is read (and cached) when `marginBank` is omitted. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:907 Collateral amount to deposit, raw units (e.g. USDso 18dp). *** ### collateral? > `optional` **collateral?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:909 Collateral token; read from the bank's getSystemConfig (cached) if omitted. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:911 Approve the collateral to the BANK if allowance is short (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:917 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/DepositVaultNativeParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DepositVaultNativeParams # Interface: DepositVaultNativeParams Defined in: packages/sdk/src/trade.ts:1130 Inputs to [Trader.depositVaultNative](Trader.md#depositvaultnative) and [Trader.depositVaultNativeFor](Trader.md#depositvaultnativefor) — pre-fund a native balance in a pool's internal vault. The amount travels as `msg.value`. ## Properties ### vault > **vault**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1132 The ERC20Vault to deposit into — the pool address. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1134 Native amount to deposit, wei. Must be > 0. *** ### owner? > `optional` **owner?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1139 Account to credit. Omit to credit the signer; set it to fund ANOTHER account's vault balance (an operator pre-funding a bot wallet). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1145 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/DepositVaultParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DepositVaultParams # Interface: DepositVaultParams Defined in: packages/sdk/src/trade.ts:1102 Inputs to [Trader.depositVault](Trader.md#depositvault) — pre-fund an ERC-20 balance in a pool's internal vault. ## Properties ### vault > **vault**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1107 The ERC20Vault to deposit into — the pool address (SpotPool/BinaryPool ARE ERC20Vaults). *** ### token > **token**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1112 ERC-20 to deposit. NOT the native sentinel — use [Trader.depositVaultNative](Trader.md#depositvaultnative) for native (the contract reverts `UseDepositNative`). *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1114 Amount to deposit, raw units. Must be > 0. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1120 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/EnableHubReactivityParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / EnableHubReactivityParams # Interface: EnableHubReactivityParams Defined in: packages/sdk/src/oracleHub.ts:494 Parameters for [OracleHubAdmin.enableReactivity](OracleHubAdmin.md#enablereactivity) / [OracleHubAdmin.migrateSubscription](OracleHubAdmin.md#migratesubscription). ## Properties ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:496 Gas-limit override for this tx (defaults to the admin config's `gas`). --- # /docs/typescript/api/index/interfaces/EntryTrade [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / EntryTrade # Interface: EntryTrade Defined in: packages/sdk/src/derivedReads.ts:1132 The one slice of a portfolio trade the entry-price math needs. ## Properties ### side > **side**: [`BinarySide`](../type-aliases/BinarySide.md) \| `null` Defined in: packages/sdk/src/derivedReads.ts:1134 The account's side on the fill, or null when not yet bridged. *** ### fillPrice > **fillPrice**: `string` Defined in: packages/sdk/src/derivedReads.ts:1136 Fill price in YES terms (raw collateral units per whole outcome token). *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/derivedReads.ts:1138 Outcome-token quantity filled (raw units). --- # /docs/typescript/api/index/interfaces/EquityPoint [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / EquityPoint # Interface: EquityPoint Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:128 One sample of the equity (cumulative window PnL) series. ## Properties ### t > **t**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:130 Sample time (ms). *** ### valueUsd > **valueUsd**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:132 Cumulative realized + unrealized PnL since the window start, USD. --- # /docs/typescript/api/index/interfaces/Erc20Metadata [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Erc20Metadata # Interface: Erc20Metadata Defined in: packages/sdk/src/balances.ts:42 ERC-20 token metadata (`symbol`, `name`, `decimals`) read in one fan-out. Handy to label a collateral/base token the indexer hasn't denormalized. ## Properties ### symbol > **symbol**: `string` Defined in: packages/sdk/src/balances.ts:44 Token ticker, e.g. "USDso". *** ### name > **name**: `string` Defined in: packages/sdk/src/balances.ts:46 Full token name, e.g. "Somnia USD". *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/balances.ts:48 Display decimals scaling the token's raw units (raw / 10^decimals = human). --- # /docs/typescript/api/index/interfaces/ExchangeDataStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ExchangeDataStatus # Interface: ExchangeDataStatus Defined in: packages/sdk/src/unified/exchange.ts:15 Opt-in mixed-tier status; each data source retains its own verdict. ## Extends - [`ExchangeStatus`](ExchangeStatus.md) ## Properties ### status > **status**: `"error"` \| `"ok"` \| `"connecting"` Defined in: packages/sdk/src/unified/exchange.ts:8 Existing chain-tail verdict only; no indexer or price threshold is inferred. #### Inherited from [`ExchangeStatus`](ExchangeStatus.md).[`status`](ExchangeStatus.md#status) *** ### updated > **updated**: `number` Defined in: packages/sdk/src/unified/exchange.ts:10 Wall-clock completion time, in milliseconds. #### Inherited from [`ExchangeStatus`](ExchangeStatus.md).[`updated`](ExchangeStatus.md#updated) *** ### info > **info**: [`TailStatus`](TailStatus.md) Defined in: packages/sdk/src/unified/exchange.ts:12 Existing chain-tail snapshot, retained for compatibility. #### Inherited from [`ExchangeStatus`](ExchangeStatus.md).[`info`](ExchangeStatus.md#info) *** ### indexer > **indexer**: [`IndexerFreshness`](../type-aliases/IndexerFreshness.md) \| `null` Defined in: packages/sdk/src/unified/exchange.ts:17 Raw independently measured indexer lag; null when no metadata row exists. *** ### prices > **prices**: `object`[] Defined in: packages/sdk/src/unified/exchange.ts:19 Every asset with price state, independently classified. #### asset > **asset**: `string` #### health > **health**: [`PriceFeedHealth`](../type-aliases/PriceFeedHealth.md) --- # /docs/typescript/api/index/interfaces/ExchangeStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ExchangeStatus # Interface: ExchangeStatus Defined in: packages/sdk/src/unified/exchange.ts:6 Local chain-tail status, available without indexer or RPC requests. ## Extended by - [`ExchangeDataStatus`](ExchangeDataStatus.md) ## Properties ### status > **status**: `"error"` \| `"ok"` \| `"connecting"` Defined in: packages/sdk/src/unified/exchange.ts:8 Existing chain-tail verdict only; no indexer or price threshold is inferred. *** ### updated > **updated**: `number` Defined in: packages/sdk/src/unified/exchange.ts:10 Wall-clock completion time, in milliseconds. *** ### info > **info**: [`TailStatus`](TailStatus.md) Defined in: packages/sdk/src/unified/exchange.ts:12 Existing chain-tail snapshot, retained for compatibility. --- # /docs/typescript/api/index/interfaces/FaucetParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FaucetParams # Interface: FaucetParams Defined in: packages/sdk/src/trade.ts:2049 Inputs to [Trader.faucet](Trader.md#faucet) — mint TestUSDC to the signer (testnet only). ## Properties ### amount? > `optional` **amount?**: `bigint` Defined in: packages/sdk/src/trade.ts:2051 Amount to mint (default 10,000 × 10^decimals). *** ### testUsdc? > `optional` **testUsdc?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2053 TestUSDC address; defaults to the configured one. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:2059 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/FetchOrderBookOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FetchOrderBookOptions # Interface: FetchOrderBookOptions Defined in: packages/sdk/src/unified/exchange.ts:85 Options for a unified chain book snapshot. ## Properties ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/unified/exchange.ts:87 Maximum levels per side, defaults to 10. The legacy numeric argument still works. *** ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/unified/exchange.ts:89 Pin both sides to this exact block; omitted selects one head. --- # /docs/typescript/api/index/interfaces/FinalizeMarketParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FinalizeMarketParams # Interface: FinalizeMarketParams Defined in: packages/sdk/src/trade.ts:1774 Permissionless keeper entry: finalize a settled market (sweep its pool's backing + resolution snapshot to the settlement singleton). No-op-guarded. ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1776 bytes32 marketId to finalize; the market must be resolved or voided. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1778 BinaryMarketsModule address; resolved from `config.addresses.binaryModule` when omitted. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1784 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/FixedFees [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FixedFees # Interface: FixedFees Defined in: packages/sdk/src/config.ts:250 Fixed EIP-1559 fees every SDK-signed write uses. The SDK never estimates fees — no per-order eth_gasPrice / fee-history round-trip. `maxFeePerGas` is a ceiling (the tx pays base fee + tip, the rest is refunded), so a generous fixed value costs nothing extra on Somnia's flat gas market. ## Properties ### maxFeePerGas > **maxFeePerGas**: `bigint` Defined in: packages/sdk/src/config.ts:252 Total fee ceiling (wei per gas); the unspent margin over base fee + tip refunds. *** ### maxPriorityFeePerGas > **maxPriorityFeePerGas**: `bigint` Defined in: packages/sdk/src/config.ts:254 Priority tip (wei per gas) paid to the proposer on top of the base fee. --- # /docs/typescript/api/index/interfaces/FundHubParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundHubParams # Interface: FundHubParams Defined in: packages/sdk/src/oracleHub.ts:434 Parameters for [OracleHubAdmin.fundHub](OracleHubAdmin.md#fundhub). ## Properties ### amountWei > **amountWei**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:440 Native amount (wei) sent to the hub's `receive()` — tops up the reactivity bond the precompile debits callbacks from. NOT credited to any operator (resolution funding is attached per-market at create/onBind). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:442 Gas-limit override for this tx (defaults to the admin config's `gas`). --- # /docs/typescript/api/index/interfaces/FundMarketCreatorParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundMarketCreatorParams # Interface: FundMarketCreatorParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:100 Params for [MarketCreatorAdmin.fundMarketCreator](MarketCreatorAdmin.md#fundmarketcreator). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:102 The MarketCreator to fund. *** ### amountWei > **amountWei**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:104 Native amount (wei) to send to the creator's `receive()`. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:106 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/FundingBucketLike [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundingBucketLike # Interface: FundingBucketLike Defined in: packages/sdk/src/funding.ts:191 The subset of a funding candle this densification needs. ## Properties ### bucketStart > **bucketStart**: `string` Defined in: packages/sdk/src/funding.ts:192 *** ### intervalSeconds > **intervalSeconds**: `number` Defined in: packages/sdk/src/funding.ts:193 --- # /docs/typescript/api/index/interfaces/GetAutoPullRequirementParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetAutoPullRequirementParams # Interface: GetAutoPullRequirementParams Defined in: packages/sdk/src/spot/poolReads.ts:20 Identifies an order shape to price for funding — see [SomniaMarketsClient.getAutoPullRequirement](SomniaMarketsClient.md#getautopullrequirement). ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/poolReads.ts:22 SpotPool to ask. *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/poolReads.ts:24 Account whose vault balance the shortfall is measured against. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/spot/poolReads.ts:26 True = buy base (input is quote); false = sell base (input is base). *** ### price > **price**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:28 Limit price, raw quote units per whole base. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:30 Base quantity, raw base units. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:35 Builder fee in bps × 1000 (the contract's own encoding — 2500 = 2.5 bps). #### Default ```ts 0n (no builder) ``` --- # /docs/typescript/api/index/interfaces/GetBankruptcyPriceOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetBankruptcyPriceOptions # Interface: GetBankruptcyPriceOptions Defined in: packages/sdk/src/perp/margin.ts:1232 Options for the client's `getBankruptcyPrice` method. ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1237 Read at this block instead of the current head. Pass an enumeration's `asOfBlock` to price its holders on the same consistent snapshot. --- # /docs/typescript/api/index/interfaces/GetBinaryOrderBookOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetBinaryOrderBookOptions # Interface: GetBinaryOrderBookOptions Defined in: packages/sdk/src/orders.ts:834 Options for a native binary chain snapshot. ## Extends - [`GetSpotOrderBookOptions`](GetSpotOrderBookOptions.md) ## Properties ### decimals? > `optional` **decimals?**: `number` Defined in: packages/sdk/src/orders.ts:836 Collateral decimals for NO inversion. Defaults to 6. *** ### depth? > `optional` **depth?**: `number` Defined in: packages/sdk/src/orders.ts:842 Maximum levels per side. Defaults to 12 for spot and 10 for binary. #### Inherited from [`GetSpotOrderBookOptions`](GetSpotOrderBookOptions.md).[`depth`](GetSpotOrderBookOptions.md#depth) *** ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/orders.ts:844 Exact block for both sides. Omitted: sample one head and pin both reads. #### Inherited from [`GetSpotOrderBookOptions`](GetSpotOrderBookOptions.md).[`blockNumber`](GetSpotOrderBookOptions.md#blocknumber) --- # /docs/typescript/api/index/interfaces/GetManualVaultModeParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetManualVaultModeParams # Interface: GetManualVaultModeParams Defined in: packages/sdk/src/spot/vaultMode.ts:70 Identifies one user's vault mode on one pool — see [SomniaMarketsClient.getManualVaultMode](SomniaMarketsClient.md#getmanualvaultmode). ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/vaultMode.ts:72 The SpotPool to read. *** ### user > **user**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/vaultMode.ts:74 The user whose mode to read. --- # /docs/typescript/api/index/interfaces/GetOrderOnchainOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetOrderOnchainOptions # Interface: GetOrderOnchainOptions Defined in: packages/sdk/src/orders.ts:663 Options for one on-chain order read. ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/orders.ts:701 Read the order as of the END of this block instead of at head. For a maker order a fill has already consumed: the fill removes it in the same transaction, so `fill.blockNumber - 1n` is the last height that still holds it. `OrderFilled` names the maker only by id, and the pool keeps no record of a removed order at head. What this recovers is the maker's IDENTITY state - `isBid`, `owner`, `userData`, `expireTimestampNs` - which no path changes under a given id, so it is exact at any height the order existed, and which no fill log carries: `OrderFilled` names the maker by id alone. Only `OrderPlaced` carries it, and a consumer that was not listening when the maker rested does not have that log - which is the whole case for this read. `price` is immutable too, and is the one immutable field NOT to read for: a fill executes at the MAKER's resting price, and the book emits that same `price` as the fill event's own. Reading the maker order to price a fill is redundant work. BOTH quantities are block-level, and neither is per-fill. A block read cannot see between transactions, so `fullQuantity` and `quantityRemaining` are the values at the block BOUNDARY: an earlier transaction in the fill's own block may have filled this maker, or reduced it - `reduceOrder` decrements both by the same amount, under the same id. Take `quantityFilled` and `makerRemainingQuantity` from the event; no block-level read reconstructs per-transaction size. Two more edges answer plausibly rather than failing: - A PARTIAL fill leaves the order in place, so a read at the fill's OWN block succeeds with a smaller `quantityRemaining` where a full fill answers `null`. - An order PLACED AND FILLED in one block does not exist at `blockNumber - 1n`, so that read is `null` and the caller needs the placement from the same block's `OrderPlaced` instead. A recent block answers against a full node. An old one needs ARCHIVE state, so this serves a live tape, not a backfill or a replay of last week. --- # /docs/typescript/api/index/interfaces/GetOutcomeBalanceParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetOutcomeBalanceParams # Interface: GetOutcomeBalanceParams Defined in: packages/sdk/src/binary/portfolio.ts:527 Identifies one ERC-6909 outcome position — see `getOutcomeBalance`. ## Properties ### outcomeToken > **outcomeToken**: `` `0x${string}` `` Defined in: packages/sdk/src/binary/portfolio.ts:529 The outcome-token singleton address (from `MarketOnchain`). *** ### account > **account**: `` `0x${string}` `` Defined in: packages/sdk/src/binary/portfolio.ts:531 The balance's owner. *** ### id > **id**: `bigint` Defined in: packages/sdk/src/binary/portfolio.ts:533 The position id — the market's `yesId`/`noId`. --- # /docs/typescript/api/index/interfaces/GetPerpMaxLeverageOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetPerpMaxLeverageOptions # Interface: GetPerpMaxLeverageOptions Defined in: packages/sdk/src/perp/margin.ts:2914 Options for the client's `getPerpMaxLeverage` method. ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:2920 Read at this block instead of the current head. Pass an enumeration's or an analytics row's `asOfBlock` to keep the cap on the same consistent snapshot as the figures it is combined with. --- # /docs/typescript/api/index/interfaces/GetPerpSideHoldersOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetPerpSideHoldersOptions # Interface: GetPerpSideHoldersOptions Defined in: packages/sdk/src/perp/margin.ts:1118 Options for `getPerpSideHolders` (the client's `getPerpSideHolders` method). ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1123 Pin the enumeration to this block instead of the current head — e.g. the `asOfBlock` of the other side's call, so both sides describe one state. *** ### pageSize? > `optional` **pageSize?**: `number` Defined in: packages/sdk/src/perp/margin.ts:1129 Holders fetched per contract call. #### Default ```ts 1000 ``` --- # /docs/typescript/api/index/interfaces/GetSpotOrderBookOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetSpotOrderBookOptions # Interface: GetSpotOrderBookOptions Defined in: packages/sdk/src/orders.ts:840 Options for a native chain snapshot. ## Extended by - [`GetBinaryOrderBookOptions`](GetBinaryOrderBookOptions.md) ## Properties ### depth? > `optional` **depth?**: `number` Defined in: packages/sdk/src/orders.ts:842 Maximum levels per side. Defaults to 12 for spot and 10 for binary. *** ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/orders.ts:844 Exact block for both sides. Omitted: sample one head and pin both reads. --- # /docs/typescript/api/index/interfaces/GetVaultBalanceParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetVaultBalanceParams # Interface: GetVaultBalanceParams Defined in: packages/sdk/src/binary/portfolio.ts:484 Identifies one owner's claimable balance in one pool vault — see [client.getVaultBalance](SomniaMarketsClient.md#getvaultbalance). ## Properties ### vault > **vault**: `` `0x${string}` `` Defined in: packages/sdk/src/binary/portfolio.ts:486 The ERC20Vault address (the pool address). *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/binary/portfolio.ts:488 The balance's owner. *** ### token > **token**: `` `0x${string}` `` Defined in: packages/sdk/src/binary/portfolio.ts:490 The ERC-20 address (or the vault's native sentinel). *** ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/binary/portfolio.ts:502 Read the balance as of this block instead of at head. For an answer that combines this balance with other reads at one height: the withdrawable balance is contract state behind an append-only payout history, so there is no indexed entity to reconstruct it from at a past height, and serving this half at head would silently mix heights inside one response. A recent block answers against a full node. An old one needs ARCHIVE state, and a node without it rejects the read rather than returning a wrong number. --- # /docs/typescript/api/index/interfaces/GovernanceAdmin [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GovernanceAdmin # Interface: GovernanceAdmin Defined in: packages/sdk/src/governanceAdmin.ts:48 The protocol-admin governance surface on BinaryMarketsModule — the one seam an operator can't self-serve (see the module notes above). Built via `client.createGovernanceAdmin(config)` with a signer ([GovernanceAdminConfig](OracleHubAdminConfig.md)); the write is module-owner only, the reads are open chain point reads. Every write throws `ContractRevertError` when the chain rejects it — at simulation, at send, or as a mined receipt with `status: "reverted"` (the reason is recovered by replaying the call at that block while the node still has the state) — and `RpcError` when the send or the receipt read does not complete. A reverted write never resolves as if it had been confirmed. ## Methods ### setAdapterApproved() > **setAdapterApproved**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/governanceAdmin.ts:55 Approve (or revoke) an oracle adapter on the module — the inert→live gate for a factory-minted adapter. MODULE-OWNER ONLY: reverts for any other caller, so a UI shows this only to the protocol admin (see [GovernanceAdmin.isModuleOwner](#ismoduleowner)). #### Parameters ##### p [`SetAdapterApprovedParams`](SetAdapterApprovedParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### getModuleOwner() > **getModuleOwner**(): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/governanceAdmin.ts:57 The module owner (the protocol admin). Needs `config.addresses.binaryModule`. #### Returns `Promise`\<`` `0x${string}` ``\> *** ### isModuleOwner() > **isModuleOwner**(`addr`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/governanceAdmin.ts:62 Whether `addr` is the module owner — gate the `setAdapterApproved` UI on this. Needs `config.addresses.binaryModule`. #### Parameters ##### addr `` `0x${string}` `` #### Returns `Promise`\<`boolean`\> --- # /docs/typescript/api/index/interfaces/HandoffToParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / HandoffToParams # Interface: HandoffToParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:244 Params for [MarketCreatorAdmin.handoffTo](MarketCreatorAdmin.md#handoffto). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:246 The OUTGOING creator to retire. Caller must be its owner. *** ### successor > **successor**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:248 The incoming creator (same owner + venue) the float is swept to. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:250 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/HoldingsPoint [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / HoldingsPoint # Interface: HoldingsPoint Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:140 One sample of the holdings series: the traded book, marked. ## Properties ### t > **t**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:142 Sample time (ms). *** ### valueUsd > **valueUsd**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:144 Marked value of the open positions this sample could price, USD. *** ### unpricedMarkets > **unpricedMarkets**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:159 How many open markets this sample could NOT price, and so left out of [HoldingsPoint.valueUsd](#valueusd). A market with no candle sample and no last price has no mark. The fold values that position at zero, which is a real price standing in for a missing one — so the level silently loses a position the wallet still holds. This count is how a caller knows. Zero means the sample priced everything and the value is the whole book. Present the shortfall rather than hiding it. A wallet holding one quiet market reads as poorer than it is, which is the fault SMK-45 reports at the account level. --- # /docs/typescript/api/index/interfaces/HubPreflightInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / HubPreflightInput # Interface: HubPreflightInput Defined in: packages/sdk/src/preflight.ts:173 Inputs for the hub-step preflight: the hub's on-chain status (from `OracleHubAdmin.getHubStatus`, or the subset a caller already holds) and whether the connected chain supports the reactivity precompile (local anvil does NOT). Unlike the retired adapter step, the armed state IS cheaply readable on-chain (`subscriptionId != 0`). ## Properties ### status > **status**: `Pick`\<[`HubStatus`](HubStatus.md), `"approved"` \| `"subscriptionId"` \| `"balanceWei"`\> Defined in: packages/sdk/src/preflight.ts:175 The subset of [HubStatus](HubStatus.md) the check needs. *** ### precompileAvailable > **precompileAvailable**: `boolean` Defined in: packages/sdk/src/preflight.ts:180 Whether the connected chain has the Somnia reactivity precompile (false on local anvil). --- # /docs/typescript/api/index/interfaces/HubQuestionState [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / HubQuestionState # Interface: HubQuestionState Defined in: packages/sdk/src/oracleHub.ts:297 One question's live dedup state on the hub. ## Properties ### questionKey > **questionKey**: `` `0x${string}` `` Defined in: packages/sdk/src/oracleHub.ts:302 Canonical dedup key for the definition (zero for non-template definitions, which bypass dedup). *** ### oracleQuestionId > **oracleQuestionId**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:304 The ACTIVE question id the key resolves to (0n = never scheduled). *** ### bindCount > **bindCount**: `number` Defined in: packages/sdk/src/oracleHub.ts:306 Lifetime bind count for that question (drives the cap-split). *** ### markets > **markets**: `` `0x${string}` ``[] Defined in: packages/sdk/src/oracleHub.ts:308 Every marketId bound to the question (the fan-out list the drain walks). --- # /docs/typescript/api/index/interfaces/HubStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / HubStatus # Interface: HubStatus Defined in: packages/sdk/src/oracleHub.ts:316 Live on-chain status of the hub (the point read a panel confirms). ## Properties ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/oracleHub.ts:318 Hub owner — the account gated into `withdraw` / gas + drain param writes. *** ### balanceWei > **balanceWei**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:323 Total native balance (wei) the hub holds (Σ earmarked + accrued credit + reactivity bond float). *** ### approved > **approved**: `boolean` Defined in: packages/sdk/src/oracleHub.ts:328 Whether the module has the hub approved (`approvedAdapters(hub)`) — the wired/live gate. *** ### subscriptionId > **subscriptionId**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:330 Reactivity subscription id; 0n until `enableReactivity` succeeds. *** ### priorityFeePerGas > **priorityFeePerGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:332 Reactivity-callback tip (wei per gas). *** ### maxFeePerGas > **maxFeePerGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:334 Reactivity-callback fee ceiling (wei per gas); one factor of `resolveReserve`. *** ### gasLimit > **gasLimit**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:336 Gas limit each reactivity callback runs with. *** ### perMarketResolveGas > **perMarketResolveGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:338 Per-market resolve-slice gas constant (sizes `resolveReserve`). *** ### callbackBaseGas > **callbackBaseGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:340 Explicitly-attributed callback overhead gas constant (metering). *** ### maxResolvesPerCallback > **maxResolvesPerCallback**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:342 Belt-and-suspenders cap on markets resolved per callback. *** ### resolveGasReserve > **resolveGasReserve**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:344 Gas reserve that breaks the drain loop to the next block. *** ### resolveReserveWei > **resolveReserveWei**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:346 Per-market resolution reserve attached+locked at onBind (`resolveReserve()`, wei). *** ### pendingResolves > **pendingResolves**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:348 Markets still queued for resolution across all pending qids. --- # /docs/typescript/api/index/interfaces/IndependentHead [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndependentHead # Interface: IndependentHead Defined in: packages/sdk/src/syncStatus.ts:75 Independent chain observation shared by a group of reads. It is not a snapshot pin. ## Properties ### chainId > `readonly` **chainId**: `number` Defined in: packages/sdk/src/syncStatus.ts:77 Owner chain. *** ### blockNumber > `readonly` **blockNumber**: `bigint` Defined in: packages/sdk/src/syncStatus.ts:79 Latest height returned by the owner's RPC. *** ### timestamp > `readonly` **timestamp**: `bigint` Defined in: packages/sdk/src/syncStatus.ts:81 Block time in Unix seconds. *** ### observedAt > `readonly` **observedAt**: `number` Defined in: packages/sdk/src/syncStatus.ts:83 Wall-clock time at RPC completion, in milliseconds. --- # /docs/typescript/api/index/interfaces/IndexedPool [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedPool # Interface: IndexedPool Defined in: packages/sdk/src/pools.ts:129 The indexer's per-pool aggregate (`Pool`; id = lowercased pool address) — the long-lived BinaryPool contract that outlives any single market. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/pools.ts:131 Lowercased pool address (== address). *** ### address > **address**: `string` Defined in: packages/sdk/src/pools.ts:133 Lowercased pool address (== id). *** ### collateral > **collateral**: `string` \| `null` Defined in: packages/sdk/src/pools.ts:135 Collateral token the pool is bound to for its whole life (lowercased). *** ### creator > **creator**: `string` \| `null` Defined in: packages/sdk/src/pools.ts:140 The pool's creator — its first-deploy market creator, the only party that can reuse it (lowercased). *** ### currentMarketId > **currentMarketId**: `string` \| `null` Defined in: packages/sdk/src/pools.ts:145 marketId of the pool's CURRENT binding; null when finalized + released and awaiting reuse. *** ### currentNonce > **currentNonce**: `string` \| `null` Defined in: packages/sdk/src/pools.ts:147 Pool market nonce of the current binding (decimal string). *** ### generationCount > **generationCount**: `number` Defined in: packages/sdk/src/pools.ts:149 Number of markets this pool has served (== the latest nonce). *** ### createdAtTimestamp > **createdAtTimestamp**: `string` Defined in: packages/sdk/src/pools.ts:151 Timestamp (unix seconds) of the pool's first MarketCreated. *** ### updatedAtTimestamp > **updatedAtTimestamp**: `string` Defined in: packages/sdk/src/pools.ts:153 Timestamp (unix seconds) of the last binding change. --- # /docs/typescript/api/index/interfaces/IndexerObservation [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexerObservation # Interface: IndexerObservation Defined in: packages/sdk/src/observedReads.ts:119 Response-associated indexing watermark. This does not claim an entity changed at that block. ## Properties ### chainId > `readonly` **chainId**: `number` Defined in: packages/sdk/src/observedReads.ts:121 Configured owner chain. *** ### latestProcessedBlock > `readonly` **latestProcessedBlock**: `bigint` \| `null` Defined in: packages/sdk/src/observedReads.ts:123 Conservative minimum across successful data-bearing requests; null if any metadata is missing. *** ### startedAt > `readonly` **startedAt**: `number` \| `null` Defined in: packages/sdk/src/observedReads.ts:125 First contributing request start, in Unix milliseconds. Null for a result requiring no request. *** ### completedAt > `readonly` **completedAt**: `number` \| `null` Defined in: packages/sdk/src/observedReads.ts:127 Last contributing response completion, in Unix milliseconds. *** ### responseCount > `readonly` **responseCount**: `number` Defined in: packages/sdk/src/observedReads.ts:129 Successful data-bearing response count; rejected aggregate attempts do not count. *** ### independentHead > `readonly` **independentHead**: [`IndependentHead`](IndependentHead.md) Defined in: packages/sdk/src/observedReads.ts:131 Shared comparison observation, not an atomic historical snapshot. --- # /docs/typescript/api/index/interfaces/InsuranceFundState [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / InsuranceFundState # Interface: InsuranceFundState Defined in: packages/sdk/src/perp/system.ts:89 The InsuranceFund's solvency picture. ## Properties ### address > **address**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:93 The fund's address. *** ### maxTiers > **maxTiers**: `bigint` Defined in: packages/sdk/src/perp/system.ts:98 The maximum tier INDEX, not a count — the fund has `maxTiers + 1` addressable buckets, because tier 0 exists alongside coverage tiers `1..maxTiers`. *** ### totalBalance > **totalBalance**: `bigint` Defined in: packages/sdk/src/perp/system.ts:112 Sum across every tier including tier 0, raw collateral units — the contract's own `getTotalTierBalances`, which is the figure the INV-TIER accounting invariant is stated against. **Not "how much bad debt this stack can absorb"**, on two counts. Tier 0 is included here but never absorbs anything, so collateral parked there inflates the number without backing a single market. And each coverage tier is charged only its own pools' realized losses, capped at `min(funded, own loss)` and never subsidising another tier — so even the `1..maxTiers` sum is an upper bound that no single event can draw down in full. For absorption against a specific market, read that market's tier from [tiers](#tiers). *** ### tiers > **tiers**: [`InsuranceFundTier`](InsuranceFundTier.md)[] Defined in: packages/sdk/src/perp/system.ts:114 Per-tier balances and how many pools each backs, tier 0 first. --- # /docs/typescript/api/index/interfaces/InsuranceFundTier [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / InsuranceFundTier # Interface: InsuranceFundTier Defined in: packages/sdk/src/perp/system.ts:70 One tier of the InsuranceFund. ## Properties ### tier > **tier**: `number` Defined in: packages/sdk/src/perp/system.ts:77 Tier index. `0` is the general/unallocated bucket — a reserved sentinel that never absorbs bad debt and backs no pools (its [poolCount](#poolcount) is structurally zero, since tier 0 means "uncovered" and is not tracked). Coverage tiers run `1..maxTiers`. *** ### balance > **balance**: `bigint` Defined in: packages/sdk/src/perp/system.ts:79 Collateral held in this tier, raw units. *** ### poolCount > **poolCount**: `bigint` Defined in: packages/sdk/src/perp/system.ts:81 How many perp pools this tier backs. --- # /docs/typescript/api/index/interfaces/IsApprovedForPoolParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IsApprovedForPoolParams # Interface: IsApprovedForPoolParams Defined in: packages/sdk/src/spot/operatorGrants.ts:218 Identifies a per-pool grant slot to read — see [SomniaMarketsClient.isApprovedForPool](SomniaMarketsClient.md#isapprovedforpool). ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/operatorGrants.ts:220 SpotPool the grant applies on. *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/operatorGrants.ts:222 Account that would have granted it (the signer of the grant). *** ### operator > **operator**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/operatorGrants.ts:224 Account acting on the owner's behalf. *** ### selector > **selector**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/operatorGrants.ts:226 4-byte function selector the operator wants to call. --- # /docs/typescript/api/index/interfaces/IsGloballyApprovedParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IsGloballyApprovedParams # Interface: IsGloballyApprovedParams Defined in: packages/sdk/src/spot/operatorGrants.ts:204 Identifies a global grant slot to read — see [SomniaMarketsClient.isGloballyApproved](SomniaMarketsClient.md#isgloballyapproved). ## Properties ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/operatorGrants.ts:206 Account that would have granted it (the signer of the grant). *** ### operator > **operator**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/operatorGrants.ts:208 Account acting on the owner's behalf. *** ### selector > **selector**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/operatorGrants.ts:210 4-byte function selector the operator wants to call. --- # /docs/typescript/api/index/interfaces/IsOperatorAuthorizedParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IsOperatorAuthorizedParams # Interface: IsOperatorAuthorizedParams Defined in: packages/sdk/src/spot/poolReads.ts:102 Identifies an operator grant to check — see [SomniaMarketsClient.isOperatorAuthorized](SomniaMarketsClient.md#isoperatorauthorized). ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/poolReads.ts:104 SpotPool the grant applies on. *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/poolReads.ts:106 Account that would have granted it. *** ### operator > **operator**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/poolReads.ts:108 Account acting on the owner's behalf. *** ### selector > **selector**: `` `0x${string}` `` Defined in: packages/sdk/src/spot/poolReads.ts:110 4-byte function selector the operator wants to call (e.g. `placeOrderFor`). --- # /docs/typescript/api/index/interfaces/LendAccount [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendAccount # Interface: LendAccount Defined in: packages/sdk/src/lend/types.ts:143 A whole SomniaLend account: the Pool's risk aggregate plus every non-empty per-reserve position, in one read. **Details** `healthFactor` is a wad (1e18): liquidation triggers below 1e18. The `*Base` aggregates are denominated in the oracle base currency (`baseCurrencyDecimals`, USD/8dp on this deployment). **Gotchas** A debt-free account reports `maxUint256` ("infinite") as its `healthFactor`. The `*Base` aggregates are cross-asset totals, not token amounts. ## Properties ### totalCollateralBase > **totalCollateralBase**: `bigint` Defined in: packages/sdk/src/lend/types.ts:145 Total collateral backing the account, base-currency units. *** ### totalDebtBase > **totalDebtBase**: `bigint` Defined in: packages/sdk/src/lend/types.ts:147 Total debt owed, base-currency units. *** ### availableBorrowsBase > **availableBorrowsBase**: `bigint` Defined in: packages/sdk/src/lend/types.ts:149 Remaining borrowing power, base-currency units. *** ### currentLiquidationThresholdBps > **currentLiquidationThresholdBps**: `number` Defined in: packages/sdk/src/lend/types.ts:151 Account-weighted liquidation threshold, bps. *** ### ltvBps > **ltvBps**: `number` Defined in: packages/sdk/src/lend/types.ts:153 Account-weighted max LTV, bps. *** ### healthFactor > **healthFactor**: `bigint` Defined in: packages/sdk/src/lend/types.ts:155 Health factor, wad (1e18); < 1e18 ⇒ liquidatable; maxUint256 ⇒ no debt. *** ### baseCurrencyDecimals > **baseCurrencyDecimals**: `number` Defined in: packages/sdk/src/lend/types.ts:157 Decimals of the base currency the `*Base` fields use. *** ### positions > **positions**: [`LendPosition`](LendPosition.md)[] Defined in: packages/sdk/src/lend/types.ts:159 Every reserve the account holds a supply or debt in (empty rows dropped). --- # /docs/typescript/api/index/interfaces/LendAddresses [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendAddresses # Interface: LendAddresses Defined in: packages/sdk/src/lend/types.ts:15 SomniaLend contract addresses (see docs.somnialend.finance/deployed-contracts). Set them on `config.addresses.lend`; every lend method throws a clear error when the address it needs is unset, like the rest of `SomniaMarketsAddresses`. ## Properties ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:17 The Pool proxy — every user action (supply/withdraw/borrow/repay) targets it. *** ### poolAddressesProvider? > `optional` **poolAddressesProvider?**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:19 PoolAddressesProvider — the market id the UiPoolDataProvider reads are keyed by. *** ### uiPoolDataProvider? > `optional` **uiPoolDataProvider?**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:21 UiPoolDataProviderV3 — the aggregated whole-market / whole-account reads. *** ### wrappedTokenGateway? > `optional` **wrappedTokenGateway?**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:26 WrappedTokenGatewayV3 — native-SOMI wrap/unwrap periphery. Optional: only the `*Native` lender methods need it; they throw when it is unset. --- # /docs/typescript/api/index/interfaces/LendPosition [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendPosition # Interface: LendPosition Defined in: packages/sdk/src/lend/types.ts:111 One asset the account has supplied or borrowed, inside [LendAccount](LendAccount.md). ## Properties ### underlying > **underlying**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:113 The underlying ERC-20 of the reserve. *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/lend/types.ts:115 Underlying ticker (denormalized from the reserve row for display). *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/lend/types.ts:117 Underlying decimals (scales both balances below). *** ### aTokenBalance > **aTokenBalance**: `bigint` Defined in: packages/sdk/src/lend/types.ts:119 Current aToken balance incl. accrued interest, raw units. *** ### variableDebt > **variableDebt**: `bigint` Defined in: packages/sdk/src/lend/types.ts:121 Current variable debt incl. accrued interest, raw units. *** ### usageAsCollateralEnabled > **usageAsCollateralEnabled**: `boolean` Defined in: packages/sdk/src/lend/types.ts:123 Whether THIS account is using the supplied balance as collateral. --- # /docs/typescript/api/index/interfaces/LendRepayOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendRepayOptions # Interface: LendRepayOptions Defined in: packages/sdk/src/lend/lender.ts:76 Options for [Lender.repay](Lender.md#repay). ## Extends - [`LendWriteOptions`](LendWriteOptions.md) ## Properties ### approve? > `optional` **approve?**: `boolean` Defined in: packages/sdk/src/lend/lender.ts:44 Auto-approve the token pull when the allowance is short (default true) — same doctrine as the trader: one allowance read per (token, spender) pair, approve `maxUint256` once, cache the grant for the lender's lifetime. #### Inherited from [`LendWriteOptions`](LendWriteOptions.md).[`approve`](LendWriteOptions.md#approve) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/lend/lender.ts:46 Per-call gas ceiling override. #### Inherited from [`LendWriteOptions`](LendWriteOptions.md).[`gas`](LendWriteOptions.md#gas) *** ### onBehalfOf? > `optional` **onBehalfOf?**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/lender.ts:78 Repay another address's debt (default: the signer's own). --- # /docs/typescript/api/index/interfaces/LendReserve [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendReserve # Interface: LendReserve Defined in: packages/sdk/src/lend/types.ts:47 One SomniaLend reserve (a listed asset), decoded from the UiPoolDataProvider aggregate — config, caps, live rates/indexes, liquidity, and the oracle price. **Details** Rates and indexes are Aave ray values (1e27) — convert a rate for display with [lendRayRateToApy](../functions/lendRayRateToApy.md). Token amounts (`availableLiquidity`, `totalVariableDebt`, `totalSupplied`) are raw `decimals`-scaled units, accrued to the read's block timestamp. **Gotchas** `borrowCap`/`supplyCap` are WHOLE tokens (Aave convention), not raw units — 0 means uncapped. ## Properties ### underlying > **underlying**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:49 The underlying ERC-20 the reserve lends (approve/supply/borrow this token). *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/lend/types.ts:51 Underlying token ticker, e.g. "USDso". *** ### name > **name**: `string` Defined in: packages/sdk/src/lend/types.ts:53 Underlying token full name. *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/lend/types.ts:55 Underlying token decimals (scales every raw amount on this row). *** ### aToken > **aToken**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:57 The interest-bearing aToken minted on supply (balance grows in place). *** ### variableDebtToken > **variableDebtToken**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/types.ts:59 The variable-debt token minted on borrow (balance grows with interest). *** ### ltvBps > **ltvBps**: `number` Defined in: packages/sdk/src/lend/types.ts:61 Max borrowing power per unit of this collateral, bps (8000 = 80%). *** ### liquidationThresholdBps > **liquidationThresholdBps**: `number` Defined in: packages/sdk/src/lend/types.ts:63 Collateral value threshold (bps) past which a position can be liquidated. *** ### liquidationBonusBps > **liquidationBonusBps**: `number` Defined in: packages/sdk/src/lend/types.ts:65 Liquidator bonus, bps over par (10500 = 5% bonus). *** ### reserveFactorBps > **reserveFactorBps**: `number` Defined in: packages/sdk/src/lend/types.ts:67 Slice of borrow interest diverted to the protocol treasury, bps. *** ### usageAsCollateralEnabled > **usageAsCollateralEnabled**: `boolean` Defined in: packages/sdk/src/lend/types.ts:69 Whether supplying this reserve can back borrows at all. *** ### borrowingEnabled > **borrowingEnabled**: `boolean` Defined in: packages/sdk/src/lend/types.ts:71 Whether the reserve can be borrowed. *** ### isActive > **isActive**: `boolean` Defined in: packages/sdk/src/lend/types.ts:73 Reserve is listed and operational (false ⇒ every action reverts). *** ### isFrozen > **isFrozen**: `boolean` Defined in: packages/sdk/src/lend/types.ts:75 Frozen: existing positions stand but new supplies/borrows revert. *** ### isPaused > **isPaused**: `boolean` Defined in: packages/sdk/src/lend/types.ts:77 Paused: every action on the reserve reverts. *** ### flashLoanEnabled > **flashLoanEnabled**: `boolean` Defined in: packages/sdk/src/lend/types.ts:79 Whether the reserve is flash-loanable. *** ### borrowCap > **borrowCap**: `bigint` Defined in: packages/sdk/src/lend/types.ts:81 Borrow cap in WHOLE tokens (0 = uncapped). *** ### supplyCap > **supplyCap**: `bigint` Defined in: packages/sdk/src/lend/types.ts:83 Supply cap in WHOLE tokens (0 = uncapped). *** ### availableLiquidity > **availableLiquidity**: `bigint` Defined in: packages/sdk/src/lend/types.ts:85 Un-borrowed underlying sitting in the aToken, raw units. *** ### totalVariableDebt > **totalVariableDebt**: `bigint` Defined in: packages/sdk/src/lend/types.ts:87 Total variable debt outstanding, raw units, accrued to the read time. *** ### totalSupplied > **totalSupplied**: `bigint` Defined in: packages/sdk/src/lend/types.ts:89 Total supplied (available + borrowed), raw units, accrued to the read time. *** ### liquidityRateRay > **liquidityRateRay**: `bigint` Defined in: packages/sdk/src/lend/types.ts:91 Annual supply rate, ray (1e27) — [lendRayRateToApy](../functions/lendRayRateToApy.md) for display. *** ### variableBorrowRateRay > **variableBorrowRateRay**: `bigint` Defined in: packages/sdk/src/lend/types.ts:93 Annual variable borrow rate, ray (1e27). *** ### liquidityIndexRay > **liquidityIndexRay**: `bigint` Defined in: packages/sdk/src/lend/types.ts:95 Supply index, ray — current aToken balance = scaled balance × this. *** ### variableBorrowIndexRay > **variableBorrowIndexRay**: `bigint` Defined in: packages/sdk/src/lend/types.ts:97 Variable borrow index, ray — current debt = scaled debt × this. *** ### lastUpdateTimestamp > **lastUpdateTimestamp**: `number` Defined in: packages/sdk/src/lend/types.ts:99 Unix seconds the reserve's stored rates/indexes were last written on-chain. *** ### priceInBaseCurrency > **priceInBaseCurrency**: `bigint` Defined in: packages/sdk/src/lend/types.ts:101 Oracle price of one whole token, in base-currency units ([baseCurrencyDecimals](#basecurrencydecimals)). *** ### baseCurrencyDecimals > **baseCurrencyDecimals**: `number` Defined in: packages/sdk/src/lend/types.ts:103 Decimals of the base currency (USD-denominated deployments use 8). --- # /docs/typescript/api/index/interfaces/LendSupplyOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendSupplyOptions # Interface: LendSupplyOptions Defined in: packages/sdk/src/lend/lender.ts:54 Options for [Lender.supply](Lender.md#supply). ## Extends - [`LendWriteOptions`](LendWriteOptions.md) ## Properties ### approve? > `optional` **approve?**: `boolean` Defined in: packages/sdk/src/lend/lender.ts:44 Auto-approve the token pull when the allowance is short (default true) — same doctrine as the trader: one allowance read per (token, spender) pair, approve `maxUint256` once, cache the grant for the lender's lifetime. #### Inherited from [`LendWriteOptions`](LendWriteOptions.md).[`approve`](LendWriteOptions.md#approve) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/lend/lender.ts:46 Per-call gas ceiling override. #### Inherited from [`LendWriteOptions`](LendWriteOptions.md).[`gas`](LendWriteOptions.md#gas) *** ### onBehalfOf? > `optional` **onBehalfOf?**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/lender.ts:56 Credit the position to another address (default: the signer). --- # /docs/typescript/api/index/interfaces/LendWithdrawOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendWithdrawOptions # Interface: LendWithdrawOptions Defined in: packages/sdk/src/lend/lender.ts:64 Options for [Lender.withdraw](Lender.md#withdraw). ## Properties ### to? > `optional` **to?**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/lender.ts:66 Send the withdrawn tokens to another address (default: the signer). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/lend/lender.ts:68 Per-call gas ceiling override. --- # /docs/typescript/api/index/interfaces/LendWriteOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LendWriteOptions # Interface: LendWriteOptions Defined in: packages/sdk/src/lend/lender.ts:38 Options shared by the ERC-20 lend writes. ## Extended by - [`LendSupplyOptions`](LendSupplyOptions.md) - [`LendRepayOptions`](LendRepayOptions.md) ## Properties ### approve? > `optional` **approve?**: `boolean` Defined in: packages/sdk/src/lend/lender.ts:44 Auto-approve the token pull when the allowance is short (default true) — same doctrine as the trader: one allowance read per (token, spender) pair, approve `maxUint256` once, cache the grant for the lender's lifetime. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/lend/lender.ts:46 Per-call gas ceiling override. --- # /docs/typescript/api/index/interfaces/Lender [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Lender # Interface: Lender Defined in: packages/sdk/src/lend/lender.ts:104 Write surface for the SomniaLend money market, bound to one signer — built by `client.lend.createLender` on the owning client. **Details** Every method resolves once the tx is MINED, with its receipt. Amounts are raw underlying-token units. ERC-20 pulls (supply / repay) auto-approve by default; the `*Native` variants route native SOMI through the WrappedTokenGateway so the caller never touches WSOMI. **Gotchas** Every method throws `ContractRevertError` if the chain rejected the action — including a mined tx with `receipt.status: "reverted"`, whose reason is recovered by replaying the call at that block when the node still has the state — and `RpcError` when the send or the receipt read does not complete. A reverted lend action never resolves as success. The `*Native` variants need `wrappedTokenGateway` in the lend addresses. Borrowing is variable-rate only. Position/risk reads live on the lend client (`getAccount`), not here. ## Properties ### account > `readonly` **account**: `` `0x${string}` `` Defined in: packages/sdk/src/lend/lender.ts:106 The signer address the lender acts as. ## Methods ### supply() > **supply**(`asset`, `amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:124 Supply `amount` of `asset` to earn interest (and optionally back borrows). Auto-approves the Pool when the allowance is short. **Details** - `asset`: Underlying ERC-20 to supply (a [LendReserve](LendReserve.md).underlying). - `amount`: Raw underlying units. - `opts`: Approval/gas overrides, or supply on behalf of another address. **Example** (Supplying an ERC-20) ```ts const lender = client.lend.createLender({ privateKey }); await lender.supply(usdso, 1_000n * 10n ** 18n); ``` #### Parameters ##### asset `` `0x${string}` `` ##### amount `bigint` ##### opts? [`LendSupplyOptions`](LendSupplyOptions.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### withdraw() > **withdraw**(`asset`, `amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:129 Withdraw supplied `asset`. Pass `maxUint256` as `amount` to withdraw the full balance including accrued interest. See [Lender.supply](#supply). #### Parameters ##### asset `` `0x${string}` `` ##### amount `bigint` ##### opts? [`LendWithdrawOptions`](LendWithdrawOptions.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### borrow() > **borrow**(`asset`, `amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:134 Borrow `asset` against the account's collateral (variable rate). Reverts on-chain if the health factor would drop below 1. See [Lender.supply](#supply). #### Parameters ##### asset `` `0x${string}` `` ##### amount `bigint` ##### opts? ###### gas? `bigint` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### repay() > **repay**(`asset`, `amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:140 Repay variable-rate debt in `asset`. Pass `maxUint256` as `amount` to clear the full debt including accrued interest (requires balance ≥ debt; the contract only pulls what is owed). See [Lender.supply](#supply). #### Parameters ##### asset `` `0x${string}` `` ##### amount `bigint` ##### opts? [`LendRepayOptions`](LendRepayOptions.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setUseAsCollateral() > **setUseAsCollateral**(`asset`, `useAsCollateral`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:145 Toggle whether the supplied `asset` balance backs borrows. Disabling reverts on-chain if it would leave existing debt under-collateralized. #### Parameters ##### asset `` `0x${string}` `` ##### useAsCollateral `boolean` ##### opts? ###### gas? `bigint` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### supplyNative() > **supplyNative**(`amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:150 Supply native SOMI (wrapped to WSOMI by the gateway). Sibling of [Lender.supply](#supply); needs `addresses.lend.wrappedTokenGateway`. #### Parameters ##### amount `bigint` ##### opts? ###### onBehalfOf? `` `0x${string}` `` ###### gas? `bigint` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### withdrawNative() > **withdrawNative**(`amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:156 Withdraw the WSOMI position as native SOMI. `maxUint256` withdraws all. Auto-approves the gateway to pull the aWSOMI (an ERC-20 approve on the aToken). Sibling of [Lender.withdraw](#withdraw). #### Parameters ##### amount `bigint` ##### opts? [`LendWithdrawOptions`](LendWithdrawOptions.md) & `object` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### borrowNative() > **borrowNative**(`amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:162 Borrow native SOMI (variable rate) via the gateway. First-use grants the gateway credit delegation on the WSOMI variable-debt token (`approveDelegation`, cached like approvals). Sibling of [Lender.borrow](#borrow). #### Parameters ##### amount `bigint` ##### opts? ###### approve? `boolean` ###### gas? `bigint` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### repayNative() > **repayNative**(`amount`, `opts?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/lend/lender.ts:168 Repay WSOMI debt with native SOMI. `maxUint256` is not supported for the native path — pass a slight overpayment instead; the gateway refunds the excess. Sibling of [Lender.repay](#repay). #### Parameters ##### amount `bigint` ##### opts? ###### onBehalfOf? `` `0x${string}` `` ###### gas? `bigint` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### clearApprovalCache() > **clearApprovalCache**(): `void` Defined in: packages/sdk/src/lend/lender.ts:174 Drop the lender's in-memory approval/delegation grant cache (mirrors the trader's `clearApprovalCache`) — needed only if an approval was revoked out-of-band while this lender instance is alive. #### Returns `void` --- # /docs/typescript/api/index/interfaces/LinkPerpStopOrdersParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LinkPerpStopOrdersParams # Interface: LinkPerpStopOrdersParams Defined in: packages/sdk/src/trade.ts:1442 Inputs to [Trader.linkPerpStopOrders](Trader.md#linkperpstoporders) — pair two stops that already exist. The after-the-fact form of [PlacePerpStopOrderParams.pair](PlacePerpStopOrderParams.md#pair), and the way to re-pair a survivor: when one leg of a pair fires WITHOUT filling, the other stays armed and is unlinked, free to be paired with a fresh leg. ## Properties ### registry > **registry**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1444 The PerpStopOrderRegistry holding both orders. *** ### orderIdA > **orderIdA**: `string` \| `bigint` Defined in: packages/sdk/src/trade.ts:1446 First order id (either operator; the pair is ordered by the registry). *** ### orderIdB > **orderIdB**: `string` \| `bigint` Defined in: packages/sdk/src/trade.ts:1448 Second order id. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1454 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/LiquidationEngineConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiquidationEngineConfig # Interface: LiquidationEngineConfig Defined in: packages/sdk/src/perp/system.ts:123 The LiquidationEngine's CONFIGURED bounds — not its history, which is indexed as `LiquidationEvent`. ## Properties ### address > **address**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:125 The engine's address. *** ### marginBank > **marginBank**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:127 The MarginBank it liquidates against — cross-check against the system config. *** ### penaltyBps > **penaltyBps**: `bigint` Defined in: packages/sdk/src/perp/system.ts:129 Penalty charged on a liquidation, bps. *** ### minSpreadBps > **minSpreadBps**: `bigint` Defined in: packages/sdk/src/perp/system.ts:131 Lower bound on the liquidation spread, bps. *** ### maxSpreadBps > **maxSpreadBps**: `bigint` Defined in: packages/sdk/src/perp/system.ts:133 Upper bound on the liquidation spread, bps. *** ### maxVolumePerBlock > **maxVolumePerBlock**: `bigint` Defined in: packages/sdk/src/perp/system.ts:135 Per-block cap on liquidated notional, raw quote units — the throughput throttle. *** ### bidderCount > **bidderCount**: `bigint` Defined in: packages/sdk/src/perp/system.ts:143 Registered stage-4 backstop bidders. Zero is a real operational signal, not just a statistic: with no bidders the takeover stage has nobody to take a position over, so the waterfall falls through to ADL sooner. --- # /docs/typescript/api/index/interfaces/ListLiquidationsOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ListLiquidationsOptions # Interface: ListLiquidationsOptions Defined in: packages/sdk/src/perp/history.ts:608 Filters and pagination for [client.listLiquidations](SomniaMarketsClient.md#listliquidations). Named rather than inline because this shape is declared twice - here and on the client member - and SDK-TYPE-005 exists so the two cannot drift as the API grows. ## Properties ### account? > `optional` **account?**: `string` Defined in: packages/sdk/src/perp/history.ts:610 Liquidated account. Case-insensitive: lowercased before the query. *** ### pool? > `optional` **pool?**: `string` Defined in: packages/sdk/src/perp/history.ts:612 Perp pool address. Case-insensitive: lowercased before the query. *** ### kind? > `optional` **kind?**: `"AutoDeleveraged"` \| `"CloseOutMarginSettled"` \| `"BadDebtAbsorbed"` \| `"PositionTransferred"` \| `"AccountLiquidated"` \| `"PositionLiquidated"` \| `"PositionTakenOver"` \| `"ResidualBadDebt"` \| `"ResidualBackedByOpenPnl"` \| `"AdlCapacityShortfall"` \| `"AdlPriceCapacityExhausted"` \| `"AdlSessionDiscarded"` \| `"PositionSkipped"` \| `"Throttled"` \| `"KeeperReward"` \| `"OrderPanicked"` \| `"CoverageDeclined"` Defined in: packages/sdk/src/perp/history.ts:618 A single stage to return. Matched EXACTLY as given and NOT lowercased, unlike the addresses above - it is the schema's own discriminator, so `"autodeleveraged"` would match nothing. A union rather than a `string` precisely because that miss is silent: an empty page reads as "no ADLs happened", so the typo has to be a compile error instead. *** ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/perp/history.ts:620 Rows per page. Defaults to 50. *** ### offset? > `optional` **offset?**: `number` Defined in: packages/sdk/src/perp/history.ts:628 Rows to skip. Defaults to 0. The query carries a TOTAL order (`timestamp`, then `blockNumber`, then the `id` primary key), so the sequence is STABLE between requests — two reads of an unchanged table agree, which `timestamp` alone did not guarantee for rows sharing a block. That fixes tie ordering; it does not make offset paging snapshot-consistent against a LIVE table. See the note on `listLiquidations`. --- # /docs/typescript/api/index/interfaces/LiveFill [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiveFill # Interface: LiveFill Defined in: packages/sdk/src/store.ts:192 One fill in the live store, with indexer-compatible identifiers and raw units. **Details** Binary-side fields are enriched from the related live orders. Spot fills leave the binary-only fields undefined. **Gotchas** A just-received fill can temporarily omit maker, taker, or side data because the related order event can arrive later in the same transaction. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/store.ts:194 `${blockNumber}_${logIndex}` — matches the indexer Fill id *** ### market\_id > **market\_id**: `string` Defined in: packages/sdk/src/store.ts:196 Id of the market the fill executed in (Hasura FK naming; joins [LiveMarket](../type-aliases/LiveMarket.md)). *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/store.ts:198 lowercased pool address (the log source) *** ### taker > **taker**: `` `0x${string}` `` \| `undefined` Defined in: packages/sdk/src/store.ts:204 Taker info is unresolved at OrderFilled emission time (the taker's OrderPlaced fires AFTER the fill in the same tx). Resolved via the takerOrder_id foreign key — enrichFill back-joins to LiveOrder. *** ### maker > **maker**: `` `0x${string}` `` \| `undefined` Defined in: packages/sdk/src/store.ts:209 Maker's address. Undefined until the maker's resting order is known — set when it was witnessed live, else back-joined from the order row via `makerOrder_id`. *** ### takerSide > **takerSide**: [`BinarySide`](../type-aliases/BinarySide.md) \| `undefined` Defined in: packages/sdk/src/store.ts:214 Taker's outcome side. Undefined on spot fills, and on binary fills until the taker order is joined (see `taker`). *** ### makerSide > **makerSide**: [`BinarySide`](../type-aliases/BinarySide.md) \| `undefined` Defined in: packages/sdk/src/store.ts:219 Maker's outcome side. Undefined on spot fills, and until the maker order is joined (see `maker`). *** ### kind > **kind**: [`BinaryFillKind`](../type-aliases/BinaryFillKind.md) \| `undefined` Defined in: packages/sdk/src/store.ts:224 How the fill settled (see [BinaryFillKind](../type-aliases/BinaryFillKind.md)). Undefined on spot fills, and on binary fills until BOTH sides are joined (classification needs both). *** ### takerIsBid > **takerIsBid**: `boolean` \| `undefined` Defined in: packages/sdk/src/store.ts:232 True when the taker bought the base/YES (the maker was the ask) — the tape's aggressor direction, valid on every market kind. Seeded from the indexer row on snapshot fills; on live fills derived at OrderFilled from the maker's resting side (undefined only when the maker order was never witnessed, until enrichFill joins the taker's OrderPlaced). *** ### takerOrder\_id > **takerOrder\_id**: `string` Defined in: packages/sdk/src/store.ts:234 Foreign keys to LiveOrder rows for join-side recovery. *** ### makerOrder\_id > **makerOrder\_id**: `string` Defined in: packages/sdk/src/store.ts:236 Maker-side counterpart of `takerOrder_id` (a [LiveOrder](LiveOrder.md) key). *** ### fillPrice > **fillPrice**: `string` Defined in: packages/sdk/src/store.ts:238 Raw quote/collateral units per whole base/outcome token. *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/store.ts:243 Base/outcome tokens exchanged — raw units scaled by the market's `baseDecimals` (decimal string). *** ### quoteQuantity > **quoteQuantity**: `string` Defined in: packages/sdk/src/store.ts:245 quote value = quantity * fillPrice / 10^baseDecimals *** ### takerRemainingQuantity > **takerRemainingQuantity**: `string` Defined in: packages/sdk/src/store.ts:247 Taker order's unfilled size after this fill — raw base/outcome units (decimal string). *** ### makerRemainingQuantity > **makerRemainingQuantity**: `string` Defined in: packages/sdk/src/store.ts:249 Maker order's unfilled size after this fill — raw base/outcome units (decimal string). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/store.ts:251 Block timestamp of the fill — unix seconds (decimal string). *** ### blockNumber > **blockNumber**: `number` Defined in: packages/sdk/src/store.ts:253 Block the fill landed in. *** ### logIndex > **logIndex**: `number` Defined in: packages/sdk/src/store.ts:255 Log index within the block — with `blockNumber`, the fill's tape position. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/store.ts:257 Transaction that produced the fill. --- # /docs/typescript/api/index/interfaces/LiveFundingUpdate [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiveFundingUpdate # Interface: LiveFundingUpdate Defined in: packages/sdk/src/store.ts:154 A funding settlement observed by the live tail, shaped to splice onto the indexed `FundingRateUpdate` series. Deliberately NOT the full indexed row. The tail sees only what `FundingUpdated` carries, and two of the indexed fields are DERIVED from state the tail does not have: `intervalsAccrued` needs `n` from the funding-parameters epoch series, and the covered span needs the settlement anchor. Rather than guess them, they are absent here and arrive with the indexed row a moment later. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/store.ts:156 `${pool}_${blockNumber}_${logIndex}` — matches the indexer FundingRateUpdate id. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/store.ts:158 Perp pool (lowercased). *** ### fundingRate > **fundingRate**: `string` Defined in: packages/sdk/src/store.ts:160 Per-CALCULATION-WINDOW rate, 1e18-scaled, signed. Normalize with `fundingWindowSec`. *** ### cumulativeFundingPerUnit > **cumulativeFundingPerUnit**: `string` Defined in: packages/sdk/src/store.ts:162 Cumulative index AFTER this settlement (1e18 x quote per whole base, signed). *** ### indexPrice > **indexPrice**: `string` Defined in: packages/sdk/src/store.ts:163 *** ### markPrice > **markPrice**: `string` \| `null` Defined in: packages/sdk/src/store.ts:165 Null when the event's 0 sentinel fired for a stale mark feed. *** ### intervalsSettled > **intervalsSettled**: `string` Defined in: packages/sdk/src/store.ts:167 UNCLAMPED interval span, as emitted. Accrual is capped at n = window / interval. *** ### fundingWindowSec > **fundingWindowSec**: `number` \| `null` Defined in: packages/sdk/src/store.ts:169 Params as last known for the market; null before the first indexed funding row. *** ### fundingIntervalSec > **fundingIntervalSec**: `number` \| `null` Defined in: packages/sdk/src/store.ts:170 *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/store.ts:171 *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/store.ts:172 *** ### logIndex > **logIndex**: `number` Defined in: packages/sdk/src/store.ts:174 Log index within the block — with blockNumber, the settlement's position in the series. --- # /docs/typescript/api/index/interfaces/LiveOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiveOrder # Interface: LiveOrder Defined in: packages/sdk/src/store.ts:265 A resting/closed order (mirror of indexer Order). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/store.ts:267 `${pool}_${orderId}` *** ### market\_id > **market\_id**: `string` Defined in: packages/sdk/src/store.ts:272 Id of the market the order was placed in. Pools are RECYCLED across markets (never concurrently), so book reads filter on this, not the pool alone. *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/store.ts:274 Lowercased pool address hosting the order's book. *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/store.ts:276 On-chain order id, unique per pool (decimal string). *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/store.ts:278 Order owner's address (as emitted — compare case-insensitively). *** ### side > **side**: [`BinarySide`](../type-aliases/BinarySide.md) \| `undefined` Defined in: packages/sdk/src/store.ts:280 Binary outcome side. Undefined on spot orders (spot has no YES/NO). *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/store.ts:285 Which side of the book's NATIVE terms the order rests on: true = bid. Native terms are YES terms for binary, quote-per-base for spot. *** ### userData > **userData**: `string` Defined in: packages/sdk/src/store.ts:290 Opaque caller bookkeeping from OrderPlaced, carried verbatim (uint256 decimal string) — never decoded; v2 takes the side from `BinaryOrderPlaced.kind` instead. *** ### price > **price**: `string` Defined in: packages/sdk/src/store.ts:295 Limit price in the book's native terms — raw quote/collateral units per whole base/outcome token (decimal string). *** ### fullQuantity > **fullQuantity**: `string` Defined in: packages/sdk/src/store.ts:297 Original size at placement — raw base/outcome units (decimal string). *** ### quantityRemaining > **quantityRemaining**: `string` Defined in: packages/sdk/src/store.ts:299 Unfilled size still resting — raw base/outcome units (decimal string). *** ### filledQuantity > **filledQuantity**: `string` Defined in: packages/sdk/src/store.ts:301 Cumulative size filled so far — raw base/outcome units (decimal string). *** ### expireTimestampNs > **expireTimestampNs**: `string` Defined in: packages/sdk/src/store.ts:307 Order expiry as a uint64 nanosecond timestamp (decimal string). GTC orders carry type(uint64).max, so they never expire; the matcher rejects a 0/past expiry at placement, so a resting order always has a real future ns value. *** ### status > **status**: [`OrderStatus`](../type-aliases/OrderStatus.md) Defined in: packages/sdk/src/store.ts:309 Lifecycle state (see [OrderStatus](../type-aliases/OrderStatus.md)). *** ### rested > **rested**: `boolean` Defined in: packages/sdk/src/store.ts:314 True once OrderRested landed — the order is ON the book. Only rested open orders count toward the materialized book levels. *** ### createdAt > **createdAt**: `string` Defined in: packages/sdk/src/store.ts:316 Placement block timestamp — unix seconds (decimal string). *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/store.ts:318 Transaction that placed the order. --- # /docs/typescript/api/index/interfaces/LivePrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LivePrice # Interface: LivePrice Defined in: packages/sdk/src/priceFeed/types.ts:52 The current price of one asset — the `Feed` singleton, parsed. This is what a live watch keeps current. ## Properties ### asset > **asset**: `string` Defined in: packages/sdk/src/priceFeed/types.ts:54 Asset symbol this feed tracks (e.g. "BTC", "ETH"), uppercased. *** ### price > **price**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:59 Latest price, human units (raw / 1e18). Lossy past ~15 sig figs — use `raw` for exact math. *** ### ema > **ema**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:61 Latest EMA-smoothed mark price, human units (the feed's `mark`). *** ### blockNumber > **blockNumber**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:63 Block the latest tick landed in (chain time, monotonic). *** ### blockTimestamp > **blockTimestamp**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:68 Block timestamp of the latest tick — unix seconds, chain time. Use this as a series x-axis; it never drifts. *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:70 Price scale (Feed.decimals, always 18 today). *** ### raw > **raw**: `object` Defined in: packages/sdk/src/priceFeed/types.ts:75 Exact 1e18-scaled integer strings — never round-trip money through the `number` fields above. #### price > **price**: `string` Exact spot price — 1e18-scaled integer string. #### ema > **ema**: `string` Exact EMA mark — 1e18-scaled integer string. --- # /docs/typescript/api/index/interfaces/LockedBalance [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LockedBalance # Interface: LockedBalance Defined in: packages/sdk/src/spot/poolReads.ts:137 Base/quote amounts one owner has locked in resting orders. ## Properties ### lockedBase > **lockedBase**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:139 Base locked across the owner's resting asks, raw base units. *** ### lockedQuote > **lockedQuote**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:141 Quote locked across the owner's resting bids, raw quote units. --- # /docs/typescript/api/index/interfaces/LockedTokenBreakdown [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LockedTokenBreakdown # Interface: LockedTokenBreakdown Defined in: packages/sdk/src/spot/poolReads.ts:194 Book-wide lock state, per token — see [SomniaMarketsClient.getLockedTokenBreakdown](SomniaMarketsClient.md#getlockedtokenbreakdown). ## Properties ### base > **base**: [`TokenLockBreakdown`](TokenLockBreakdown.md) Defined in: packages/sdk/src/spot/poolReads.ts:195 *** ### quote > **quote**: [`TokenLockBreakdown`](TokenLockBreakdown.md) Defined in: packages/sdk/src/spot/poolReads.ts:196 --- # /docs/typescript/api/index/interfaces/MachineryStep [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MachineryStep # Interface: MachineryStep Defined in: packages/sdk/src/marketTypes/types.ts:17 One type-specific machinery onboarding step (rendered by a wizard; the preflight validators key off `id`). Descriptive only — no logic here. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/marketTypes/types.ts:19 Stable step id (e.g. "market-creator", "funding", "series"). *** ### label > **label**: `string` Defined in: packages/sdk/src/marketTypes/types.ts:21 Short human label. *** ### description > **description**: `string` Defined in: packages/sdk/src/marketTypes/types.ts:23 One-line description of what the operator does in this step. --- # /docs/typescript/api/index/interfaces/MarginAccount [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarginAccount # Interface: MarginAccount Defined in: packages/sdk/src/perp/margin.ts:43 An account's cross-margin state in the MarginBank (collateral is the bank's single collateral token, e.g. USDso — raw units). ## Properties ### unlockedCollateralBalance > **unlockedCollateralBalance**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:45 Free collateral after locks (signed — settlement can drive it negative). *** ### lockedCollateral > **lockedCollateral**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:47 Collateral reserved for pending orders. *** ### activePerpPools > **activePerpPools**: `` `0x${string}` ``[] Defined in: packages/sdk/src/perp/margin.ts:49 Perp pools where the account holds an open position. *** ### equity > **equity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:51 Equity = collateral + unrealized PnL − pending funding (signed). *** ### withdrawable > **withdrawable**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:53 Collateral withdrawable right now (respects margin requirements). *** ### imReq > **imReq**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:55 Sum of notional × initialMarginBps / 10000 across all markets (raw). *** ### mmReq > **mmReq**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:57 Sum of notional × maintenanceMarginBps / 10000 across all markets (raw). *** ### cmReq > **cmReq**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:59 Sum of notional × closeOutMarginBps / 10000 across all markets (raw). *** ### marginStatus > **marginStatus**: [`MarginStatus`](../type-aliases/MarginStatus.md) Defined in: packages/sdk/src/perp/margin.ts:61 Health bucket derived from equity vs the requirements. --- # /docs/typescript/api/index/interfaces/MarkSources [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarkSources # Interface: MarkSources Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:116 Mark sources per market key, plus a fallback price for quiet markets. ## Properties ### series > **series**: `ReadonlyMap`\<`string`, [`MarkSeries`](../type-aliases/MarkSeries.md)\> Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:118 Candle-close series per market (oldest first). *** ### lastPrice > **lastPrice**: `ReadonlyMap`\<`string`, `number`\> Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:120 Last known price per market, used when a series has no sample yet. --- # /docs/typescript/api/index/interfaces/MarketCreatorAdmin [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketCreatorAdmin # Interface: MarketCreatorAdmin Defined in: packages/sdk/src/marketCreatorAdmin.ts:326 The MarketCreator write + status surface — stamp out creators, register rolling series, fund/roll/tune them (see the module notes above). Built via `client.createMarketCreatorAdmin(config)` with a signer ([MarketCreatorAdminConfig](OracleHubAdminConfig.md)); every write sends one tx and resolves with its receipt after inclusion. Every write throws `ContractRevertError` when the chain rejects it — at simulation, at send, or as a mined receipt with `status: "reverted"` (the reason is recovered by replaying the call at that block while the node still has the state) — and `RpcError` when the send or the receipt read does not complete. A reverted write never resolves as if it had been confirmed. ## Methods ### createMarketCreator() > **createMarketCreator**(`p`): `Promise`\<[`CreateMarketCreatorResult`](CreateMarketCreatorResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:332 Stamp out a new MarketCreator (+ its policy) from the factory, bound to `(operatorId, venueId, core, adapter)` + a default book config. Resolves with the minted `creator` + `policy` (decoded from `MarketCreatorCreated`). #### Parameters ##### p [`CreateMarketCreatorParams`](CreateMarketCreatorParams.md) #### Returns `Promise`\<[`CreateMarketCreatorResult`](CreateMarketCreatorResult.md)\> *** ### fundMarketCreator() > **fundMarketCreator**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:337 Send native currency to a creator's `receive()` — it pays for reactivity rolls, so it must hold a balance on testnet/mainnet. #### Parameters ##### p [`FundMarketCreatorParams`](FundMarketCreatorParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### registerSeries() > **registerSeries**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:343 Register (or overwrite) a rolling-market series under a creator. Owner-only. `intervalSec` must be >= 60 and `asset` non-empty (the module reverts otherwise). #### Parameters ##### p [`RegisterSeriesParams`](RegisterSeriesParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### updateSeries() > **updateSeries**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:348 Overwrite an existing series — alias of [registerSeries](#registerseries) (the module upserts by `seriesId`). Provided for wizard clarity. #### Parameters ##### p [`RegisterSeriesParams`](RegisterSeriesParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### triggerRoll() > **triggerRoll**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:357 V1 ONLY: roll a series to its next market (owner-only). MarketCreatorV2 dropped `triggerRoll` — its one start path is [armFirstRoll](#armfirstroll) at a wall-clock boundary (restart = re-register + armFirstRoll), and stalls are handled by the permissionless [recoverSeries](#recoverseries). Calling this against a v2 creator reverts (selector absent). NOTE: calls the Somnia reactivity precompile — only succeeds on testnet/mainnet, not local anvil. #### Parameters ##### p [`TriggerRollParams`](TriggerRollParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### recoverSeries() > **recoverSeries**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:367 V2: PERMISSIONLESS last-resort recovery of a provably stalled series — covers dead subscriptions (out-of-funds auto-cancel / subscribe strand) and a refunded-but-comatose creator. Rate-limited on-chain (one attempt per backstop period per series); reverts `SeriesNotStalled` without evidence. The ops story after an out-of-funds incident: refuel the creator, call this once per stalled series. Touches the reactivity precompile → testnet/mainnet only. #### Parameters ##### p [`RecoverSeriesParams`](RecoverSeriesParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### armFirstRoll() > **armFirstRoll**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:374 A1: arm a series' FIRST roll at a future boundary WITHOUT minting now (owner-only) — the seamless-migration tool: start a fresh MC's series exactly at the outgoing MC's expiry. NOTE: touches the reactivity precompile — testnet/mainnet only. #### Parameters ##### p [`ArmFirstRollParams`](ArmFirstRollParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### reclaimOracleCredit() > **reclaimOracleCredit**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:380 A1: pull the creator's own accrued oracle surplus (payer credit) out of the hub into its native float. Runs automatically each roll cycle; this is the manual sweep of any leftovers. Permissionless. #### Parameters ##### p [`ReclaimOracleCreditParams`](ReclaimOracleCreditParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### adoptFrom() > **adoptFrom**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:390 In-place creator migration — PULL side (v2). `adoptFrom` inherits a quiesced predecessor's whole series set + each series' pending oracle qid onto the successor, so the next roll fires on the successor off the outgoing market's own answer (strike chain intact, no bootstrap). Reverts unless same operator/venue/owner, the predecessor is quiesced, and the successor's reactivity gas params are set. Touches the reactivity precompile → testnet/mainnet only. See RUNBOOK-mc-migration.md. #### Parameters ##### p [`AdoptFromParams`](AdoptFromParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### handoffTo() > **handoffTo**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:397 In-place creator migration — PUSH side (v2). Retire the outgoing creator: tear down its subscriptions, sweep its native float to `successor`, and set `retired` (bricks rolling). Owner-only; the successor must share owner + venue. Touches the reactivity precompile → testnet/mainnet only. #### Parameters ##### p [`HandoffToParams`](HandoffToParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### swapCreator() > **swapCreator**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:403 Atomically flip a venue's `MarketCreatorPolicy` allowlist from `from` to `to` (policy-owner only) — the cutover switch paired with adoptFrom/handoffTo, so there is never a window where both or neither creator is authorized. #### Parameters ##### p [`SwapCreatorParams`](SwapCreatorParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setReactivityGasParams() > **setReactivityGasParams**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:405 Update the creator's reactivity gas params (owner-only). #### Parameters ##### p [`SetReactivityGasParamsParams`](SetReactivityGasParamsParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### getMarketCreatorOnchain() > **getMarketCreatorOnchain**(`creator`): `Promise`\<[`MarketCreatorOnchain`](MarketCreatorOnchain.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:410 One creator's live binding (core/adapter/operatorId/venueId/owner + default book params). On-chain point read. #### Parameters ##### creator `` `0x${string}` `` #### Returns `Promise`\<[`MarketCreatorOnchain`](MarketCreatorOnchain.md)\> *** ### getSeriesOnchain() > **getSeriesOnchain**(`creator`, `seriesId`): `Promise`\<[`SeriesOnchain`](SeriesOnchain.md)\> Defined in: packages/sdk/src/marketCreatorAdmin.ts:415 One series' live config under a creator. On-chain point read; the returned `intervalSec === 0` means the series was never registered. #### Parameters ##### creator `` `0x${string}` `` ##### seriesId `number` #### Returns `Promise`\<[`SeriesOnchain`](SeriesOnchain.md)\> --- # /docs/typescript/api/index/interfaces/MarketCreatorInfo [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketCreatorInfo # Interface: MarketCreatorInfo Defined in: packages/sdk/src/system.ts:19 On-chain state of the configured MarketCreator (part of [SystemInfo](SystemInfo.md)). Every field is a live read: a failed read throws, so each value here is something the chain actually answered. ## Properties ### marketCount > **marketCount**: `bigint` Defined in: packages/sdk/src/system.ts:21 Markets this creator has minted (`marketCount()`). *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/system.ts:23 Creator owner (`owner()`). *** ### reactivityGasLimit > **reactivityGasLimit**: `bigint` Defined in: packages/sdk/src/system.ts:25 Gas limit its reactivity roll callbacks run with. *** ### reactivityMaxFeePerGas > **reactivityMaxFeePerGas**: `bigint` Defined in: packages/sdk/src/system.ts:27 Reactivity-callback fee ceiling (wei per gas). *** ### reactivityPriorityFeePerGas > **reactivityPriorityFeePerGas**: `bigint` Defined in: packages/sdk/src/system.ts:29 Reactivity-callback tip (wei per gas). *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/system.ts:31 Origin operator id this creator's markets are attributed to. *** ### venueId > **venueId**: `string` Defined in: packages/sdk/src/system.ts:33 Origin venue id within the operator (bytes32 hex). --- # /docs/typescript/api/index/interfaces/MarketCreatorOnchain [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketCreatorOnchain # Interface: MarketCreatorOnchain Defined in: packages/sdk/src/marketCreatorAdmin.ts:274 One MarketCreator's live on-chain binding (the point read a wizard confirms). ## Properties ### core > **core**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:276 Core BinaryMarketsModule the creator schedules markets through (immutable). *** ### adapter > **adapter**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:278 Oracle adapter every series question resolves against (immutable). *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:280 Origin operator id the creator's markets are attributed to (immutable). *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:282 Origin venue id (within the operator) the markets are attributed to (immutable). *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:284 Current owner (can register series / trigger rolls). *** ### defaultBookParams > **defaultBookParams**: [`OrderBookParams`](OrderBookParams.md) Defined in: packages/sdk/src/marketCreatorAdmin.ts:286 Default order-book config applied to every market the creator deploys. --- # /docs/typescript/api/index/interfaces/MarketCreatorPreflightInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketCreatorPreflightInput # Interface: MarketCreatorPreflightInput Defined in: packages/sdk/src/preflight.ts:270 Inputs for the creator-step preflight: the creator's native balance and whether the connected chain supports rolls. ## Properties ### balanceWei > **balanceWei**: `bigint` Defined in: packages/sdk/src/preflight.ts:272 The creator's native balance (wei) — it pays for reactivity rolls. *** ### precompileAvailable > **precompileAvailable**: `boolean` Defined in: packages/sdk/src/preflight.ts:277 Whether the connected chain has the Somnia reactivity precompile (false on local anvil — see [isLocalPrecompileUnavailable](../functions/isLocalPrecompileUnavailable.md)). --- # /docs/typescript/api/index/interfaces/MarketOnchain [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketOnchain # Interface: MarketOnchain Defined in: packages/sdk/src/markets.ts:1706 A BinaryMarket's wiring + live state, read straight from chain (works before the indexer has the market). ## Properties ### marketAddress > **marketAddress**: `` `0x${string}` `` Defined in: packages/sdk/src/markets.ts:1708 The BinaryMarket contract address (resolved from the module record). *** ### outcomeToken > **outcomeToken**: `` `0x${string}` `` Defined in: packages/sdk/src/markets.ts:1710 Protocol-level ERC-6909 outcome-token singleton (shared across all markets). *** ### yesId > **yesId**: `bigint` Defined in: packages/sdk/src/markets.ts:1712 This market's YES position id on the singleton. *** ### noId > **noId**: `bigint` Defined in: packages/sdk/src/markets.ts:1714 This market's NO position id on the singleton. *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/markets.ts:1721 The pool hosting (or that hosted) this market's CLOB. Settlement-extraction v2: a pool address is a TIME-VARYING binding — the same pool serves successive markets, so never key a market by pool address; `(pool, nonce)` identifies this market's slice of the pool's history. *** ### nonce > **nonce**: `bigint` Defined in: packages/sdk/src/markets.ts:1723 The pool's market nonce for THIS market (part of the outcome-id encoding). *** ### collateral > **collateral**: `` `0x${string}` `` Defined in: packages/sdk/src/markets.ts:1725 ERC-20 collateral token the market settles in (its `decimals` scale `backing`). *** ### status > **status**: `number` Defined in: packages/sdk/src/markets.ts:1727 MarketStatus enum: 0 Listed · 1 Trading · 2 Locked · 3 Settling · 4 Resolved · 5 Voided *** ### backing > **backing**: `bigint` Defined in: packages/sdk/src/markets.ts:1734 Live collateral backing. While trading this is the pool's `setBacking` (via `market.backing()`); once the market is FINALIZED onto the settlement singleton the pool reads 0, so this falls back to the settlement record's remaining NET backing (post fee-skim, decremented by each redemption). *** ### finalized > **finalized**: `boolean` Defined in: packages/sdk/src/markets.ts:1739 True once the market's backing + resolution snapshot were swept to the BinarySettlement singleton (redemption is served there from then on). *** ### expiry > **expiry**: `bigint` Defined in: packages/sdk/src/markets.ts:1741 Trading-close / settlement timestamp (seconds). *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/markets.ts:1743 Collateral decimals (falls back to DECIMALS if the read reverts). *** ### winningOutcome > **winningOutcome**: `number` Defined in: packages/sdk/src/markets.ts:1749 Winning outcome (0 = YES, 1 = NO). Only meaningful when `isResolved` — the contract returns 0 by default which would otherwise read as a YES win on a market that hasn't resolved yet. *** ### isResolved > **isResolved**: `boolean` Defined in: packages/sdk/src/markets.ts:1751 Oracle has resolved the market to a concrete winning outcome. *** ### isVoided > **isVoided**: `boolean` Defined in: packages/sdk/src/markets.ts:1753 Oracle has voided the market (payout per the frozen void policy; see `voidPolicy`). *** ### voidPolicy > **voidPolicy**: `number` \| `null` Defined in: packages/sdk/src/markets.ts:1759 Void payout policy frozen at creation: 0 UNIFORM, 2 CLOB_SNAPSHOT (a void pays `[p, D-p]` at the closing YES price). `null` on pre-policy market clones, which lack the selector and always void uniform. --- # /docs/typescript/api/index/interfaces/MarketOnchainSources [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketOnchainSources # Interface: MarketOnchainSources Defined in: packages/sdk/src/markets.ts:1853 Module/settlement wiring `getMarketOnchain` resolves the market through. ## Properties ### module > **module**: `` `0x${string}` `` Defined in: packages/sdk/src/markets.ts:1855 BinaryMarketsModule address (the on-chain market registry). *** ### settlement? > `optional` **settlement?**: `` `0x${string}` `` Defined in: packages/sdk/src/markets.ts:1861 BinarySettlement singleton — enables the post-finalize backing fallback. Omit on pre-v2 deploys; `finalized` then stays false and `backing` is the raw `market.backing()` value. --- # /docs/typescript/api/index/interfaces/MarketOrderEstimate [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketOrderEstimate # Interface: MarketOrderEstimate Defined in: packages/sdk/src/unified/quotes.ts:33 A market-order fill estimate from walking the book, human units. ## Properties ### averagePrice > **averagePrice**: `number` Defined in: packages/sdk/src/unified/quotes.ts:35 Volume-weighted average fill price (Σ quote / Σ base). *** ### baseFilled > **baseFilled**: `number` Defined in: packages/sdk/src/unified/quotes.ts:37 Base units the walk filled. *** ### quoteFilled > **quoteFilled**: `number` Defined in: packages/sdk/src/unified/quotes.ts:39 Quote units the walk exchanged (Σ qty·price). *** ### levelsConsumed > **levelsConsumed**: `number` Defined in: packages/sdk/src/unified/quotes.ts:45 Book levels the order crosses. Each matched level is a fill and execution gas scales with it — the signal for sizing a gas limit ahead of submission. --- # /docs/typescript/api/index/interfaces/MarketStats24h [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketStats24h # Interface: MarketStats24h Defined in: packages/sdk/src/derivedReads.ts:154 A market's trailing-24h activity, derived from OHLCV candle buckets. Prices are RAW quote units; volume is RAW quote (collateral) units. ## Properties ### volume24h > **volume24h**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:156 Σ quote volume over the window (raw collateral units). *** ### baseVolume24h > **baseVolume24h**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:158 Σ base/outcome-token volume over the window (raw base units). *** ### trades24h > **trades24h**: `number` Defined in: packages/sdk/src/derivedReads.ts:160 Σ trade count over the window. *** ### priceChange24h > **priceChange24h**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:165 closePrice(last) − openPrice(first) over the window (raw, signed). `0n` if fewer than one candle in-window. *** ### high24h > **high24h**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:167 Max high across the window (raw). `null` if no candles in-window. *** ### low24h > **low24h**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:169 Min low across the window (raw). `null` if no candles in-window. *** ### openPrice24h > **openPrice24h**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:171 openPrice of the first in-window candle (raw). `null` if none. --- # /docs/typescript/api/index/interfaces/MarketTypePlugin [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketTypePlugin # Interface: MarketTypePlugin\ Defined in: packages/sdk/src/marketTypes/types.ts:33 A market-type plugin: the fee-param codec + machinery descriptor for one bytes4 `marketType`. `TParams` is the type's plain fee-param shape (e.g. [BinaryVenueParams](BinaryVenueParams.md) for BINARY_V1). ## Type Parameters ### TParams `TParams` = `unknown` ## Properties ### marketType > **marketType**: `` `0x${string}` `` Defined in: packages/sdk/src/marketTypes/types.ts:35 The bytes4 market-type id (e.g. `MARKET_TYPE_BINARY_V1`). *** ### label > **label**: `string` Defined in: packages/sdk/src/marketTypes/types.ts:37 Human label for the type. *** ### machinerySteps > **machinerySteps**: readonly [`MachineryStep`](MachineryStep.md)[] Defined in: packages/sdk/src/marketTypes/types.ts:39 The type-specific machinery onboarding steps, in order. ## Methods ### encodeVenueFeeParams() > **encodeVenueFeeParams**(`params`, `client`, `moduleAddress`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/marketTypes/types.ts:45 Encode plain fee params into a venue's opaque `feeParams` bytes — for binary this defers to the module's on-chain encoder (needs a client + the module address), so it is async. #### Parameters ##### params `TParams` ##### client ##### moduleAddress `` `0x${string}` `` \| `undefined` #### Returns `Promise`\<`` `0x${string}` ``\> *** ### decodeVenueFeeParams() > **decodeVenueFeeParams**(`feeParams`): `TParams` \| `null` Defined in: packages/sdk/src/marketTypes/types.ts:50 Decode a venue's `feeParams` bytes back into plain params for display, or null if the bytes aren't this type's shape. Pure/local. #### Parameters ##### feeParams `` `0x${string}` `` #### Returns `TParams` \| `null` --- # /docs/typescript/api/index/interfaces/MintSetNativeParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MintSetNativeParams # Interface: MintSetNativeParams Defined in: packages/sdk/src/trade.ts:1974 Params for [Trader.mintSetNative](Trader.md#mintsetnative) — mint a YES+NO set by paying in the chain's native coin. **When to use** Use when the market's collateral IS wrapped native: the router wraps `msg.value` for you, so the caller needs no prior approval and no wrap step. For ERC-20 collateral use [MintSetPermit2Params](MintSetPermit2Params.md) instead. **Gotchas** - Throws [ContractRevertError](../classes/ContractRevertError.md) `CollateralNotWNative` when the market's collateral is not wrapped native, or `ZeroAmount` when `amount` is 0. ## Extends - [`RouterMintBase`](RouterMintBase.md) ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1940 bytes32 market key the set is minted for (the market's `marketId`). #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`marketId`](RouterMintBase.md#marketid) *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/trade.ts:1942 Routing operator id (uint32) for attribution; 0 = none. #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`operatorId`](RouterMintBase.md#operatorid) *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1944 Routing venue id (bytes32 hex); 32-byte zero = none. #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`venueId`](RouterMintBase.md#venueid) *** ### router? > `optional` **router?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1949 CollateralRouter address; resolved from `config.addresses.collateralRouter` if omitted. Throws if neither is set (never sends to the zero address). #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`router`](RouterMintBase.md#router) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1955 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`gas`](RouterMintBase.md#gas) *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1979 Native (SOMI/STT) amount to wrap → wNative and mint as `amount` YES + NO. Sent as `msg.value`; the target market's collateral must be wNative. --- # /docs/typescript/api/index/interfaces/MintSetParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MintSetParams # Interface: MintSetParams Defined in: packages/sdk/src/trade.ts:1485 Inputs to [Trader.mintSet](Trader.md#mintset) — deposit collateral, receive equal YES + NO. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1487 BinaryPool address — pool pulls collateral and mints YES+NO. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1489 Collateral amount → mints `amount` YES + `amount` NO to the signer. *** ### collateral? > `optional` **collateral?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1491 Collateral token; resolved from the live store (by pool) if omitted. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:1493 Approve collateral → pool if allowance is short (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1499 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/MintSetPermit2Params [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MintSetPermit2Params # Interface: MintSetPermit2Params Defined in: packages/sdk/src/trade.ts:1998 Params for [Trader.mintSetPermit2](Trader.md#mintsetpermit2) — mint a YES+NO set from ERC-20 collateral pulled with a signed Permit2 permit. **When to use** Use as the sibling of [MintSetNativeParams](MintSetNativeParams.md), for markets whose collateral is a real ERC-20: one signature replaces the separate `approve` transaction. **Gotchas** - Throws [ContractRevertError](../classes/ContractRevertError.md) `PermitTokenMismatch` when `permit.permitted.token` is not the market's collateral, or `ZeroAmount` when `amount` is 0. ## Extends - [`RouterMintBase`](RouterMintBase.md) ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1940 bytes32 market key the set is minted for (the market's `marketId`). #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`marketId`](RouterMintBase.md#marketid) *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/trade.ts:1942 Routing operator id (uint32) for attribution; 0 = none. #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`operatorId`](RouterMintBase.md#operatorid) *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1944 Routing venue id (bytes32 hex); 32-byte zero = none. #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`venueId`](RouterMintBase.md#venueid) *** ### router? > `optional` **router?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1949 CollateralRouter address; resolved from `config.addresses.collateralRouter` if omitted. Throws if neither is set (never sends to the zero address). #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`router`](RouterMintBase.md#router) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1955 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from [`RouterMintBase`](RouterMintBase.md).[`gas`](RouterMintBase.md#gas) *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:2003 Collateral amount to pull via Permit2 and mint as `amount` YES + NO. Must match `permit.permitted.amount` semantics on the app side. *** ### permit > **permit**: [`Permit2TransferFrom`](Permit2TransferFrom.md) Defined in: packages/sdk/src/trade.ts:2005 Signed Permit2 permit whose `permitted.token` must equal the market collateral. *** ### signature > **signature**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2007 EIP-712 signature over `permit` by the signer. --- # /docs/typescript/api/index/interfaces/NetworkTapeOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / NetworkTapeOptions # Interface: NetworkTapeOptions Defined in: packages/sdk/src/networkTape.ts:46 Tuning knobs for [SomniaMarketsClient.createNetworkTape](SomniaMarketsClient.md#createnetworktape). All optional. ## Properties ### maxRows? > `optional` **maxRows?**: `number` Defined in: packages/sdk/src/networkTape.ts:48 Rows retained per column (bids / fills / asks). Default 60. *** ### ownerMapCap? > `optional` **ownerMapCap?**: `number` Defined in: packages/sdk/src/networkTape.ts:50 `(pool, orderId) → owner` entries retained for fill attribution. Default 20 000. --- # /docs/typescript/api/index/interfaces/NetworkTapeStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / NetworkTapeStatus # Interface: NetworkTapeStatus Defined in: packages/sdk/src/networkTape.ts:99 The tape's health + rolling event rates. ## Properties ### connected > **connected**: `boolean` Defined in: packages/sdk/src/networkTape.ts:100 *** ### lastBlock > **lastBlock**: `number` Defined in: packages/sdk/src/networkTape.ts:102 Highest block seen on the heads stream (0 until the first head). *** ### poolsSeen > **poolsSeen**: `number` Defined in: packages/sdk/src/networkTape.ts:104 Distinct pools that have emitted since the tape started. *** ### bidRate > **bidRate**: `number` Defined in: packages/sdk/src/networkTape.ts:106 Events per second over the tape's rolling 5s window, by column. *** ### fillRate > **fillRate**: `number` Defined in: packages/sdk/src/networkTape.ts:107 *** ### askRate > **askRate**: `number` Defined in: packages/sdk/src/networkTape.ts:108 --- # /docs/typescript/api/index/interfaces/ObservedReadResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ObservedReadResult # Interface: ObservedReadResult\ Defined in: packages/sdk/src/observedReads.ts:134 Data keeps its legacy shape inside an immutable observation envelope. ## Type Parameters ### T `T` ## Properties ### data > `readonly` **data**: `T` Defined in: packages/sdk/src/observedReads.ts:135 *** ### observation > `readonly` **observation**: [`IndexerObservation`](IndexerObservation.md) Defined in: packages/sdk/src/observedReads.ts:136 --- # /docs/typescript/api/index/interfaces/ObservedReads [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ObservedReads # Interface: ObservedReads Defined in: packages/sdk/src/observedReads.ts:164 Owner-derived observations sharing one independent head. Create a new capability to refresh that head. Each read captures its own response metadata. Concurrent reads cannot replace older observations. Owner/caller cancellation retains its abort reason. The capability has no polling or separate transport. ## Properties ### independentHead > `readonly` **independentHead**: [`IndependentHead`](IndependentHead.md) Defined in: packages/sdk/src/observedReads.ts:166 The independently measured head shared by these reads. ## Methods ### read() > **read**\<`K`\>(`request`): `Promise`\<[`ObservedReadResult`](ObservedReadResult.md)\<`Awaited`\<`ReturnType`\<[`ObservedReadMethods`](../type-aliases/ObservedReadMethods.md)\[`K`\]\>\>\>\> Defined in: packages/sdk/src/observedReads.ts:176 Run one supported domain read with metadata from the same response. #### Type Parameters ##### K `K` *extends* [`ObservedReadOperation`](../type-aliases/ObservedReadOperation.md) #### Parameters ##### request [`ObservedReadRequest`](../type-aliases/ObservedReadRequest.md)\<`K`\> #### Returns `Promise`\<[`ObservedReadResult`](ObservedReadResult.md)\<`Awaited`\<`ReturnType`\<[`ObservedReadMethods`](../type-aliases/ObservedReadMethods.md)\[`K`\]\>\>\>\> #### Throws Indexer request or decoding failed. #### Throws Domain arguments or cursor are invalid. #### Throws A mixed-tier domain read needs missing chain configuration. #### Throws A mixed-tier chain read failed. #### Throws A mixed-tier contract read reverted. #### Throws A domain invariant failed. *** ### batch() > **batch**\<`R`\>(`requests`): `Promise`\<\{ readonly \[P in string \| number \| symbol\]: ObservedReadResult\\>\> \}\> Defined in: packages/sdk/src/observedReads.ts:189 Run several reads concurrently, sharing the head but not a database transaction. Result order matches request order. Each result keeps its own watermark and span. #### Type Parameters ##### R `R` *extends* readonly [`ObservedReadRequest`](../type-aliases/ObservedReadRequest.md)\<[`ObservedReadOperation`](../type-aliases/ObservedReadOperation.md)\>[] #### Parameters ##### requests `R` #### Returns `Promise`\<\{ readonly \[P in string \| number \| symbol\]: ObservedReadResult\\>\> \}\> #### Throws A member's indexer request failed. #### Throws A member's arguments are invalid. #### Throws A member needs missing chain configuration. #### Throws A member's chain read failed. #### Throws A member's contract read reverted. #### Throws A domain invariant failed. --- # /docs/typescript/api/index/interfaces/OnchainOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OnchainOrder # Interface: OnchainOrder Defined in: packages/sdk/src/orders.ts:613 One resting order exactly as the pool holds it — raw units, `bigint` fields. Order ids are unique per POOL, not globally: always carry the pool alongside the id. ## Properties ### orderId > **orderId**: `bigint` Defined in: packages/sdk/src/orders.ts:615 The pool's order id (`OrderId`, a uint128). *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/orders.ts:617 True for a bid (buy), false for an ask (sell). *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/orders.ts:619 The account the order rests for. *** ### userData > **userData**: `bigint` Defined in: packages/sdk/src/orders.ts:621 Caller-supplied tag echoed back by the book; 0 when unused. *** ### price > **price**: `bigint` Defined in: packages/sdk/src/orders.ts:623 Limit price, raw quote/collateral units per whole base unit. *** ### fullQuantity > **fullQuantity**: `bigint` Defined in: packages/sdk/src/orders.ts:625 Quantity as originally placed, raw base units. *** ### quantityRemaining > **quantityRemaining**: `bigint` Defined in: packages/sdk/src/orders.ts:627 Quantity still resting, raw base units — what a cancel would return. *** ### expireTimestampNs > **expireTimestampNs**: `bigint` Defined in: packages/sdk/src/orders.ts:629 Expiry as a UNIX timestamp in NANOseconds; 0 means no expiry. --- # /docs/typescript/api/index/interfaces/OnchainResolutionPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OnchainResolutionPrice # Interface: OnchainResolutionPrice Defined in: packages/sdk/src/markets.ts:1768 A market's resolution price, read from the oracle adapter it was bound to — what `client.getOnchainResolutionPrice(marketId)` resolves. ## Properties ### numericValue > **numericValue**: `string` Defined in: packages/sdk/src/markets.ts:1770 Raw numeric answer as the adapter posted it, at [decimals](#decimals) scale. *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/markets.ts:1772 Scale of [numericValue](#numericvalue) — the adapter's `PRICE_DECIMALS`, or the fallback. *** ### voided > **voided**: `boolean` Defined in: packages/sdk/src/markets.ts:1774 The oracle voided the question rather than answering it. *** ### adapter > **adapter**: `` `0x${string}` `` Defined in: packages/sdk/src/markets.ts:1776 The adapter the answer was read from (markets bind to exactly one). *** ### oracleQuestionId > **oracleQuestionId**: `string` Defined in: packages/sdk/src/markets.ts:1778 The adapter-scoped question id the answer belongs to. --- # /docs/typescript/api/index/interfaces/OperatorAdmin [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OperatorAdmin # Interface: OperatorAdmin Defined in: packages/sdk/src/operatorAdmin.ts:255 The MarketsCore control-plane write surface — register/update operators, create/update venues. Built via `client.createOperatorAdmin(config)` with a signer ([OperatorAdminConfig](OperatorAdminConfig.md)); every method sends one tx and resolves with its receipt after inclusion. Directory reads live on the client (indexer-backed `listOperators` / `listVenues` / `getOperator` / `getVenue`). Every write throws `ContractRevertError` when the chain rejects it — at simulation, at send, or as a mined receipt with `status: "reverted"` (the reason is recovered by replaying the call at that block while the node still has the state) — and `RpcError` when the send or the receipt read does not complete. A reverted write never resolves as if it had been confirmed. ## Methods ### registerOperator() > **registerOperator**(`p`): `Promise`\<[`RegisterOperatorResult`](RegisterOperatorResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:260 Permissionlessly claim a new operator identity. Resolves with the auto-assigned `operatorId` (decoded from `OperatorRegistered`). #### Parameters ##### p [`RegisterOperatorParams`](RegisterOperatorParams.md) #### Returns `Promise`\<[`RegisterOperatorResult`](RegisterOperatorResult.md)\> *** ### updateOperator() > **updateOperator**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:262 Update all mutable operator fields at once. Operator-owner only. #### Parameters ##### p [`UpdateOperatorParams`](UpdateOperatorParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setOperatorEnabled() > **setOperatorEnabled**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:264 Flip the operator's kill switch without touching other fields. #### Parameters ##### p [`SetOperatorEnabledParams`](SetOperatorEnabledParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### transferOperatorOwnership() > **transferOperatorOwnership**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:269 Stage a two-step operator-ownership transfer (or cancel a pending one by re-staging the current owner). #### Parameters ##### p [`TransferOperatorOwnershipParams`](TransferOperatorOwnershipParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### acceptOperatorOwnership() > **acceptOperatorOwnership**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:271 Complete a pending operator-ownership transfer. Caller must be the staged owner. #### Parameters ##### p [`AcceptOperatorOwnershipParams`](AcceptOperatorOwnershipParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### createVenue() > **createVenue**(`p`): `Promise`\<[`CreateVenueResult`](CreateVenueResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:276 Create a venue under an operator. Resolves with the contract-generated `venueId` (decoded from `VenueCreated`). #### Parameters ##### p [`CreateVenueParams`](CreateVenueParams.md) #### Returns `Promise`\<[`CreateVenueResult`](CreateVenueResult.md)\> *** ### updateVenue() > **updateVenue**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:278 Replace a venue's mutable config (`marketType` cannot change here). #### Parameters ##### p [`UpdateVenueParams`](UpdateVenueParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setVenueEnabled() > **setVenueEnabled**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/operatorAdmin.ts:280 Flip a venue's creation flag without touching other fields. #### Parameters ##### p [`SetVenueEnabledParams`](SetVenueEnabledParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> --- # /docs/typescript/api/index/interfaces/OperatorAdminConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OperatorAdminConfig # Interface: OperatorAdminConfig Defined in: packages/sdk/src/operatorAdmin.ts:31 Signer + target config for an [OperatorAdmin](OperatorAdmin.md) (reached via `client.createOperatorAdmin(config)`). Pass exactly one signer source: `walletClient`, `account`, or `privateKey`. ## Properties ### walletClient? > `optional` **walletClient?**: `object` Defined in: packages/sdk/src/operatorAdmin.ts:33 A pre-built signer (e.g. a browser/wagmi wallet over an injected provider). *** ### account? > `optional` **account?**: `` `0x${string}` `` \| `Account` Defined in: packages/sdk/src/operatorAdmin.ts:35 A local signing account (e.g. from viem's privateKeyToAccount). *** ### privateKey? > `optional` **privateKey?**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:37 Private key — the SDK derives the account. *** ### publicClient? > `optional` **publicClient?**: `object` Defined in: packages/sdk/src/operatorAdmin.ts:39 Read client for receipts. Defaults to the client's WebSocket client. *** ### marketsCore? > `optional` **marketsCore?**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:41 MarketsCore address override. Defaults to `config.addresses.marketsCore`. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:46 Default gas ceiling per tx. #### Default ```ts 10_000_000n ``` --- # /docs/typescript/api/index/interfaces/OperatorPreflightInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OperatorPreflightInput # Interface: OperatorPreflightInput Defined in: packages/sdk/src/preflight.ts:84 The operator fields the operator-step preflight inspects (subset of [IndexedOperator](../type-aliases/IndexedOperator.md)). ## Properties ### caller > **caller**: `` `0x${string}` `` Defined in: packages/sdk/src/preflight.ts:86 The connected signer — must own the operator to run machinery under it. *** ### owner > **owner**: `string` Defined in: packages/sdk/src/preflight.ts:88 The operator's current on-chain owner — a mismatch with `caller` blocks. *** ### enabled > **enabled**: `boolean` Defined in: packages/sdk/src/preflight.ts:90 The operator's kill switch — disabled blocks market creation under it. *** ### feeRecipient > **feeRecipient**: `string` Defined in: packages/sdk/src/preflight.ts:95 The operator's default fee recipient — the zero address only warns (fees fall to the zero address unless a venue overrides it). --- # /docs/typescript/api/index/interfaces/OracleHubAdmin [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OracleHubAdmin # Interface: OracleHubAdmin Defined in: packages/sdk/src/oracleHub.ts:515 Admin handle for the OracleHub — the protocol's ONE governance-approved oracle adapter (Oracle v2 §8e, earmark-at-creation). Point reads (quotes, the earmark/credit accounts, dedup state, live status) plus the signed writes (schedule, credit-only withdrawals, funding, owner-gated gas/drain params, reactivity wiring). Built via `client.createOracleHubAdmin(config)`; needs `config.addresses.oracleHub` (and `binaryModule` for the approval reads). Every write throws `ContractRevertError` when the chain rejects it — at simulation, at send, or as a mined receipt with `status: "reverted"` (the reason is recovered by replaying the call at that block while the node still has the state) — and `RpcError` when the send or the receipt read does not complete. A reverted write never resolves as if it had been confirmed. ## Methods ### getSchedulingCost() > **getSchedulingCost**(`def`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:518 Marginal scheduling cost for `def` (0 = would dedup). #### Parameters ##### def [`QuestionDefinitionInput`](QuestionDefinitionInput.md) #### Returns `Promise`\<`bigint`\> *** ### earmarkedOf() > **earmarkedOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:520 Native LOCKED for an operator's outstanding markets (wei; never withdrawable). #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> *** ### creditOf() > **creditOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:522 An operator's accrued WITHDRAWABLE surplus credit on the hub (wei). #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> *** ### outstandingOf() > **outstandingOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:524 Count of an operator's bound-but-unresolved markets. #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> *** ### withdrawableOf() > **withdrawableOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:526 Wei an operator's owner may withdraw right now (== `creditOf`). #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> *** ### payerCreditOf() > **payerCreditOf**(`payer`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:531 A1: withdrawable surplus credited to a reserve-PAYER (open-venue creator or the autonomous MarketCreator), drawn by that account itself. #### Parameters ##### payer `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> *** ### payerOf() > **payerOf**(`marketId`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/oracleHub.ts:536 A1: the reserve-payer recorded for a market at onBind (surplus recipient); zero-address once settled + swept. #### Parameters ##### marketId `` `0x${string}` `` #### Returns `Promise`\<`` `0x${string}` ``\> *** ### resolveReserve() > **resolveReserve**(): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:538 The per-market resolution reserve attached+locked at onBind (wei). #### Returns `Promise`\<`bigint`\> *** ### quoteCreateMarketValue() > **quoteCreateMarketValue**(`def`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:544 THE §8e create-market value rule: `getSchedulingCost(def) + resolveReserve()` (the reserve is attached to the create; attach exactly this to `scheduleAndCreateMarket`; excess refunds). #### Parameters ##### def [`QuestionDefinitionInput`](QuestionDefinitionInput.md) #### Returns `Promise`\<`bigint`\> *** ### getQuestionState() > **getQuestionState**(`def`): `Promise`\<[`HubQuestionState`](HubQuestionState.md)\> Defined in: packages/sdk/src/oracleHub.ts:549 One definition's full dedup state: canonical key, the active question id it resolves to (0n = none), bind count, and the bound-market fan-out list. #### Parameters ##### def [`QuestionDefinitionInput`](QuestionDefinitionInput.md) #### Returns `Promise`\<[`HubQuestionState`](HubQuestionState.md)\> *** ### getQuestionIdByKey() > **getQuestionIdByKey**(`questionKey`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/oracleHub.ts:551 The ACTIVE question id for a canonical key (0n = never scheduled). #### Parameters ##### questionKey `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> *** ### getBindCount() > **getBindCount**(`oracleQuestionId`): `Promise`\<`number`\> Defined in: packages/sdk/src/oracleHub.ts:553 Lifetime bind count for a question id. #### Parameters ##### oracleQuestionId `bigint` #### Returns `Promise`\<`number`\> *** ### getMarketsForQuestion() > **getMarketsForQuestion**(`oracleQuestionId`): `Promise`\<`` `0x${string}` ``[]\> Defined in: packages/sdk/src/oracleHub.ts:555 Every marketId bound to a question id (the fan-out list). #### Parameters ##### oracleQuestionId `bigint` #### Returns `Promise`\<`` `0x${string}` ``[]\> *** ### isHubApproved() > **isHubApproved**(): `Promise`\<`boolean`\> Defined in: packages/sdk/src/oracleHub.ts:561 Whether the module has the hub approved (`approvedAdapters(hub)`) — the Oracle v2 equivalent of the old per-adapter `isAdapterApproved`. Needs `config.addresses.binaryModule`. #### Returns `Promise`\<`boolean`\> *** ### getHubStatus() > **getHubStatus**(): `Promise`\<[`HubStatus`](HubStatus.md)\> Defined in: packages/sdk/src/oracleHub.ts:566 The hub's full live status (owner / balance / approval / subscription / gas + drain params / resolveReserve + pending drain). #### Returns `Promise`\<[`HubStatus`](HubStatus.md)\> *** ### scheduleQuestion() > **scheduleQuestion**(`p`): `Promise`\<[`ScheduleQuestionResult`](ScheduleQuestionResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:575 Schedule a question through the hub (content-addressed: an identical template definition returns the EXISTING id and refunds the value). Resolves with the question id decoded from `QuestionScheduled` / `QuestionReused` and whether it deduplicated. #### Parameters ##### p [`ScheduleQuestionParams`](ScheduleQuestionParams.md) #### Returns `Promise`\<[`ScheduleQuestionResult`](ScheduleQuestionResult.md)\> *** ### withdraw() > **withdraw**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:582 Withdraw an operator's accrued WITHDRAWABLE surplus credit (credit-only; OWNER-gated on-chain: only the operator's owner, read from MarketsCore, may draw it, and only up to `withdrawableOf` — else `InsufficientCredit`). The earmark backing live markets is untouchable. #### Parameters ##### p [`WithdrawParams`](WithdrawParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### withdrawMyCredit() > **withdrawMyCredit**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:589 A1: withdraw the CALLER's own accrued payer credit (msg.sender-gated — the connected signer draws only its own surplus, up to `payerCreditOf(caller)`). This is how an open-venue creator claims their refund, and how the autonomous MarketCreator self-reclaims (via its own on-chain call). #### Parameters ##### p [`WithdrawMyCreditParams`](WithdrawMyCreditParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### fundHub() > **fundHub**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:594 Send native to the hub's `receive()` — funds the reactivity bond (hub float; NOT credited to any operator — resolution funding is per-market). #### Parameters ##### p [`FundHubParams`](FundHubParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setGasParams() > **setGasParams**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:599 Update the reactivity gas params (OWNER-only). `maxFeePerGas` also reprices `resolveReserve()` immediately. #### Parameters ##### p [`SetHubGasParams`](SetHubGasParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setDrainParams() > **setDrainParams**(`p`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:605 Update the bounded-drain metering params (OWNER-only): `perMarketResolveGas` sizes `resolveReserve`, `callbackBaseGas` is the attributed overhead term, `maxResolvesPerCallback` + `resolveGasReserve` bound one callback's work. #### Parameters ##### p [`SetHubDrainParams`](SetHubDrainParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### enableReactivity() > **enableReactivity**(`p?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:611 Register the Somnia reactivity subscription (OWNER-only, one-shot). NOTE: calls the reactivity precompile at 0x0100, which does NOT exist on local anvil — testnet/mainnet only. #### Parameters ##### p? [`EnableHubReactivityParams`](EnableHubReactivityParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### migrateSubscription() > **migrateSubscription**(`p?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/oracleHub.ts:616 Unsubscribe + re-subscribe with the current topic/gas params (OWNER-only; for upstream event-signature changes). Precompile — testnet/mainnet only. #### Parameters ##### p? [`EnableHubReactivityParams`](EnableHubReactivityParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> --- # /docs/typescript/api/index/interfaces/OracleHubAdminConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OracleHubAdminConfig # Interface: OracleHubAdminConfig Defined in: packages/sdk/src/machineryWriter.ts:46 Signer + read-client config shared by every machinery admin. Mirrors [OperatorAdminConfig](OperatorAdminConfig.md) — pass a `walletClient`, a local `account`, or a `privateKey`. ## Properties ### walletClient? > `optional` **walletClient?**: `object` Defined in: packages/sdk/src/machineryWriter.ts:48 A pre-built signer (e.g. a browser/wagmi wallet over an injected provider). *** ### account? > `optional` **account?**: `` `0x${string}` `` \| `Account` Defined in: packages/sdk/src/machineryWriter.ts:50 A local signing account (e.g. from viem's privateKeyToAccount). *** ### privateKey? > `optional` **privateKey?**: `` `0x${string}` `` Defined in: packages/sdk/src/machineryWriter.ts:52 Private key — the SDK derives the account. *** ### publicClient? > `optional` **publicClient?**: `object` Defined in: packages/sdk/src/machineryWriter.ts:54 Read client for receipts. Defaults to the client's WebSocket client. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/machineryWriter.ts:56 Default gas ceiling per tx. --- # /docs/typescript/api/index/interfaces/OrderBookParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrderBookParams # Interface: OrderBookParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:33 Default CLOB order-book parameters a MarketCreator stamps onto each market it creates (mirror of the on-chain `OrderBookParameters` struct). All raw. ## Properties ### tickSize > **tickSize**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:35 Minimum price increment, in raw quote-token (collateral) units. *** ### minQuantity > **minQuantity**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:37 Minimum order quantity, in raw base-token (outcome-share) units. *** ### lotSize > **lotSize**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:39 Minimum quantity increment, in raw base-token (outcome-share) units. --- # /docs/typescript/api/index/interfaces/OrderFill [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrderFill # Interface: OrderFill Defined in: packages/sdk/src/trade.ts:102 A single fill that occurred within a tx (decoded from the pool's OrderFilled). ## Properties ### takerOrderId > **takerOrderId**: `bigint` Defined in: packages/sdk/src/trade.ts:104 On-chain id of the taker (incoming) order. *** ### makerOrderId > **makerOrderId**: `bigint` Defined in: packages/sdk/src/trade.ts:106 On-chain id of the maker (resting) order that matched. *** ### quantityFilled > **quantityFilled**: `bigint` Defined in: packages/sdk/src/trade.ts:108 Quantity exchanged in this fill, raw units (outcome tokens on binary, base on spot). *** ### takerRemainingQuantity > **takerRemainingQuantity**: `bigint` Defined in: packages/sdk/src/trade.ts:110 Taker order's quantity still unfilled after this fill, raw units. *** ### makerRemainingQuantity > **makerRemainingQuantity**: `bigint` Defined in: packages/sdk/src/trade.ts:112 Maker order's quantity still resting after this fill, raw units. *** ### fillPrice > **fillPrice**: `bigint` Defined in: packages/sdk/src/trade.ts:117 Fill price — the YES price on a binary pool (raw collateral units per whole outcome token); raw quote units per whole base on a spot pool. --- # /docs/typescript/api/index/interfaces/OutcomePositionMark [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OutcomePositionMark # Interface: OutcomePositionMark Defined in: packages/sdk/src/derivedReads.ts:1208 An outcome position marked to a live price — one portfolio row's numbers. ## Properties ### value > **value**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:1210 Current position value in collateral (raw): `balance × mark`. *** ### upnl > **upnl**: `bigint` \| `null` Defined in: packages/sdk/src/derivedReads.ts:1212 Unrealized PnL in collateral (raw), or `null` when entry is unknown. *** ### upnlFraction > **upnlFraction**: `number` \| `null` Defined in: packages/sdk/src/derivedReads.ts:1214 Unrealized PnL as a signed fraction (0.12 = +12%), or `null`. --- # /docs/typescript/api/index/interfaces/Permit2TransferFrom [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Permit2TransferFrom # Interface: Permit2TransferFrom Defined in: packages/sdk/src/trade.ts:1919 A canonical Permit2 `PermitTransferFrom` — the signed authorization the Permit2 mint path forwards to the router (which relays it to Permit2). Build it (and the EIP-712 signature) with a Permit2 SDK on the app side. ## Properties ### permitted > **permitted**: `object` Defined in: packages/sdk/src/trade.ts:1921 Token + amount the signature authorizes. `token` must equal the market collateral. #### token > **token**: `` `0x${string}` `` The ERC-20 the signature authorizes — must equal the market's collateral token. #### amount > **amount**: `bigint` Max amount the signature authorizes, raw collateral units. *** ### nonce > **nonce**: `bigint` Defined in: packages/sdk/src/trade.ts:1928 Unordered Permit2 nonce. *** ### deadline > **deadline**: `bigint` Defined in: packages/sdk/src/trade.ts:1930 Signature deadline (unix seconds). --- # /docs/typescript/api/index/interfaces/PerpFeedStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpFeedStatus # Interface: PerpFeedStatus Defined in: packages/sdk/src/perp/state.ts:263 Whether a perp pool's MARK feed is live, and how much open interest is riding on it. ## Properties ### markPriceOk > **markPriceOk**: `boolean` Defined in: packages/sdk/src/perp/state.ts:269 The pool's OWN verdict on its mark feed, from `tryGetMarkPrice`. Never re-derive it by comparing a timestamp: the staleness bound lives on `FundingParametersEpoch` per pool and moves per epoch, so an outside comparison can disagree with the pool. *** ### markPrice > **markPrice**: `bigint` Defined in: packages/sdk/src/perp/state.ts:275 The mark itself, because `markPriceOk` is not the whole verdict: a feed can report ok and hand back 0, and a zero mark is never a real price for a live perp. Treat `markPriceOk && markPrice > 0n` as live — the same test [perpMarkForPnl](../functions/perpMarkForPnl.md) makes. *** ### openInterest > **openInterest**: `bigint` Defined in: packages/sdk/src/perp/state.ts:278 Total open interest in base units. What makes a stale mark dangerous rather than merely untidy: margin and liquidation prices are struck against the mark. *** ### indexUpdatedAt? > `optional` **indexUpdatedAt?**: `bigint` Defined in: packages/sdk/src/perp/state.ts:287 The INDEX oracle's timestamp (epoch seconds) — a DIFFERENT feed from the mark, so it corroborates a verdict rather than dating it. `undefined` when that leg reverted, which is the case this read exists to survive: it is diagnostic, and it must never take the verdict down with it. See the note on [client.getPerpFeedStatus](SomniaMarketsClient.md#getperpfeedstatus). --- # /docs/typescript/api/index/interfaces/PerpFundingPremium [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpFundingPremium # Interface: PerpFundingPremium Defined in: packages/sdk/src/perp/state.ts:340 A perp pool's funding-premium state — what the next settlement will charge, and the raw accumulator behind it. ## Properties ### timeWeightedPremium > **timeWeightedPremium**: `bigint` Defined in: packages/sdk/src/perp/state.ts:349 The premium the NEXT settlement will charge: the time-weighted average of the order-book premium over the interval so far, PRE-clamp, 1e18-scaled and signed. Positive means the perp is rich and longs pay. This is the value to build a predicted funding rate from. Do not read `lastObservedPremium` for that — see its note. *** ### lastObservedPremium > **lastObservedPremium**: `bigint` Defined in: packages/sdk/src/perp/state.ts:361 The standing INSTANTANEOUS sample, 1e18-scaled and signed. Exposed beside `timeWeightedPremium` because the contract's getter for this kept its signature and changed its meaning: before Wave 28 it WAS the premium the next settlement would charge. Anything still treating it that way is silently wrong, and a spot reading is the one number that looks most like the right one. Useful for "where is the book right now" and for reproducing the open segment. Not for predicting a charge. *** ### accumulator > **accumulator**: `bigint` Defined in: packages/sdk/src/perp/state.ts:363 Raw premium integral accumulated since `intervalStartNs`, for exact reproduction. *** ### intervalStartNs > **intervalStartNs**: `bigint` Defined in: packages/sdk/src/perp/state.ts:365 Start of the interval being averaged, in NANOseconds. Zero when un-armed — see `armed`. *** ### observedAtNs > **observedAtNs**: `bigint` Defined in: packages/sdk/src/perp/state.ts:367 When the standing sample was taken, in NANOseconds. *** ### validUntilNs > **validUntilNs**: `bigint` Defined in: packages/sdk/src/perp/state.ts:377 When the standing sample stops accruing credit, in NANOseconds. Every nanosecond past it is credited at ZERO, which is what makes a quote's weight its resting duration rather than its presence at one instant. It can legitimately sit BEHIND `observedAtNs`: a freeze writes the current time here, and an observation in the same block then advances `observedAtNs` to match. Do not subtract them without ordering them first. *** ### armed > **armed**: `boolean` Defined in: packages/sdk/src/perp/state.ts:387 Whether the time-weighted mechanism is running for this market yet. Derived from `intervalStartNs !== 0n`, which is the contract's own migration sentinel: it is armed by each market's FIRST settlement after the beacon upgrade. While this is `false` the pool still charges the point sample, so `timeWeightedPremium` equals `lastObservedPremium` and the accumulator is empty — correct, not missing, and it resolves on the market's next settlement. --- # /docs/typescript/api/index/interfaces/PerpLeverage [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpLeverage # Interface: PerpLeverage Defined in: packages/sdk/src/perp/margin.ts:520 How levered an account is — measured at one position, and across the whole cross-margin account. Every ratio is **bps of 1x**: `10_000` is 1.00x, `25_000` is 2.5x, `200_000` is 20x. That is the protocol's own unit for every margin figure, so these compose with [PerpRiskParams](PerpRiskParams.md) without a rescale. ## Properties ### asOfBlock > **asOfBlock**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:522 The block every read was pinned to. *** ### size > **size**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:524 SIGNED position size in this market, raw base units (positive = long, 0 = flat). *** ### markPrice > **markPrice**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:526 Mark price the notionals were measured at, raw quote units per whole base. *** ### positionNotional > **positionNotional**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:528 This position's notional: `|size| × mark / oneBase`, raw collateral units. *** ### accountNotional > **accountNotional**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:538 Σ notional across EVERY market the account holds a position in, this one included, raw collateral units. Costs two extra reads per OTHER active market — the MarginBank exposes no aggregate notional view, and `imReq` cannot be inverted back into notional because each market applies its own OI-scaled IMF. So this grows with the account's footprint; a single-market account pays nothing extra. *** ### equity > **equity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:540 Account equity = collateral + Σ unrealized PnL − Σ pending funding (signed). *** ### positionLeverageBps > **positionLeverageBps**: `bigint` \| `null` Defined in: packages/sdk/src/perp/margin.ts:550 This position's notional over account equity, bps — "this position is Nx my equity". `null` when equity is ≤ 0, where the ratio has no meaning: an account with no equity left is not running infinite leverage, it is insolvent, and rendering an enormous number would say the wrong thing. Read [MarginStatus](../type-aliases/MarginStatus.md) for that state instead. *** ### accountLeverageBps > **accountLeverageBps**: `bigint` \| `null` Defined in: packages/sdk/src/perp/margin.ts:559 Total notional over account equity, bps. **The figure that actually governs risk here.** Margin is cross, so every position draws on the same collateral: a second position at the same notional doubles the account's leverage without changing the first one's [positionLeverageBps](#positionleveragebps). `null` on non-positive equity, as above. *** ### marketMaxLeverageBps > **marketMaxLeverageBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:570 The most leverage THIS MARKET will open a position at, bps — `10000² / effectiveImfBps`, using the OI-scaled IMF actually in force rather than the static `initialMarginBps`. A ceiling on new size, not a measurement of the position: it does not move when the position or the equity does. It DOES move when market-wide open interest does, which is why it is read per call rather than derived from [PerpRiskParams.initialMarginBps](PerpRiskParams.md#initialmarginbps). *** ### accountMaxLeverageX > **accountMaxLeverageX**: `number` Defined in: packages/sdk/src/perp/margin.ts:581 The account's OWN per-market cap as an integer multiplier, `0` when unset — what `trader.setPerpLeverage` writes, read back. A cap STRICTER than the market's effective IMF adds margin on top of the base requirement; that surcharge is quoted by `PerpOrderMarginPreview.leverageSurcharge`. Being a setting rather than a measurement, it can sit far above the position's actual [positionLeverageBps](#positionleveragebps). *** ### protocolMaxLeverageX > **protocolMaxLeverageX**: `number` Defined in: packages/sdk/src/perp/margin.ts:583 Protocol-wide ceiling that clamps the above, integer multiplier. *** ### creditFloor > **creditFloor**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:590 The account's non-withdrawable credit-voucher floor, raw collateral units. `0n` for an ordinary account, and the switch that arms the two fields below. Self-clearing: the confinement lifts on its own once the floor reaches zero. *** ### voucherLeverageCapX > **voucherLeverageCapX**: `number` Defined in: packages/sdk/src/perp/margin.ts:630 The protocol's voucher leverage cap, integer multiplier — what a voucher-holding account is confined to when it INCREASES a position. `0` means unset, which is a hard block rather than "no cap" (see [voucherMarketAllowed](#vouchermarketallowed)). Reported, not applied to [protocolMaxLeverageX](#protocolmaxleveragex), because it does not bound the position this call measures. `MarginBank._meetsIM` gates the whole voucher branch on `additionalSize > 0`, so it never touches a reduce or a close — a voucher holder can always close out, or place a stop, even on a market since removed from the allowlist. Folding it into the protocol ceiling would report a constraint on a reduce-only action that the chain does not apply. What it bounds is a NEW increase, and the composition is not a plain minimum: ``` // voucher inactive (creditFloor == 0n) // accountMaxLeverageX == 0 -> no leverage-derived requirement at all; // marketMaxLeverageBps is what binds // otherwise -> min(accountMaxLeverageX, protocolMaxLeverageX) // // voucher active and allowed // the cap REPLACES an unset or looser account setting, then the // protocol ceiling clamps the result: const confined = accountMaxLeverageX !== 0 && accountMaxLeverageX <= voucherLeverageCapX ? accountMaxLeverageX // a STRICTER user setting still wins : voucherLeverageCapX; const bindingX = Math.min(confined, protocolMaxLeverageX); ``` The load-bearing half is the first branch: a voucher turns an *unset* account cap into an enforced one. On an ordinary account `accountMaxLeverageX === 0` means "no cap set"; on a voucher account increasing a position it means "confined to `voucherLeverageCapX`". For whether a specific order passes, use [SomniaMarketsClient.previewPerpOrderMargin](SomniaMarketsClient.md#previewperpordermargin) — it applies all of this and reports `voucherBlocked` alongside the margin numbers. *** ### voucherMarketAllowed > **voucherMarketAllowed**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:642 Whether THIS market is on the voucher allowlist. Only consequential while [creditFloor](#creditfloor) is positive, and then it is a hard placement revert rather than an arithmetic clamp: an increase on a non-allowlisted market reverts `VoucherMarketNotAllowed`, and an unset [voucherLeverageCapX](#voucherleveragecapx) reverts `VoucherLeverageCapNotSet` — a deliberate fail safe, so an unconfigured cap never silently grants full leverage. Neither outcome is expressible as a leverage number, which is the other reason these are reported rather than folded in. --- # /docs/typescript/api/index/interfaces/PerpLiquidationPriceInputs [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpLiquidationPriceInputs # Interface: PerpLiquidationPriceInputs Defined in: packages/sdk/src/perp/margin.ts:380 Everything the maintenance-margin solve needs — and nothing that has to come from a particular block, so `perpLiquidationPrice` stays pure. ## Properties ### equity > **equity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:382 Account equity across every market (signed, raw collateral units). *** ### mmReq > **mmReq**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:384 Aggregate maintenance requirement across every market (raw collateral units). *** ### size > **size**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:386 SIGNED position size in THIS market, raw base units. Zero yields `null`. *** ### markPrice > **markPrice**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:388 This market's mark price, raw quote units per whole base. *** ### maintenanceMarginBps > **maintenanceMarginBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:390 This market's maintenance-margin threshold, bps. *** ### oneBase > **oneBase**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:392 10^decimals of this market's synthetic base — the divisor for notional math. --- # /docs/typescript/api/index/interfaces/PerpMainFunding [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpMainFunding # Interface: PerpMainFunding Defined in: packages/sdk/src/perp/linkedWallet.ts:112 The outstanding claim against a child, and who it is owed to. What a main funds can be BORROWED, NEVER WITHDRAWN: `withdraw` pays the child at most `balance - principal`, so a compromised child key can trade the money and lose it but cannot take it out. ## Properties ### principal > **principal**: `bigint` Defined in: packages/sdk/src/perp/linkedWallet.ts:122 Principal a main has funded and not yet recovered, in collateral units. Zero means nothing is outstanding. It is NOT a segregated bucket. The child's own money and its main's are one fungible balance, and the claim is clamped to `min(principal, balance)` at flat moments — so the child's own contribution is the JUNIOR tranche and a loss eats it first. A child that genuinely lost the money does not owe it forever. *** ### payer > **payer**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/linkedWallet.ts:131 The payer recorded AT FUNDING TIME, or zero when nothing is outstanding. Snapshotted deliberately: both routes home settle against this address, so an unlink or re-link between the pull and the repayment cannot misroute the money to whoever happens to be linked later. When this disagrees with the LIVE resolution ([PerpFundingPayer](../type-aliases/PerpFundingPayer.md)), THIS is who gets repaid. *** ### withdrawableFromPrincipal > `readonly` **withdrawableFromPrincipal**: `0n` Defined in: packages/sdk/src/perp/linkedWallet.ts:138 How much of `principal` the child could withdraw: always zero while a claim stands, and present as a field only so a caller does not have to re-derive the rule from prose. Included because "why can I not withdraw my balance" is the commonest question this surface has to answer. --- # /docs/typescript/api/index/interfaces/PerpOrderMarginQuote [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpOrderMarginQuote # Interface: PerpOrderMarginQuote Defined in: packages/sdk/src/perp/margin.ts:1848 The placement gates and the lock they are measured against. ## Properties ### increasingQuantity > **increasingQuantity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1850 The part of the order that increases the position — the only part that locks. *** ### reducingQuantity > **reducingQuantity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1852 The part absorbed by existing exposure. Locks nothing. *** ### lockAmount > **lockAmount**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1854 Total collateral the pool will lock. *** ### initialMarginPortion > **initialMarginPortion**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1856 The initial-margin component of [lockAmount](#lockamount). *** ### adverseGapPortion > **adverseGapPortion**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1858 The adverse mark-to-entry component, zero on a favourable entry. *** ### leverageSurcharge > **leverageSurcharge**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1860 Extra margin a leverage cap stricter than the market's IMF demands. *** ### feeHeadroom > **feeHeadroom**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1878 The pool's worst-case fee reserve for this order (`PerpPool._feeHeadroom`). Not part of [lockAmount](#lockamount) and not charged — perps locks only initial margin and takes fees from the unlocked balance at fill. It exists solely as an auto-pull addend, so that pulling exactly the lock cannot leave a max-leverage open at `equity = IM − fees` against an `IM` requirement, i.e. in `MarginCall` at birth. The rate is an envelope, not a prediction: an order rests as a maker or crosses as a taker but never both, so it takes the larger of the two — with a negative (rebate) maker rate floored at zero first, since a rebate must not shrink the reserve below the taker case — plus the order's builder fee. Ceil-rounded, on the **full** order notional rather than the increasing leg, because fees are charged on the whole fill. Reported whatever [topUpRequired](#topuprequired) does, but it only enters the arithmetic when auto-pull is modelled. *** ### topUpRequired > **topUpRequired**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1899 What auto-pull would REQUEST in total (`MarginBank.quoteOrderTopUp`) — `0n` when [PerpOrderMarginQuoteInputs.wallet](PerpOrderMarginQuoteInputs.md#wallet) is omitted, i.e. when auto-pull is not being modelled at all. **Not the owner's wallet debit once a main is in play.** It is the requirement, and [ownWalletPull](#ownwalletpull) / [mainWalletPull](#mainwalletpull) are the two wallets that meet it. Showing this figure as the child's spend over-states it by exactly the main's leg. `lockAmount + feeHeadroom + leverageSurcharge` less the unlocked balance, floored at zero. **Order-local by design**: it excludes the initial margin of the account's positions in other markets, so it is exactly sufficient for a FLAT account and best-effort for one already carrying exposure — a pre-existing cross-market deficit still fails [meetsInitialMargin](#meetsinitialmargin). Auto-pull funds an ORDER, not an ACCOUNT. A `0n` is three different things, which is why it should be read beside the balance rather than alone: no pull needed, or one of the pool's three declines — a purely reducing order (closing never debits a wallet), an account already in debt (a pull would silently cure bad debt), or a voucher-blocked increase. *** ### walletCoversTopUp > **walletCoversTopUp**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1919 The funding wallets can together cover [topUpRequired](#topuprequired) — the owner's own balance and allowance, plus a linked main's capacity when one was supplied. Vacuously `true` when no pull is needed or auto-pull is not modelled. **What a `false` MEANS depends on whether a main is in play**, and the two are not the same outcome: - **No main.** The pool asks for a fixed `topUpRequired`, so the `transferFrom` inside `depositFor` reverts and the placement fails on the TOKEN's error rather than a margin gate — deliberate, because that error names the fix. This is a placement gate and it folds into [sufficient](#sufficient). - **With a main.** Both legs are `min(...)`-sized and neither can revert, so the pool pulls what it can and the margin gates judge the result. This is then INFORMATIONAL and does NOT fold into [sufficient](#sufficient): the order can be accepted with the lock funded and the fee reserve short, which is precisely what [feeHeadroom](#feeheadroom) exists to avoid. Read a `false` here as "the position may be born close to its own initial margin", not as "this will be rejected". *** ### ownWalletPull > **ownWalletPull**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1926 How much of [topUpRequired](#topuprequired) the OWNER's own wallet would supply. `min(topUpRequired, min(balance, allowance))`. The owner's wallet always pays first, so a child holding some collateral spends its own before it touches its main's. *** ### mainWalletPull > **mainWalletPull**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1942 How much of [topUpRequired](#topuprequired) a linked MAIN's wallet would supply — the residual the owner's own wallet could not cover, capped at [PerpOrderMarginQuoteInputs.mainWalletCapacity](PerpOrderMarginQuoteInputs.md#mainwalletcapacity). `0n` with no main, `0n` for an account that funds itself, and `0n` while [mainFundingBlocked](#mainfundingblocked). **Non-zero is the only proof another wallet is actually debited** — an eligible payer alone is not, since the order may need no top-up or the owner's own wallet may cover all of it. This is the number to show a trader before they sign. `ownWalletPull + mainWalletPull` is what the pull actually moves, and it is BELOW [topUpRequired](#topuprequired) exactly when [walletCoversTopUp](#walletcoverstopup) is `false` — neither leg reverts on a short wallet, so the shortfall surfaces at the margin gates instead. *** ### hasCollateralForLock > **hasCollateralForLock**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1950 Gate 1 — the unlocked balance covers the lock, **after any auto-pull**. With [PerpOrderMarginQuoteInputs.wallet](PerpOrderMarginQuoteInputs.md#wallet) supplied this is the real post-pull gate. Without it, the in-bank balance alone — conservative rather than wrong on the self-send path, since the pool tops up before `lockCollateral` runs. *** ### meetsInitialMargin > **meetsInitialMargin**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1964 Gate 2 — post-lock equity still meets the initial-margin requirement, **after any auto-pull** (the top-up lands in the unlocked balance that seeds equity). Note this is NOT monotone in quantity once auto-pull is modelled, and the reason is worth knowing: in the pulled regime the surcharge cancels from both sides and the gate reduces to `(equity − unlocked) + feeHeadroom ≥ imRequirement`, whose only quantity-dependent term GROWS. An account whose existing positions sit below their own initial margin can therefore be rejected at a middling size and accepted at a far larger one, whose headroom over-pulls enough to cover the deficit. `client.getMaxPerpOrderSize` deliberately does not offer sizes from that disconnected upper region. *** ### mainFundingBlocked > **mainFundingBlocked**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1970 The main's leg was withheld because the account still owes a prior payer — see [PerpOrderMarginQuoteInputs.mainFundingBlocked](PerpOrderMarginQuoteInputs.md#mainfundingblocked). Placement is not blocked outright, only the main's contribution. *** ### voucherBlocked > **voucherBlocked**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1972 The order would revert on the voucher allowlist / unset-cap guard. *** ### restrictedBlocked > **restrictedBlocked**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1977 The market is close-only and this order has an increasing leg, so placement reverts `MarketRestricted`. Never blocks a pure reduce. *** ### isolationBlocked > **isolationBlocked**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1983 The account is in isolated margin with a footprint in a DIFFERENT market, so placement reverts `IsolatedMarketBlocked`. Unlike every other gate here this blocks the reducing legs too — it is about which market may be traded, not about margin. *** ### sufficient > **sufficient**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1985 Every gate passes. --- # /docs/typescript/api/index/interfaces/PerpOrderMarginQuoteInputs [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpOrderMarginQuoteInputs # Interface: PerpOrderMarginQuoteInputs Defined in: packages/sdk/src/perp/margin.ts:1731 Everything the placement gates need, and nothing that has to come from a particular block — so `perpOrderMarginQuote` stays pure. ## Properties ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1733 True = a buy. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1735 Order quantity, raw base units. *** ### price > **price**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1737 Limit price, raw quote units per whole base. *** ### oneBase > **oneBase**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1739 10^decimals of the synthetic base. *** ### markPrice > **markPrice**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1741 Current mark, raw quote units per whole base. *** ### effectiveImfBps > **effectiveImfBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1743 The OI-scaled IMF in force, bps. *** ### positionSize > **positionSize**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1745 SIGNED existing position size, raw base units. *** ### effectiveReducingCapacity > **effectiveReducingCapacity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1747 Reducing capacity resting orders have not already spoken for, raw base units. *** ### equity > **equity**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1749 Account equity, signed. *** ### imRequirement > **imRequirement**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1751 Aggregate initial-margin requirement. *** ### unlockedCollateral > **unlockedCollateral**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1753 Unlocked collateral balance, signed. *** ### accountMaxLeverageX > **accountMaxLeverageX**: `number` Defined in: packages/sdk/src/perp/margin.ts:1755 The account's own per-market cap, `0` when unset. *** ### protocolMaxLeverageX > **protocolMaxLeverageX**: `number` Defined in: packages/sdk/src/perp/margin.ts:1757 Protocol-wide ceiling. *** ### creditFloor > **creditFloor**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1759 The account's credit-voucher floor. *** ### voucherLeverageCapX > **voucherLeverageCapX**: `number` Defined in: packages/sdk/src/perp/margin.ts:1761 The protocol's voucher leverage cap, `0` when unset. *** ### voucherMarketAllowed > **voucherMarketAllowed**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1763 Whether this market is voucher-allowlisted. *** ### wallet? > `optional` **wallet?**: `object` Defined in: packages/sdk/src/perp/margin.ts:1780 The owner's wallet, which turns auto-pull (T70) modelling ON. Supply it **only when the transaction sender will be the order owner**, because that is the pool's entire gate: `PerpPool._autoPullMargin` returns early unless `msg.sender == order.owner`, deliberately narrower than spot's, which also admits registry-approved operators. Routing through `placeOrderFor`, an operator grant, a router, or the stop registry means no pull — omit this and the gates fall back to the in-bank balance, which is what those paths actually face. `balance` is the owner's collateral-token balance and `allowance` their approval to the **MarginBank** (the same one `deposit` already needs — the pool reaches the wallet through `depositFor`). Both bind: the pull is an ordinary `transferFrom`, so whichever is smaller is the ceiling, and an insufficient one reverts from the TOKEN rather than being swallowed. #### balance > **balance**: `bigint` #### allowance > **allowance**: `bigint` *** ### mainWalletCapacity? > `optional` **mainWalletCapacity?**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1801 A linked MAIN's spendable capacity — `MarginBank.quoteWalletCapacity(payer)`, which is `min(balance, allowance)` in one number. Omit it when the account has no main. This is the SECOND funding leg, and without it a linked child's placement reads as underfunded when it is not. `PerpPool._reserveAndPullMargin` spends the owner's own wallet first and takes the residual from the main, so the two legs add: the pull succeeds when `ownCapacity + mainWalletCapacity` covers [PerpOrderMarginQuote.topUpRequired](PerpOrderMarginQuote.md#topuprequired). It only participates when [wallet](#wallet) is also supplied, because the whole pull — both legs — is gated on `msg.sender == order.owner`. A main never funds an operator-routed or stop-triggered order. One number rather than a balance/allowance pair on purpose: the bank exposes only the minimum for another wallet, and reading the pair separately would let the SDK's sizing disagree with the contract's. The cost is that a main-side shortfall does not say which of the two bound — a caller that needs to know reads the main's token balance and allowance directly. *** ### mainFundingBlocked? > `optional` **mainFundingBlocked?**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1817 The main's leg cannot be spent because the account still owes a DIFFERENT payer. Defaults to `false`. `MarginBank.depositForFromMain` allows one payer at a time: while `mainFundedPrincipal` is outstanding it reverts `PriorFundingPayerOutstanding` unless the live payer IS the recorded one. A child funded by main A, unlinked, and re-linked to main B is exactly that state, and `quoteFundingPayer` names B — so counting B's capacity would quote an executable order that reverts. While `true` the main's leg is treated as zero, whatever [mainWalletCapacity](#mainwalletcapacity) says. The account can still place whatever its own wallet and bank balance fund. The fix is to clear the old claim with `trader.repayPerpMainFunding`, not to fund either main. *** ### takerFeeBpsTimes1k? > `optional` **takerFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1822 The pool's taker fee, `BPS_TIMES_1K`. Feeds [PerpOrderMarginQuote.feeHeadroom](PerpOrderMarginQuote.md#feeheadroom) only; the lock itself is fee-free. Defaults to `0n`. *** ### makerFeeBpsTimes1k? > `optional` **makerFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1824 The pool's maker fee, `BPS_TIMES_1K` and SIGNED — negative is a rebate. Defaults to `0n`. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1826 The builder fee attached to this order, `BPS_TIMES_1K`. Defaults to `0n`. *** ### restricted? > `optional` **restricted?**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1833 The market is in close-only mode (`PerpPool.isRestricted()`). Defaults to `false`. Rejects any order with an increasing leg outright — no arithmetic involved — so it behaves like the voucher block rather than like a margin gate. *** ### isolationAllowsMarket? > `optional` **isolationAllowsMarket?**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1840 `MarginBank.isolationAllowsMarket(account, pool)`. Defaults to `true`. `false` rejects the WHOLE order, reducing legs included — the one placement gate that does, because it is a market-selection rule rather than a margin one. --- # /docs/typescript/api/index/interfaces/PerpPosition [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPosition # Interface: PerpPosition Defined in: packages/sdk/src/perp/state.ts:451 An account's position in one perp pool (from the MarginBank). `size` is signed base units: positive = long, negative = short, zero = flat. ## Properties ### size > **size**: `bigint` Defined in: packages/sdk/src/perp/state.ts:456 Signed position size in raw base units: positive = long, negative = short, zero = flat. *** ### avgEntryPrice > **avgEntryPrice**: `bigint` Defined in: packages/sdk/src/perp/state.ts:458 Volume-weighted average entry price (raw quote units per whole base). *** ### entryFundingIndex > **entryFundingIndex**: `bigint` Defined in: packages/sdk/src/perp/state.ts:460 Cumulative funding index at open / last settlement (1e18-scaled, signed). *** ### lastUpdatedTimestampNs > **lastUpdatedTimestampNs**: `bigint` Defined in: packages/sdk/src/perp/state.ts:462 Last position update (nanoseconds). --- # /docs/typescript/api/index/interfaces/PerpPositionAnalyticsInputs [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPositionAnalyticsInputs # Interface: PerpPositionAnalyticsInputs Defined in: packages/sdk/src/perp/margin.ts:789 Everything the per-position arithmetic needs, and nothing that has to come from a particular block — so `perpPositionAnalytics` stays pure and testable. The last six all arrive together from one `tryGetHealthSnapshot`; the first three are the stored `Position`. ## Properties ### size > **size**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:791 SIGNED position size, raw base units (positive = long, negative = short). *** ### avgEntryPrice > **avgEntryPrice**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:793 Volume-weighted average entry price, raw quote units per whole base. *** ### entryFundingIndex > **entryFundingIndex**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:795 Cumulative funding index stamped at open / last settlement (1e18-scaled, signed). *** ### markPrice > **markPrice**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:797 Current mark price, raw quote units per whole base. *** ### projectedCumulativeFunding > **projectedCumulativeFunding**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:799 Cumulative funding per unit INCLUDING unsettled intervals (1e18-scaled, signed). *** ### oneBase > **oneBase**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:801 10^decimals of the synthetic base asset. *** ### effectiveImfBps > **effectiveImfBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:803 The OI-scaled IMF actually in force, bps. *** ### maintenanceMarginBps > **maintenanceMarginBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:805 Maintenance threshold, bps. *** ### closeOutMarginBps > **closeOutMarginBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:807 Close-out / takeover threshold, bps. --- # /docs/typescript/api/index/interfaces/PerpPositionMetrics [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPositionMetrics # Interface: PerpPositionMetrics Defined in: packages/sdk/src/perp/margin.ts:815 One position, marked to the current mark and funding index. ## Properties ### size > **size**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:817 SIGNED size, raw base units — echoed so a result stands alone. *** ### notional > **notional**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:819 `|size| × mark / oneBase`, raw collateral units. Zero when flat. *** ### unrealizedPnl > **unrealizedPnl**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:827 Mark-to-market PnL on price alone, signed: `(mark − entry) × size / oneBase`. **Excludes funding**, deliberately — see [accruedFunding](#accruedfunding). Truncates toward zero, matching `PerpMath.unrealizedPnl`'s plain `int256` division, which is NOT the rounding the funding leg uses. *** ### accruedFunding > **accruedFunding**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:845 Funding **owed** since the position's entry index, signed and raw collateral units. **Positive means the account pays**; negative means it receives. Sign is the contract's, not a display convention, and it is the opposite of [unrealizedPnl](#unrealizedpnl)'s: this is a payment, so it is SUBTRACTED to reach [equityContribution](#equitycontribution). Rendering it beside PnL without flipping it shows a cost as a gain. Includes unsettled intervals, because it is computed against the pool's *projected* cumulative index rather than its last settled one — settlement is permissionless and lazy, so the settled index can lag by hours, and a position measured against it under-reports what the account already owes. Ceils toward +∞ (`divCeilInt`), so a payer pays at least what is owed and a receiver receives at most it. *** ### equityContribution > **equityContribution**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:853 This position's contribution to account equity: `unrealizedPnl − accruedFunding`. The figure the MarginBank actually sums. Across every active market these add to `equity − collateral`, exactly — which is the invariant that makes this a port of the contract rather than a re-derivation of it. *** ### initialMarginRequirement > **initialMarginRequirement**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:868 This position's share of the account's initial-margin requirement: `ceil(notional × effectiveImfBps / 10000)`. **This is "position margin" in the only sense the protocol defines one.** Margin is cross, so no collateral is segregated per position and there is nothing to read; what a position *does* have is the requirement it adds to the account. Note it uses the market's IMF only. An account leverage setting stricter than the market's IMF raises the bar for a NEW order (`MarginBank._meetsIM`) but does not appear here, because `_marketHealthFromSnapshot` does not apply it — health, liquidation and equity are all measured without it. Use [SomniaMarketsClient.previewPerpOrderMargin](SomniaMarketsClient.md#previewperpordermargin) for the order-gating figure. *** ### maintenanceMarginRequirement > **maintenanceMarginRequirement**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:870 `ceil(notional × maintenanceMarginBps / 10000)` — the liquidation threshold's share. *** ### closeOutMarginRequirement > **closeOutMarginRequirement**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:872 `ceil(notional × closeOutMarginBps / 10000)` — the takeover threshold's share. *** ### returnOnMarginBps > **returnOnMarginBps**: `bigint` \| `null` Defined in: packages/sdk/src/perp/margin.ts:889 [equityContribution](#equitycontribution) over [initialMarginRequirement](#initialmarginrequirement), in bps — "this position has returned N% of the margin it ties up". **Net of funding**, because funding is a real cost of holding the position and a gross figure flatters a position that is up on price and bleeding carry. For the price-only ratio, use `unrealizedPnl × 10000n / initialMarginRequirement`. `null` whenever [initialMarginRequirement](#initialmarginrequirement) is zero and the ratio is therefore undefined — not `0n`, which would read as a real break-even. That is a flat position in the ordinary case, and also a dust one whose [notional](#notional) floors to zero, which the protocol likewise asks no margin for. Floors (toward −∞) rather than truncating, so a loss never rounds toward looking smaller than it is. --- # /docs/typescript/api/index/interfaces/PerpPositionRef [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPositionRef # Interface: PerpPositionRef Defined in: packages/sdk/src/perp/state.ts:474 Identifies one account's position in one perp pool — the (bank, account, pool) triple every per-position read keys on. Shared by `getPerpPosition` and `getLiquidationPrice` (perp/margin.ts); one object instead of three positional `Address` args (which compiled fine with any two swapped). ## Properties ### marginBank > **marginBank**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/state.ts:476 The MarginBank holding the position — comes off the `PerpMarket` row. *** ### account > **account**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/state.ts:478 The position's owner. *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/state.ts:480 The perp pool the position is in. --- # /docs/typescript/api/index/interfaces/PerpRiskParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpRiskParams # Interface: PerpRiskParams Defined in: packages/sdk/src/perp/margin.ts:147 A perp market's RISK CONFIG — the static parameters frozen on the pool, read straight from `getPerpPoolParameters`. Never reverts, so this is the dependable source for maintenance margin even when the mark feed is down. All bps values are standard basis points (100 = 1%) EXCEPT the two fee fields, which are bps × 1000 (the pool's own unit — 1500 = 1.5 bps = 0.015%). ## Properties ### initialMarginBps > **initialMarginBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:154 The initial-margin curve's FLOOR, bps — not necessarily what an order is charged. When dynamic IMF is enabled the pool scales this up with open interest; read `effectiveImfBps` off [PerpHealthSnapshot](../type-aliases/PerpHealthSnapshot.md) for the rate actually in force. Equal to the effective IMF only when dynamic IMF is off. *** ### maintenanceMarginBps > **maintenanceMarginBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:161 Maintenance-margin threshold, bps — the level below which a position is liquidatable. Unlike initial margin this does **not** scale with open interest, deliberately: the liquidation threshold must not move under a position because the market's OI grew. *** ### closeOutMarginBps > **closeOutMarginBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:163 Close-out / takeover threshold, bps. Strictly below maintenance. *** ### maxOpenInterest > **maxOpenInterest**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:165 Market-wide open-interest cap, raw base units. *** ### maxPositionSize > **maxPositionSize**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:167 Per-position size cap, raw base units. *** ### takerFeeBpsTimes1k > **takerFeeBpsTimes1k**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:169 Taker fee, bps × 1000. *** ### makerFeeBpsTimes1k > **makerFeeBpsTimes1k**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:171 Maker fee, bps × 1000 — SIGNED, because a negative value is a maker rebate. *** ### insuranceFundShareBps > **insuranceFundShareBps**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:173 Share of collected fees routed to the Insurance Fund, bps. --- # /docs/typescript/api/index/interfaces/PerpSideHolders [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpSideHolders # Interface: PerpSideHolders Defined in: packages/sdk/src/perp/margin.ts:1137 One side of one perp market's complete holder set, as of one block. ## Properties ### holders > **holders**: `` `0x${string}` ``[] Defined in: packages/sdk/src/perp/margin.ts:1143 Every account holding an open position on the requested side. Ordering is UNSPECIFIED by the contract and can change on any close — treat it as a set, never as a stable sequence. Empty when nobody holds that side. *** ### asOfBlock > **asOfBlock**: `bigint` Defined in: packages/sdk/src/perp/margin.ts:1150 The block height every page was read at. Feed it into the reads that take a block pin — `getBankruptcyPrice`'s `opts.blockNumber`, and a sibling call for the other side — to keep a sweep on one consistent snapshot. (The other position/health reads answer at head only.) --- # /docs/typescript/api/index/interfaces/PerpSideHoldersRef [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpSideHoldersRef # Interface: PerpSideHoldersRef Defined in: packages/sdk/src/perp/margin.ts:1104 Identifies one side of one perp market in the MarginBank — the (bank, pool, side) triple the holder-enumeration read keys on. ## Properties ### marginBank > **marginBank**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/margin.ts:1106 The MarginBank holding the positions — comes off the `PerpMarket` row. *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/margin.ts:1108 The perp pool whose holders to enumerate. *** ### isLong > **isLong**: `boolean` Defined in: packages/sdk/src/perp/margin.ts:1110 True for the long side, false for the short side. --- # /docs/typescript/api/index/interfaces/PerpStateOnchain [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpStateOnchain # Interface: PerpStateOnchain Defined in: packages/sdk/src/perp/state.ts:22 A perp pool's live pricing/funding state, read straight from chain in one pipelined fan-out. Fresher than the indexed Market row (funding fields there only update when FundingUpdated fires, i.e. per settlement window). ## Properties ### markPrice > **markPrice**: `bigint` Defined in: packages/sdk/src/perp/state.ts:24 EMA-smoothed oracle mark price (raw quote units per whole base). *** ### markPriceOk > **markPriceOk**: `boolean` Defined in: packages/sdk/src/perp/state.ts:29 Whether the mark feed is live. When false, `markPrice` is not meaningful — the FundingUpdated event signals the same condition with a 0 sentinel. *** ### indexPrice > **indexPrice**: `bigint` Defined in: packages/sdk/src/perp/state.ts:31 Unsmoothed oracle index price (raw quote units per whole base). *** ### indexUpdatedAt > **indexUpdatedAt**: `bigint` Defined in: packages/sdk/src/perp/state.ts:33 Index price oracle timestamp (seconds). *** ### fundingRate > **fundingRate**: `bigint` Defined in: packages/sdk/src/perp/state.ts:35 Current funding rate per settlement window (1e18-scaled fraction, signed). *** ### cumulativeFundingPerUnit > **cumulativeFundingPerUnit**: `bigint` Defined in: packages/sdk/src/perp/state.ts:37 Settled cumulative funding per base unit (1e18-scaled, signed). *** ### projectedCumulativeFundingPerUnit > **projectedCumulativeFundingPerUnit**: `bigint` Defined in: packages/sdk/src/perp/state.ts:39 Cumulative funding projected to now (unsettled accrual included). *** ### openInterest > **openInterest**: `bigint` Defined in: packages/sdk/src/perp/state.ts:47 TOTAL open interest in base units. Replaces `longOpenInterest` / `shortOpenInterest`: the contract keeps ONE counter because the short side is provably equal in a matched CLOB, and the two-field form did not match the deployed ABI at all — it made every `getPerpState` call throw. *** ### fundingWindowSec > **fundingWindowSec**: `number` Defined in: packages/sdk/src/perp/state.ts:53 The rate's DENOMINATOR in seconds (`fundingCalculationWindowSec`), 28800 on every live pool. `fundingRate` is per THIS window — not per settlement interval and not annualized. Normalize with it; never with a hardcoded constant. *** ### fundingIntervalSec > **fundingIntervalSec**: `number` Defined in: packages/sdk/src/perp/state.ts:60 Settlement cadence in seconds. **3600 on every live pool**, so `fundingWindowSec / fundingIntervalSec` is 8. It has been 300 (n = 96), and the same emitted rate means a 12x different per-interval accrual across that boundary — which is why this is read per pool and never assumed. Indexed history still spans it. *** ### lastFundingUpdateAt > **lastFundingUpdateAt**: `bigint` Defined in: packages/sdk/src/perp/state.ts:62 Last settlement, unix seconds (the chain stores nanoseconds). *** ### nextFundingAt > **nextFundingAt**: `bigint` Defined in: packages/sdk/src/perp/state.ts:64 When the next settlement becomes due. Settlement is LAZY, so it may pass unmet. *** ### emaPremium > **emaPremium**: `bigint` Defined in: packages/sdk/src/perp/state.ts:86 EMA'd premium driving the rate, and NOT mark vs index — expect it to disagree with `(mark - index) / index`, which is a different quantity by design. Since DEX-2252 the underlying premium is Binance's impact-price shape rather than a book midpoint: `[max(0, impactBid - index) - max(0, index - impactAsk)] / index`, where each impact price is the quantity-weighted price of filling a configured impact notional on that side, counting only orders that pass a fillability check, and time-weighted across the settlement interval. Three consequences: - **There is a deadband.** An index sitting anywhere inside the impact spread prices exactly zero, so a merely wide book is no longer charged funding for its spread. - **Zero does not mean an empty book.** A side that cannot show the impact notional of fillable depth drops out and the other side stands alone, so a ONE-SIDED book can carry a non-zero premium. Only a book with nothing priceable on either side is reliably zero. - **It lags the book**, because it is an average over the interval rather than a reading at an instant. Not recoverable from events, so this read is the only source. *** ### oracle > **oracle**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/state.ts:96 The pool's aggregator oracle contract. This is the address the pool itself reads prices from, so it is the head of the chain that produces `markPrice` and `indexPrice` — the aggregator chains to the sim-controlled oracle and then to the agent EMA feed. It is a per-pool address: every live pool reports a different one, so it cannot be substituted with a per-network constant such as the deployment config's `oracleHub`. --- # /docs/typescript/api/index/interfaces/PerpStopOrderLeg [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpStopOrderLeg # Interface: PerpStopOrderLeg Defined in: packages/sdk/src/trade.ts:1350 One leg of a perp stop order — the terms shared by a single stop and by each half of a linked pair. ## Extended by - [`PlacePerpStopOrderParams`](PlacePerpStopOrderParams.md) ## Properties ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:1352 True = the triggered order buys, false = sells. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:1362 Base quantity to trade at trigger, raw base units. ZERO is a sentinel meaning "the whole position at trigger time" — the size is resolved against the live position when it fires, so the stop keeps covering a position that GREW after it was armed. A non-zero quantity is fixed at creation and only ever clamped DOWN. Rejected for `"opening"` intent, where it has no meaning. *** ### triggerPrice > **triggerPrice**: `bigint` Defined in: packages/sdk/src/trade.ts:1364 Mark price that arms the trigger (raw collateral units per whole base). *** ### triggerOperator > **triggerOperator**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1366 0 = GTE (fires when mark ≥ triggerPrice), 1 = LTE (mark ≤ triggerPrice). *** ### stopOrderType > **stopOrderType**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1368 0 = LIMIT (uses limitPrice), 1 = MARKET (slippage-bounded by the registry). *** ### limitPrice? > `optional` **limitPrice?**: `bigint` Defined in: packages/sdk/src/trade.ts:1370 Limit price for a LIMIT stop (raw collateral per whole base). Must be 0 for MARKET. *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1372 Builder to tag on the triggered order. Omit for none. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/trade.ts:1374 Builder fee in bps x 1000 (so 1500 = 1.5bps). Requires `builder`. --- # /docs/typescript/api/index/interfaces/PerpSystemConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpSystemConfig # Interface: PerpSystemConfig Defined in: packages/sdk/src/perp/system.ts:36 How the perps stack is wired, straight from `MarginBank.getSystemConfig`. This is the address book. Every other contract in the plane is reachable from here, so a consumer never hardcodes one per chain — and the bank's own view of them is the authoritative one, since these are the addresses it will actually call. ## Properties ### marginBank > **marginBank**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:38 The MarginBank reporting this config (echoed back). *** ### collateralToken > **collateralToken**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:40 The single collateral token every perp market is quoted in. *** ### perpPoolFactory > **perpPoolFactory**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:42 The factory that deploys PerpPools. *** ### liquidationEngine > **liquidationEngine**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:44 The LiquidationEngine — the PROXY, which is what to call. *** ### insuranceFund > **insuranceFund**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:46 The tiered InsuranceFund that absorbs bad debt. *** ### feeRecipient > **feeRecipient**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/system.ts:48 Where protocol fees are routed. *** ### maxLeverageLimit > **maxLeverageLimit**: `number` Defined in: packages/sdk/src/perp/system.ts:50 Protocol-wide ceiling on per-account leverage; clamps a stricter user setting. *** ### fullyWired > **fullyWired**: `boolean` Defined in: packages/sdk/src/perp/system.ts:62 Whether the factory, liquidation engine and insurance fund are all set. **`feeRecipient` is NOT part of it**, despite sitting in the same struct — the contract's flag covers three of the five addresses above. A go-live check that read this as "everything is configured" would sign off a stack whose fee routing is still unset, so check [feeRecipient](#feerecipient) separately. False means some part of the stack is half-configured, which is the state in which liquidation or settlement paths degrade silently rather than reverting. --- # /docs/typescript/api/index/interfaces/PerpWalletLinkTarget [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpWalletLinkTarget # Interface: PerpWalletLinkTarget Defined in: packages/sdk/src/trade.ts:956 How a linked-wallet consent write finds its `LinkedWalletRegistry` — the resolution triple every one of the four registry writes shares. Supply ONE of the three. `registry` is used as given. Otherwise the SDK reads `getLinkedWalletRegistry()` off the bank, because the bank is what decides which registry is authoritative — a registry nobody armed is inert. `pool` resolves the bank first. A bank holding no registry throws [NotConfiguredError](../classes/NotConfiguredError.md): the rail is dormant on that deployment. Pass `registry` to reach a registry anyway; the consent writes still work, they just fund nothing until the bank is armed. ## Extended by - [`ProposePerpWalletLinkParams`](ProposePerpWalletLinkParams.md) - [`AcceptPerpWalletLinkParams`](AcceptPerpWalletLinkParams.md) - [`CancelPerpWalletLinkProposalParams`](CancelPerpWalletLinkProposalParams.md) - [`UnlinkPerpWalletParams`](UnlinkPerpWalletParams.md) ## Properties ### registry? > `optional` **registry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:958 The LinkedWalletRegistry. Skips resolution entirely. *** ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:960 MarginBank address — its `getLinkedWalletRegistry()` is read (never cached). *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:962 A PerpPool — its `marginBank()` is read (and cached), then the registry. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:968 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PerpWalletLinkage [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpWalletLinkage # Interface: PerpWalletLinkage Defined in: packages/sdk/src/perp/linkedWallet.ts:153 A link group, with the maturity the raw graph does not carry. `maturesAt` matters for a reason worth stating: ADL netting is gated on maturity so that a link armed in reaction to an impending auto-deleveraging cannot buy netting credit. The FUNDING rail deliberately reads the raw graph instead, because the main proposed the link and owns the allowance, and there is no analogous surprise. So a link can be fundable and not yet mature — do not use `maturesAt` to decide whether a pull will happen. ## Properties ### main > **main**: `` `0x${string}` `` Defined in: packages/sdk/src/perp/linkedWallet.ts:155 The group's main. Zero when the wallet is unlinked. *** ### members > **members**: readonly `` `0x${string}` ``[] Defined in: packages/sdk/src/perp/linkedWallet.ts:157 The main plus every child. Empty when the wallet is unlinked. *** ### linkedAt > **linkedAt**: `bigint` Defined in: packages/sdk/src/perp/linkedWallet.ts:159 Unix seconds the link was formed, or 0. *** ### maturesAt > **maturesAt**: `bigint` Defined in: packages/sdk/src/perp/linkedWallet.ts:161 Unix seconds the link becomes mature FOR ADL NETTING, or 0. Not a funding gate. *** ### isChild > **isChild**: `boolean` Defined in: packages/sdk/src/perp/linkedWallet.ts:163 Convenience: whether this wallet is a child (has a main that is not itself). *** ### isMain > **isMain**: `boolean` Defined in: packages/sdk/src/perp/linkedWallet.ts:165 Convenience: whether this wallet is a main with at least one child. --- # /docs/typescript/api/index/interfaces/PlaceOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlaceOrderParams # Interface: PlaceOrderParams Defined in: packages/sdk/src/trade.ts:171 Inputs to [Trader.placeOrder](Trader.md#placeorder) — a binary YES/NO limit or market order on a BinaryPool. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:173 BinaryPool address. *** ### side > **side**: [`BinarySide`](../type-aliases/BinarySide.md) Defined in: packages/sdk/src/trade.ts:178 Side + outcome ("BUY_YES" | "SELL_YES" | "BUY_NO" | "SELL_NO") — mapped onto the pool's OrderKind enum. Buys escrow collateral, sells escrow outcome tokens. *** ### price > **price**: `bigint` Defined in: packages/sdk/src/trade.ts:180 YES limit price as raw collateral units per whole outcome token (price × 10^decimals). *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:182 Outcome-token quantity, raw units. *** ### outcomeToken? > `optional` **outcomeToken?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:187 Outcome-token singleton + this pool's YES/NO ids. Resolved from the pool (IBinaryPool.outcomeToken/yesId/noId) if omitted. *** ### yesId? > `optional` **yesId?**: `bigint` Defined in: packages/sdk/src/trade.ts:189 This pool's YES position id on the singleton; resolved from the pool if omitted. *** ### noId? > `optional` **noId?**: `bigint` Defined in: packages/sdk/src/trade.ts:191 This pool's NO position id on the singleton; resolved from the pool if omitted. *** ### collateral? > `optional` **collateral?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:193 Collateral (buy-side escrow) token; resolved from the pool if omitted. *** ### expireTimestampNs? > `optional` **expireTimestampNs?**: `bigint` Defined in: packages/sdk/src/trade.ts:207 Order expiry in ns. Defaults to the POOL'S MARKET EXPIRY, not to a far future — a binary order must satisfy `0 < expireNs <= pool.marketExpiryNs` or the pool rejects it with `OrderExpiryBeyondMarket`, which keeps the book drainable by the expiry sweeps once the market locks. So an order left to default stops resting when its market expires. On a rolling series that is hours, not decades. There is no GTC here; ~50y is the spot and perp default, where there is no market expiry to outlive. A value already in the past reverts (`OrderAlreadyExpired`) — a deliberate choice is honoured verbatim rather than silently clamped. *** ### orderType? > `optional` **orderType?**: `number` Defined in: packages/sdk/src/trade.ts:213 OrderBook OrderType (see [ORDER\_TYPE](../variables/ORDER_TYPE.md)): 0 NormalOrder (rest), 1 FillOrKill, 2 ImmediateOrCancel, 3 PostOnly. Defaults to 0. A market order is an IOC (2) placed at the price extreme so it crosses immediately and cancels the remainder. *** ### selfMatchingOption? > `optional` **selfMatchingOption?**: `number` Defined in: packages/sdk/src/trade.ts:218 Self-match behaviour when this order crosses your OWN resting order, default 0 (`CANCEL_TAKER`). See [SELF\_MATCHING\_OPTION](../variables/SELF_MATCHING_OPTION.md). *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:220 Approve the escrow token to the pool if allowance is short (default true). *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:226 Routing/builder frontend address to attribute the order to. Requires the trader to have opted this builder in via [Trader.approveBuilder](Trader.md#approvebuilder). Omit (or zero) for no routing fee. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/trade.ts:231 Per-order builder/routing fee in the pool's native bps×1000 unit (≤ the venue's frozen `maxBuilderFee` ceiling AND ≤ the trader's approval). 0 = none. *** ### userData? > `optional` **userData?**: `bigint` Defined in: packages/sdk/src/trade.ts:237 Opaque market-maker bookkeeping tag (v2). Forwarded verbatim to the pool (stored on the order + emitted in `OrderPlaced`); the SDK never interprets it and the pool no longer uses it for side derivation. Default 0. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:243 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PlaceOrderResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlaceOrderResult # Interface: PlaceOrderResult Defined in: packages/sdk/src/trade.ts:158 Base result of a confirmed write — the SDK waits for the receipt before resolving. ## Extends - [`TxResult`](TxResult.md) ## Properties ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) *** ### orderId? > `optional` **orderId?**: `bigint` Defined in: packages/sdk/src/trade.ts:160 The resting order's on-chain id, if the order rested (OrderPlaced emitted). *** ### fills > **fills**: [`OrderFill`](OrderFill.md)[] Defined in: packages/sdk/src/trade.ts:162 Fills that executed in this tx (empty for a cleanly-resting limit order). --- # /docs/typescript/api/index/interfaces/PlacePerpOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlacePerpOrderParams # Interface: PlacePerpOrderParams Defined in: packages/sdk/src/trade.ts:696 Inputs to [Trader.placePerpOrder](Trader.md#placeperporder) — a perp limit or market order on a PerpPool. Margin is locked from the signer's MarginBank balance (no escrow transfer in this tx) — [Trader.depositMargin](Trader.md#depositmargin) first. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:698 PerpPool address. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:700 True = buy/long the synthetic base; false = sell/short. *** ### price > **price**: `bigint` Defined in: packages/sdk/src/trade.ts:705 Limit price — raw quote (collateral) units per whole base. For a MARKET order pass a crossing price; it bounds the margin lock. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:707 Base quantity, raw base units. *** ### expireTimestampNs? > `optional` **expireTimestampNs?**: `bigint` Defined in: packages/sdk/src/trade.ts:709 Order expiry in ns. Defaults to ~50y (GTC). *** ### orderType? > `optional` **orderType?**: `number` Defined in: packages/sdk/src/trade.ts:711 0 limit (default) or 2 market (IOC). See [ORDER\_TYPE](../variables/ORDER_TYPE.md). *** ### selfMatchingOption? > `optional` **selfMatchingOption?**: `number` Defined in: packages/sdk/src/trade.ts:716 Self-match behaviour when this order crosses your OWN resting order, default 0 (`CANCEL_TAKER`). See [SELF\_MATCHING\_OPTION](../variables/SELF_MATCHING_OPTION.md). *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:722 Routing/builder frontend address to attribute the order to. Requires the trader to have opted this builder in via [Trader.approveBuilder](Trader.md#approvebuilder) on this pool. Omit (or zero) for no routing fee. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/trade.ts:729 Per-order builder/routing fee in the pool's native bps×1000 unit (≤ the pool's `maxBuilderFee` ceiling AND ≤ the trader's approval). 0 = none. The ceiling is owner-updatable on a PerpPool, so read it rather than caching it indefinitely. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:735 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PlacePerpStopOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlacePerpStopOrderParams # Interface: PlacePerpStopOrderParams Defined in: packages/sdk/src/trade.ts:1389 Inputs to [Trader.placePerpStopOrder](Trader.md#placeperpstoporder) — a take-profit / stop-loss (or, with `intent: "opening"`, a stop-entry) that the PerpStopOrderRegistry holds pending and places on the PerpPool when the MARK price crosses the trigger. Pass `pair` to arm two legs as a linked one-cancels-other set in a single transaction, at 2x the SOMI payment. There is no separate "place linked" method on purpose: a pair is the same order with a second leg, and splitting it would give callers two ways to say one thing. ## Extends - [`PerpStopOrderLeg`](PerpStopOrderLeg.md) ## Properties ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:1352 True = the triggered order buys, false = sells. #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`isBid`](PerpStopOrderLeg.md#isbid) *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:1362 Base quantity to trade at trigger, raw base units. ZERO is a sentinel meaning "the whole position at trigger time" — the size is resolved against the live position when it fires, so the stop keeps covering a position that GREW after it was armed. A non-zero quantity is fixed at creation and only ever clamped DOWN. Rejected for `"opening"` intent, where it has no meaning. #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`quantity`](PerpStopOrderLeg.md#quantity) *** ### triggerPrice > **triggerPrice**: `bigint` Defined in: packages/sdk/src/trade.ts:1364 Mark price that arms the trigger (raw collateral units per whole base). #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`triggerPrice`](PerpStopOrderLeg.md#triggerprice) *** ### triggerOperator > **triggerOperator**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1366 0 = GTE (fires when mark ≥ triggerPrice), 1 = LTE (mark ≤ triggerPrice). #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`triggerOperator`](PerpStopOrderLeg.md#triggeroperator) *** ### stopOrderType > **stopOrderType**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1368 0 = LIMIT (uses limitPrice), 1 = MARKET (slippage-bounded by the registry). #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`stopOrderType`](PerpStopOrderLeg.md#stopordertype) *** ### limitPrice? > `optional` **limitPrice?**: `bigint` Defined in: packages/sdk/src/trade.ts:1370 Limit price for a LIMIT stop (raw collateral per whole base). Must be 0 for MARKET. #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`limitPrice`](PerpStopOrderLeg.md#limitprice) *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1372 Builder to tag on the triggered order. Omit for none. #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`builder`](PerpStopOrderLeg.md#builder) *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/trade.ts:1374 Builder fee in bps x 1000 (so 1500 = 1.5bps). Requires `builder`. #### Inherited from [`PerpStopOrderLeg`](PerpStopOrderLeg.md).[`builderFeeBpsTimes1k`](PerpStopOrderLeg.md#builderfeebpstimes1k) *** ### registry > **registry**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1391 PerpStopOrderRegistry address (one per PerpPool). *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1393 The PerpPool the registry places on — needed for the operator-auth check. *** ### operatorRegistry? > `optional` **operatorRegistry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1398 Shared OperatorPermissionsRegistry where the one-time global approval is granted. Resolved from the live config (addresses.operatorPermissionsRegistry) if omitted. *** ### intent? > `optional` **intent?**: [`PerpStopIntent`](../type-aliases/PerpStopIntent.md) Defined in: packages/sdk/src/trade.ts:1403 Reduce-only (default) or opening. Omit and existing callers keep the behaviour they always had. *** ### pair? > `optional` **pair?**: [`PerpStopOrderLeg`](PerpStopOrderLeg.md) Defined in: packages/sdk/src/trade.ts:1414 A second leg, armed atomically and LINKED to the first: when one fires and fills, the other is cancelled and its SOMI refunded. The pair must be a coherent TP/SL set — same side, OPPOSITE trigger operators, and straddling (the GTE leg's trigger above the LTE leg's) — or the registry rejects it. Both legs are reduce-only; an opening leg cannot be paired, because a bracket whose children activate on the parent's FILL is not expressible (the pool does not notify the registry on fill). *** ### somiPayment? > `optional` **somiPayment?**: `bigint` Defined in: packages/sdk/src/trade.ts:1419 SOMI to fund the reactivity trigger gas, PER LEG. Read from registry.somiPaymentPerOrder() if omitted; a pair sends twice this. *** ### skipOperatorApproval? > `optional` **skipOperatorApproval?**: `boolean` Defined in: packages/sdk/src/trade.ts:1424 Skip the one-time operator-approval check/tx (default false). Set true if you know the registry is already operator-approved for this owner. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1430 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PlacePerpStopOrderResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlacePerpStopOrderResult # Interface: PlacePerpStopOrderResult Defined in: packages/sdk/src/trade.ts:143 [Trader.placePerpStopOrder](Trader.md#placeperpstoporder)'s result: the tx plus the registry id(s). Both ids come from `PendingOrderCreated`, because the function's return value is unreadable from a receipt. ## Extends - [`TxResult`](TxResult.md) ## Other ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) *** ### stopOrderId? > `optional` **stopOrderId?**: `bigint` Defined in: packages/sdk/src/trade.ts:149 The id of the leg described by the call's own top-level fields — pass to [Trader.cancelPerpStopOrder](Trader.md#cancelperpstoporder). Undefined only if the event wasn't found in the receipt (an ABI/deployment drift, not a normal path). ## trading ### pairedStopOrderId? > `optional` **pairedStopOrderId?**: `bigint` Defined in: packages/sdk/src/trade.ts:155 The `pair` leg's id, when one was placed. Undefined for a single stop. --- # /docs/typescript/api/index/interfaces/PlaceSpotOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlaceSpotOrderParams # Interface: PlaceSpotOrderParams Defined in: packages/sdk/src/trade.ts:416 Inputs to [Trader.placeSpotOrder](Trader.md#placespotorder) — a spot limit or market order on a SpotPool. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:418 SpotPool address. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:420 True = buy the base asset (pay quote); false = sell base (pay base/native). *** ### price > **price**: `bigint` Defined in: packages/sdk/src/trade.ts:425 Limit price — raw quote units per whole base token. For a MARKET order pass a crossing price (best opposite level ± slippage); it bounds the escrow. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:427 Base quantity, raw base units. *** ### ~~baseDecimals?~~ > `optional` **baseDecimals?**: `number` Defined in: packages/sdk/src/trade.ts:434 Base-token decimals. The pool now reports its exact funding requirement, so the SDK no longer uses this value. #### Deprecated Retained for source compatibility. New calls can omit it. *** ### quoteToken > **quoteToken**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:436 Quote token (approved on a buy). *** ### baseToken > **baseToken**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:438 Base token (approved on a non-native sell). *** ### baseIsNative? > `optional` **baseIsNative?**: `boolean` Defined in: packages/sdk/src/trade.ts:446 True when the base asset is native SOMI. A sell then pays via `msg.value` instead of an approval — the pool's exact vault shortfall, fee headroom included, read from `getAutoPullRequirement` (one `eth_call`) right before the order is encoded. The bare quantity would revert `InvalidMsgValue` on any fee-bearing pool. *** ### expireTimestampNs? > `optional` **expireTimestampNs?**: `bigint` Defined in: packages/sdk/src/trade.ts:462 Order expiry in ns. Defaults to ~50y (GTC). A spot pool has no market expiry to outlive, so the binary verb's `OrderExpiryBeyondMarket` cap does not apply here. Two traps: - A timestamp already in the PAST reverts with `OrderAlreadyExpired`. It used to be accepted silently — the pool skipped the placement and returned no order id, so the transaction succeeded having placed nothing — but the current protocol rejects it outright. - An expired order does NOT auto-return its escrow, and this one IS silent. The funds stay locked in the pool until someone sweeps it — [Trader.cancelExpiredOrders](Trader.md#cancelexpiredorders) reclaims them, and is callable by anyone, not only the owner. *** ### orderType? > `optional` **orderType?**: `number` Defined in: packages/sdk/src/trade.ts:464 0 limit (default) or 2 market (IOC). See [ORDER\_TYPE](../variables/ORDER_TYPE.md). *** ### selfMatchingOption? > `optional` **selfMatchingOption?**: `number` Defined in: packages/sdk/src/trade.ts:469 Self-match behaviour when this order crosses your OWN resting order, default 0 (`CANCEL_TAKER`). See [SELF\_MATCHING\_OPTION](../variables/SELF_MATCHING_OPTION.md). *** ### userData? > `optional` **userData?**: `bigint` Defined in: packages/sdk/src/trade.ts:471 Opaque market-maker bookkeeping tag, forwarded verbatim. Default 0. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:473 Approve the escrow token if allowance is short (default true). *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:479 Routing/builder frontend address to attribute the order to. Requires the trader to have opted this builder in via [Trader.approveBuilder](Trader.md#approvebuilder) on this pool. Omit (or zero) for no routing fee. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/trade.ts:486 Per-order builder/routing fee in the pool's native bps×1000 unit (≤ the pool's `maxBuilderFee` ceiling AND ≤ the trader's approval). 0 = none. The ceiling is owner-updatable on a SpotPool, so read it rather than caching it indefinitely. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:492 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PlaceSpotOrdersParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlaceSpotOrdersParams # Interface: PlaceSpotOrdersParams Defined in: packages/sdk/src/trade.ts:544 Inputs to [Trader.placeSpotOrders](Trader.md#placespotorders) — place several orders on ONE SpotPool in a single transaction. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:546 SpotPool address every order in this batch targets. *** ### orders > **orders**: [`SpotOrderRequest`](SpotOrderRequest.md)[] Defined in: packages/sdk/src/trade.ts:548 The orders to place, in the order the results come back. *** ### ~~baseDecimals?~~ > `optional` **baseDecimals?**: `number` Defined in: packages/sdk/src/trade.ts:555 Base-token decimals. The pool now reports each order's exact funding requirement, so the SDK no longer uses this value. #### Deprecated Retained for source compatibility. New calls can omit it. *** ### quoteToken > **quoteToken**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:557 Quote token (approved once for the batch's total buy-side escrow). *** ### baseToken > **baseToken**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:559 Base token (approved once for the batch's total sell-side quantity). *** ### baseIsNative? > `optional` **baseIsNative?**: `boolean` Defined in: packages/sdk/src/trade.ts:566 True when the base asset is native SOMI. Batch writes are NON-payable, so a native-base sell here funds from the pool's vault balance — pre-deposit native to the vault first (the batch cannot send `msg.value`, and nothing is approved for a native base). *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:568 Approve the escrow tokens if allowance is short (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:574 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PlaceSpotOrdersResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlaceSpotOrdersResult # Interface: PlaceSpotOrdersResult Defined in: packages/sdk/src/trade.ts:598 Result of [Trader.placeSpotOrders](Trader.md#placespotorders). ## Extends - [`TxResult`](TxResult.md) ## Properties ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) *** ### outcomes > **outcomes**: [`BatchPlaceOutcome`](BatchPlaceOutcome.md)[] Defined in: packages/sdk/src/trade.ts:604 Per-request outcomes, index-aligned with the `orders` input. Reconstructed from the receipt's `OrderPlaced` events (a transaction's return data is not readable by an EOA). *** ### fills > **fills**: [`OrderFill`](OrderFill.md)[] Defined in: packages/sdk/src/trade.ts:606 Fills that executed in this tx, across every request in the batch. --- # /docs/typescript/api/index/interfaces/PlaceSpotStopOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlaceSpotStopOrderParams # Interface: PlaceSpotStopOrderParams Defined in: packages/sdk/src/trade.ts:1239 Inputs to [Trader.placeSpotStopOrder](Trader.md#placespotstoporder) — a stop-loss / take-profit order the SpotStopOrderRegistry holds pending and places on the pool when the mark price crosses the trigger. Funded by SOMI `msg.value` for the trigger gas. ## Properties ### registry > **registry**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1241 SpotStopOrderRegistry address (the per-pool registry). *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1246 The SpotPool the registry trades on — needed for the operator-auth check, the ERC-20 escrow approval, and the native vault pre-load math. *** ### operatorRegistry? > `optional` **operatorRegistry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1251 Shared OperatorPermissionsRegistry where the one-time global approval is granted. Resolved from the live config (addresses.operatorPermissionsRegistry) if omitted. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:1253 True = buy stop (escrows quote at trigger); false = sell stop (escrows base/native). *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:1255 Base quantity to trade at trigger, raw base units. *** ### triggerPrice > **triggerPrice**: `bigint` Defined in: packages/sdk/src/trade.ts:1257 Mark price that arms the trigger (raw quote per whole base). *** ### triggerOperator > **triggerOperator**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1259 0 = GTE (trigger when mark ≥ triggerPrice), 1 = LTE (mark ≤ triggerPrice). *** ### stopOrderType > **stopOrderType**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1261 0 = LIMIT (uses limitPrice), 1 = MARKET (slippage-bounded). *** ### limitPrice? > `optional` **limitPrice?**: `bigint` Defined in: packages/sdk/src/trade.ts:1263 Limit price for a LIMIT stop order (raw quote per whole base). *** ### quoteToken > **quoteToken**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1265 Quote token — the input escrow on a buy stop. *** ### baseToken > **baseToken**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1267 Base token — the input escrow on a (non-native) sell stop. *** ### baseIsNative? > `optional` **baseIsNative?**: `boolean` Defined in: packages/sdk/src/trade.ts:1269 True when the base asset is native SOMI (sell stops pre-load the pool vault). *** ### somiPayment? > `optional` **somiPayment?**: `bigint` Defined in: packages/sdk/src/trade.ts:1274 SOMI to fund the reactivity subscription gas. Read from registry.somiPaymentPerOrder() if omitted. *** ### skipOperatorApproval? > `optional` **skipOperatorApproval?**: `boolean` Defined in: packages/sdk/src/trade.ts:1279 Skip the one-time operator-approval check/tx (default false). Set true if you know the registry is already operator-approved for this owner. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:1281 Approve the ERC-20 escrow token to the pool if allowance is short (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1287 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PlaceStopOrderResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PlaceStopOrderResult # Interface: PlaceStopOrderResult Defined in: packages/sdk/src/trade.ts:126 [Trader.placeSpotStopOrder](Trader.md#placespotstoporder)'s result: the tx plus the registry id. ## Extends - [`TxResult`](TxResult.md) ## Properties ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) *** ### stopOrderId? > `optional` **stopOrderId?**: `bigint` Defined in: packages/sdk/src/trade.ts:132 The pending order's id on the registry (from `PendingOrderCreated`) — pass to [Trader.cancelStopOrder](Trader.md#cancelstoporder). Undefined only if the event wasn't found in the receipt (an ABI/deployment drift, not a normal path). --- # /docs/typescript/api/index/interfaces/PnLEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PnLEvent # Interface: PnLEvent Defined in: packages/sdk/src/derivedReads.ts:347 One position-affecting event for the PnL fold, in the account's perspective, RAW units. Buys/sells are per-outcome; a mint/merge touches BOTH outcomes. ## Properties ### kind > **kind**: `"buy"` \| `"sell"` \| `"mint"` \| `"merge"` Defined in: packages/sdk/src/derivedReads.ts:349 Order-book buy/sell of one outcome, or a router mint/merge of a complete set. *** ### outcomeIndex > **outcomeIndex**: `0` \| `1` Defined in: packages/sdk/src/derivedReads.ts:351 0 = YES, 1 = NO. Ignored for mint/merge (they touch both). *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:353 Token quantity (raw). For mint/merge this is the pair (set) amount. *** ### price > **price**: `bigint` Defined in: packages/sdk/src/derivedReads.ts:355 Fill price for the fill's own outcome, raw. Ignored for mint/merge. --- # /docs/typescript/api/index/interfaces/PnlBucket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PnlBucket # Interface: PnlBucket Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:167 One PnL bucket: the PnL attributed to (prevSample, t]. ## Properties ### t > **t**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:169 Bucket end time (ms). *** ### pnlUsd > **pnlUsd**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:171 Signed PnL attributed to the bucket, USD. --- # /docs/typescript/api/index/interfaces/PokeOracleParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PokeOracleParams # Interface: PokeOracleParams Defined in: packages/sdk/src/trade.ts:1832 Permissionless oracle retry: ask the module to re-pull the answer for one oracle question. ## Properties ### oracleQuestionId > **oracleQuestionId**: `bigint` Defined in: packages/sdk/src/trade.ts:1838 The ORACLE QUESTION id to retry — not a market id. The module fans out to every market bound to this question; read it from a market row's `oracleQuestion` or the module's market record. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1840 BinaryMarketsModule address; resolved from `config.addresses.binaryModule` when omitted. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1846 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/PoolBindingRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PoolBindingRecord # Interface: PoolBindingRecord Defined in: packages/sdk/src/pools.ts:81 One interval in a pool's life during which it was bound 1:1 to a single market (indexer `PoolBinding`; id = `${pool}_${nonce}`). `MarketCreated` OPENS a binding; `PoolReleased` or the next `MarketCreated` on the same pool CLOSES it. An open binding (`toBlock` null) is the pool's current market. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/pools.ts:83 `${poolAddress}_${nonce}` *** ### poolAddress > **poolAddress**: `string` Defined in: packages/sdk/src/pools.ts:85 Lowercased pool address. *** ### marketId > **marketId**: `string` Defined in: packages/sdk/src/pools.ts:87 Lowercased bytes32 marketId this binding served. *** ### nonce > **nonce**: `string` Defined in: packages/sdk/src/pools.ts:89 Pool market nonce for this binding (decimal string). *** ### fromBlock > **fromBlock**: `string` Defined in: packages/sdk/src/pools.ts:91 Block the binding opened in (the MarketCreated; decimal string). *** ### fromLogIndex > **fromLogIndex**: `number` Defined in: packages/sdk/src/pools.ts:93 Log index of the opening event within its block. *** ### fromTimestamp > **fromTimestamp**: `string` Defined in: packages/sdk/src/pools.ts:95 Timestamp (unix seconds) the binding opened. *** ### toBlock > **toBlock**: `string` \| `null` Defined in: packages/sdk/src/pools.ts:97 Null while the binding is open (the pool's current market). *** ### toLogIndex > **toLogIndex**: `number` \| `null` Defined in: packages/sdk/src/pools.ts:99 Log index of the closing event; null while the binding is open. *** ### toTimestamp > **toTimestamp**: `string` \| `null` Defined in: packages/sdk/src/pools.ts:101 Timestamp (unix seconds) the binding closed; null while open. *** ### closedBy > **closedBy**: `"Released"` \| `"Rotated"` \| `null` Defined in: packages/sdk/src/pools.ts:106 How the binding closed: `"Released"` (PoolReleased) | `"Rotated"` (the next MarketCreated recycled the pool onward); null while open. --- # /docs/typescript/api/index/interfaces/PortfolioAnalytics [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioAnalytics # Interface: PortfolioAnalytics Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:179 The computed metrics plane — mirrors what a portfolio page renders. ## Properties ### timeframe > **timeframe**: [`PortfolioTimeframe`](../type-aliases/PortfolioTimeframe.md) Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:180 *** ### asOf > **asOf**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:182 Upper bound of the series (ms). *** ### equity > **equity**: [`EquityPoint`](EquityPoint.md)[] Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:184 Cumulative window PnL over time, oldest first; first point is 0. *** ### holdings > **holdings**: [`HoldingsPoint`](HoldingsPoint.md)[] Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:215 Marked value of the traded book over time, oldest first, on the same sample grid as [PortfolioAnalytics.equity](#equity). The first point is the carried-in book valued at the window start, not zero. This series is a LEVEL, where `equity` is a change. It sums `qty × mark` over every open position at each sample, before the cost basis is taken off. It sums SIGNED position value. Every book this fold keeps today is long-only, because `applyTrade` floors each market's quantity at zero, so today the sum cannot go below zero. Do not lock a chart axis to that. The module note above commits this fold to taking the perp plane as new event kinds, a perp book is signed, and a short marks negative. The marks are the caller's, and this fold does not validate them. A negative price carries into this value unchanged, exactly as it already carries into the PnL and MWRR figures. A position the sample cannot price is left OUT of the value rather than guessed at, and [HoldingsPoint.unpricedMarkets](HoldingsPoint.md#unpricedmarkets) counts what was left out. Check it before presenting a sample as the whole book. It measures the TRADED BOOK, not the wallet. A token that arrived without a fill — bridged in, transferred in, minted — is not in the book, so it is not in this value. Idle quote balance is not a position, so it is not included either. [PortfolioFundingEvent](PortfolioFundingEvent.md)s refine the capital base only, so a deposit inside the window does not step this curve. Read balances from the chain when you need what the wallet itself is worth. *** ### pnl > **pnl**: `object` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:216 #### totalUsd > **totalUsd**: `number` Signed total PnL over the timeframe, USD (== last equity point). #### buckets > **buckets**: [`PnlBucket`](PnlBucket.md)[] *** ### mwrr > **mwrr**: `object` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:221 #### return > **return**: `number` \| `null` Period money-weighted return as a fraction: [gainUsd](#mwrr) over [weightedCapitalUsd](#mwrr). Not annualized. Null when the capital base is not meaningfully positive — at or below one US cent, which includes a base driven negative by withdrawals or by an account extracting more than it put in. Null is not zero: the other fields stay readable so a caller can present the window another way. On the funding basis this can exceed 100% in either direction, because capital at risk for only part of the window is weighted down while the gain covers all of it. That is what a money-weighted period rate states, so it is reported rather than withheld. Read [weightedCapitalUsd](#mwrr) to see how much capital the figure measures against before presenting it as a headline. #### gainUsd > **gainUsd**: `number` Signed money gained over the period, USD. #### depositedUsd > **depositedUsd**: `number` Unweighted capital base: carried-in position value + the window's net flows, per [capitalBasis](#mwrr). On the trades basis, buys deploy capital and the MATCHED proceeds of sells return it — proceeds of tokens never bought on the venue are scored nowhere, so an external seller reads 0 rather than a negative base. Signed. #### weightedCapitalUsd > **weightedCapitalUsd**: `number` The denominator the return divides by. On the funding basis this is the Modified Dietz base: carried-in value plus each external movement weighted by the fraction of the window remaining after it. On the trades basis it equals [depositedUsd](#mwrr), because a trade moves capital already inside the account and weighting it would collapse the base for an account that merely rearranged what it held. Signed. #### capitalBasis > **capitalBasis**: `"trades"` \| `"funding"` Which definition produced the capital figures. `"funding"` when the caller supplied [PortfolioFundingEvent](PortfolioFundingEvent.md)s that fall inside the window, else `"trades"` — the proxy, which cannot see capital that never passed through a trade. Funding that predates the window does not select the funding basis: it contributes no in-window flow, and any capital it left invested is already in the carried-in position's value, which both bases count. Branch on this rather than on the package version. *** ### volume > **volume**: `object` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:269 #### periodUsd > **periodUsd**: `number` Trading volume over the timeframe, USD. #### lifetimeUsd > **lifetimeUsd**: `number` Volume across every supplied event, USD. #### sessionUsd? > `optional` **sessionUsd?**: `number` Volume since `sessionSince`, when supplied. *** ### feesSaved > **feesSaved**: `object` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:277 #### cexRateBps > **cexRateBps**: `number` The comparison taker rate (bps) the savings are computed against. #### periodUsd > **periodUsd**: `number` Volume × rate over the timeframe, USD. #### lifetimeUsd > **lifetimeUsd**: `number` Volume × rate across every supplied event, USD. --- # /docs/typescript/api/index/interfaces/PortfolioAnalyticsOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioAnalyticsOptions # Interface: PortfolioAnalyticsOptions Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:353 Options for [computePortfolioAnalytics](../functions/computePortfolioAnalytics.md). ## Properties ### timeframe > **timeframe**: [`PortfolioTimeframe`](../type-aliases/PortfolioTimeframe.md) Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:354 *** ### asOf > **asOf**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:356 Upper bound of the series (ms) — the caller's clock. *** ### marks > **marks**: [`MarkSources`](MarkSources.md) Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:358 Marks for unrealized valuation. *** ### sessionSince? > `optional` **sessionSince?**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:360 Session start (ms) for `volume.sessionUsd`. *** ### cexRateBps? > `optional` **cexRateBps?**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:366 Comparison taker rate, bps. #### Default [DEFAULT\_CEX\_RATE\_BPS](../variables/DEFAULT_CEX_RATE_BPS.md) --- # /docs/typescript/api/index/interfaces/PortfolioFundingEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioFundingEvent # Interface: PortfolioFundingEvent Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:86 External capital entering or leaving the wallet — a bridge delivery, a transfer from another wallet, a withdrawal. Funding events refine the MWRR capital base ONLY. They never touch the equity curve, PnL, or volume: moving money into an account is not profit, and it is not a trade. Venue fills are NOT funding. A trade's settlement transfer is an internal rearrangement the trade event already carries, so a caller sourcing funding from raw token transfers MUST exclude transfers whose counterparty is a venue contract (pool, router, settlement) or the same capital is counted twice. These are caller-supplied because the SDK cannot derive them: the indexer has no wallet token-transfer entity, and the public Somnia RPC caps `eth_getLogs` at 1,000 blocks. Source them from app records, bridge history, or a private RPC scan, valued in USD at the event time. ## Properties ### kind > **kind**: `"funding"` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:88 Event kind. *** ### timestamp > **timestamp**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:90 Event time (ms). *** ### direction > **direction**: `"in"` \| `"out"` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:92 Whether capital entered or left the wallet. *** ### valueUsd > **valueUsd**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:94 Absolute value moved, human USD units (positive). --- # /docs/typescript/api/index/interfaces/PortfolioTradeEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioTradeEvent # Interface: PortfolioTradeEvent Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:50 A trade the account took part in, human USD-quote units. ## Properties ### kind > **kind**: `"trade"` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:52 Event kind. *** ### timestamp > **timestamp**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:54 Event time (ms). *** ### market > **market**: `string` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:56 The market the event belongs to (any stable key; symbol works). *** ### side > **side**: `"buy"` \| `"sell"` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:58 Trade direction from the account's perspective. *** ### baseAmount > **baseAmount**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:60 Base size exchanged, human units (positive). *** ### quoteAmount > **quoteAmount**: `number` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:62 Quote value exchanged, human USD units (positive). --- # /docs/typescript/api/index/interfaces/PreflightResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PreflightResult # Interface: PreflightResult Defined in: packages/sdk/src/preflight.ts:31 The uniform result every validator returns. `ok` is `blockers.length === 0`. ## Properties ### ok > **ok**: `boolean` Defined in: packages/sdk/src/preflight.ts:33 True when there are no blockers (`blockers.length === 0`); warnings don't affect it. *** ### blockers > **blockers**: `string`[] Defined in: packages/sdk/src/preflight.ts:38 Conditions that STOP the step — the on-chain write would revert or produce a dead market. Human-readable, ready to render as-is. *** ### warnings > **warnings**: `string`[] Defined in: packages/sdk/src/preflight.ts:40 Advisory notices — the step can proceed, but the operator should know. --- # /docs/typescript/api/index/interfaces/PriceCandle [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PriceCandle # Interface: PriceCandle Defined in: packages/sdk/src/priceFeed/types.ts:127 One OHLC candle — a `Candle` row, parsed to human units. ## Properties ### asset > **asset**: `string` Defined in: packages/sdk/src/priceFeed/types.ts:129 Asset symbol this candle rolls up (e.g. "BTC"), uppercased. *** ### resolution > **resolution**: [`PriceCandleResolution`](../type-aliases/PriceCandleResolution.md) Defined in: packages/sdk/src/priceFeed/types.ts:131 Rollup bucket width — see [PriceCandleResolution](../type-aliases/PriceCandleResolution.md). *** ### bucketStart > **bucketStart**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:133 Bucket start — unix seconds, chain time. *** ### open > **open**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:135 Spot price at the first tick in the bucket, human units (raw / 1e18). *** ### high > **high**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:137 Highest spot price in the bucket, human units. *** ### low > **low**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:139 Lowest spot price in the bucket, human units. *** ### close > **close**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:141 Spot price at the last tick in the bucket, human units. *** ### emaClose > **emaClose**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:143 EMA mark at bucket close (the feed's `markClose`). *** ### count > **count**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:145 Number of feed ticks in the bucket (update density — NOT trade volume). --- # /docs/typescript/api/index/interfaces/PriceFeedConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PriceFeedConfig # Interface: PriceFeedConfig Defined in: packages/sdk/src/config.ts:182 The realtime price-feed endpoint — the standalone EMA price-feed indexer (Hasura GraphQL). ONE endpoint serves every tracked asset (BTC/USDC, ETH/USDC, …); callers select an asset by filter. Snapshot + history read over HTTP; live prices stream over a Hasura WebSocket subscription. ## Properties ### url > **url**: `string` Defined in: packages/sdk/src/config.ts:184 HTTP GraphQL endpoint (snapshot + history + candles, all assets). *** ### wsUrl? > `optional` **wsUrl?**: `string` Defined in: packages/sdk/src/config.ts:189 WebSocket GraphQL endpoint for live subscriptions. Derived from `url` (http→ws, https→wss) when omitted. *** ### quote? > `optional` **quote?**: `string` Defined in: packages/sdk/src/config.ts:199 Quote asset to pin every read to (e.g. `"USDC"`), case-insensitive. The feed indexes SEVERAL quotes per base (`BTC/USDC`, `BTC/USDT`), so `base` alone is no longer a unique feed key: leaving this unset matches every quote, which double-counts a base that trades against more than one quote — duplicate candle buckets (a hard error in charting libs that require strictly ascending, unique timestamps), an arbitrary `Feed`/tick row per push. Set it to the quote you want (leave unset only if a base has one quote). --- # /docs/typescript/api/index/interfaces/PriceFeedInfo [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PriceFeedInfo # Interface: PriceFeedInfo Defined in: packages/sdk/src/priceFeed/types.ts:153 Feed metadata + current price for one asset — the `Feed` singleton, parsed. ## Properties ### asset > **asset**: `string` Defined in: packages/sdk/src/priceFeed/types.ts:155 Asset key (the pair's base, e.g. `BTC`), uppercased. *** ### decimals > **decimals**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:157 Price scale (Feed.decimals — always 18 today; raw values are 10^decimals-scaled). *** ### symbol > **symbol**: `string` \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:159 The feed's on-chain pair symbol, e.g. `BTC/USDT`. *** ### base > **base**: `string` \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:161 Base asset, e.g. `BTC`. *** ### quote > **quote**: `string` \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:163 Quote asset, e.g. `USDT`. *** ### description > **description**: `string` \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:165 Free-form feed description from the scheduler, or null when unset. *** ### updatedAtMs > **updatedAtMs**: `number` \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:176 When the oracle last WROTE this feed — unix **milliseconds**, or null if unknown. This is the freshness signal to judge a price by: the feed ticks ~1/s, so an age beyond a few seconds means the asset has stalled. A live subscription does NOT keep this moving on a stalled asset — a feed that stops updating simply stops pushing, so the value freezes and its age grows. Compute age against a local clock (`Date.now() - updatedAtMs`) and re-render on a timer; do not wait for a data event that will never arrive. *** ### sourceUpdatedAtMs > **sourceUpdatedAtMs**: `number` \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:184 When the underlying market data was timestamped at the SOURCE — unix milliseconds, or null if unknown. Compare against [updatedAtMs](#updatedatms) to separate "the oracle stopped writing" from "the oracle is writing, but with stale source data": a large `updatedAtMs - sourceUpdatedAtMs` gap means the price was already old when it landed on chain. *** ### resynced > **resynced**: `boolean` \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:189 Whether the last write was a resync (a correction/backfill rather than a routine tick), or null if unknown. *** ### latest > **latest**: [`LivePrice`](LivePrice.md) \| `null` Defined in: packages/sdk/src/priceFeed/types.ts:194 Current price (same value a live watch keeps current), or null if the feed has no observations yet. --- # /docs/typescript/api/index/interfaces/PricePoint [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PricePoint # Interface: PricePoint Defined in: packages/sdk/src/priceFeed/types.ts:89 One raw tick — a `PricePoint` row (one feed tick: the spot median + its EMA mark), parsed. `price` is the spot index; `ema` is the EMA-smoothed mark. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/priceFeed/types.ts:91 Indexer row id (`-`). *** ### asset > **asset**: `string` Defined in: packages/sdk/src/priceFeed/types.ts:93 Asset symbol this tick prices (e.g. "BTC"), uppercased. *** ### price > **price**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:98 Spot index at this tick, human units (raw / 1e18). Lossy past ~15 sig figs — use `raw` for exact math. *** ### ema > **ema**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:100 EMA-smoothed mark at this tick, human units (the feed's `mark`). *** ### requestId > **requestId**: `string` Defined in: packages/sdk/src/priceFeed/types.ts:106 Somnia-Agents batch request that produced this tick (provenance). One request prices every symbol in the tick, so all of a tick's rows share it. Decimal string (uint256). *** ### blockNumber > **blockNumber**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:108 Block the tick landed in (chain time, monotonic). *** ### blockTimestamp > **blockTimestamp**: `number` Defined in: packages/sdk/src/priceFeed/types.ts:110 Block timestamp of the tick — unix seconds, chain time. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/priceFeed/types.ts:112 Transaction that delivered the tick. *** ### raw > **raw**: `object` Defined in: packages/sdk/src/priceFeed/types.ts:114 Exact 1e18-scaled integer strings for precise math. #### price > **price**: `string` Exact spot price — 1e18-scaled integer string. #### ema > **ema**: `string` Exact EMA mark — 1e18-scaled integer string. --- # /docs/typescript/api/index/interfaces/PriceWatchHandle [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PriceWatchHandle # Interface: PriceWatchHandle Defined in: packages/sdk/src/priceFeed/priceFeed.ts:32 A live price watch. `stop()` releases it (idempotent); the underlying subscription is shared and torn down when the last handle stops. ## Methods ### stop() > **stop**(): `void` Defined in: packages/sdk/src/priceFeed/priceFeed.ts:40 Release this handle's reference on the asset's watch (idempotent — extra calls are no-ops). Handles on the same asset share one subscription; stopping the LAST one tears the asset down after a short linger (which absorbs unmount/remount without re-snapshotting): the socket closes, the asset's rows are purged, and live price reads for it return null/empty again. #### Returns `void` --- # /docs/typescript/api/index/interfaces/ProposePerpWalletLinkParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ProposePerpWalletLinkParams # Interface: ProposePerpWalletLinkParams Defined in: packages/sdk/src/trade.ts:980 Inputs to [Trader.proposePerpWalletLink](Trader.md#proposeperpwalletlink) — offer a child wallet a link to the signer as its main. The signer is the prospective MAIN. Half of a two-sided handshake: the child must then send [Trader.acceptPerpWalletLink](Trader.md#acceptperpwalletlink). ## Extends - [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md) ## Properties ### registry? > `optional` **registry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:958 The LinkedWalletRegistry. Skips resolution entirely. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`registry`](PerpWalletLinkTarget.md#registry) *** ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:960 MarginBank address — its `getLinkedWalletRegistry()` is read (never cached). #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`marginBank`](PerpWalletLinkTarget.md#marginbank) *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:962 A PerpPool — its `marginBank()` is read (and cached), then the registry. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`pool`](PerpWalletLinkTarget.md#pool) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:968 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`gas`](PerpWalletLinkTarget.md#gas) *** ### child > **child**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:982 The prospective child. Must not be the signer, and must not already be linked. --- # /docs/typescript/api/index/interfaces/QuestionDefinitionInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / QuestionDefinitionInput # Interface: QuestionDefinitionInput Defined in: packages/sdk/src/oracleHub.ts:112 Full question definition — the input to `scheduleQuestion` / `getSchedulingCost` / `questionKeyOf`. Mirrors the on-chain `QuestionDefinition` struct field-for-field. ## Properties ### questionText > **questionText**: `string` Defined in: packages/sdk/src/oracleHub.ts:117 Free-form question text. EXCLUDED from the dedup key for template (all-JSON-source) definitions — the sources determine the answer. *** ### sources > **sources**: [`QuestionSourceInput`](QuestionSourceInput.md)[] Defined in: packages/sdk/src/oracleHub.ts:119 Answer sources the oracle fetches; all-JSON definitions dedup content-addressed. *** ### validAnswers > **validAnswers**: [`ValidAnswersInput`](ValidAnswersInput.md) Defined in: packages/sdk/src/oracleHub.ts:121 The answer space the question resolves within. *** ### resolutionTime > **resolutionTime**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:123 Unix-seconds the oracle answers at. *** ### minAgreement > **minAgreement**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:125 Minimum count of sources that must agree for the oracle to resolve (else void). *** ### subcommitteeSize > **subcommitteeSize**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:127 Oracle subcommittee nodes assigned to answer the question. *** ### subcommitteeThreshold > **subcommitteeThreshold**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:129 Subcommittee nodes that must concur on the answer. --- # /docs/typescript/api/index/interfaces/QuestionIntervalInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / QuestionIntervalInput # Interface: QuestionIntervalInput Defined in: packages/sdk/src/oracleHub.ts:82 Inclusive numeric interval (`low <= value <= high` matches the bucket). ## Properties ### low > **low**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:84 Lower bound (inclusive), scaled by `numericDecimals`. *** ### high > **high**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:86 Upper bound (inclusive), scaled by `numericDecimals`. --- # /docs/typescript/api/index/interfaces/QuestionSourceInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / QuestionSourceInput # Interface: QuestionSourceInput Defined in: packages/sdk/src/oracleHub.ts:70 One answer source (website URL / JSON URL / on-chain contract) with its encoded params. ## Properties ### sourceType > **sourceType**: `number` Defined in: packages/sdk/src/oracleHub.ts:72 [QUESTION\_SOURCE\_TYPE](../variables/QUESTION_SOURCE_TYPE.md) value (uint8 on the wire). *** ### params > **params**: `` `0x${string}` `` Defined in: packages/sdk/src/oracleHub.ts:74 Source-type-specific encoded params. --- # /docs/typescript/api/index/interfaces/RecallPerpMainFundingParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RecallPerpMainFundingParams # Interface: RecallPerpMainFundingParams Defined in: packages/sdk/src/trade.ts:1064 Inputs to [Trader.recallPerpMainFunding](Trader.md#recallperpmainfunding) — the PAYER pulls principal back out of a child. Signed by the payer. Same clamped accounting as [Trader.repayPerpMainFunding](Trader.md#repayperpmainfunding), and the same destination. ## Extends - [`RepayPerpMainFundingParams`](RepayPerpMainFundingParams.md) ## Properties ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1036 MarginBank address (from the PerpMarket row), or pass `pool` to resolve it. #### Inherited from [`RepayPerpMainFundingParams`](RepayPerpMainFundingParams.md).[`marginBank`](RepayPerpMainFundingParams.md#marginbank) *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1038 A PerpPool — its `marginBank()` is read (and cached) when `marginBank` is omitted. #### Inherited from [`RepayPerpMainFundingParams`](RepayPerpMainFundingParams.md).[`pool`](RepayPerpMainFundingParams.md#pool) *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1046 Principal to return, raw units. Over-asking is SAFE and does not revert: the bank returns `min(amount, outstanding, present balance)`. Pass the outstanding principal from `client.getPerpMainFunding` to repay in full. #### Inherited from [`RepayPerpMainFundingParams`](RepayPerpMainFundingParams.md).[`amount`](RepayPerpMainFundingParams.md#amount) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1052 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from [`RepayPerpMainFundingParams`](RepayPerpMainFundingParams.md).[`gas`](RepayPerpMainFundingParams.md#gas) *** ### child > **child**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1066 The child to recall from. The signer must be its recorded payer. --- # /docs/typescript/api/index/interfaces/ReclaimOracleCreditParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ReclaimOracleCreditParams # Interface: ReclaimOracleCreditParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:215 Params for [MarketCreatorAdmin.reclaimOracleCredit](MarketCreatorAdmin.md#reclaimoraclecredit). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:217 The MarketCreator whose oracle credit is swept (permissionless). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:219 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/RecoverSeriesParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RecoverSeriesParams # Interface: RecoverSeriesParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:160 Params for [MarketCreatorAdmin.recoverSeries](MarketCreatorAdmin.md#recoverseries). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:162 The MarketCreatorV2 owning the series. Permissionless — any caller. *** ### seriesId > **seriesId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:164 The provably stalled series to recover. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:166 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/RedeemAuthorization [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RedeemAuthorization # Interface: RedeemAuthorization Defined in: packages/sdk/src/trade.ts:1633 A signed authorization the position OWNER produces so a relayer can call [Trader.redeemFor](Trader.md#redeemfor) on their behalf. The on-chain payout is hard-pinned to `owner` (never the relayer), so this is a pure gas sponsorship — the signer keeps every cent of the proceeds. Produced by [Trader.signRedeemAuth](Trader.md#signredeemauth), consumed by [Trader.redeemFor](Trader.md#redeemfor). ## Properties ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1635 The position owner (the signer). The payout is paid here on-chain. *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/trade.ts:1637 Routing operator id (uint32) for attribution; part of the signed struct. *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1639 Routing venue id (bytes32 hex); part of the signed struct. *** ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1641 bytes32 marketId the redemption targets. *** ### outcomeIdx > **outcomeIdx**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1643 Outcome the owner holds (0 = YES, 1 = NO). *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1645 Outcome-token amount to burn for collateral. *** ### nonce > **nonce**: `bigint` Defined in: packages/sdk/src/trade.ts:1647 Per-owner replay nonce (module tracks `(owner, nonce)`); any unused value. *** ### deadline > **deadline**: `bigint` Defined in: packages/sdk/src/trade.ts:1649 Signature deadline (unix seconds). The module rejects a stale authorization. *** ### signature > **signature**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1651 The EIP-712 signature over the authorization (65-byte r‖s‖v hex). --- # /docs/typescript/api/index/interfaces/RedeemDirectParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RedeemDirectParams # Interface: RedeemDirectParams Defined in: packages/sdk/src/trade.ts:1722 Low-level direct redemption against the BinarySettlement singleton — bypasses the module (no operator attribution). Burns the caller's outcome tokens and pays `to`. Prefer the module-routed [RedeemParams](RedeemParams.md) for normal trading; use this for keeper/tooling paths that hold the raw outcome id. ## Properties ### outcomeId > **outcomeId**: `bigint` Defined in: packages/sdk/src/trade.ts:1724 The ERC-6909 outcome id to redeem (encodes pool + nonce + index). *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1726 Outcome-token quantity to burn. *** ### to? > `optional` **to?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1728 Recipient of the released collateral (default: the trader's own address). *** ### settlement? > `optional` **settlement?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1733 BinarySettlement address; resolved from `config.addresses.binarySettlement` when omitted. Throws if neither is set. *** ### outcomeToken? > `optional` **outcomeToken?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1738 Outcome-token singleton (for the operator grant). Resolved from the settlement's `outcomeToken()` when omitted. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:1740 Ensure the settlement is an operator on the outcome-token singleton (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1746 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/RedeemForParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RedeemForParams # Interface: RedeemForParams Defined in: packages/sdk/src/trade.ts:1697 Relayer path: submit a position owner's pre-signed [RedeemAuthorization](RedeemAuthorization.md) so THEY pay the gas while the OWNER receives the payout. The caller (relayer) need not be the owner; the module recovers the signature to `owner` and pays `owner` directly. ## Properties ### authorization > **authorization**: [`RedeemAuthorization`](RedeemAuthorization.md) Defined in: packages/sdk/src/trade.ts:1699 The owner's signed authorization (from [Trader.signRedeemAuth](Trader.md#signredeemauth)). *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1705 BinaryMarketsModule address; resolved from `config.addresses.binaryModule` when omitted. Must match the `verifyingContract` the authorization was signed against. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1711 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/RedeemManyParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RedeemManyParams # Interface: RedeemManyParams Defined in: packages/sdk/src/trade.ts:1593 Claim winnings from several settled markets in ONE transaction — the batch form of [RedeemParams](RedeemParams.md). Each entry is redeemed independently for the signer (settlement pays each straight to their wallet); all-or-nothing. ## Properties ### entries > **entries**: `object`[] Defined in: packages/sdk/src/trade.ts:1595 Per-market redemptions. `outcomeIdx` is required per entry (0 = YES, 1 = NO). #### marketId > **marketId**: `` `0x${string}` `` bytes32 marketId of the market to redeem on. #### outcomeIdx > **outcomeIdx**: `0` \| `1` Which outcome's tokens to redeem (0 = YES, 1 = NO). #### amount > **amount**: `bigint` Outcome tokens to redeem, raw units (collateral decimals). *** ### operatorId? > `optional` **operatorId?**: `number` Defined in: packages/sdk/src/trade.ts:1604 Routing operator id (uint32) for attribution; 0 = none (default). *** ### venueId? > `optional` **venueId?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1606 Routing venue id (bytes32 hex); 32-byte zero = none (default). *** ### outcomeToken? > `optional` **outcomeToken?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1611 Outcome-token singleton to grant the module operator on (one grant covers all ids). Resolved from the settlement singleton when omitted. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1613 BinaryMarketsModule address; resolved from `config.addresses.binaryModule`. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:1615 Ensure the module is an operator on the outcome-token singleton (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1621 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/RedeemNativeParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RedeemNativeParams # Interface: RedeemNativeParams Defined in: packages/sdk/src/trade.ts:2016 Inputs to [Trader.redeemNative](Trader.md#redeemnative) — redeem winning outcome tokens for a NATIVE payout via the CollateralRouter (unwraps wNative → native). ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2018 bytes32 market key redeemed against; its collateral must be wNative. *** ### outcomeIdx > **outcomeIdx**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:2024 Outcome the caller holds (0 = YES, 1 = NO). The router is type-blind — it forwards this to the core, which the pool prices (winner 1:1, void 1/N per side). *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:2026 Amount of that outcome's tokens to redeem for a native payout. *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/trade.ts:2028 Routing operator id (uint32) for attribution; 0 = none. *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2030 Routing venue id (bytes32 hex); 32-byte zero = none. *** ### router? > `optional` **router?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2035 CollateralRouter address; resolved from `config.addresses.collateralRouter` if omitted. Throws if neither is set. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:2041 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/RedeemOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RedeemOptions # Interface: RedeemOptions Defined in: packages/sdk/src/unified/exchange.ts:206 Optional leg selection for [SomniaMarkets.redeem](../classes/SomniaMarkets.md#redeem). ## Properties ### outcomeIdx? > `optional` **outcomeIdx?**: `0` \| `1` Defined in: packages/sdk/src/unified/exchange.ts:212 Leg to redeem (0 = YES, 1 = NO). Omit it on a resolved market to let the SDK verify the terminal state and read the winner on-chain. A voided market requires the leg because both can redeem. --- # /docs/typescript/api/index/interfaces/RedeemParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RedeemParams # Interface: RedeemParams Defined in: packages/sdk/src/trade.ts:1533 Inputs to [Trader.redeem](Trader.md#redeem) — burn winning outcome tokens for collateral on a resolved/voided market (module-routed redemption). ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1539 bytes32 marketId the module keys the redemption on (settlement-extraction v2: redemption is module-routed — the module pulls the caller's winning tokens, finalizes-if-needed, and redeems through the BinarySettlement singleton). *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1541 Outcome-token amount to burn for collateral. *** ### outcomeIdx? > `optional` **outcomeIdx?**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1555 Outcome leg to redeem (0 = YES, 1 = NO). When omitted, the SDK first confirms `market.isResolved()`, then derives the leg from the finalized one-hot payout vector. This needs `market`; otherwise pass `outcomeIdx` explicitly. Settlement v3 stores a payout vector — `winningOutcome()` was removed and reverts on the deployed contract. The lookup is RESOLUTION-ONLY. An unresolved market throws instead of guessing from an unfinished vector. A voided market has no winner — both legs are redeemable — so redeem throws [InvalidInputError](../classes/InvalidInputError.md) rather than picking one. Pass the leg you hold, or use [RedeemManyParams](RedeemManyParams.md) with one entry per leg to claim both in one transaction. *** ### market? > `optional` **market?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1561 BinaryMarket address — only needed to auto-look-up `outcomeIdx` / `outcomeToken` when those are omitted. The `outcomeIdx` lookup reads the terminal flags first, then the finalized payout vector and denominator. *** ### operatorId? > `optional` **operatorId?**: `number` Defined in: packages/sdk/src/trade.ts:1563 Routing operator id (uint32) for attribution; 0 = none (default). *** ### venueId? > `optional` **venueId?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1565 Routing venue id (bytes32 hex); 32-byte zero = none (default). *** ### outcomeToken? > `optional` **outcomeToken?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1570 Outcome-token singleton the winning position lives on (for the operator grant). Looked up via `market.outcomeToken()` when omitted. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1575 BinaryMarketsModule address; resolved from `config.addresses.binaryModule` when omitted. Throws if neither is set. *** ### autoApprove? > `optional` **autoApprove?**: `boolean` Defined in: packages/sdk/src/trade.ts:1577 Ensure the module is an operator on the outcome-token singleton (default true). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1583 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ReduceOrderParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ReduceOrderParams # Interface: ReduceOrderParams Defined in: packages/sdk/src/trade.ts:295 Shrink a resting order's remaining quantity IN PLACE — keeps its price-time queue priority (unlike [Trader.placeOrder](Trader.md#placeorder) + amend, which re-queues at the back). Works on spot AND binary pools: BinaryPool implements the reduce-refund hook, so the freed escrow (collateral for a buy, outcome tokens for a sell) is returned to the owner. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:297 BinaryPool (or SpotPool) address hosting the resting order. *** ### orderId > **orderId**: `string` \| `bigint` Defined in: packages/sdk/src/trade.ts:299 uint128 OrderId of the resting order to shrink (decimal string or bigint). *** ### newQuantityRemaining > **newQuantityRemaining**: `bigint` Defined in: packages/sdk/src/trade.ts:306 The order's NEW remaining quantity. Must be a `lotSize` multiple, `>= minQuantity`, and strictly less than the current remaining. Reverts on-chain (`ExpiredOrderMustBeCancelled`) if the order has already expired — use [Trader.cancelOrder](Trader.md#cancelorder) to recover an expired order's funds. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:312 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ReduceOrderRequest [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ReduceOrderRequest # Interface: ReduceOrderRequest Defined in: packages/sdk/src/trade.ts:660 One reduction inside a [Trader.reduceOrders](Trader.md#reduceorders) batch. ## Properties ### orderId > **orderId**: `string` \| `bigint` Defined in: packages/sdk/src/trade.ts:662 uint128 OrderId of the resting order to shrink (decimal string or bigint). *** ### newQuantityRemaining > **newQuantityRemaining**: `bigint` Defined in: packages/sdk/src/trade.ts:667 The order's NEW remaining quantity. Must be a `lotSize` multiple, `>= minQuantity`, and strictly less than the current remaining. --- # /docs/typescript/api/index/interfaces/ReduceOrdersParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ReduceOrdersParams # Interface: ReduceOrdersParams Defined in: packages/sdk/src/trade.ts:676 Inputs to [Trader.reduceOrders](Trader.md#reduceorders) — shrink several resting orders on ONE pool in a single transaction. Works on spot AND binary pools. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:678 SpotPool (or BinaryPool) address hosting the resting orders. *** ### reductions > **reductions**: [`ReduceOrderRequest`](ReduceOrderRequest.md)[] Defined in: packages/sdk/src/trade.ts:680 The reductions to apply. Any invalid entry reverts the whole batch. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:686 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/RegisterOperatorParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RegisterOperatorParams # Interface: RegisterOperatorParams Defined in: packages/sdk/src/operatorAdmin.ts:89 Params for [OperatorAdmin.registerOperator](OperatorAdmin.md#registeroperator). ## Properties ### feeRecipient > **feeRecipient**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:91 Default recipient of the operator's venue fees (a venue can override it). *** ### enabled > **enabled**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:96 Whether the operator starts live; flip later via [OperatorAdmin.setOperatorEnabled](OperatorAdmin.md#setoperatorenabled). *** ### policy > **policy**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:98 IVenuePolicy address; zero for none (operator-wide gate is optional). *** ### context? > `optional` **context?**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:100 Opaque metadata bytes attached to the operator; empty (`0x`) by default. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:102 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/RegisterOperatorResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RegisterOperatorResult # Interface: RegisterOperatorResult Defined in: packages/sdk/src/operatorAdmin.ts:110 Result of [OperatorAdmin.registerOperator](OperatorAdmin.md#registeroperator) — carries the id the contract assigned, which every later operator call keys on. ## Extends - [`TxResult`](TxResult.md) ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:112 The auto-assigned operator id (decoded from `OperatorRegistered`). *** ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) --- # /docs/typescript/api/index/interfaces/RegisterSeriesParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RegisterSeriesParams # Interface: RegisterSeriesParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:115 Params for [MarketCreatorAdmin.registerSeries](MarketCreatorAdmin.md#registerseries) / [MarketCreatorAdmin.updateSeries](MarketCreatorAdmin.md#updateseries). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:117 The MarketCreator to register the series under. Caller must be its owner. *** ### seriesId > **seriesId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:122 Series key within the creator; re-registering the same id overwrites the config and resets the series' oracle reference. *** ### collateral > **collateral**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:124 Per-series collateral ERC-20. *** ### asset > **asset**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:130 Display ticker (e.g. "BTC" — NOT a pair). Doubles as the exchange base symbol for the USDC-quoted candle sources built per roll, so it must match the spot listing on the source exchanges (Binance/OKX/…). *** ### numericDecimals > **numericDecimals**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:132 Decimal precision of the oracle's numeric price answer. *** ### intervalSec > **intervalSec**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:134 Roll interval in seconds; the module rejects < 60 (`InvalidSeriesConfig`). *** ### settlementWindow > **settlementWindow**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:136 Post-expiry settlement window in seconds. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:138 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/RegistrySweep [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RegistrySweep # Interface: RegistrySweep Defined in: packages/sdk/src/markets.ts:886 A registry sweep with the silent drop made visible — see [SomniaMarketsClient.listRegistryMarketsChecked](SomniaMarketsClient.md#listregistrymarketschecked). ## Properties ### markets > **markets**: [`Market`](../type-aliases/Market.md)[] Defined in: packages/sdk/src/markets.ts:888 The markets that parsed, exactly what `listRegistryMarkets` returns. *** ### dropped > **dropped**: `number` Defined in: packages/sdk/src/markets.ts:894 Rows the indexer served that the SDK could not parse, and so are absent from `markets`. Zero means the sweep is complete: every row the registry holds is in hand. --- # /docs/typescript/api/index/interfaces/ReleasePoolParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ReleasePoolParams # Interface: ReleasePoolParams Defined in: packages/sdk/src/trade.ts:1813 Permissionless keeper entry: release a finalized, drained pool back to its creator's free list for recycle onto the next market. ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1815 bytes32 marketId whose (finalized, book-empty) pool to release. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1817 BinaryMarketsModule address; resolved from `config.addresses.binaryModule` when omitted. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1823 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/RepayPerpMainFundingParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RepayPerpMainFundingParams # Interface: RepayPerpMainFundingParams Defined in: packages/sdk/src/trade.ts:1034 Inputs to [Trader.repayPerpMainFunding](Trader.md#repayperpmainfunding) — the CHILD returns principal its main funded. Signed by the child. The money goes to the payer the bank snapshotted at funding time, not to whoever is linked now. ## Extended by - [`RecallPerpMainFundingParams`](RecallPerpMainFundingParams.md) ## Properties ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1036 MarginBank address (from the PerpMarket row), or pass `pool` to resolve it. *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1038 A PerpPool — its `marginBank()` is read (and cached) when `marginBank` is omitted. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1046 Principal to return, raw units. Over-asking is SAFE and does not revert: the bank returns `min(amount, outstanding, present balance)`. Pass the outstanding principal from `client.getPerpMainFunding` to repay in full. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1052 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ResolveParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ResolveParams # Interface: ResolveParams Defined in: packages/sdk/src/trade.ts:2068 Inputs to [Trader.resolve](Trader.md#resolve) — resolve a market via the FakeOracle (demo/dev resolver only). ## Properties ### market > **market**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2070 BinaryMarket address to resolve. *** ### outcomeIdx > **outcomeIdx**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:2072 The outcome to resolve to (0 = YES wins, 1 = NO wins). *** ### fakeOracle? > `optional` **fakeOracle?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2074 FakeOracle address; defaults to the configured one. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:2080 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/RevertContext [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RevertContext # Interface: RevertContext Defined in: packages/sdk/src/revert.ts:26 Where the failing call was aimed — carried onto the error for diagnosis. ## Properties ### address? > `optional` **address?**: `string` Defined in: packages/sdk/src/revert.ts:28 The contract that was called, when known. *** ### functionName? > `optional` **functionName?**: `string` Defined in: packages/sdk/src/revert.ts:30 The function that was called, when known. --- # /docs/typescript/api/index/interfaces/RollPreflightInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RollPreflightInput # Interface: RollPreflightInput Defined in: packages/sdk/src/preflight.ts:352 Inputs for the roll-step preflight: the series exists on-chain (its `intervalSec > 0`), the creator is funded, and the chain supports rolls. ## Properties ### seriesIntervalSec > **seriesIntervalSec**: `number` Defined in: packages/sdk/src/preflight.ts:354 The series' on-chain `intervalSec` (0 ⇒ never registered). *** ### creatorBalanceWei > **creatorBalanceWei**: `bigint` Defined in: packages/sdk/src/preflight.ts:359 The MarketCreator's native balance (wei) — 0 blocks (the roll can't pay its reactivity gas). *** ### precompileAvailable > **precompileAvailable**: `boolean` Defined in: packages/sdk/src/preflight.ts:364 Whether the connected chain has the Somnia reactivity precompile (false on local anvil — see [isLocalPrecompileUnavailable](../functions/isLocalPrecompileUnavailable.md)). --- # /docs/typescript/api/index/interfaces/RouterMintBase [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RouterMintBase # Interface: RouterMintBase Defined in: packages/sdk/src/trade.ts:1938 Shared inputs for the CollateralRouter complete-set entry points. ## Extended by - [`MintSetNativeParams`](MintSetNativeParams.md) - [`MintSetPermit2Params`](MintSetPermit2Params.md) ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1940 bytes32 market key the set is minted for (the market's `marketId`). *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/trade.ts:1942 Routing operator id (uint32) for attribution; 0 = none. *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1944 Routing venue id (bytes32 hex); 32-byte zero = none. *** ### router? > `optional` **router?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1949 CollateralRouter address; resolved from `config.addresses.collateralRouter` if omitted. Throws if neither is set (never sends to the zero address). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1955 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/ScheduleQuestionParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ScheduleQuestionParams # Interface: ScheduleQuestionParams Defined in: packages/sdk/src/oracleHub.ts:356 Parameters for [OracleHubAdmin.scheduleQuestion](OracleHubAdmin.md#schedulequestion). ## Properties ### def > **def**: [`QuestionDefinitionInput`](QuestionDefinitionInput.md) Defined in: packages/sdk/src/oracleHub.ts:358 The question to schedule (deduped content-addressed for template definitions). *** ### valueWei? > `optional` **valueWei?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:363 Native value to attach. Defaults to the live `getSchedulingCost(def)` quote (the marginal price — 0 for a dedup reuse). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:365 Gas-limit override for this tx (defaults to the admin config's `gas`). --- # /docs/typescript/api/index/interfaces/ScheduleQuestionResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ScheduleQuestionResult # Interface: ScheduleQuestionResult Defined in: packages/sdk/src/oracleHub.ts:382 Result of [OracleHubAdmin.scheduleQuestion](OracleHubAdmin.md#schedulequestion). **Details** Scheduling is idempotent by question DEFINITION: an identical definition deduplicates onto the existing question instead of creating a second one. **Gotchas** Because of that deduplication, check `reused` before assuming this call is what created the id. ## Extends - [`TxResult`](TxResult.md) ## Properties ### oracleQuestionId > **oracleQuestionId**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:384 Oracle-assigned (or deduplicated) question id. *** ### reused > **reused**: `boolean` Defined in: packages/sdk/src/oracleHub.ts:389 True when the definition deduplicated onto an EXISTING question (`QuestionReused` — the caller was charged nothing). *** ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. #### Inherited from [`TxResult`](TxResult.md).[`hash`](TxResult.md#hash) *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). #### Inherited from [`TxResult`](TxResult.md).[`receipt`](TxResult.md#receipt) --- # /docs/typescript/api/index/interfaces/SeriesOnchain [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SeriesOnchain # Interface: SeriesOnchain Defined in: packages/sdk/src/marketCreatorAdmin.ts:294 One Series' live on-chain config (mirror of the `Series` struct). ## Properties ### collateral > **collateral**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:296 Per-series collateral ERC-20. *** ### asset > **asset**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:302 Display ticker (e.g. "BTC" — NOT a pair). Doubles as the exchange base symbol for the USDC-quoted candle sources built per roll, so it must match the spot listing on the source exchanges (Binance/OKX/…). *** ### numericDecimals > **numericDecimals**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:304 Decimal precision of the oracle's numeric price answer. *** ### intervalSec > **intervalSec**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:306 Roll interval in seconds; `0` means the series was never registered. *** ### settlementWindow > **settlementWindow**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:308 Post-expiry settlement window in seconds. --- # /docs/typescript/api/index/interfaces/SeriesPreflightInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SeriesPreflightInput # Interface: SeriesPreflightInput Defined in: packages/sdk/src/preflight.ts:309 The series fields the series-step preflight inspects. ## Properties ### seriesId > **seriesId**: `number` Defined in: packages/sdk/src/preflight.ts:311 The series id to register — 0 blocks (the module rejects it as UnknownSeries). *** ### asset > **asset**: `string` Defined in: packages/sdk/src/preflight.ts:313 The series' asset label (e.g. "BTC/USDT") — empty blocks. *** ### intervalSec > **intervalSec**: `number` Defined in: packages/sdk/src/preflight.ts:318 The roll interval in seconds — below [MIN\_SERIES\_INTERVAL\_SEC](../variables/MIN_SERIES_INTERVAL_SEC.md) blocks (InvalidSeriesConfig). *** ### collateral > **collateral**: `` `0x${string}` `` Defined in: packages/sdk/src/preflight.ts:320 The venue's collateral token — the zero address blocks. --- # /docs/typescript/api/index/interfaces/SetAdapterApprovedParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetAdapterApprovedParams # Interface: SetAdapterApprovedParams Defined in: packages/sdk/src/governanceAdmin.ts:24 Params for [GovernanceAdmin.setAdapterApproved](GovernanceAdmin.md#setadapterapproved). ## Properties ### adapter > **adapter**: `` `0x${string}` `` Defined in: packages/sdk/src/governanceAdmin.ts:26 The oracle adapter to approve or revoke on BinaryMarketsModule. *** ### approved > **approved**: `boolean` Defined in: packages/sdk/src/governanceAdmin.ts:28 `true` approves (adapter can back new markets); `false` revokes. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/governanceAdmin.ts:30 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/SetHubDrainParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetHubDrainParams # Interface: SetHubDrainParams Defined in: packages/sdk/src/oracleHub.ts:469 Parameters for [OracleHubAdmin.setDrainParams](OracleHubAdmin.md#setdrainparams) (OWNER-only). ## Properties ### perMarketResolveGas > **perMarketResolveGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:474 Gas budgeted per market resolve — sizes `resolveReserve()` (`perMarketResolveGas × maxFeePerGas`). *** ### callbackBaseGas > **callbackBaseGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:479 Callback overhead gas explicitly attributed across the markets resolved in it (the metering overhead term). *** ### maxResolvesPerCallback > **maxResolvesPerCallback**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:481 Belt-and-suspenders cap on markets resolved per callback. *** ### resolveGasReserve > **resolveGasReserve**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:483 Remaining-gas floor at which the drain loop breaks to the next block. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:485 Gas-limit override for this tx (defaults to the admin config's `gas`). --- # /docs/typescript/api/index/interfaces/SetHubGasParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetHubGasParams # Interface: SetHubGasParams Defined in: packages/sdk/src/oracleHub.ts:450 Parameters for [OracleHubAdmin.setGasParams](OracleHubAdmin.md#setgasparams) (OWNER-only). ## Properties ### priorityFeePerGas > **priorityFeePerGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:452 New reactivity-callback tip (wei per gas). *** ### maxFeePerGas > **maxFeePerGas**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:457 New reactivity-callback fee ceiling (wei per gas) — also reprices `resolveReserve()` immediately. *** ### gasLimit > **gasLimit**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:459 New gas limit each reactivity callback runs with. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:461 Gas-limit override for this tx (defaults to the admin config's `gas`). --- # /docs/typescript/api/index/interfaces/SetManualVaultModeParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetManualVaultModeParams # Interface: SetManualVaultModeParams Defined in: packages/sdk/src/trade.ts:1154 Inputs to [Trader.setManualVaultMode](Trader.md#setmanualvaultmode) — flip a SpotPool's auto-pull opt-out for the signer. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1156 SpotPool the mode applies to. Scoped per user PER POOL. *** ### enabled > **enabled**: `boolean` Defined in: packages/sdk/src/trade.ts:1158 True to draw only on vault balance; false to restore wallet auto-pull. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1164 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/SetOperatorApprovalForPoolParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetOperatorApprovalForPoolParams # Interface: SetOperatorApprovalForPoolParams Defined in: packages/sdk/src/trade.ts:1206 Inputs to [Trader.setOperatorApprovalForPool](Trader.md#setoperatorapprovalforpool) — admit an operator on ONE SpotPool (the tighter default). ## Extends - `OperatorApprovalParamsBase` ## Properties ### operator > **operator**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1170 Account being admitted to act for the signer (a bot, a router, a helper contract). #### Inherited from `OperatorApprovalParamsBase.operator` *** ### selectors > **selectors**: readonly `` `0x${string}` ``[] Defined in: packages/sdk/src/trade.ts:1176 4-byte selectors the operator may call. Grant only what it needs — [PLACE\_ORDER\_FOR\_SELECTOR](../variables/PLACE_ORDER_FOR_SELECTOR.md) to place, [CANCEL\_ORDER\_FOR\_SELECTOR](../variables/CANCEL_ORDER_FOR_SELECTOR.md) to cancel. Must not be empty. #### Inherited from `OperatorApprovalParamsBase.selectors` *** ### approved > **approved**: `boolean` Defined in: packages/sdk/src/trade.ts:1178 True to grant, false to revoke. #### Inherited from `OperatorApprovalParamsBase.approved` *** ### operatorRegistry? > `optional` **operatorRegistry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1183 OperatorPermissionsRegistry address. #### Default `addresses.operatorPermissionsRegistry` #### Inherited from `OperatorApprovalParamsBase.operatorRegistry` *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1189 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from `OperatorApprovalParamsBase.gas` *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1208 SpotPool the grant applies on. --- # /docs/typescript/api/index/interfaces/SetOperatorApprovalGlobalParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetOperatorApprovalGlobalParams # Interface: SetOperatorApprovalGlobalParams Defined in: packages/sdk/src/trade.ts:1198 Inputs to [Trader.setOperatorApprovalGlobal](Trader.md#setoperatorapprovalglobal) — admit an operator across every registered pool (what `SpotRouter` requires). ## Extends - `OperatorApprovalParamsBase` ## Properties ### operator > **operator**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1170 Account being admitted to act for the signer (a bot, a router, a helper contract). #### Inherited from `OperatorApprovalParamsBase.operator` *** ### selectors > **selectors**: readonly `` `0x${string}` ``[] Defined in: packages/sdk/src/trade.ts:1176 4-byte selectors the operator may call. Grant only what it needs — [PLACE\_ORDER\_FOR\_SELECTOR](../variables/PLACE_ORDER_FOR_SELECTOR.md) to place, [CANCEL\_ORDER\_FOR\_SELECTOR](../variables/CANCEL_ORDER_FOR_SELECTOR.md) to cancel. Must not be empty. #### Inherited from `OperatorApprovalParamsBase.selectors` *** ### approved > **approved**: `boolean` Defined in: packages/sdk/src/trade.ts:1178 True to grant, false to revoke. #### Inherited from `OperatorApprovalParamsBase.approved` *** ### operatorRegistry? > `optional` **operatorRegistry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1183 OperatorPermissionsRegistry address. #### Default `addresses.operatorPermissionsRegistry` #### Inherited from `OperatorApprovalParamsBase.operatorRegistry` *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1189 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from `OperatorApprovalParamsBase.gas` --- # /docs/typescript/api/index/interfaces/SetOperatorEnabledParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetOperatorEnabledParams # Interface: SetOperatorEnabledParams Defined in: packages/sdk/src/operatorAdmin.ts:141 Params for [OperatorAdmin.setOperatorEnabled](OperatorAdmin.md#setoperatorenabled). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:143 The operator to flip. Caller must be its owner. *** ### enabled > **enabled**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:145 New enabled flag (the operator-wide kill switch). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:147 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/SetPerpLeverageParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetPerpLeverageParams # Interface: SetPerpLeverageParams Defined in: packages/sdk/src/trade.ts:1217 Inputs to [Trader.setPerpLeverage](Trader.md#setperpleverage) — cap the signer's max leverage on one perp pool (the MarginBank sizes positions against margin with it). ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1219 PerpPool the leverage cap applies to. *** ### leverageX > **leverageX**: `number` Defined in: packages/sdk/src/trade.ts:1221 Max leverage multiplier (e.g. 10 = 10x), bounded by the protocol limit. *** ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1223 MarginBank address; read (and cached) from `pool.marginBank()` when omitted. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1229 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/SetReactivityGasParamsParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetReactivityGasParamsParams # Interface: SetReactivityGasParamsParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:174 Params for [MarketCreatorAdmin.setReactivityGasParams](MarketCreatorAdmin.md#setreactivitygasparams). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:176 The MarketCreator to update. Caller must be its owner. *** ### priorityFeePerGas > **priorityFeePerGas**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:178 Priority fee per gas (wei) the reactivity callback bids. *** ### maxFeePerGas > **maxFeePerGas**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:180 Max fee per gas (wei) the reactivity callback bids. *** ### gasLimit > **gasLimit**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:182 Gas limit reserved per reactivity subscription (gas units). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:184 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/SetVenueEnabledParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SetVenueEnabledParams # Interface: SetVenueEnabledParams Defined in: packages/sdk/src/operatorAdmin.ts:229 Params for [OperatorAdmin.setVenueEnabled](OperatorAdmin.md#setvenueenabled). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:231 The operator owning the venue. Caller must be its owner. *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:233 The venue to flip (within the operator). *** ### creationEnabled > **creationEnabled**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:235 New creation flag; trading on existing markets is unaffected. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:237 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/SettlementRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SettlementRecord # Interface: SettlementRecord Defined in: packages/sdk/src/trade.ts:1880 A market's settlement record on the BinarySettlement singleton (the permanent redemption home). Mirrors the on-chain `MarketSettlement` struct. ## Properties ### collateralToken > **collateralToken**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1882 The ERC-20 collateral the net backing is held in. *** ### backing > **backing**: `bigint` Defined in: packages/sdk/src/trade.ts:1887 The NET collateral held for this market (post fee-skim on resolution), decremented by each redemption's payout. *** ### finalized > **finalized**: `boolean` Defined in: packages/sdk/src/trade.ts:1889 True once the pool's backing + snapshot have been swept in. Gates redemption. *** ### voided > **voided**: `boolean` Defined in: packages/sdk/src/trade.ts:1891 True if the market voided (each side redeems against the stored payout vector — a half per side under `UNIFORM`, `[p, D−p]` on a captured `CLOB_SNAPSHOT` void; never a settlement fee). *** ### winningOutcome > **winningOutcome**: `number` Defined in: packages/sdk/src/trade.ts:1896 The winning outcome index (0 = YES, 1 = NO); derived as argmax of `payoutNumerators`. Meaningful only when `!voided`. *** ### payoutNumerators > **payoutNumerators**: `bigint`[] Defined in: packages/sdk/src/trade.ts:1901 Settlement v3 fee-scaled payout VECTOR (denominator 10_000_000). Redemption of outcome `i` pays `amount × payoutNumerators[i] / 10_000_000`. *** ### settlementFeeBpsTimes1k > **settlementFeeBpsTimes1k**: `bigint` Defined in: packages/sdk/src/trade.ts:1903 The one-time settlement-fee rate skimmed at finalize (bps×1000; retained for audit). *** ### feeRecipient > **feeRecipient**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1905 The address the settlement fee was skimmed to at finalize. *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1907 The pool that finalized this market (the address encoded in the outcome ids). *** ### nonce > **nonce**: `bigint` Defined in: packages/sdk/src/trade.ts:1909 The pool's market nonce for this record. --- # /docs/typescript/api/index/interfaces/SignRedeemAuthParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SignRedeemAuthParams # Interface: SignRedeemAuthParams Defined in: packages/sdk/src/trade.ts:1662 Inputs to [Trader.signRedeemAuth](Trader.md#signredeemauth) — everything in the signed struct EXCEPT the signature (which the call produces). Signed by the connected signer (the position owner); the resulting [RedeemAuthorization](RedeemAuthorization.md) is handed to a relayer to submit via [Trader.redeemFor](Trader.md#redeemfor). ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1664 bytes32 marketId the redemption targets. *** ### outcomeIdx > **outcomeIdx**: `0` \| `1` Defined in: packages/sdk/src/trade.ts:1666 Outcome the owner holds (0 = YES, 1 = NO). *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1668 Outcome-token amount to burn for collateral. *** ### nonce > **nonce**: `bigint` Defined in: packages/sdk/src/trade.ts:1670 Per-owner replay nonce; any value not yet consumed for this owner. *** ### deadline > **deadline**: `bigint` Defined in: packages/sdk/src/trade.ts:1672 Signature deadline (unix seconds). *** ### operatorId? > `optional` **operatorId?**: `number` Defined in: packages/sdk/src/trade.ts:1674 Routing operator id (uint32) for attribution; 0 = none (default). *** ### venueId? > `optional` **venueId?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1676 Routing venue id (bytes32 hex); 32-byte zero = none (default). *** ### owner? > `optional` **owner?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1681 Owner the payout is pinned to; defaults to the connected signer's address. Must be the address whose signer produces the signature. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1686 BinaryMarketsModule address — the EIP-712 `verifyingContract`; resolved from `config.addresses.binaryModule` when omitted. --- # /docs/typescript/api/index/interfaces/SomniaLendClient [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaLendClient # Interface: SomniaLendClient Defined in: packages/sdk/src/lend/client.ts:22 The SomniaLend client — reads over the deployed Aave-v3-fork contracts plus the [Lender](Lender.md) write factory, bound to one markets client's chain transport. Reached as `client.lend`. ## Methods ### listReserves() > **listReserves**(): `Promise`\<[`LendReserve`](LendReserve.md)[]\> Defined in: packages/sdk/src/lend/client.ts:41 Every SomniaLend reserve — config, caps, live rates/indexes, liquidity, and the oracle price, in one aggregated eth_call. Chain read (current to head). **Details** Rates come back as ray bigints; convert for display with [lendRayRateToApy](../functions/lendRayRateToApy.md). See [LendReserve](LendReserve.md) for the unit conventions. **Example** (Displaying reserve APY) ```ts const reserves = await client.lend.listReserves(); for (const r of reserves) { console.log(r.symbol, `supply APY ${(lendRayRateToApy(r.liquidityRateRay) * 100).toFixed(2)}%`); } ``` #### Returns `Promise`\<[`LendReserve`](LendReserve.md)[]\> *** ### getAccount() > **getAccount**(`account`): `Promise`\<[`LendAccount`](LendAccount.md)\> Defined in: packages/sdk/src/lend/client.ts:46 A whole SomniaLend account: health factor, borrowing power, and every non-empty supplied/borrowed position. Chain read (current to head). #### Parameters ##### account `` `0x${string}` `` #### Returns `Promise`\<[`LendAccount`](LendAccount.md)\> *** ### createLender() > **createLender**(`config`): [`Lender`](Lender.md) Defined in: packages/sdk/src/lend/client.ts:52 Build a [Lender](Lender.md) bound to a signer — the write surface (supply / withdraw / borrow / repay, ERC-20 and native, auto-approving). Same signer doctrine as every SDK write factory (privateKey / local account / walletClient). #### Parameters ##### config [`OracleHubAdminConfig`](OracleHubAdminConfig.md) #### Returns [`Lender`](Lender.md) --- # /docs/typescript/api/index/interfaces/SomniaMarketsAddresses [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsAddresses # Interface: SomniaMarketsAddresses Defined in: packages/sdk/src/config.ts:16 Protocol contract addresses (all optional — features degrade if unset). ## Properties ### fakeOracle? > `optional` **fakeOracle?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:18 FakeOracle resolver (demo resolve/void). *** ### collateral? > `optional` **collateral?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:24 Per-venue collateral ERC-20 (the venue's quote/collateral token; on test environments this is the faucet-capable TestUSDC). Preferred over `testUsdc`, which remains as the legacy/fallback alias. *** ### testUsdc? > `optional` **testUsdc?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:29 TestUSDC collateral (faucet + balances). Legacy/fallback alias for [SomniaMarketsAddresses.collateral](#collateral). *** ### binaryModule? > `optional` **binaryModule?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:35 BinaryMarketsModule — the binary product's core module (complete-set mint/redeem, market creation, adapter approval). Needed by the trader writes, the hub-approval reads, and /system diagnostics. *** ### marketCreator? > `optional` **marketCreator?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:40 MarketCreator factory. When set, the live tail watches MarketCreated and picks up new binary markets the block they deploy — no indexer round-trip. *** ### clobFactory? > `optional` **clobFactory?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:45 ClobFactory — /system-diagnostics fallback when the module's live `clobFactory()` read fails; a live/config mismatch is flagged. *** ### binaryPoolImpl? > `optional` **binaryPoolImpl?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:53 BinaryPool implementation behind the fleet (distinct from the factory's `binaryMarketImpl`). On beacon-generation deploys this is the impl the [SomniaMarketsAddresses.binaryPoolBeacon](#binarypoolbeacon) points at; on pre-beacon deploys it is the EIP-1167 master copy the factory cloned. Not read by the SDK itself, but surfaced to apps — the explorer's system overview renders it. *** ### binaryPoolBeacon? > `optional` **binaryPoolBeacon?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:60 The fleet's `UpgradeableBeacon` (beacon generation onwards). Every pool the factory deploys is a `BeaconProxy` against it, so upgrading the beacon moves the whole fleet at once. Absent on pre-beacon manifests, where pools are independent clones of [SomniaMarketsAddresses.binaryPoolImpl](#binarypoolimpl). *** ### binarySettlement? > `optional` **binarySettlement?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:68 The permanent BinarySettlement singleton (settlement-extraction v2). Every pool finalizes its markets into it and every redemption routes through it, so a pool can be recycled onto the next market. Needed by the low-level `redeemDirect` / `claimOwed` / `getSettlement` trader methods, which throw if it is unset. Absent on pre-v2 (pool-redeem) deploys. *** ### operatorPermissionsRegistry? > `optional` **operatorPermissionsRegistry?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:73 Shared OperatorPermissionsRegistry — users operator-approve a SpotStopOrderRegistry here (once, globally) so it can place their stop order via the pool at trigger time. *** ### marketsCore? > `optional` **marketsCore?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:79 MarketsCore — the control-plane registry of operators, typed venues, and the module binding per market type. Needed by the operator/venue admin reads + `createOperatorAdmin` writes. *** ### collateralRouter? > `optional` **collateralRouter?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:86 CollateralRouter periphery — the native-token (wrap/unwrap) + Permit2 entry over BinaryMarketsModule's complete-set flow. May be absent for an environment where only the plain-ERC-20 path is deployed; the router-based trader methods throw if it is unset rather than sending to the zero address. *** ### marketCreatorFactory? > `optional` **marketCreatorFactory?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:92 MarketCreatorFactory — stamps out per-operator/venue MarketCreator (+ its policy) instances, the operator "market machinery" layer. Needed by `createMarketCreatorAdmin` writes; the admin throws if it is unset. *** ### marketCreatorFactoryV2? > `optional` **marketCreatorFactoryV2?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:101 v2 sibling of [SomniaMarketsAddresses.marketCreatorFactory](#marketcreatorfactory) — stamps out `MarketCreatorV2` (interval/bucket-mode rolling series) instances. Additive: coexists with the v1 factory. Not read by `createMarketCreatorAdmin` automatically — pass it explicitly via that call's `factory` override to mint a v2 creator instead of v1. Undefined on deploys that predate it. *** ### oracleHub? > `optional` **oracleHub?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:112 The OracleHub proxy (Oracle v2 §8e) — the protocol's ONE governance-approved oracle adapter. Every market creation binds through it (content-addressed `scheduleQuestion` dedup, earmark-at-creation resolution funding + bounded-drain exact metering, payout-vector delivery). Needed by the OracleHub reads (`quoteCreateMarketValue`, `getSchedulingCost`, `earmarkedOf`, `resolveReserve`) and the `createOracleHubAdmin` writes; those throw if it is unset. Also the default `adapter` for `createMarketCreatorAdmin.createMarketCreator`. *** ### ~~oracleAdapterFactory?~~ > `optional` **oracleAdapterFactory?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:120 Legacy OracleAdapterFactory address retained for source compatibility. #### Deprecated LEGACY (pre-oracle-v2): OracleAdapterFactory. The factory contract was deleted in Oracle v2 — use [SomniaMarketsAddresses.oracleHub](#oraclehub). Kept only so old configs keep type-checking; nothing in the SDK reads it. *** ### ~~sharedOracleAdapter?~~ > `optional` **sharedOracleAdapter?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:128 Legacy shared oracle-adapter address retained for source compatibility. #### Deprecated LEGACY (pre-oracle-v2): the shared ProphecyOracleAdapter proxy. Replaced by [SomniaMarketsAddresses.oracleHub](#oraclehub). Kept only so old configs keep type-checking; nothing in the SDK reads it. *** ### perpPoolFactory? > `optional` **perpPoolFactory?**: `` `0x${string}` `` Defined in: packages/sdk/src/config.ts:144 PerpPoolFactory — the on-chain authority on which perp markets exist. Normally UNNECESSARY. [SomniaMarkets.loadMarkets](../classes/SomniaMarkets.md#loadmarkets) finds the factory itself: any indexed perp row carries its `marginBank`, and `MarginBank.getSystemConfig()` reports the factory the bank actually calls. That is the better source — it is the deployment's own view of its wiring, so it cannot drift from a stale config the way a hardcoded address can. Set this only for the one case the bootstrap cannot cover: an indexer with NO perp rows at all (a fresh reindex, or a chain whose perp manifest was never written), where there is no `marginBank` to ask. When set it takes precedence, so it also serves as an override while a bank's reported factory is being rotated. *** ### lend? > `optional` **lend?**: [`LendAddresses`](LendAddresses.md) Defined in: packages/sdk/src/config.ts:171 SomniaLend money-market addresses — a THIRD-PARTY Aave v3 fork (docs.somnialend.finance), so unlike the first-party fields above these are NOT in the deployments manifests. Set `SOMNIA_MAINNET_LEND` or `SOMNIA_TESTNET_LEND` (from the root entry) for the published deployments. Backs the `client.lend` namespace; its methods throw a clear error when the address they need is unset. **Gotchas** This is the ONLY way to point the lend surface at a deployment — and the addresses must belong to this client's `chain`. A testnet deployment needs a testnet client; there is no way to graft one chain's lend addresses onto another chain's socket. **Example** (Configuring SomniaLend) ```ts const exchange = new SomniaMarkets({ ...config, addresses: { lend: SOMNIA_MAINNET_LEND }, }); const account = await exchange.client.lend.getAccount(me); console.log(`health factor ${account.healthFactor}`); ``` --- # /docs/typescript/api/index/interfaces/SomniaMarketsClient [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClient # Interface: SomniaMarketsClient Defined in: packages/sdk/src/somniaMarketsClient.ts:263 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: 1. **Live store** (`getLive*`, synchronous): zero round-trips, updates the moment an event lands on-chain. Requires a watch ([watchMarket](#watchmarket) / [watchMarkets](#watchmarkets)) covering the market you read. 2. **Chain** (`getBinaryOrderBook`, `getMarketOnchain`, …): one `eth_call` round-trip, current to head. Works without any watch. 3. **Indexer** (`listMarkets`, `getPortfolio`, …): history and aggregates; lags the chain slightly. Works without any watch or the socket. ## Extended by - [`SomniaMarketsClientWithObservations`](SomniaMarketsClientWithObservations.md) ## Properties ### config > `readonly` **config**: [`ClientConfig`](ClientConfig.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:265 The config this client was built with. *** ### lend > `readonly` **lend**: [`SomniaLendClient`](SomniaLendClient.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:311 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. ## Methods ### getViemClient() > **getViemClient**(): `object` Defined in: packages/sdk/src/somniaMarketsClient.ts:298 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 `PublicClient` for 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](../classes/ContractRevertError.md) 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](../classes/NotConfiguredError.md) on a client built without `wsRpcUrl`. #### Returns `object` *** ### watchMarket() > **watchMarket**(`pool`): `Promise`\<[`WatchHandle`](WatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:337 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. #### Parameters ##### pool `string` #### Returns `Promise`\<[`WatchHandle`](WatchHandle.md)\> *** ### watchMarkets() > **watchMarkets**(`opts?`): `Promise`\<[`WatchHandle`](WatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:349 Watch every market the indexer currently knows — the whole-protocol tail for list views and multi-market bots. Prefer [watchMarket](#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 (requires `config.addresses.marketCreator`). Off by default. #### Parameters ##### opts? ###### discover? `boolean` #### Returns `Promise`\<[`WatchHandle`](WatchHandle.md)\> *** ### watchUser() > **watchUser**(`user`): `Promise`\<[`WatchHandle`](WatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:360 Hydrate one account's order/fill **history** (one indexer fetch) so [getLiveUserFills](#getliveuserfills) / [getLiveUserOrders](#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](#watchmarket) / [watchMarkets](#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`](WatchHandle.md)\> *** ### getWatchStatus() > **getWatchStatus**(`pool`): [`WatchStatus`](../type-aliases/WatchStatus.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:368 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 [`WatchStatus`](../type-aliases/WatchStatus.md) *** ### stopLive() > **stopLive**(): `void` Defined in: packages/sdk/src/somniaMarketsClient.ts:382 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*` 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:394 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`](TailStatus.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:402 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](#getwatchstatus). #### Returns [`TailStatus`](TailStatus.md) *** ### isTailing() > **isTailing**(): `boolean` Defined in: packages/sdk/src/somniaMarketsClient.ts:405 True once at least one watch is live (`mode === "tailing"`). #### Returns `boolean` *** ### getLiveMarkets() > **getLiveMarkets**(): [`Market`](../type-aliases/Market.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:413 Every market the store knows (spot + binary, as the discriminated [Market](../type-aliases/Market.md) union) — markets hydrated by any watch, past or present (market rows are kept as metadata after a watch is released). Synchronous, memoized. #### Returns [`Market`](../type-aliases/Market.md)[] *** ### getLiveMarketByPool() > **getLiveMarketByPool**(`pool`): [`Market`](../type-aliases/Market.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:416 One market by its pool address (either kind), or null if unknown. #### Parameters ##### pool `string` #### Returns [`Market`](../type-aliases/Market.md) \| `null` *** ### getLiveMarketByAddress() > **getLiveMarketByAddress**(`marketAddress`): [`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:422 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`](../type-aliases/BinaryMarket.md) \| `null` *** ### getLiveFills() > **getLiveFills**(`pool`, `opts?`): [`LiveFill`](LiveFill.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:432 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`](LiveFill.md)[] *** ### getLiveFundingUpdates() > **getLiveFundingUpdates**(`pool`, `opts?`): [`LiveFundingUpdate`](LiveFundingUpdate.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:450 Funding settlements the live tail has seen for a perp pool, OLDEST FIRST. The tail's counterpart to [listFundingRateHistory](#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 [`LiveFundingUpdate`](LiveFundingUpdate.md)[] *** ### getLiveUserFills() > **getLiveUserFills**(`pool`, `user`, `opts?`): [`LiveFill`](LiveFill.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:460 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`](LiveFill.md)[] *** ### getLiveUserOrders() > **getLiveUserOrders**(`pool`, `user`, `opts?`): [`LiveOrder`](LiveOrder.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:472 `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](#watchuser) plus everything witnessed live on watched markets. **Details** - `opts.limit`: Max rows (default 100). #### Parameters ##### pool `string` ##### user `string` ##### opts? ###### limit? `number` #### Returns [`LiveOrder`](LiveOrder.md)[] *** ### getLiveBinaryOrderBook() > **getLiveBinaryOrderBook**(`pool`, `opts?`): [`BinaryOrderBook`](BinaryOrderBook.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:486 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 [`BinaryOrderBook`](BinaryOrderBook.md) *** ### getLiveBinaryOrderBookByMarket() > **getLiveBinaryOrderBookByMarket**(`marketId`, `opts?`): [`BinaryOrderBook`](BinaryOrderBook.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:503 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](#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 [`BinaryOrderBook`](BinaryOrderBook.md) *** ### getLiveSpotOrderBook() > **getLiveSpotOrderBook**(`pool`, `opts?`): [`SpotOrderBook`](SpotOrderBook.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:513 The locally-materialized resting book of a **spot** pool (`bids`/`asks`, best price first) — the zero-round-trip mirror of [getSpotOrderBook](#getspotorderbook). **Details** - `opts.depth`: Price levels per side (default 12). #### Parameters ##### pool `string` ##### opts? ###### depth? `number` #### Returns [`SpotOrderBook`](SpotOrderBook.md) *** ### quoteBinaryOrder() > **quoteBinaryOrder**(`params`): [`BinaryOrderQuote`](BinaryOrderQuote.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:535 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 [`BinarySide`](../type-aliases/BinarySide.md) ###### quantity `bigint` ###### depth? `number` #### Returns [`BinaryOrderQuote`](BinaryOrderQuote.md) *** ### getBinaryBookParams() > **getBinaryBookParams**(`pool`): `Promise`\<[`BinaryBookParams`](BinaryBookParams.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:550 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](#quotebinarystake) and [quoteBinarySell](#quotebinarysell) read it through this cache. #### Parameters ##### pool `string` #### Returns `Promise`\<[`BinaryBookParams`](BinaryBookParams.md)\> *** ### getClosingPrice() > **getClosingPrice**(`pool`): `Promise`\<[`ClosingPriceState`](ClosingPriceState.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:569 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](Trader.md#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`](ClosingPriceState.md) \| `null`\> #### Throws [RpcError](../classes/RpcError.md) The chain read did not complete. #### Throws [ContractRevertError](../classes/ContractRevertError.md) The pool declares `closingPrice()` and rejected the call. *** ### quoteBinaryStake() > **quoteBinaryStake**(`params`): `Promise`\<[`BinaryStakeQuote`](BinaryStakeQuote.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:595 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](#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](#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 [`BinaryBuySide`](../type-aliases/BinaryBuySide.md) ###### stake `bigint` ###### depth? `number` ###### slippageBps? `bigint` ###### slippageMinTicks? `bigint` #### Returns `Promise`\<[`BinaryStakeQuote`](BinaryStakeQuote.md) \| `null`\> *** ### quoteBinarySell() > **quoteBinarySell**(`params`): `Promise`\<[`BinarySellQuote`](BinarySellQuote.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:622 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](#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 [`BinarySellSide`](../type-aliases/BinarySellSide.md) ###### quantity `bigint` ###### depth? `number` ###### slippageBps? `bigint` ###### slippageMinTicks? `bigint` #### Returns `Promise`\<[`BinarySellQuote`](BinarySellQuote.md) \| `null`\> *** ### getMarketStats24h() > **getMarketStats24h**(`target`): `Promise`\<[`MarketStats24h`](MarketStats24h.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:638 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`](MarketStats24h.md)\> *** ### getBinaryPositionPnL() > **getBinaryPositionPnL**(`account`, `marketId`): `Promise`\<[`BinaryPositionPnL`](BinaryPositionPnL.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:667 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](BinaryPositionPnL.md) 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](../classes/InvalidInputError.md) - no binary market with that id. - Throws [IndexerError](../classes/IndexerError.md) - a fills, actions or balances read did not complete. - Throws [RpcError](../classes/RpcError.md) - the top-of-book `eth_call` did not complete (only with a chain client configured; a failed read is never marked on `lastPrice` as if it had succeeded). - Throws [ContractRevertError](../classes/ContractRevertError.md) - the pool rejected the top-of-book read. #### Parameters ##### account `string` ##### marketId `string` #### Returns `Promise`\<[`BinaryPositionPnL`](BinaryPositionPnL.md)\> *** ### getOpenPositionsWithPnL() > **getOpenPositionsWithPnL**(`account`): `Promise`\<[`OpenPositionPnL`](../type-aliases/OpenPositionPnL.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:698 PnL for ALL of an account's open binary positions in one call — the batched, positions-list companion to [getBinaryPositionPnL](#getbinarypositionpnl). Each entry is a [OpenPositionPnL](../type-aliases/OpenPositionPnL.md): 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](../classes/IndexerError.md) when the positions, fills, router actions, or top-of-book request does not complete. - Throws [InvalidInputError](../classes/InvalidInputError.md) 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`\<[`OpenPositionPnL`](../type-aliases/OpenPositionPnL.md)[]\> *** ### getClaimable() > **getClaimable**(`account`): `Promise`\<[`ClaimablePosition`](ClaimablePosition.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:718 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](../classes/IndexerError.md) when the portfolio or settlement-fee request does not complete. - Throws [InvalidInputError](../classes/InvalidInputError.md) 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`](ClaimablePosition.md)[]\> *** ### watchPrice() > **watchPrice**(`asset`): `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:736 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](#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` to be set; rejects (and releases) otherwise. #### Parameters ##### asset `string` #### Returns `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> *** ### watchPrices() > **watchPrices**(`assets`): `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:743 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](#watchprice) calls. #### Parameters ##### assets `string`[] #### Returns `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> *** ### getPriceStatus() > **getPriceStatus**(`asset`): [`PriceFeedStatus`](../type-aliases/PriceFeedStatus.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:751 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](../type-aliases/PriceFeedStatus.md). #### Parameters ##### asset `string` #### Returns [`PriceFeedStatus`](../type-aliases/PriceFeedStatus.md) *** ### subscribePrices() > **subscribePrices**(`listener`): () => `void` Defined in: packages/sdk/src/somniaMarketsClient.ts:763 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](#subscribelive) (prices are a separate store/service). **Details** - Returns: An unsubscribe function. #### Parameters ##### listener () => `void` #### Returns () => `void` *** ### getLivePrice() > **getLivePrice**(`asset`): [`LivePrice`](LivePrice.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:769 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`](LivePrice.md) \| `null` *** ### getLivePrices() > **getLivePrices**(`assets`): ([`LivePrice`](LivePrice.md) \| `null`)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:775 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`](LivePrice.md) \| `null`)[] *** ### getLivePriceTicks() > **getLivePriceTicks**(`asset`, `opts?`): [`PricePoint`](PricePoint.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:784 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 [`PricePoint`](PricePoint.md)[] *** ### getLivePriceFeedInfo() > **getLivePriceFeedInfo**(`asset`): [`PriceFeedInfo`](PriceFeedInfo.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:790 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](#fetchpricefeedinfo). #### Parameters ##### asset `string` #### Returns [`PriceFeedInfo`](PriceFeedInfo.md) \| `null` *** ### fetchPriceFeedInfo() > **fetchPriceFeedInfo**(`asset`): `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:793 One-shot feed metadata + current price (one HTTP round-trip; no watch needed). #### Parameters ##### asset `string` #### Returns `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)\> *** ### fetchPrice() > **fetchPrice**(`asset`): `Promise`\<[`LivePrice`](LivePrice.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:799 One-shot current price (one HTTP round-trip), or null if the feed has no observations yet. #### Parameters ##### asset `string` #### Returns `Promise`\<[`LivePrice`](LivePrice.md) \| `null`\> *** ### fetchPrices() > **fetchPrices**(`assets?`): `Promise`\<[`LivePrice`](LivePrice.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:806 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`](LivePrice.md)[]\> *** ### listPriceFeeds() > **listPriceFeeds**(): `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:812 One-shot feed catalog — metadata + current price for every tracked asset (discovery). One HTTP round-trip; no watch needed. #### Returns `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)[]\> *** ### fetchPriceHistory() > **fetchPriceHistory**(`asset`, `opts?`): `Promise`\<[`PricePoint`](PricePoint.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:818 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`](PricePoint.md)[]\> *** ### fetchPriceCandles() > **fetchPriceCandles**(`asset`, `resolution`, `opts?`): `Promise`\<[`PriceCandle`](PriceCandle.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:824 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 [`PriceCandleResolution`](../type-aliases/PriceCandleResolution.md) ##### opts? ###### limit? `number` ###### from? `number` ###### to? `number` #### Returns `Promise`\<[`PriceCandle`](PriceCandle.md)[]\> *** ### listMarkets() > **listMarkets**(`opts?`): `Promise`\<[`Market`](../type-aliases/Market.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:844 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? [`MarketType`](../type-aliases/MarketType.md) ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`Market`](../type-aliases/Market.md)[]\> *** ### listRegistryMarkets() > **listRegistryMarkets**(): `Promise`\<[`Market`](../type-aliases/Market.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:852 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`](../type-aliases/Market.md)[]\> *** ### listRegistryMarketsChecked() > **listRegistryMarketsChecked**(): `Promise`\<[`RegistrySweep`](RegistrySweep.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:866 [listRegistryMarkets](#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`](RegistrySweep.md)\> #### Throws [IndexerError](../classes/IndexerError.md) The indexed read did not complete. The complete union is [SomniaMarketsClientListRegistryMarketsCheckedError](../type-aliases/SomniaMarketsClientListRegistryMarketsCheckedError.md). *** ### countMarkets() > **countMarkets**(`opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:874 Server-side COUNT of markets (optionally one type) for pagination totals. Needs the privileged `_aggregate` role (server-only), like [countBinaryMarkets](#countbinarymarkets). Without it the count is a row scan capped at 10,000 and a larger total reads as exactly `10000` — [countMarketsBounded](#countmarketsbounded) reports whether it did. #### Parameters ##### opts? ###### marketType? [`MarketType`](../type-aliases/MarketType.md) #### Returns `Promise`\<`number`\> *** ### countMarketsBounded() > **countMarketsBounded**(`opts?`): `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:880 [countMarkets](#countmarkets) with the truncation reported: `truncated: true` means the public-role scan hit its cap and `count` is a lower bound. #### Parameters ##### opts? ###### marketType? [`MarketType`](../type-aliases/MarketType.md) #### Returns `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> *** ### getMarket() > **getMarket**(`id`): `Promise`\<[`Market`](../type-aliases/Market.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:886 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`](../type-aliases/Market.md) \| `null`\> *** ### listBinaryMarkets() > **listBinaryMarkets**(`opts?`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:889 [listMarkets](#listmarkets) pre-narrowed to binary markets. #### Parameters ##### opts? [`BinaryMarketFilter`](../type-aliases/BinaryMarketFilter.md) & `object` #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> *** ### listLiveBinaryMarkets() > **listLiveBinaryMarkets**(`filter?`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:897 Currently-live binary markets (`expiry > now`), soonest-to-expire first. Call with no argument for all live markets, or pass a [LiveBinaryMarketsFilter](../type-aliases/LiveBinaryMarketsFilter.md) to narrow by `operatorId` / `venueId` / `asset` / `intervalSec` / `status` (e.g. `{ venueId: "0x4d41494e" }`). #### Parameters ##### filter? [`LiveBinaryMarketsFilter`](../type-aliases/LiveBinaryMarketsFilter.md) #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> *** ### listBinaryVenueIds() > **listBinaryVenueIds**(): `Promise`\<`object`[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:904 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:917 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:925 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](#countbinarymarketsbounded) says which. #### Parameters ##### opts [`BinaryMarketFilter`](../type-aliases/BinaryMarketFilter.md) & `object` #### Returns `Promise`\<`number`\> *** ### countBinaryMarketsBounded() > **countBinaryMarketsBounded**(`opts`): `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:932 [countBinaryMarkets](#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`](../type-aliases/BinaryMarketFilter.md) & `object` #### Returns `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> *** ### listPastBinaryMarkets() > **listPastBinaryMarkets**(`opts?`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:940 Past binary markets (`expiry ≤ now`), most-recently-expired first, paginated with `limit` + `offset`. #### Parameters ##### opts? [`PastBinaryMarketsOptions`](../type-aliases/PastBinaryMarketsOptions.md) #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> *** ### getBinaryMarket() > **getBinaryMarket**(`id`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:946 One binary market by bytes32 marketId, or null (also null if the id resolves to a spot market). #### Parameters ##### id `string` #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null`\> *** ### getBinaryMarketByAddress() > **getBinaryMarketByAddress**(`marketAddress`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:952 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`](../type-aliases/BinaryMarket.md) \| `null`\> *** ### getMarketFees() > **getMarketFees**(`id`): `Promise`\<[`MarketFees`](../type-aliases/MarketFees.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:957 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`](../type-aliases/MarketFees.md) \| `null`\> *** ### listSpotMarkets() > **listSpotMarkets**(`opts?`): `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:963 [listMarkets](#listmarkets) pre-narrowed to spot markets. Pass a [SpotMarketFilter](../type-aliases/SpotMarketFilter.md) (+ `limit`) to narrow by base/quote symbol. #### Parameters ##### opts? [`SpotMarketFilter`](../type-aliases/SpotMarketFilter.md) & `object` #### Returns `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md)[]\> *** ### getSpotMarket() > **getSpotMarket**(`id`): `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:966 One spot market by pool address, or null (also null if not spot). #### Parameters ##### id `string` #### Returns `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md) \| `null`\> *** ### getMarketStatusHistory() > **getMarketStatusHistory**(`marketId`): `Promise`\<[`MarketStatusUpdate`](../type-aliases/MarketStatusUpdate.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:972 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`](../type-aliases/MarketStatusUpdate.md)[]\> *** ### listPerpMarkets() > **listPerpMarkets**(`opts?`): `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:978 [listMarkets](#listmarkets) pre-narrowed to perp markets. Pass a [PerpMarketFilter](../type-aliases/PerpMarketFilter.md) (+ `limit`) to narrow by base/quote symbol. #### Parameters ##### opts? [`PerpMarketFilter`](../type-aliases/PerpMarketFilter.md) & `object` #### Returns `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)[]\> *** ### getPerpMarket() > **getPerpMarket**(`id`): `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:984 One perp market by pool address, or null (also null if the id resolves to another market kind). #### Parameters ##### id `string` #### Returns `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md) \| `null`\> *** ### getCandles() > **getCandles**(`poolAddress`, `intervalSeconds`, `opts?`): `Promise`\<[`Candle`](../type-aliases/Candle.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:996 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`](../type-aliases/Candle.md)[]\> *** ### getMarketActivity() > **getMarketActivity**(`market`, `opts?`): `Promise`\<[`MarketActivity`](../type-aliases/MarketActivity.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1029 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](../type-aliases/MarketActivity.md)). 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](#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](../type-aliases/MarketActivityOptions.md)). #### Parameters ##### market `string` The market's bytes32 marketId (case-insensitive). On spot and perp this is the pool address. ##### opts? [`MarketActivityOptions`](../type-aliases/MarketActivityOptions.md) #### Returns `Promise`\<[`MarketActivity`](../type-aliases/MarketActivity.md)[]\> *** ### getTransactionActivity() > **getTransactionActivity**(`txHash`, `opts?`): `Promise`\<[`TransactionActivity`](../type-aliases/TransactionActivity.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1049 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](../type-aliases/TransactionActivity.md)). The read behind a transaction detail view, and the counterpart to [getTradeContext](#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](#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? [`TransactionActivityOptions`](../type-aliases/TransactionActivityOptions.md) #### Returns `Promise`\<[`TransactionActivity`](../type-aliases/TransactionActivity.md)\> *** ### getBlockActivity() > **getBlockActivity**(`blockNumber`, `opts?`): `Promise`\<[`BlockActivity`](../type-aliases/BlockActivity.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1072 What the protocol traded in one block, grouped by market — the level above [getTransactionActivity](#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](#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? [`BlockActivityOptions`](../type-aliases/BlockActivityOptions.md) Rows per stream and the offset to page from. #### Returns `Promise`\<[`BlockActivity`](../type-aliases/BlockActivity.md)\> *** ### getLatestActiveBlock() > **getLatestActiveBlock**(): `Promise`\<\{ `blockNumber`: `bigint`; `timestamp`: `bigint`; \} \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1082 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](#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:1097 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](#getblockactivity), and for the same reason resolves that anchor itself. #### Parameters ##### blockNumber `bigint` The block being viewed; excluded from both answers. ##### opts? [`BlockActivityOptions`](../type-aliases/BlockActivityOptions.md) Rows per stream per direction. #### Returns `Promise`\<\{ `prev`: `bigint` \| `null`; `next`: `bigint` \| `null`; \}\> *** ### getFills() > **getFills**(`pool`, `opts?`): `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1102 #### Parameters ##### pool `string` ##### opts? [`FillsOptions`](../type-aliases/FillsOptions.md) #### Returns `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> *** ### getTradeContext() > **getTradeContext**(`id`): `Promise`\<[`TradeContext`](../type-aliases/TradeContext.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1122 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](../type-aliases/TradeContext.md)). [getFill](#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](#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`](../type-aliases/TradeContext.md) \| `null`\> *** ### getUserFills() > **getUserFills**(`account`, `opts?`): `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1134 Fills a user participated in (maker OR taker), newest first — the one-shot indexer counterpart to [getLiveUserFills](#getliveuserfills). Optionally scope to one market and/or pool and/or a `since`/`until` window ([FillsScope](../type-aliases/FillsScope.md)). 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? [`FillsScope`](../type-aliases/FillsScope.md) #### Returns `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> *** ### getUserFillsPage() > **getUserFillsPage**(`account`, `options?`): `Promise`\<[`UserFillsPage`](../type-aliases/UserFillsPage.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1168 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? [`GetUserFillsPageOptions`](../type-aliases/GetUserFillsPageOptions.md) Market/pool and inclusive time filters, bounded limit and cursor. #### Returns `Promise`\<[`UserFillsPage`](../type-aliases/UserFillsPage.md)\> Existing fill rows and the next cursor, or null when this read has no next row. #### Throws [InvalidInputError](../classes/InvalidInputError.md) For invalid input or malformed/foreign cursors. #### Throws [IndexerError](../classes/IndexerError.md) When the read fails or returned position scalars are invalid. #### Example ```ts 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); } ``` *** ### getFill() > **getFill**(`id`): `Promise`\<[`FillDetail`](../type-aliases/FillDetail.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1175 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`](../type-aliases/FillDetail.md) \| `null`\> *** ### getOrderFills() > **getOrderFills**(`pool`, `orderId`, `opts?`): `Promise`\<[`OrderFillRow`](../type-aliases/OrderFillRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1181 Every fill one order participated in — either side, newest first. `(pool, orderId)` names exactly one order forever (ids never reuse). #### Parameters ##### pool `string` ##### orderId `string` \| `bigint` ##### opts? ###### limit? `number` #### Returns `Promise`\<[`OrderFillRow`](../type-aliases/OrderFillRow.md)[]\> *** ### getOrder() > **getOrder**(`pool`, `orderId`): `Promise`\<[`OrderDetail`](../type-aliases/OrderDetail.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1188 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](#getorderonchain). #### Parameters ##### pool `string` ##### orderId `string` \| `bigint` #### Returns `Promise`\<[`OrderDetail`](../type-aliases/OrderDetail.md) \| `null`\> *** ### listMarketsByPool() > **listMarketsByPool**(`pool`, `opts?`): `Promise`\<[`Market`](../type-aliases/Market.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1195 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](#getmarketbypool). #### Parameters ##### pool `string` ##### opts? ###### limit? `number` #### Returns `Promise`\<[`Market`](../type-aliases/Market.md)[]\> *** ### getOpenOrders() > **getOpenOrders**(`owner`, `opts?`): `Promise`\<[`OpenOrder`](../type-aliases/OpenOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1204 `owner`'s currently-OPEN orders, newest first. Pass [OrdersOptions](../type-aliases/OrdersOptions.md) (minus `status` — always "Open" here) to scope by `pool`/`side` and page. NOTE: this lags the chain — for a trading loop prefer [getLiveUserOrders](#getliveuserorders) (or track the `orderId`s your own `placeOrder` calls return). For non-open history use [getOrders](#getorders). #### Parameters ##### owner `string` ##### opts? `Omit`\<[`OrdersOptions`](../type-aliases/OrdersOptions.md), `"status"`\> #### Returns `Promise`\<[`OpenOrder`](../type-aliases/OpenOrder.md)[]\> *** ### getOrders() > **getOrders**(`owner`, `opts?`): `Promise`\<[`OrderRow`](../type-aliases/OrderRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1212 `owner`'s orders across ALL statuses (Open/Filled/Cancelled/Expired/Closed), newest first — the order-history counterpart to [getOpenOrders](#getopenorders). Each row carries its lifecycle `status` + fill progress. Filter by `status`/`side`/`pool` and page via [OrdersOptions](../type-aliases/OrdersOptions.md). #### Parameters ##### owner `string` ##### opts? [`OrdersOptions`](../type-aliases/OrdersOptions.md) #### Returns `Promise`\<[`OrderRow`](../type-aliases/OrderRow.md)[]\> *** ### listSweepableOrders() > **listSweepableOrders**(`opts?`): `Promise`\<[`SweepableOrder`](../type-aliases/SweepableOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1233 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? [`MarketType`](../type-aliases/MarketType.md) ###### owner? `string` ###### asOfSec? `number` \| `bigint` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`SweepableOrder`](../type-aliases/SweepableOrder.md)[]\> *** ### getOutcomeBalances() > **getOutcomeBalances**(`account`, `marketAddress`): `Promise`\<[`OutcomeBalances`](../type-aliases/OutcomeBalances.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1247 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](#geterc20balance) instead. #### Parameters ##### account `string` ##### marketAddress `string` #### Returns `Promise`\<[`OutcomeBalances`](../type-aliases/OutcomeBalances.md)\> *** ### getPortfolio() > **getPortfolio**(`account`, `opts?`): `Promise`\<[`Portfolio`](../type-aliases/Portfolio.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1255 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](../type-aliases/PortfolioOptions.md) 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? [`PortfolioOptions`](../type-aliases/PortfolioOptions.md) #### Returns `Promise`\<[`Portfolio`](../type-aliases/Portfolio.md)\> *** ### getSpotPortfolio() > **getSpotPortfolio**(`account`, `opts?`): `Promise`\<[`SpotPortfolio`](../type-aliases/SpotPortfolio.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1262 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](../type-aliases/PortfolioOptions.md) to page. Trades default to the last seven days — the bound comes back as `tradesSince`; pass `since` to widen it. #### Parameters ##### account `string` ##### opts? [`PortfolioOptions`](../type-aliases/PortfolioOptions.md) #### Returns `Promise`\<[`SpotPortfolio`](../type-aliases/SpotPortfolio.md)\> *** ### getSpotStopOrders() > **getSpotStopOrders**(`account`, `opts?`): `Promise`\<[`SpotStopOrder`](../type-aliases/SpotStopOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1269 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? [`StopOrderStatus`](../type-aliases/StopOrderStatus.md) ###### limit? `number` #### Returns `Promise`\<[`SpotStopOrder`](../type-aliases/SpotStopOrder.md)[]\> *** ### getPerpPortfolio() > **getPerpPortfolio**(`account`, `opts?`): `Promise`\<[`PerpPortfolio`](../type-aliases/PerpPortfolio.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1280 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](#getperpposition) / [getMarginAccount](#getmarginaccount). Pass [PortfolioOptions](../type-aliases/PortfolioOptions.md) to page. Trades default to the last seven days — the bound comes back as `tradesSince`; pass `since` to widen it. #### Parameters ##### account `string` ##### opts? [`PortfolioOptions`](../type-aliases/PortfolioOptions.md) #### Returns `Promise`\<[`PerpPortfolio`](../type-aliases/PerpPortfolio.md)\> *** ### listPerpStopOrders() > **listPerpStopOrders**(`opts?`): `Promise`\<[`PerpStopOrder`](../type-aliases/PerpStopOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1300 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? [`StopOrderStatus`](../type-aliases/StopOrderStatus.md)[] ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`PerpStopOrder`](../type-aliases/PerpStopOrder.md)[]\> *** ### getPerpStopOrder() > **getPerpStopOrder**(`ref`): `Promise`\<[`PerpStopOrderOnChain`](../type-aliases/PerpStopOrderOnChain.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1320 One pending stop read straight from its registry — the chain tier [listPerpStopOrders](#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](../type-aliases/PerpStopOrder.md) 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 ###### registry `` `0x${string}` `` ###### orderId `string` \| `bigint` #### Returns `Promise`\<[`PerpStopOrderOnChain`](../type-aliases/PerpStopOrderOnChain.md) \| `null`\> *** ### getPerpStopOrderSomiPayment() > **getPerpStopOrderSomiPayment**(`registry`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1326 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:1334 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`](../type-aliases/PerpOrderHistoryRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1352 An account's FINISHED perp orders, most-recently-ended first — the history tab behind [getPerpPortfolio](#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? [`TerminalOrderStatus`](../type-aliases/TerminalOrderStatus.md)[] ###### orderBy? `"placed"` \| `"ended"` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`PerpOrderHistoryRow`](../type-aliases/PerpOrderHistoryRow.md)[]\> *** ### getSyncStatus() > **getSyncStatus**(`chainId`): `Promise`\<[`IndexerSyncStatus`](../type-aliases/IndexerSyncStatus.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1369 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`](../type-aliases/IndexerSyncStatus.md) \| `null`\> #### Throws A query variable is invalid. #### Throws The metadata request failed. *** ### getMarketByPool() > **getMarketByPool**(`pool`): `Promise`\<[`Market`](../type-aliases/Market.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1375 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`](../type-aliases/Market.md) \| `null`\> *** ### countOrders() > **countOrders**(`owner`, `opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1387 Server-side COUNT of `owner`'s orders matching an [OrdersOptions](../type-aliases/OrdersOptions.md) 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](#countmarketsbounded) is the shape to copy. #### Parameters ##### owner `string` ##### opts? [`OrdersOptions`](../type-aliases/OrdersOptions.md) #### Returns `Promise`\<`number`\> *** ### countUserFills() > **countUserFills**(`account`, `opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1400 Server-side COUNT of the fills `account` participated in (maker OR taker), optionally scoped by market and/or pool + a `since`/`until` window ([FillsScope](../type-aliases/FillsScope.md)) — 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](#countmarketsbounded) is the shape to copy. #### Parameters ##### account `string` ##### opts? [`FillsScope`](../type-aliases/FillsScope.md) #### Returns `Promise`\<`number`\> *** ### getRouterActions() > **getRouterActions**(`account`, `opts?`): `Promise`\<[`RouterActionRecord`](../type-aliases/RouterActionRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1411 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](../type-aliases/RouterActionsOptions.md)). 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? [`RouterActionsOptions`](../type-aliases/RouterActionsOptions.md) #### Returns `Promise`\<[`RouterActionRecord`](../type-aliases/RouterActionRecord.md)[]\> *** ### getMarketResolution() > **getMarketResolution**(`marketId`): `Promise`\<\{ `events`: [`MarketResolutionEvent`](../type-aliases/MarketResolutionEvent.md)[]; `reference`: [`MarketReferenceLink`](../type-aliases/MarketReferenceLink.md) \| `null`; `closingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `openingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `oracleAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; \}\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1421 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`](../type-aliases/MarketResolutionEvent.md)[]; `reference`: [`MarketReferenceLink`](../type-aliases/MarketReferenceLink.md) \| `null`; `closingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `openingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `oracleAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; \}\> *** ### getOpeningPrices() > **getOpeningPrices**(`marketIds`): `Promise`\<`Record`\<`string`, `string` \| `null`\>\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1453 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:1461 Batch RESOLUTION (settlement) prices for many markets in one pair of round-trips — the settlement counterpart to [getOpeningPrices](#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`](OnchainResolutionPrice.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1471 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`](OnchainResolutionPrice.md) \| `null`\> *** ### getBookTops() > **getBookTops**(`marketIds`): `Promise`\<`Record`\<`string`, [`BookTop`](../type-aliases/BookTop.md)\>\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1481 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](../type-aliases/BookTop.md), whose prices are raw and in each market's own terms; empty-book markets are absent. #### Parameters ##### marketIds `string`[] #### Returns `Promise`\<`Record`\<`string`, [`BookTop`](../type-aliases/BookTop.md)\>\> *** ### listProtocolFees() > **listProtocolFees**(`opts?`): `Promise`\<[`ProtocolFeeRecord`](../type-aliases/ProtocolFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1488 Realized protocol-fee records, newest first — filter by `recipient` / `market` / `pool` / `payer`, paginate. The per-fill stream behind [getMarketFees](#getmarketfees)'s running total. #### Parameters ##### opts? ###### recipient? `string` ###### market? `string` ###### pool? `string` ###### payer? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`ProtocolFeeRecord`](../type-aliases/ProtocolFeeRecord.md)[]\> *** ### listBuilderFees() > **listBuilderFees**(`opts?`): `Promise`\<[`BuilderFeeRecord`](../type-aliases/BuilderFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1501 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`](../type-aliases/BuilderFeeRecord.md)[]\> *** ### listSettlementFees() > **listSettlementFees**(`opts?`): `Promise`\<[`SettlementFeeRecord`](../type-aliases/SettlementFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1513 Realized settlement-fee records, newest first — filter by `market` / `recipient`, paginate. #### Parameters ##### opts? ###### market? `string` ###### recipient? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`SettlementFeeRecord`](../type-aliases/SettlementFeeRecord.md)[]\> *** ### listBuilderApprovals() > **listBuilderApprovals**(`opts?`): `Promise`\<[`BuilderApproval`](../type-aliases/BuilderApproval.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1525 Builder-approval directory, newest-updated first — filter by `user` and/or `builder`, paginate. The directory complement to the on-chain point read [getBuilderApproval](#getbuilderapproval). #### Parameters ##### opts? ###### user? `string` ###### builder? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`BuilderApproval`](../type-aliases/BuilderApproval.md)[]\> *** ### getVaultPayoutFallbacks() > **getVaultPayoutFallbacks**(`owner`, `opts?`): `Promise`\<[`VaultPayoutFallback`](../type-aliases/VaultPayoutFallback.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1537 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](#getvaultbalance). #### Parameters ##### owner `string` ##### opts? ###### token? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`VaultPayoutFallback`](../type-aliases/VaultPayoutFallback.md)[]\> *** ### getFundingPayments() > **getFundingPayments**(`account`, `opts?`): `Promise`\<[`FundingPayment`](../type-aliases/FundingPayment.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1546 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`](../type-aliases/FundingPayment.md)[]\> *** ### getMarginEvents() > **getMarginEvents**(`account`, `opts?`): `Promise`\<[`MarginEvent`](../type-aliases/MarginEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1555 An account's margin-account movement history (deposits/withdraws/locks), newest first — paginated. #### Parameters ##### account `string` ##### opts? ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`MarginEvent`](../type-aliases/MarginEvent.md)[]\> *** ### listLiquidations() > **listLiquidations**(`opts?`): `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1573 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](../type-aliases/LiquidationEvent.md#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? [`ListLiquidationsOptions`](ListLiquidationsOptions.md) #### Returns `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> #### Throws [IndexerError](../classes/IndexerError.md) The indexed read did not complete. The complete union is [SomniaMarketsClientListLiquidationsError](../type-aliases/SomniaMarketsClientListLiquidationsError.md). *** ### ~~getLiquidations()~~ > **getLiquidations**(`opts?`): `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1584 Liquidation events, newest first. #### Parameters ##### opts? [`ListLiquidationsOptions`](ListLiquidationsOptions.md) #### Returns `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> #### Deprecated Renamed to [listLiquidations](#listliquidations), per SDK-TYPE-006. Forwards verbatim. #### Throws [IndexerError](../classes/IndexerError.md) As [SomniaMarketsClient.listLiquidations](#listliquidations). The union is [SomniaMarketsClientGetLiquidationsError](../type-aliases/SomniaMarketsClientGetLiquidationsError.md). *** ### listFundingRateHistory() > **listFundingRateHistory**(`pool`, `opts?`): `Promise`\<[`FundingRateUpdate`](../type-aliases/FundingRateUpdate.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1598 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`](../type-aliases/FundingRateUpdate.md)[]\> *** ### listFundingRateCandles() > **listFundingRateCandles**(`pool`, `intervalSeconds`, `opts?`): `Promise`\<[`FundingRateCandle`](../type-aliases/FundingRateCandle.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1620 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`](../type-aliases/FundingRateCandle.md)[]\> *** ### listPerpFees() > **listPerpFees**(`opts?`): `Promise`\<[`PerpFeeRecord`](../type-aliases/PerpFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1634 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`](../type-aliases/PerpFeeRecord.md)[]\> *** ### listPerpOrderRejections() > **listPerpOrderRejections**(`opts?`): `Promise`\<[`PerpOrderRejection`](../type-aliases/PerpOrderRejection.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1655 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`](../type-aliases/PerpOrderRejection.md)[]\> *** ### ~~getFundingRateHistory()~~ > **getFundingRateHistory**(`pool`, `opts?`): `Promise`\<[`FundingRateUpdate`](../type-aliases/FundingRateUpdate.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1668 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`](../type-aliases/FundingRateUpdate.md)[]\> #### Deprecated Use [listFundingRateHistory](#listfundingratehistory) instead. This alias forwards verbatim. *** ### getOpenInterestHistory() > **getOpenInterestHistory**(`pool`, `opts?`): `Promise`\<[`OpenInterestSnapshot`](../type-aliases/OpenInterestSnapshot.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1674 A perp pool's open-interest history, newest first — paginated. #### Parameters ##### pool `string` ##### opts? ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`OpenInterestSnapshot`](../type-aliases/OpenInterestSnapshot.md)[]\> *** ### listPerpPositions() > **listPerpPositions**(`account`, `opts?`): `Promise`\<[`IndexedPerpPosition`](../type-aliases/IndexedPerpPosition.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1689 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](#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`](../type-aliases/IndexedPerpPosition.md)[]\> *** ### getBinaryOrderBook() > **getBinaryOrderBook**(`pool`, `opts?`): `Promise`\<[`BinaryOrderBook`](BinaryOrderBook.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1716 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](#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? [`GetBinaryOrderBookOptions`](GetBinaryOrderBookOptions.md) #### Returns `Promise`\<[`BinaryOrderBook`](BinaryOrderBook.md)\> #### Throws [InvalidInputError](../classes/InvalidInputError.md) If depth or the block pin is invalid. #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [RpcError](../classes/RpcError.md) If selecting the head or reading either side fails. #### Throws [ContractRevertError](../classes/ContractRevertError.md) If the contract rejects either read. *** ### getSpotOrderBook() > **getSpotOrderBook**(`pool`, `opts?`): `Promise`\<[`SpotOrderBook`](SpotOrderBook.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1733 Read a spot OR perp pool's resting book from the contract (both ride the shared OrderBook base). Live variant: [getLiveSpotOrderBook](#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? [`GetSpotOrderBookOptions`](GetSpotOrderBookOptions.md) #### Returns `Promise`\<[`SpotOrderBook`](SpotOrderBook.md)\> #### Throws [InvalidInputError](../classes/InvalidInputError.md) If depth or the block pin is invalid. #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [RpcError](../classes/RpcError.md) If selecting the head or reading either side fails. #### Throws [ContractRevertError](../classes/ContractRevertError.md) If the contract rejects either read. *** ### getOrderOnchain() > **getOrderOnchain**(`pool`, `orderId`, `opts?`): `Promise`\<[`OnchainOrder`](OnchainOrder.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1778 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](#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. ```ts // 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? [`GetOrderOnchainOptions`](GetOrderOnchainOptions.md) #### Returns `Promise`\<[`OnchainOrder`](OnchainOrder.md) \| `null`\> #### Throws [InvalidInputError](../classes/InvalidInputError.md) If `opts.blockNumber` is negative. #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [RpcError](../classes/RpcError.md) If the read fails. #### Throws [ContractRevertError](../classes/ContractRevertError.md) If the contract rejects the read for any reason other than the id having no active order. *** ### getOwnOpenOrdersOnchain() > **getOwnOpenOrdersOnchain**(`pool`, `owner`): `Promise`\<`bigint`[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1786 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](#getopenorders). #### Parameters ##### pool `` `0x${string}` `` ##### owner `` `0x${string}` `` #### Returns `Promise`\<`bigint`[]\> *** ### getAllOpenOrdersOnchain() > **getAllOpenOrdersOnchain**(`pool`, `opts`): `Promise`\<\{ `orders`: [`OnchainOrder`](OnchainOrder.md)[]; `hasMore`: `boolean`; `nextCursor`: `bigint`; \}\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1800 One page of every open order on one side, at chain head — the per-order detail the aggregated book reads ([getBinaryOrderBook](#getbinaryorderbook), [getSpotOrderBook](#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). #### Parameters ##### pool `` `0x${string}` `` ##### opts ###### isBid `boolean` ###### maxCount? `number` ###### cursor? `bigint` #### Returns `Promise`\<\{ `orders`: [`OnchainOrder`](OnchainOrder.md)[]; `hasMore`: `boolean`; `nextCursor`: `bigint`; \}\> *** ### getPerpState() > **getPerpState**(`pool`): `Promise`\<[`PerpStateOnchain`](PerpStateOnchain.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1810 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`](PerpStateOnchain.md)\> *** ### getPerpFeedStatus() > **getPerpFeedStatus**(`pool`): `Promise`\<[`PerpFeedStatus`](PerpFeedStatus.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1835 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](#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](#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`](PerpFeedStatus.md)\> #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) 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](../classes/RpcError.md) A chain read did not complete — the block pin included. #### Throws [ContractRevertError](../classes/ContractRevertError.md) 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](../type-aliases/SomniaMarketsClientGetPerpFeedStatusError.md). *** ### getPerpFundingPremium() > **getPerpFundingPremium**(`pool`): `Promise`\<[`PerpFundingPremium`](PerpFundingPremium.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1850 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](#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`](PerpFundingPremium.md)\> *** ### getPerpPosition() > **getPerpPosition**(`ref`): `Promise`\<[`PerpPosition`](PerpPosition.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1856 An account's position in one perp pool, from the MarginBank (signed size: positive = long). `ref.marginBank` comes off the [PerpMarket](../type-aliases/PerpMarket.md) row. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<[`PerpPosition`](PerpPosition.md)\> *** ### getMarginAccount() > **getMarginAccount**(`marginBank`, `account`): `Promise`\<[`MarginAccount`](MarginAccount.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1863 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`. #### Parameters ##### marginBank `` `0x${string}` `` ##### account `` `0x${string}` `` #### Returns `Promise`\<[`MarginAccount`](MarginAccount.md)\> *** ### getAccountHealth() > **getAccountHealth**(`marginBank`, `account`): `Promise`\<[`AccountHealth`](AccountHealth.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1869 An account's cross-margin health alone (equity vs IM/MM/CM + the derived status) — a lighter read than [getMarginAccount](#getmarginaccount) when only health matters. #### Parameters ##### marginBank `` `0x${string}` `` ##### account `` `0x${string}` `` #### Returns `Promise`\<[`AccountHealth`](AccountHealth.md)\> *** ### getLiquidationPrice() > **getLiquidationPrice**(`ref`): `Promise`\<`bigint` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1881 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](#getbankruptcyprice). #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<`bigint` \| `null`\> *** ### getPerpLeverage() > **getPerpLeverage**(`ref`): `Promise`\<[`PerpLeverage`](PerpLeverage.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1896 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](PerpLeverage.md#voucherleveragecapx). For whether a specific order passes, use `previewPerpOrderMargin`. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<[`PerpLeverage`](PerpLeverage.md)\> *** ### getPerpPositionAnalytics() > **getPerpPositionAnalytics**(`ref`): `Promise`\<[`PerpPositionAnalytics`](../type-aliases/PerpPositionAnalytics.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1912 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 [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<[`PerpPositionAnalytics`](../type-aliases/PerpPositionAnalytics.md)\> *** ### listPerpPositionAnalytics() > **listPerpPositionAnalytics**(`p`): `Promise`\<[`PerpPositionAnalytics`](../type-aliases/PerpPositionAnalytics.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1925 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 `equityContribution`s 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`](../type-aliases/PerpPositionAnalytics.md)[]\> *** ### getMaxPerpOrderSize() > **getMaxPerpOrderSize**(`p`): `Promise`\<[`PerpMaxOrderSize`](../type-aliases/PerpMaxOrderSize.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1946 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`](../type-aliases/PerpMaxOrderSize.md)\> *** ### previewPerpClosePnl() > **previewPerpClosePnl**(`p`): `Promise`\<[`PerpClosePreview`](../type-aliases/PerpClosePreview.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1969 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`](../type-aliases/PerpClosePreview.md)\> *** ### previewPerpLiquidationPrice() > **previewPerpLiquidationPrice**(`p`): `Promise`\<[`PerpLiquidationPreview`](../type-aliases/PerpLiquidationPreview.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1988 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](#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](#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`](../type-aliases/PerpLiquidationPreview.md)\> *** ### getPerpSideHolders() > **getPerpSideHolders**(`ref`, `opts?`): `Promise`\<[`PerpSideHolders`](PerpSideHolders.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2020 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](#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](#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 head - `opts.pageSize`: holders per contract call (default 1000) #### Parameters ##### ref [`PerpSideHoldersRef`](PerpSideHoldersRef.md) ##### opts? [`GetPerpSideHoldersOptions`](GetPerpSideHoldersOptions.md) #### Returns `Promise`\<[`PerpSideHolders`](PerpSideHolders.md)\> *** ### getBankruptcyPrice() > **getBankruptcyPrice**(`ref`, `opts?`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2041 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](#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](../classes/ContractRevertError.md) 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's `asOfBlock` — at head, a holder that closed after the snapshot reverts `NoOpenPosition`. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) ##### opts? [`GetBankruptcyPriceOptions`](GetBankruptcyPriceOptions.md) #### Returns `Promise`\<`bigint`\> *** ### getPerpSystemConfig() > **getPerpSystemConfig**(`marginBank`): `Promise`\<[`PerpSystemConfig`](PerpSystemConfig.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2056 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`](PerpSystemConfig.md)\> *** ### getInsuranceFundState() > **getInsuranceFundState**(`fund`): `Promise`\<[`InsuranceFundState`](InsuranceFundState.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2062 The InsuranceFund's per-tier balances and the total bad debt it can absorb. Point it at `insuranceFund` from [getPerpSystemConfig](#getperpsystemconfig). #### Parameters ##### fund `` `0x${string}` `` #### Returns `Promise`\<[`InsuranceFundState`](InsuranceFundState.md)\> *** ### listPerpInsuranceFundEvents() > **listPerpInsuranceFundEvents**(`opts?`): `Promise`\<[`PerpInsuranceFundEvent`](../type-aliases/PerpInsuranceFundEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2073 The InsuranceFund's tier ledger, newest first — how each tier reached the balance [getInsuranceFundState](#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`](../type-aliases/PerpInsuranceFundEvent.md)[]\> *** ### getLiquidationEngineConfig() > **getLiquidationEngineConfig**(`engine`): `Promise`\<[`LiquidationEngineConfig`](LiquidationEngineConfig.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2090 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`](LiquidationEngineConfig.md)\> *** ### tryGetPerpAccountEquity() > **tryGetPerpAccountEquity**(`marginBank`, `account`): `Promise`\<`bigint` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2099 An account's equity, or `null` when it could not be computed. [getAccountHealth](#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:2108 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`](../type-aliases/PerpPoolStatus.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2131 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](#getmarginaccount) / [getPerpPosition](#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`](../type-aliases/PerpPoolStatus.md)[]\> *** ### listTradeablePerpPools() > **listTradeablePerpPools**(`p`): `Promise`\<`` `0x${string}` ``[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2134 Just the tradeable perp pools, filtered from [listPerpPoolStatuses](#listperppoolstatuses). #### Parameters ##### p ###### factory `` `0x${string}` `` #### Returns `Promise`\<`` `0x${string}` ``[]\> *** ### readPerpMarketFromChain() > **readPerpMarketFromChain**(`p`): `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2150 One factory-deployed perp market as a native [PerpMarket](../type-aliases/PerpMarket.md) 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](UnifiedMarket.md#indexed) for which ones and what they mean. **Gotchas** - Throws [RpcError](../classes/RpcError.md) when a read cannot be completed, and [ContractRevertError](../classes/ContractRevertError.md) 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()` yields `baseSymbol: null`, and a factory predating `IPerpPoolFactoryStopRegistry` yields `stopRegistry: null`. #### Parameters ##### p ###### status [`PerpPoolStatus`](../type-aliases/PerpPoolStatus.md) ###### collateralToken `` `0x${string}` `` ###### collateralDecimals `number` ###### collateralSymbol `string` \| `null` ###### factory `` `0x${string}` `` #### Returns `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)\> *** ### isPerpPoolRegistered() > **isPerpPoolRegistered**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2167 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`](../type-aliases/PerpOrderMarginPreview.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2216 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`](../type-aliases/PerpOrderMarginPreview.md)\> *** ### meetsPerpImForFill() > **meetsPerpImForFill**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2235 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](#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:2252 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](#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:2274 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:2299 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](#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](#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:2313 [getPerpLeverageImSurcharge](#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](../classes/RpcError.md) 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:2334 One account's own leverage cap for one perp pool, as the MarginBank stores it — the cheap path to the number [getPerpLeverage](#getperpleverage) reports as `accountMaxLeverageX`. Chain tier, exactly one storage read. Unlike [getPerpLeverage](#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](#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) triple - `opts.blockNumber`: read at this block instead of head. Combining the cap with an enumeration's or analytics row's figures? Pass that row's `asOfBlock` so both describe one moment. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) ##### opts? [`GetPerpMaxLeverageOptions`](GetPerpMaxLeverageOptions.md) #### Returns `Promise`\<`number`\> *** ### getPerpLinkedWalletRegistry() > **getPerpLinkedWalletRegistry**(`marginBank`): `Promise`\<`` `0x${string}` `` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2344 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`](../type-aliases/PerpFundingPayer.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2354 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`](../type-aliases/PerpFundingPayer.md)\> *** ### getPerpMainFunding() > **getPerpMainFunding**(`marginBank`, `account`): `Promise`\<[`PerpMainFunding`](PerpMainFunding.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2364 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`](PerpMainFunding.md)\> *** ### getPerpWalletPullCapacity() > **getPerpWalletPullCapacity**(`marginBank`, `wallet`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2373 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`](PerpWalletLinkage.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2383 A wallet's link group and its ADL-netting maturity. Takes the REGISTRY address — resolve it with [getPerpLinkedWalletRegistry](#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`](PerpWalletLinkage.md)\> *** ### listPerpLinkedChildren() > **listPerpLinkedChildren**(`registry`, `main`): `Promise`\ Defined in: packages/sdk/src/somniaMarketsClient.ts:2389 Every child of a main, excluding the main — the isolated buckets one treasury currently serves. #### Parameters ##### registry `` `0x${string}` `` ##### main `` `0x${string}` `` #### Returns `Promise`\ *** ### getPerpMaxLinkedChildren() > **getPerpMaxLinkedChildren**(`registry`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2395 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`](../type-aliases/PerpWalletLinkEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2406 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](#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`](../type-aliases/PerpWalletLinkEvent.md)[]\> *** ### listPerpMarginPulls() > **listPerpMarginPulls**(`opts?`): `Promise`\<[`PerpMarginPull`](../type-aliases/PerpMarginPull.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2425 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](#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`](../type-aliases/PerpMarginPull.md)[]\> *** ### listPerpMainFundingEvents() > **listPerpMainFundingEvents**(`opts?`): `Promise`\<[`PerpMainFundingEvent`](../type-aliases/PerpMainFundingEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2444 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](#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](#listperpmarginpulls)** — same wei, two sides. #### Parameters ##### opts? ###### account? `string` ###### payer? `string` ###### kind? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`PerpMainFundingEvent`](../type-aliases/PerpMainFundingEvent.md)[]\> *** ### getPerpRiskParams() > **getPerpRiskParams**(`pool`): `Promise`\<[`PerpRiskParams`](PerpRiskParams.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2452 #### Parameters ##### pool `` `0x${string}` `` #### Returns `Promise`\<[`PerpRiskParams`](PerpRiskParams.md)\> *** ### getPerpHealthSnapshot() > **getPerpHealthSnapshot**(`pool`): `Promise`\<[`PerpHealthSnapshot`](../type-aliases/PerpHealthSnapshot.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2465 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`](../type-aliases/PerpHealthSnapshot.md)\> *** ### getEffectiveImfBps() > **getEffectiveImfBps**(`pool`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2477 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](#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:2494 Claimable balance an owner can withdraw from a pool's internal ERC20Vault for `token`, raw units — the value behind the append-only [getVaultPayoutFallbacks](#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. ```ts 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 [`GetVaultBalanceParams`](GetVaultBalanceParams.md) #### Returns `Promise`\<`bigint`\> *** ### getManualVaultMode() > **getManualVaultMode**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2501 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 [`GetManualVaultModeParams`](GetManualVaultModeParams.md) #### Returns `Promise`\<`boolean`\> *** ### getAutoPullRequirement() > **getAutoPullRequirement**(`p`): `Promise`\<[`AutoPullRequirement`](AutoPullRequirement.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2509 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 [`GetAutoPullRequirementParams`](GetAutoPullRequirementParams.md) #### Returns `Promise`\<[`AutoPullRequirement`](AutoPullRequirement.md)\> *** ### isOperatorAuthorized() > **isOperatorAuthorized**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2516 Whether `owner` authorized `operator` for `selector` on this SpotPool, at chain head — resolved through the pool's OperatorPermissionsRegistry, so no indexer lag. #### Parameters ##### p [`IsOperatorAuthorizedParams`](IsOperatorAuthorizedParams.md) #### Returns `Promise`\<`boolean`\> *** ### isGloballyApproved() > **isGloballyApproved**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2526 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](#isoperatorauthorized). #### Parameters ##### p [`IsGloballyApprovedParams`](IsGloballyApprovedParams.md) #### Returns `Promise`\<`boolean`\> *** ### isApprovedForPool() > **isApprovedForPool**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2535 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](#isoperatorauthorized). #### Parameters ##### p [`IsApprovedForPoolParams`](IsApprovedForPoolParams.md) #### Returns `Promise`\<`boolean`\> *** ### getOperatorPermissionsRegistry() > **getOperatorPermissionsRegistry**(`pool`): `Promise`\<`` `0x${string}` `` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2559 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](../classes/NotConfiguredError.md), 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](../classes/NotConfiguredError.md) when neither `wsRpcUrl` nor the chain definition's own WebSocket endpoint exists. It throws [ContractRevertError](../classes/ContractRevertError.md) when the pool rejects the call, and [RpcError](../classes/RpcError.md) 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`](LockedBalance.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2565 Base/quote `owner` has locked in this pool's resting orders. Pair with [getVaultBalance](#getvaultbalance) to account for everything the pool holds for them. #### Parameters ##### p ###### pool `` `0x${string}` `` ###### owner `` `0x${string}` `` #### Returns `Promise`\<[`LockedBalance`](LockedBalance.md)\> *** ### getLockedTokenBreakdown() > **getLockedTokenBreakdown**(`pool`): `Promise`\<[`LockedTokenBreakdown`](LockedTokenBreakdown.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2571 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`](LockedTokenBreakdown.md)\> *** ### convertToQuoteAtPriceCeil() > **convertToQuoteAtPriceCeil**(`p`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2577 Base→quote at a price using the pool's OWN ceil rounding — for interpreting [getLockedTokenBreakdown](#getlockedtokenbreakdown) without reimplementing it. #### Parameters ##### p ###### pool `` `0x${string}` `` ###### baseQuantity `bigint` ###### price `bigint` #### Returns `Promise`\<`bigint`\> *** ### getMarketOnchain() > **getMarketOnchain**(`marketId`): `Promise`\<[`MarketOnchain`](MarketOnchain.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2590 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`](MarketOnchain.md)\> *** ### getPoolCreator() > **getPoolCreator**(`pool`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2598 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:2606 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`](PoolBindingRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2615 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`](PoolBindingRecord.md)[]\> *** ### getPool() > **getPool**(`address`): `Promise`\<[`IndexedPool`](IndexedPool.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2622 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`](IndexedPool.md) \| `null`\> *** ### getErc20Balance() > **getErc20Balance**(`token`, `account`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2628 ERC-20 `balanceOf(account)`, raw units. For outcome positions use [getOutcomeBalance](#getoutcomebalance) (ERC-6909), not this. #### Parameters ##### token `` `0x${string}` `` ##### account `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> *** ### getErc20Metadata() > **getErc20Metadata**(`token`): `Promise`\<[`Erc20Metadata`](Erc20Metadata.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2634 ERC-20 `symbol`/`name`/`decimals` in one fan-out — label a token the indexer hasn't denormalized. #### Parameters ##### token `` `0x${string}` `` #### Returns `Promise`\<[`Erc20Metadata`](Erc20Metadata.md)\> *** ### getErc20Allowance() > **getErc20Allowance**(`token`, `owner`, `spender`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2640 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:2647 ERC-6909 `balanceOf(account, id)` on the outcome-token singleton, raw units. `p.outcomeToken` is the singleton (from [getMarketOnchain](#getmarketonchain)); `p.id` is the market's `yesId`/`noId`. #### Parameters ##### p [`GetOutcomeBalanceParams`](GetOutcomeBalanceParams.md) #### Returns `Promise`\<`bigint`\> *** ### getBalances() > **getBalances**(`tokens`, `account`): `Promise`\<`bigint`[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2657 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`](BalanceQuery.md)[] ##### account `` `0x${string}` `` #### Returns `Promise`\<`bigint`[]\> *** ### getStopOrderSomiPayment() > **getStopOrderSomiPayment**(`registry`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2663 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:2669 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:2672 A user's raw per-builder approval cap on a pool (pool bps×1000; 0 = none). #### Parameters ##### ref [`BuilderApprovalRef`](BuilderApprovalRef.md) #### Returns `Promise`\<`bigint`\> *** ### getEffectiveBuilderApproval() > **getEffectiveBuilderApproval**(`ref`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2679 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 [`BuilderApprovalRef`](BuilderApprovalRef.md) #### Returns `Promise`\<`bigint`\> *** ### getContractMeta() > **getContractMeta**(`address`, `opts?`): `Promise`\<[`ContractMeta`](ContractMeta.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2685 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`](ContractMeta.md)\> *** ### getNativeBalance() > **getNativeBalance**(`address`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2688 Native (SOMI/STT) balance, raw wei. #### Parameters ##### address `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> *** ### getTransactionSummary() > **getTransactionSummary**(`hash`): `Promise`\<[`TransactionSummary`](TransactionSummary.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2700 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`](TransactionSummary.md) \| `null`\> #### Throws [RpcError](../classes/RpcError.md) The chain read did not complete. *** ### createNetworkTape() > **createNetworkTape**(`opts?`): [`NetworkTape`](../classes/NetworkTape.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2709 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? [`NetworkTapeOptions`](NetworkTapeOptions.md) #### Returns [`NetworkTape`](../classes/NetworkTape.md) *** ### getHeadBlock() > **getHeadBlock**(): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2712 Latest block number as the RPC sees it. #### Returns `Promise`\<`number`\> *** ### getSystemInfo() > **getSystemInfo**(): `Promise`\<[`SystemInfo`](SystemInfo.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2724 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`](SystemInfo.md)\> #### Throws [RpcError](../classes/RpcError.md) A chain read did not complete. #### Throws [ContractRevertError](../classes/ContractRevertError.md) A configured contract rejected its read (usually an ABI mismatch). *** ### listOperators() > **listOperators**(`opts?`): `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2735 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`](../type-aliases/OperatorFilter.md) & `object` #### Returns `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md)[]\> *** ### countOperators() > **countOperators**(`opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2745 Server-side COUNT of operators matching a filter (for directory pagination). Needs the privileged `_aggregate` role (server-only), like [countBinaryMarkets](#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? [`OperatorFilter`](../type-aliases/OperatorFilter.md) #### Returns `Promise`\<`number`\> *** ### getOperator() > **getOperator**(`operatorId`): `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2747 One operator by id, or null if never registered. Indexer read. #### Parameters ##### operatorId `number` #### Returns `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md) \| `null`\> *** ### listVenues() > **listVenues**(`opts?`): `Promise`\<[`IndexedVenue`](../type-aliases/IndexedVenue.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2752 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`](../type-aliases/IndexedVenue.md)[]\> *** ### countVenues() > **countVenues**(`opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2767 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](#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`](../type-aliases/IndexedVenue.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2769 One venue by its opaque bytes32 id, or null. Indexer read. #### Parameters ##### venueId `string` #### Returns `Promise`\<[`IndexedVenue`](../type-aliases/IndexedVenue.md) \| `null`\> *** ### encodeBinaryVenueFeeParams() > **encodeBinaryVenueFeeParams**(`vp`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2776 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 [`BinaryVenueParams`](BinaryVenueParams.md) #### Returns `Promise`\<`` `0x${string}` ``\> *** ### getMaxVenueFeeBps() > **getMaxVenueFeeBps**(): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2781 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`](../type-aliases/IndexedMarketCreator.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2795 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`](../type-aliases/MarketCreatorFilter.md) & `object` #### Returns `Promise`\<[`IndexedMarketCreator`](../type-aliases/IndexedMarketCreator.md)[]\> *** ### getMarketCreator() > **getMarketCreator**(`creator`): `Promise`\<[`IndexedMarketCreator`](../type-aliases/IndexedMarketCreator.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2797 One MarketCreator by address (with its series), or null. Indexer read. #### Parameters ##### creator `string` #### Returns `Promise`\<[`IndexedMarketCreator`](../type-aliases/IndexedMarketCreator.md) \| `null`\> *** ### listOracleAdapters() > **listOracleAdapters**(`opts?`): `Promise`\<[`IndexedOracleAdapter`](../type-aliases/IndexedOracleAdapter.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2804 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`](../type-aliases/IndexedOracleAdapter.md)[]\> *** ### getOracleAdapter() > **getOracleAdapter**(`adapter`): `Promise`\<[`IndexedOracleAdapter`](../type-aliases/IndexedOracleAdapter.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2811 One oracle adapter by address, or null. Indexer read. #### Parameters ##### adapter `string` #### Returns `Promise`\<[`IndexedOracleAdapter`](../type-aliases/IndexedOracleAdapter.md) \| `null`\> *** ### listSeries() > **listSeries**(`opts?`): `Promise`\<[`IndexedSeries`](../type-aliases/IndexedSeries.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2813 List series, creation-order, optionally scoped to one creator. Indexer read. #### Parameters ##### opts? ###### creator? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`IndexedSeries`](../type-aliases/IndexedSeries.md)[]\> *** ### getSeries() > **getSeries**(`creator`, `seriesId`): `Promise`\<[`IndexedSeries`](../type-aliases/IndexedSeries.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2820 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`](../type-aliases/IndexedSeries.md) \| `null`\> *** ### getSchedulingCost() > **getSchedulingCost**(`def`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2836 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 [`QuestionDefinitionInput`](QuestionDefinitionInput.md) #### Returns `Promise`\<`bigint`\> *** ### earmarkedOf() > **earmarkedOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2841 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:2846 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:2851 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:2856 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:2863 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:2868 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:2873 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:2880 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 [`QuestionDefinitionInput`](QuestionDefinitionInput.md) #### Returns `Promise`\<`bigint`\> *** ### getOracleQuestion() > **getOracleQuestion**(`oracleQuestionId`): `Promise`\<[`OracleQuestionRecord`](../type-aliases/OracleQuestionRecord.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2885 One hub-scheduled oracle question (dedup key, scheduler, bind count) by its oracleQuestionId, or null. Indexer read. #### Parameters ##### oracleQuestionId `string` #### Returns `Promise`\<[`OracleQuestionRecord`](../type-aliases/OracleQuestionRecord.md) \| `null`\> *** ### listOracleQuestions() > **listOracleQuestions**(`opts?`): `Promise`\<[`OracleQuestionRecord`](../type-aliases/OracleQuestionRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2890 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`](../type-aliases/OracleQuestionRecord.md)[]\> *** ### getOperatorHubAccount() > **getOperatorHubAccount**(`operatorId`): `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2900 One operator's hub account (earmarked / credit / outstanding) by operatorId, or null. Indexer read. #### Parameters ##### operatorId `string` \| `number` #### Returns `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md) \| `null`\> *** ### listOperatorHubAccounts() > **listOperatorHubAccounts**(`opts?`): `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2905 Operator hub-account records, most-recently-updated first, paginated. Indexer read. #### Parameters ##### opts? ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md)[]\> *** ### listOracleBinds() > **listOracleBinds**(`opts?`): `Promise`\<[`OracleBindRecord`](../type-aliases/OracleBindRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2911 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`](../type-aliases/OracleBindRecord.md)[]\> *** ### listOracleCallbacks() > **listOracleCallbacks**(`opts?`): `Promise`\<[`OracleCallbackRecord`](../type-aliases/OracleCallbackRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2923 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`](../type-aliases/OracleCallbackRecord.md)[]\> *** ### createTrader() > **createTrader**(`traderConfig`): [`Trader`](Trader.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2937 Build a [Trader](Trader.md) 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. #### Parameters ##### traderConfig [`TraderConfig`](TraderConfig.md) #### Returns [`Trader`](Trader.md) *** ### createOperatorAdmin() > **createOperatorAdmin**(`config`): [`OperatorAdmin`](OperatorAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2944 Build an [OperatorAdmin](OperatorAdmin.md) bound to a signer — registers/updates operators and creates/updates venues on MarketsCore. Same signer doctrine as [createTrader](#createtrader) (privateKey/local account, or a browser walletClient). #### Parameters ##### config [`OperatorAdminConfig`](OperatorAdminConfig.md) #### Returns [`OperatorAdmin`](OperatorAdmin.md) *** ### createOracleHubAdmin() > **createOracleHubAdmin**(`config`): [`OracleHubAdmin`](OracleHubAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2955 Build an [OracleHubAdmin](OracleHubAdmin.md) 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](#createoperatoradmin). Needs `config.addresses.oracleHub`. #### Parameters ##### config [`OracleHubAdminConfig`](OracleHubAdminConfig.md) #### Returns [`OracleHubAdmin`](OracleHubAdmin.md) *** ### createGovernanceAdmin() > **createGovernanceAdmin**(`config`): [`GovernanceAdmin`](GovernanceAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2963 Build a [GovernanceAdmin](GovernanceAdmin.md) 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](GovernanceAdmin.md#ismoduleowner). #### Parameters ##### config [`OracleHubAdminConfig`](OracleHubAdminConfig.md) #### Returns [`GovernanceAdmin`](GovernanceAdmin.md) *** ### createMarketCreatorAdmin() > **createMarketCreatorAdmin**(`config`): [`MarketCreatorAdmin`](MarketCreatorAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2970 Build a [MarketCreatorAdmin](MarketCreatorAdmin.md) 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](#createoperatoradmin). #### Parameters ##### config [`OracleHubAdminConfig`](OracleHubAdminConfig.md) #### Returns [`MarketCreatorAdmin`](MarketCreatorAdmin.md) --- # /docs/typescript/api/index/interfaces/SomniaMarketsClientWithObservations [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientWithObservations # Interface: SomniaMarketsClientWithObservations Defined in: packages/sdk/src/somniaMarketsClient.ts:2974 Concrete configured client with opt-in data observations. Existing client implementations need not provide these additions. ## Extends - [`SomniaMarketsClient`](SomniaMarketsClient.md) ## Properties ### config > `readonly` **config**: [`ClientConfig`](ClientConfig.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:265 The config this client was built with. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`config`](SomniaMarketsClient.md#config) *** ### lend > `readonly` **lend**: [`SomniaLendClient`](SomniaLendClient.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:311 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. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`lend`](SomniaMarketsClient.md#lend) ## Methods ### getViemClient() > **getViemClient**(): `object` Defined in: packages/sdk/src/somniaMarketsClient.ts:298 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 `PublicClient` for 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](../classes/ContractRevertError.md) 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](../classes/NotConfiguredError.md) on a client built without `wsRpcUrl`. #### Returns `object` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getViemClient`](SomniaMarketsClient.md#getviemclient) *** ### watchMarket() > **watchMarket**(`pool`): `Promise`\<[`WatchHandle`](WatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:337 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. #### Parameters ##### pool `string` #### Returns `Promise`\<[`WatchHandle`](WatchHandle.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`watchMarket`](SomniaMarketsClient.md#watchmarket) *** ### watchMarkets() > **watchMarkets**(`opts?`): `Promise`\<[`WatchHandle`](WatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:349 Watch every market the indexer currently knows — the whole-protocol tail for list views and multi-market bots. Prefer [watchMarket](SomniaMarketsClient.md#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 (requires `config.addresses.marketCreator`). Off by default. #### Parameters ##### opts? ###### discover? `boolean` #### Returns `Promise`\<[`WatchHandle`](WatchHandle.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`watchMarkets`](SomniaMarketsClient.md#watchmarkets) *** ### watchUser() > **watchUser**(`user`): `Promise`\<[`WatchHandle`](WatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:360 Hydrate one account's order/fill **history** (one indexer fetch) so [getLiveUserFills](SomniaMarketsClient.md#getliveuserfills) / [getLiveUserOrders](SomniaMarketsClient.md#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](SomniaMarketsClient.md#watchmarket) / [watchMarkets](SomniaMarketsClient.md#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`](WatchHandle.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`watchUser`](SomniaMarketsClient.md#watchuser) *** ### getWatchStatus() > **getWatchStatus**(`pool`): [`WatchStatus`](../type-aliases/WatchStatus.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:368 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 [`WatchStatus`](../type-aliases/WatchStatus.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getWatchStatus`](SomniaMarketsClient.md#getwatchstatus) *** ### stopLive() > **stopLive**(): `void` Defined in: packages/sdk/src/somniaMarketsClient.ts:382 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*` 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` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`stopLive`](SomniaMarketsClient.md#stoplive) *** ### subscribeLive() > **subscribeLive**(`listener`): () => `void` Defined in: packages/sdk/src/somniaMarketsClient.ts:394 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` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`subscribeLive`](SomniaMarketsClient.md#subscribelive) *** ### getLiveStatus() > **getLiveStatus**(): [`TailStatus`](TailStatus.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:402 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](SomniaMarketsClient.md#getwatchstatus). #### Returns [`TailStatus`](TailStatus.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveStatus`](SomniaMarketsClient.md#getlivestatus) *** ### isTailing() > **isTailing**(): `boolean` Defined in: packages/sdk/src/somniaMarketsClient.ts:405 True once at least one watch is live (`mode === "tailing"`). #### Returns `boolean` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`isTailing`](SomniaMarketsClient.md#istailing) *** ### getLiveMarkets() > **getLiveMarkets**(): [`Market`](../type-aliases/Market.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:413 Every market the store knows (spot + binary, as the discriminated [Market](../type-aliases/Market.md) union) — markets hydrated by any watch, past or present (market rows are kept as metadata after a watch is released). Synchronous, memoized. #### Returns [`Market`](../type-aliases/Market.md)[] #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveMarkets`](SomniaMarketsClient.md#getlivemarkets) *** ### getLiveMarketByPool() > **getLiveMarketByPool**(`pool`): [`Market`](../type-aliases/Market.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:416 One market by its pool address (either kind), or null if unknown. #### Parameters ##### pool `string` #### Returns [`Market`](../type-aliases/Market.md) \| `null` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveMarketByPool`](SomniaMarketsClient.md#getlivemarketbypool) *** ### getLiveMarketByAddress() > **getLiveMarketByAddress**(`marketAddress`): [`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:422 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`](../type-aliases/BinaryMarket.md) \| `null` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveMarketByAddress`](SomniaMarketsClient.md#getlivemarketbyaddress) *** ### getLiveFills() > **getLiveFills**(`pool`, `opts?`): [`LiveFill`](LiveFill.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:432 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`](LiveFill.md)[] #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveFills`](SomniaMarketsClient.md#getlivefills) *** ### getLiveFundingUpdates() > **getLiveFundingUpdates**(`pool`, `opts?`): [`LiveFundingUpdate`](LiveFundingUpdate.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:450 Funding settlements the live tail has seen for a perp pool, OLDEST FIRST. The tail's counterpart to [listFundingRateHistory](SomniaMarketsClient.md#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 [`LiveFundingUpdate`](LiveFundingUpdate.md)[] #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveFundingUpdates`](SomniaMarketsClient.md#getlivefundingupdates) *** ### getLiveUserFills() > **getLiveUserFills**(`pool`, `user`, `opts?`): [`LiveFill`](LiveFill.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:460 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`](LiveFill.md)[] #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveUserFills`](SomniaMarketsClient.md#getliveuserfills) *** ### getLiveUserOrders() > **getLiveUserOrders**(`pool`, `user`, `opts?`): [`LiveOrder`](LiveOrder.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:472 `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](SomniaMarketsClient.md#watchuser) plus everything witnessed live on watched markets. **Details** - `opts.limit`: Max rows (default 100). #### Parameters ##### pool `string` ##### user `string` ##### opts? ###### limit? `number` #### Returns [`LiveOrder`](LiveOrder.md)[] #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveUserOrders`](SomniaMarketsClient.md#getliveuserorders) *** ### getLiveBinaryOrderBook() > **getLiveBinaryOrderBook**(`pool`, `opts?`): [`BinaryOrderBook`](BinaryOrderBook.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:486 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 [`BinaryOrderBook`](BinaryOrderBook.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveBinaryOrderBook`](SomniaMarketsClient.md#getlivebinaryorderbook) *** ### getLiveBinaryOrderBookByMarket() > **getLiveBinaryOrderBookByMarket**(`marketId`, `opts?`): [`BinaryOrderBook`](BinaryOrderBook.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:503 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](SomniaMarketsClient.md#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 [`BinaryOrderBook`](BinaryOrderBook.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveBinaryOrderBookByMarket`](SomniaMarketsClient.md#getlivebinaryorderbookbymarket) *** ### getLiveSpotOrderBook() > **getLiveSpotOrderBook**(`pool`, `opts?`): [`SpotOrderBook`](SpotOrderBook.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:513 The locally-materialized resting book of a **spot** pool (`bids`/`asks`, best price first) — the zero-round-trip mirror of [getSpotOrderBook](SomniaMarketsClient.md#getspotorderbook). **Details** - `opts.depth`: Price levels per side (default 12). #### Parameters ##### pool `string` ##### opts? ###### depth? `number` #### Returns [`SpotOrderBook`](SpotOrderBook.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiveSpotOrderBook`](SomniaMarketsClient.md#getlivespotorderbook) *** ### quoteBinaryOrder() > **quoteBinaryOrder**(`params`): [`BinaryOrderQuote`](BinaryOrderQuote.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:535 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 [`BinarySide`](../type-aliases/BinarySide.md) ###### quantity `bigint` ###### depth? `number` #### Returns [`BinaryOrderQuote`](BinaryOrderQuote.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`quoteBinaryOrder`](SomniaMarketsClient.md#quotebinaryorder) *** ### getBinaryBookParams() > **getBinaryBookParams**(`pool`): `Promise`\<[`BinaryBookParams`](BinaryBookParams.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:550 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](SomniaMarketsClient.md#quotebinarystake) and [quoteBinarySell](SomniaMarketsClient.md#quotebinarysell) read it through this cache. #### Parameters ##### pool `string` #### Returns `Promise`\<[`BinaryBookParams`](BinaryBookParams.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBinaryBookParams`](SomniaMarketsClient.md#getbinarybookparams) *** ### getClosingPrice() > **getClosingPrice**(`pool`): `Promise`\<[`ClosingPriceState`](ClosingPriceState.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:569 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](Trader.md#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`](ClosingPriceState.md) \| `null`\> #### Throws [RpcError](../classes/RpcError.md) The chain read did not complete. #### Throws [ContractRevertError](../classes/ContractRevertError.md) The pool declares `closingPrice()` and rejected the call. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getClosingPrice`](SomniaMarketsClient.md#getclosingprice) *** ### quoteBinaryStake() > **quoteBinaryStake**(`params`): `Promise`\<[`BinaryStakeQuote`](BinaryStakeQuote.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:595 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](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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 [`BinaryBuySide`](../type-aliases/BinaryBuySide.md) ###### stake `bigint` ###### depth? `number` ###### slippageBps? `bigint` ###### slippageMinTicks? `bigint` #### Returns `Promise`\<[`BinaryStakeQuote`](BinaryStakeQuote.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`quoteBinaryStake`](SomniaMarketsClient.md#quotebinarystake) *** ### quoteBinarySell() > **quoteBinarySell**(`params`): `Promise`\<[`BinarySellQuote`](BinarySellQuote.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:622 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](SomniaMarketsClient.md#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 [`BinarySellSide`](../type-aliases/BinarySellSide.md) ###### quantity `bigint` ###### depth? `number` ###### slippageBps? `bigint` ###### slippageMinTicks? `bigint` #### Returns `Promise`\<[`BinarySellQuote`](BinarySellQuote.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`quoteBinarySell`](SomniaMarketsClient.md#quotebinarysell) *** ### getMarketStats24h() > **getMarketStats24h**(`target`): `Promise`\<[`MarketStats24h`](MarketStats24h.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:638 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`](MarketStats24h.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketStats24h`](SomniaMarketsClient.md#getmarketstats24h) *** ### getBinaryPositionPnL() > **getBinaryPositionPnL**(`account`, `marketId`): `Promise`\<[`BinaryPositionPnL`](BinaryPositionPnL.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:667 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](BinaryPositionPnL.md) 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](../classes/InvalidInputError.md) - no binary market with that id. - Throws [IndexerError](../classes/IndexerError.md) - a fills, actions or balances read did not complete. - Throws [RpcError](../classes/RpcError.md) - the top-of-book `eth_call` did not complete (only with a chain client configured; a failed read is never marked on `lastPrice` as if it had succeeded). - Throws [ContractRevertError](../classes/ContractRevertError.md) - the pool rejected the top-of-book read. #### Parameters ##### account `string` ##### marketId `string` #### Returns `Promise`\<[`BinaryPositionPnL`](BinaryPositionPnL.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBinaryPositionPnL`](SomniaMarketsClient.md#getbinarypositionpnl) *** ### getOpenPositionsWithPnL() > **getOpenPositionsWithPnL**(`account`): `Promise`\<[`OpenPositionPnL`](../type-aliases/OpenPositionPnL.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:698 PnL for ALL of an account's open binary positions in one call — the batched, positions-list companion to [getBinaryPositionPnL](SomniaMarketsClient.md#getbinarypositionpnl). Each entry is a [OpenPositionPnL](../type-aliases/OpenPositionPnL.md): 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](../classes/IndexerError.md) when the positions, fills, router actions, or top-of-book request does not complete. - Throws [InvalidInputError](../classes/InvalidInputError.md) 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`\<[`OpenPositionPnL`](../type-aliases/OpenPositionPnL.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOpenPositionsWithPnL`](SomniaMarketsClient.md#getopenpositionswithpnl) *** ### getClaimable() > **getClaimable**(`account`): `Promise`\<[`ClaimablePosition`](ClaimablePosition.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:718 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](../classes/IndexerError.md) when the portfolio or settlement-fee request does not complete. - Throws [InvalidInputError](../classes/InvalidInputError.md) 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`](ClaimablePosition.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getClaimable`](SomniaMarketsClient.md#getclaimable) *** ### watchPrice() > **watchPrice**(`asset`): `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:736 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](SomniaMarketsClient.md#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` to be set; rejects (and releases) otherwise. #### Parameters ##### asset `string` #### Returns `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`watchPrice`](SomniaMarketsClient.md#watchprice) *** ### watchPrices() > **watchPrices**(`assets`): `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:743 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](SomniaMarketsClient.md#watchprice) calls. #### Parameters ##### assets `string`[] #### Returns `Promise`\<[`PriceWatchHandle`](PriceWatchHandle.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`watchPrices`](SomniaMarketsClient.md#watchprices) *** ### getPriceStatus() > **getPriceStatus**(`asset`): [`PriceFeedStatus`](../type-aliases/PriceFeedStatus.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:751 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](../type-aliases/PriceFeedStatus.md). #### Parameters ##### asset `string` #### Returns [`PriceFeedStatus`](../type-aliases/PriceFeedStatus.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPriceStatus`](SomniaMarketsClient.md#getpricestatus) *** ### subscribePrices() > **subscribePrices**(`listener`): () => `void` Defined in: packages/sdk/src/somniaMarketsClient.ts:763 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](SomniaMarketsClient.md#subscribelive) (prices are a separate store/service). **Details** - Returns: An unsubscribe function. #### Parameters ##### listener () => `void` #### Returns () => `void` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`subscribePrices`](SomniaMarketsClient.md#subscribeprices) *** ### getLivePrice() > **getLivePrice**(`asset`): [`LivePrice`](LivePrice.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:769 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`](LivePrice.md) \| `null` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLivePrice`](SomniaMarketsClient.md#getliveprice) *** ### getLivePrices() > **getLivePrices**(`assets`): ([`LivePrice`](LivePrice.md) \| `null`)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:775 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`](LivePrice.md) \| `null`)[] #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLivePrices`](SomniaMarketsClient.md#getliveprices) *** ### getLivePriceTicks() > **getLivePriceTicks**(`asset`, `opts?`): [`PricePoint`](PricePoint.md)[] Defined in: packages/sdk/src/somniaMarketsClient.ts:784 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 [`PricePoint`](PricePoint.md)[] #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLivePriceTicks`](SomniaMarketsClient.md#getlivepriceticks) *** ### getLivePriceFeedInfo() > **getLivePriceFeedInfo**(`asset`): [`PriceFeedInfo`](PriceFeedInfo.md) \| `null` Defined in: packages/sdk/src/somniaMarketsClient.ts:790 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](SomniaMarketsClient.md#fetchpricefeedinfo). #### Parameters ##### asset `string` #### Returns [`PriceFeedInfo`](PriceFeedInfo.md) \| `null` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLivePriceFeedInfo`](SomniaMarketsClient.md#getlivepricefeedinfo) *** ### fetchPriceFeedInfo() > **fetchPriceFeedInfo**(`asset`): `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:793 One-shot feed metadata + current price (one HTTP round-trip; no watch needed). #### Parameters ##### asset `string` #### Returns `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`fetchPriceFeedInfo`](SomniaMarketsClient.md#fetchpricefeedinfo) *** ### fetchPrice() > **fetchPrice**(`asset`): `Promise`\<[`LivePrice`](LivePrice.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:799 One-shot current price (one HTTP round-trip), or null if the feed has no observations yet. #### Parameters ##### asset `string` #### Returns `Promise`\<[`LivePrice`](LivePrice.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`fetchPrice`](SomniaMarketsClient.md#fetchprice) *** ### fetchPrices() > **fetchPrices**(`assets?`): `Promise`\<[`LivePrice`](LivePrice.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:806 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`](LivePrice.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`fetchPrices`](SomniaMarketsClient.md#fetchprices) *** ### listPriceFeeds() > **listPriceFeeds**(): `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:812 One-shot feed catalog — metadata + current price for every tracked asset (discovery). One HTTP round-trip; no watch needed. #### Returns `Promise`\<[`PriceFeedInfo`](PriceFeedInfo.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPriceFeeds`](SomniaMarketsClient.md#listpricefeeds) *** ### fetchPriceHistory() > **fetchPriceHistory**(`asset`, `opts?`): `Promise`\<[`PricePoint`](PricePoint.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:818 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`](PricePoint.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`fetchPriceHistory`](SomniaMarketsClient.md#fetchpricehistory) *** ### fetchPriceCandles() > **fetchPriceCandles**(`asset`, `resolution`, `opts?`): `Promise`\<[`PriceCandle`](PriceCandle.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:824 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 [`PriceCandleResolution`](../type-aliases/PriceCandleResolution.md) ##### opts? ###### limit? `number` ###### from? `number` ###### to? `number` #### Returns `Promise`\<[`PriceCandle`](PriceCandle.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`fetchPriceCandles`](SomniaMarketsClient.md#fetchpricecandles) *** ### listMarkets() > **listMarkets**(`opts?`): `Promise`\<[`Market`](../type-aliases/Market.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:844 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? [`MarketType`](../type-aliases/MarketType.md) ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`Market`](../type-aliases/Market.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listMarkets`](SomniaMarketsClient.md#listmarkets) *** ### listRegistryMarkets() > **listRegistryMarkets**(): `Promise`\<[`Market`](../type-aliases/Market.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:852 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`](../type-aliases/Market.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listRegistryMarkets`](SomniaMarketsClient.md#listregistrymarkets) *** ### listRegistryMarketsChecked() > **listRegistryMarketsChecked**(): `Promise`\<[`RegistrySweep`](RegistrySweep.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:866 [listRegistryMarkets](SomniaMarketsClient.md#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`](RegistrySweep.md)\> #### Throws [IndexerError](../classes/IndexerError.md) The indexed read did not complete. The complete union is [SomniaMarketsClientListRegistryMarketsCheckedError](../type-aliases/SomniaMarketsClientListRegistryMarketsCheckedError.md). #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listRegistryMarketsChecked`](SomniaMarketsClient.md#listregistrymarketschecked) *** ### countMarkets() > **countMarkets**(`opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:874 Server-side COUNT of markets (optionally one type) for pagination totals. Needs the privileged `_aggregate` role (server-only), like [countBinaryMarkets](SomniaMarketsClient.md#countbinarymarkets). Without it the count is a row scan capped at 10,000 and a larger total reads as exactly `10000` — [countMarketsBounded](SomniaMarketsClient.md#countmarketsbounded) reports whether it did. #### Parameters ##### opts? ###### marketType? [`MarketType`](../type-aliases/MarketType.md) #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countMarkets`](SomniaMarketsClient.md#countmarkets) *** ### countMarketsBounded() > **countMarketsBounded**(`opts?`): `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:880 [countMarkets](SomniaMarketsClient.md#countmarkets) with the truncation reported: `truncated: true` means the public-role scan hit its cap and `count` is a lower bound. #### Parameters ##### opts? ###### marketType? [`MarketType`](../type-aliases/MarketType.md) #### Returns `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countMarketsBounded`](SomniaMarketsClient.md#countmarketsbounded) *** ### getMarket() > **getMarket**(`id`): `Promise`\<[`Market`](../type-aliases/Market.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:886 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`](../type-aliases/Market.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarket`](SomniaMarketsClient.md#getmarket) *** ### listBinaryMarkets() > **listBinaryMarkets**(`opts?`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:889 [listMarkets](SomniaMarketsClient.md#listmarkets) pre-narrowed to binary markets. #### Parameters ##### opts? [`BinaryMarketFilter`](../type-aliases/BinaryMarketFilter.md) & `object` #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listBinaryMarkets`](SomniaMarketsClient.md#listbinarymarkets) *** ### listLiveBinaryMarkets() > **listLiveBinaryMarkets**(`filter?`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:897 Currently-live binary markets (`expiry > now`), soonest-to-expire first. Call with no argument for all live markets, or pass a [LiveBinaryMarketsFilter](../type-aliases/LiveBinaryMarketsFilter.md) to narrow by `operatorId` / `venueId` / `asset` / `intervalSec` / `status` (e.g. `{ venueId: "0x4d41494e" }`). #### Parameters ##### filter? [`LiveBinaryMarketsFilter`](../type-aliases/LiveBinaryMarketsFilter.md) #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listLiveBinaryMarkets`](SomniaMarketsClient.md#listlivebinarymarkets) *** ### listBinaryVenueIds() > **listBinaryVenueIds**(): `Promise`\<`object`[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:904 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`[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listBinaryVenueIds`](SomniaMarketsClient.md#listbinaryvenueids) *** ### listBinaryAssets() > **listBinaryAssets**(): `Promise`\<`string`[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:917 Distinct asset symbols across binary markets — the cheap server-side source for an asset filter's options. #### Returns `Promise`\<`string`[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listBinaryAssets`](SomniaMarketsClient.md#listbinaryassets) *** ### countBinaryMarkets() > **countBinaryMarkets**(`opts`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:925 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](SomniaMarketsClient.md#countbinarymarketsbounded) says which. #### Parameters ##### opts [`BinaryMarketFilter`](../type-aliases/BinaryMarketFilter.md) & `object` #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countBinaryMarkets`](SomniaMarketsClient.md#countbinarymarkets) *** ### countBinaryMarketsBounded() > **countBinaryMarketsBounded**(`opts`): `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:932 [countBinaryMarkets](SomniaMarketsClient.md#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`](../type-aliases/BinaryMarketFilter.md) & `object` #### Returns `Promise`\<[`CountResult`](../type-aliases/CountResult.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countBinaryMarketsBounded`](SomniaMarketsClient.md#countbinarymarketsbounded) *** ### listPastBinaryMarkets() > **listPastBinaryMarkets**(`opts?`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:940 Past binary markets (`expiry ≤ now`), most-recently-expired first, paginated with `limit` + `offset`. #### Parameters ##### opts? [`PastBinaryMarketsOptions`](../type-aliases/PastBinaryMarketsOptions.md) #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPastBinaryMarkets`](SomniaMarketsClient.md#listpastbinarymarkets) *** ### getBinaryMarket() > **getBinaryMarket**(`id`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:946 One binary market by bytes32 marketId, or null (also null if the id resolves to a spot market). #### Parameters ##### id `string` #### Returns `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBinaryMarket`](SomniaMarketsClient.md#getbinarymarket) *** ### getBinaryMarketByAddress() > **getBinaryMarketByAddress**(`marketAddress`): `Promise`\<[`BinaryMarket`](../type-aliases/BinaryMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:952 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`](../type-aliases/BinaryMarket.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBinaryMarketByAddress`](SomniaMarketsClient.md#getbinarymarketbyaddress) *** ### getMarketFees() > **getMarketFees**(`id`): `Promise`\<[`MarketFees`](../type-aliases/MarketFees.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:957 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`](../type-aliases/MarketFees.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketFees`](SomniaMarketsClient.md#getmarketfees) *** ### listSpotMarkets() > **listSpotMarkets**(`opts?`): `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:963 [listMarkets](SomniaMarketsClient.md#listmarkets) pre-narrowed to spot markets. Pass a [SpotMarketFilter](../type-aliases/SpotMarketFilter.md) (+ `limit`) to narrow by base/quote symbol. #### Parameters ##### opts? [`SpotMarketFilter`](../type-aliases/SpotMarketFilter.md) & `object` #### Returns `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listSpotMarkets`](SomniaMarketsClient.md#listspotmarkets) *** ### getSpotMarket() > **getSpotMarket**(`id`): `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:966 One spot market by pool address, or null (also null if not spot). #### Parameters ##### id `string` #### Returns `Promise`\<[`SpotMarket`](../type-aliases/SpotMarket.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSpotMarket`](SomniaMarketsClient.md#getspotmarket) *** ### getMarketStatusHistory() > **getMarketStatusHistory**(`marketId`): `Promise`\<[`MarketStatusUpdate`](../type-aliases/MarketStatusUpdate.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:972 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`](../type-aliases/MarketStatusUpdate.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketStatusHistory`](SomniaMarketsClient.md#getmarketstatushistory) *** ### listPerpMarkets() > **listPerpMarkets**(`opts?`): `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:978 [listMarkets](SomniaMarketsClient.md#listmarkets) pre-narrowed to perp markets. Pass a [PerpMarketFilter](../type-aliases/PerpMarketFilter.md) (+ `limit`) to narrow by base/quote symbol. #### Parameters ##### opts? [`PerpMarketFilter`](../type-aliases/PerpMarketFilter.md) & `object` #### Returns `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpMarkets`](SomniaMarketsClient.md#listperpmarkets) *** ### getPerpMarket() > **getPerpMarket**(`id`): `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:984 One perp market by pool address, or null (also null if the id resolves to another market kind). #### Parameters ##### id `string` #### Returns `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpMarket`](SomniaMarketsClient.md#getperpmarket) *** ### getCandles() > **getCandles**(`poolAddress`, `intervalSeconds`, `opts?`): `Promise`\<[`Candle`](../type-aliases/Candle.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:996 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`](../type-aliases/Candle.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getCandles`](SomniaMarketsClient.md#getcandles) *** ### getMarketActivity() > **getMarketActivity**(`market`, `opts?`): `Promise`\<[`MarketActivity`](../type-aliases/MarketActivity.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1029 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](../type-aliases/MarketActivity.md)). 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](SomniaMarketsClient.md#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](../type-aliases/MarketActivityOptions.md)). #### Parameters ##### market `string` The market's bytes32 marketId (case-insensitive). On spot and perp this is the pool address. ##### opts? [`MarketActivityOptions`](../type-aliases/MarketActivityOptions.md) #### Returns `Promise`\<[`MarketActivity`](../type-aliases/MarketActivity.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketActivity`](SomniaMarketsClient.md#getmarketactivity) *** ### getTransactionActivity() > **getTransactionActivity**(`txHash`, `opts?`): `Promise`\<[`TransactionActivity`](../type-aliases/TransactionActivity.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1049 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](../type-aliases/TransactionActivity.md)). The read behind a transaction detail view, and the counterpart to [getTradeContext](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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? [`TransactionActivityOptions`](../type-aliases/TransactionActivityOptions.md) #### Returns `Promise`\<[`TransactionActivity`](../type-aliases/TransactionActivity.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getTransactionActivity`](SomniaMarketsClient.md#gettransactionactivity) *** ### getBlockActivity() > **getBlockActivity**(`blockNumber`, `opts?`): `Promise`\<[`BlockActivity`](../type-aliases/BlockActivity.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1072 What the protocol traded in one block, grouped by market — the level above [getTransactionActivity](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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? [`BlockActivityOptions`](../type-aliases/BlockActivityOptions.md) Rows per stream and the offset to page from. #### Returns `Promise`\<[`BlockActivity`](../type-aliases/BlockActivity.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBlockActivity`](SomniaMarketsClient.md#getblockactivity) *** ### getLatestActiveBlock() > **getLatestActiveBlock**(): `Promise`\<\{ `blockNumber`: `bigint`; `timestamp`: `bigint`; \} \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1082 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](SomniaMarketsClient.md#getblockactivity). #### Returns `Promise`\<\{ `blockNumber`: `bigint`; `timestamp`: `bigint`; \} \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLatestActiveBlock`](SomniaMarketsClient.md#getlatestactiveblock) *** ### getAdjacentActiveBlocks() > **getAdjacentActiveBlocks**(`blockNumber`, `opts?`): `Promise`\<\{ `prev`: `bigint` \| `null`; `next`: `bigint` \| `null`; \}\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1097 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](SomniaMarketsClient.md#getblockactivity), and for the same reason resolves that anchor itself. #### Parameters ##### blockNumber `bigint` The block being viewed; excluded from both answers. ##### opts? [`BlockActivityOptions`](../type-aliases/BlockActivityOptions.md) Rows per stream per direction. #### Returns `Promise`\<\{ `prev`: `bigint` \| `null`; `next`: `bigint` \| `null`; \}\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getAdjacentActiveBlocks`](SomniaMarketsClient.md#getadjacentactiveblocks) *** ### getFills() > **getFills**(`pool`, `opts?`): `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1102 #### Parameters ##### pool `string` ##### opts? [`FillsOptions`](../type-aliases/FillsOptions.md) #### Returns `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getFills`](SomniaMarketsClient.md#getfills) *** ### getTradeContext() > **getTradeContext**(`id`): `Promise`\<[`TradeContext`](../type-aliases/TradeContext.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1122 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](../type-aliases/TradeContext.md)). [getFill](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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`](../type-aliases/TradeContext.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getTradeContext`](SomniaMarketsClient.md#gettradecontext) *** ### getUserFills() > **getUserFills**(`account`, `opts?`): `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1134 Fills a user participated in (maker OR taker), newest first — the one-shot indexer counterpart to [getLiveUserFills](SomniaMarketsClient.md#getliveuserfills). Optionally scope to one market and/or pool and/or a `since`/`until` window ([FillsScope](../type-aliases/FillsScope.md)). 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? [`FillsScope`](../type-aliases/FillsScope.md) #### Returns `Promise`\<[`FillRow`](../type-aliases/FillRow.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getUserFills`](SomniaMarketsClient.md#getuserfills) *** ### getUserFillsPage() > **getUserFillsPage**(`account`, `options?`): `Promise`\<[`UserFillsPage`](../type-aliases/UserFillsPage.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1168 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? [`GetUserFillsPageOptions`](../type-aliases/GetUserFillsPageOptions.md) Market/pool and inclusive time filters, bounded limit and cursor. #### Returns `Promise`\<[`UserFillsPage`](../type-aliases/UserFillsPage.md)\> Existing fill rows and the next cursor, or null when this read has no next row. #### Throws [InvalidInputError](../classes/InvalidInputError.md) For invalid input or malformed/foreign cursors. #### Throws [IndexerError](../classes/IndexerError.md) When the read fails or returned position scalars are invalid. #### Example ```ts 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); } ``` #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getUserFillsPage`](SomniaMarketsClient.md#getuserfillspage) *** ### getFill() > **getFill**(`id`): `Promise`\<[`FillDetail`](../type-aliases/FillDetail.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1175 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`](../type-aliases/FillDetail.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getFill`](SomniaMarketsClient.md#getfill) *** ### getOrderFills() > **getOrderFills**(`pool`, `orderId`, `opts?`): `Promise`\<[`OrderFillRow`](../type-aliases/OrderFillRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1181 Every fill one order participated in — either side, newest first. `(pool, orderId)` names exactly one order forever (ids never reuse). #### Parameters ##### pool `string` ##### orderId `string` \| `bigint` ##### opts? ###### limit? `number` #### Returns `Promise`\<[`OrderFillRow`](../type-aliases/OrderFillRow.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOrderFills`](SomniaMarketsClient.md#getorderfills) *** ### getOrder() > **getOrder**(`pool`, `orderId`): `Promise`\<[`OrderDetail`](../type-aliases/OrderDetail.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1188 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](SomniaMarketsClient.md#getorderonchain). #### Parameters ##### pool `string` ##### orderId `string` \| `bigint` #### Returns `Promise`\<[`OrderDetail`](../type-aliases/OrderDetail.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOrder`](SomniaMarketsClient.md#getorder) *** ### listMarketsByPool() > **listMarketsByPool**(`pool`, `opts?`): `Promise`\<[`Market`](../type-aliases/Market.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1195 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](SomniaMarketsClient.md#getmarketbypool). #### Parameters ##### pool `string` ##### opts? ###### limit? `number` #### Returns `Promise`\<[`Market`](../type-aliases/Market.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listMarketsByPool`](SomniaMarketsClient.md#listmarketsbypool) *** ### getOpenOrders() > **getOpenOrders**(`owner`, `opts?`): `Promise`\<[`OpenOrder`](../type-aliases/OpenOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1204 `owner`'s currently-OPEN orders, newest first. Pass [OrdersOptions](../type-aliases/OrdersOptions.md) (minus `status` — always "Open" here) to scope by `pool`/`side` and page. NOTE: this lags the chain — for a trading loop prefer [getLiveUserOrders](SomniaMarketsClient.md#getliveuserorders) (or track the `orderId`s your own `placeOrder` calls return). For non-open history use [getOrders](SomniaMarketsClient.md#getorders). #### Parameters ##### owner `string` ##### opts? `Omit`\<[`OrdersOptions`](../type-aliases/OrdersOptions.md), `"status"`\> #### Returns `Promise`\<[`OpenOrder`](../type-aliases/OpenOrder.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOpenOrders`](SomniaMarketsClient.md#getopenorders) *** ### getOrders() > **getOrders**(`owner`, `opts?`): `Promise`\<[`OrderRow`](../type-aliases/OrderRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1212 `owner`'s orders across ALL statuses (Open/Filled/Cancelled/Expired/Closed), newest first — the order-history counterpart to [getOpenOrders](SomniaMarketsClient.md#getopenorders). Each row carries its lifecycle `status` + fill progress. Filter by `status`/`side`/`pool` and page via [OrdersOptions](../type-aliases/OrdersOptions.md). #### Parameters ##### owner `string` ##### opts? [`OrdersOptions`](../type-aliases/OrdersOptions.md) #### Returns `Promise`\<[`OrderRow`](../type-aliases/OrderRow.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOrders`](SomniaMarketsClient.md#getorders) *** ### listSweepableOrders() > **listSweepableOrders**(`opts?`): `Promise`\<[`SweepableOrder`](../type-aliases/SweepableOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1233 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? [`MarketType`](../type-aliases/MarketType.md) ###### owner? `string` ###### asOfSec? `number` \| `bigint` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`SweepableOrder`](../type-aliases/SweepableOrder.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listSweepableOrders`](SomniaMarketsClient.md#listsweepableorders) *** ### getOutcomeBalances() > **getOutcomeBalances**(`account`, `marketAddress`): `Promise`\<[`OutcomeBalances`](../type-aliases/OutcomeBalances.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1247 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](SomniaMarketsClient.md#geterc20balance) instead. #### Parameters ##### account `string` ##### marketAddress `string` #### Returns `Promise`\<[`OutcomeBalances`](../type-aliases/OutcomeBalances.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOutcomeBalances`](SomniaMarketsClient.md#getoutcomebalances) *** ### getPortfolio() > **getPortfolio**(`account`, `opts?`): `Promise`\<[`Portfolio`](../type-aliases/Portfolio.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1255 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](../type-aliases/PortfolioOptions.md) 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? [`PortfolioOptions`](../type-aliases/PortfolioOptions.md) #### Returns `Promise`\<[`Portfolio`](../type-aliases/Portfolio.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPortfolio`](SomniaMarketsClient.md#getportfolio) *** ### getSpotPortfolio() > **getSpotPortfolio**(`account`, `opts?`): `Promise`\<[`SpotPortfolio`](../type-aliases/SpotPortfolio.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1262 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](../type-aliases/PortfolioOptions.md) to page. Trades default to the last seven days — the bound comes back as `tradesSince`; pass `since` to widen it. #### Parameters ##### account `string` ##### opts? [`PortfolioOptions`](../type-aliases/PortfolioOptions.md) #### Returns `Promise`\<[`SpotPortfolio`](../type-aliases/SpotPortfolio.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSpotPortfolio`](SomniaMarketsClient.md#getspotportfolio) *** ### getSpotStopOrders() > **getSpotStopOrders**(`account`, `opts?`): `Promise`\<[`SpotStopOrder`](../type-aliases/SpotStopOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1269 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? [`StopOrderStatus`](../type-aliases/StopOrderStatus.md) ###### limit? `number` #### Returns `Promise`\<[`SpotStopOrder`](../type-aliases/SpotStopOrder.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSpotStopOrders`](SomniaMarketsClient.md#getspotstoporders) *** ### getPerpPortfolio() > **getPerpPortfolio**(`account`, `opts?`): `Promise`\<[`PerpPortfolio`](../type-aliases/PerpPortfolio.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1280 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](SomniaMarketsClient.md#getperpposition) / [getMarginAccount](SomniaMarketsClient.md#getmarginaccount). Pass [PortfolioOptions](../type-aliases/PortfolioOptions.md) to page. Trades default to the last seven days — the bound comes back as `tradesSince`; pass `since` to widen it. #### Parameters ##### account `string` ##### opts? [`PortfolioOptions`](../type-aliases/PortfolioOptions.md) #### Returns `Promise`\<[`PerpPortfolio`](../type-aliases/PerpPortfolio.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpPortfolio`](SomniaMarketsClient.md#getperpportfolio) *** ### listPerpStopOrders() > **listPerpStopOrders**(`opts?`): `Promise`\<[`PerpStopOrder`](../type-aliases/PerpStopOrder.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1300 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? [`StopOrderStatus`](../type-aliases/StopOrderStatus.md)[] ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`PerpStopOrder`](../type-aliases/PerpStopOrder.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpStopOrders`](SomniaMarketsClient.md#listperpstoporders) *** ### getPerpStopOrder() > **getPerpStopOrder**(`ref`): `Promise`\<[`PerpStopOrderOnChain`](../type-aliases/PerpStopOrderOnChain.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1320 One pending stop read straight from its registry — the chain tier [listPerpStopOrders](SomniaMarketsClient.md#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](../type-aliases/PerpStopOrder.md) 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 ###### registry `` `0x${string}` `` ###### orderId `string` \| `bigint` #### Returns `Promise`\<[`PerpStopOrderOnChain`](../type-aliases/PerpStopOrderOnChain.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpStopOrder`](SomniaMarketsClient.md#getperpstoporder) *** ### getPerpStopOrderSomiPayment() > **getPerpStopOrderSomiPayment**(`registry`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1326 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpStopOrderSomiPayment`](SomniaMarketsClient.md#getperpstopordersomipayment) *** ### getUnclaimedPerpStopSomi() > **getUnclaimedPerpStopSomi**(`ref`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1334 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getUnclaimedPerpStopSomi`](SomniaMarketsClient.md#getunclaimedperpstopsomi) *** ### listPerpOrderHistory() > **listPerpOrderHistory**(`account`, `opts?`): `Promise`\<[`PerpOrderHistoryRow`](../type-aliases/PerpOrderHistoryRow.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1352 An account's FINISHED perp orders, most-recently-ended first — the history tab behind [getPerpPortfolio](SomniaMarketsClient.md#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? [`TerminalOrderStatus`](../type-aliases/TerminalOrderStatus.md)[] ###### orderBy? `"placed"` \| `"ended"` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`PerpOrderHistoryRow`](../type-aliases/PerpOrderHistoryRow.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpOrderHistory`](SomniaMarketsClient.md#listperporderhistory) *** ### getSyncStatus() > **getSyncStatus**(`chainId`): `Promise`\<[`IndexerSyncStatus`](../type-aliases/IndexerSyncStatus.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1369 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`](../type-aliases/IndexerSyncStatus.md) \| `null`\> #### Throws A query variable is invalid. #### Throws The metadata request failed. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSyncStatus`](SomniaMarketsClient.md#getsyncstatus) *** ### getMarketByPool() > **getMarketByPool**(`pool`): `Promise`\<[`Market`](../type-aliases/Market.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1375 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`](../type-aliases/Market.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketByPool`](SomniaMarketsClient.md#getmarketbypool) *** ### countOrders() > **countOrders**(`owner`, `opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1387 Server-side COUNT of `owner`'s orders matching an [OrdersOptions](../type-aliases/OrdersOptions.md) 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](SomniaMarketsClient.md#countmarketsbounded) is the shape to copy. #### Parameters ##### owner `string` ##### opts? [`OrdersOptions`](../type-aliases/OrdersOptions.md) #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countOrders`](SomniaMarketsClient.md#countorders) *** ### countUserFills() > **countUserFills**(`account`, `opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1400 Server-side COUNT of the fills `account` participated in (maker OR taker), optionally scoped by market and/or pool + a `since`/`until` window ([FillsScope](../type-aliases/FillsScope.md)) — 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](SomniaMarketsClient.md#countmarketsbounded) is the shape to copy. #### Parameters ##### account `string` ##### opts? [`FillsScope`](../type-aliases/FillsScope.md) #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countUserFills`](SomniaMarketsClient.md#countuserfills) *** ### getRouterActions() > **getRouterActions**(`account`, `opts?`): `Promise`\<[`RouterActionRecord`](../type-aliases/RouterActionRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1411 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](../type-aliases/RouterActionsOptions.md)). 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? [`RouterActionsOptions`](../type-aliases/RouterActionsOptions.md) #### Returns `Promise`\<[`RouterActionRecord`](../type-aliases/RouterActionRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getRouterActions`](SomniaMarketsClient.md#getrouteractions) *** ### getMarketResolution() > **getMarketResolution**(`marketId`): `Promise`\<\{ `events`: [`MarketResolutionEvent`](../type-aliases/MarketResolutionEvent.md)[]; `reference`: [`MarketReferenceLink`](../type-aliases/MarketReferenceLink.md) \| `null`; `closingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `openingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `oracleAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; \}\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1421 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`](../type-aliases/MarketResolutionEvent.md)[]; `reference`: [`MarketReferenceLink`](../type-aliases/MarketReferenceLink.md) \| `null`; `closingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `openingAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; `oracleAnswer`: [`OracleAnswer`](../type-aliases/OracleAnswer.md) \| `null`; \}\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketResolution`](SomniaMarketsClient.md#getmarketresolution) *** ### getOpeningPrices() > **getOpeningPrices**(`marketIds`): `Promise`\<`Record`\<`string`, `string` \| `null`\>\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1453 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`\>\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOpeningPrices`](SomniaMarketsClient.md#getopeningprices) *** ### getResolutionPrices() > **getResolutionPrices**(`marketIds`): `Promise`\<`Record`\<`string`, `string` \| `null`\>\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1461 Batch RESOLUTION (settlement) prices for many markets in one pair of round-trips — the settlement counterpart to [getOpeningPrices](SomniaMarketsClient.md#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`\>\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getResolutionPrices`](SomniaMarketsClient.md#getresolutionprices) *** ### getOnchainResolutionPrice() > **getOnchainResolutionPrice**(`marketId`): `Promise`\<[`OnchainResolutionPrice`](OnchainResolutionPrice.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1471 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`](OnchainResolutionPrice.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOnchainResolutionPrice`](SomniaMarketsClient.md#getonchainresolutionprice) *** ### getBookTops() > **getBookTops**(`marketIds`): `Promise`\<`Record`\<`string`, [`BookTop`](../type-aliases/BookTop.md)\>\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1481 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](../type-aliases/BookTop.md), whose prices are raw and in each market's own terms; empty-book markets are absent. #### Parameters ##### marketIds `string`[] #### Returns `Promise`\<`Record`\<`string`, [`BookTop`](../type-aliases/BookTop.md)\>\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBookTops`](SomniaMarketsClient.md#getbooktops) *** ### listProtocolFees() > **listProtocolFees**(`opts?`): `Promise`\<[`ProtocolFeeRecord`](../type-aliases/ProtocolFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1488 Realized protocol-fee records, newest first — filter by `recipient` / `market` / `pool` / `payer`, paginate. The per-fill stream behind [getMarketFees](SomniaMarketsClient.md#getmarketfees)'s running total. #### Parameters ##### opts? ###### recipient? `string` ###### market? `string` ###### pool? `string` ###### payer? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`ProtocolFeeRecord`](../type-aliases/ProtocolFeeRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listProtocolFees`](SomniaMarketsClient.md#listprotocolfees) *** ### listBuilderFees() > **listBuilderFees**(`opts?`): `Promise`\<[`BuilderFeeRecord`](../type-aliases/BuilderFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1501 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`](../type-aliases/BuilderFeeRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listBuilderFees`](SomniaMarketsClient.md#listbuilderfees) *** ### listSettlementFees() > **listSettlementFees**(`opts?`): `Promise`\<[`SettlementFeeRecord`](../type-aliases/SettlementFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1513 Realized settlement-fee records, newest first — filter by `market` / `recipient`, paginate. #### Parameters ##### opts? ###### market? `string` ###### recipient? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`SettlementFeeRecord`](../type-aliases/SettlementFeeRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listSettlementFees`](SomniaMarketsClient.md#listsettlementfees) *** ### listBuilderApprovals() > **listBuilderApprovals**(`opts?`): `Promise`\<[`BuilderApproval`](../type-aliases/BuilderApproval.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1525 Builder-approval directory, newest-updated first — filter by `user` and/or `builder`, paginate. The directory complement to the on-chain point read [getBuilderApproval](SomniaMarketsClient.md#getbuilderapproval). #### Parameters ##### opts? ###### user? `string` ###### builder? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`BuilderApproval`](../type-aliases/BuilderApproval.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listBuilderApprovals`](SomniaMarketsClient.md#listbuilderapprovals) *** ### getVaultPayoutFallbacks() > **getVaultPayoutFallbacks**(`owner`, `opts?`): `Promise`\<[`VaultPayoutFallback`](../type-aliases/VaultPayoutFallback.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1537 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](SomniaMarketsClient.md#getvaultbalance). #### Parameters ##### owner `string` ##### opts? ###### token? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`VaultPayoutFallback`](../type-aliases/VaultPayoutFallback.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getVaultPayoutFallbacks`](SomniaMarketsClient.md#getvaultpayoutfallbacks) *** ### getFundingPayments() > **getFundingPayments**(`account`, `opts?`): `Promise`\<[`FundingPayment`](../type-aliases/FundingPayment.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1546 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`](../type-aliases/FundingPayment.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getFundingPayments`](SomniaMarketsClient.md#getfundingpayments) *** ### getMarginEvents() > **getMarginEvents**(`account`, `opts?`): `Promise`\<[`MarginEvent`](../type-aliases/MarginEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1555 An account's margin-account movement history (deposits/withdraws/locks), newest first — paginated. #### Parameters ##### account `string` ##### opts? ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`MarginEvent`](../type-aliases/MarginEvent.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarginEvents`](SomniaMarketsClient.md#getmarginevents) *** ### listLiquidations() > **listLiquidations**(`opts?`): `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1573 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](../type-aliases/LiquidationEvent.md#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? [`ListLiquidationsOptions`](ListLiquidationsOptions.md) #### Returns `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> #### Throws [IndexerError](../classes/IndexerError.md) The indexed read did not complete. The complete union is [SomniaMarketsClientListLiquidationsError](../type-aliases/SomniaMarketsClientListLiquidationsError.md). #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listLiquidations`](SomniaMarketsClient.md#listliquidations) *** ### ~~getLiquidations()~~ > **getLiquidations**(`opts?`): `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1584 Liquidation events, newest first. #### Parameters ##### opts? [`ListLiquidationsOptions`](ListLiquidationsOptions.md) #### Returns `Promise`\<[`LiquidationEvent`](../type-aliases/LiquidationEvent.md)[]\> #### Deprecated Renamed to [listLiquidations](SomniaMarketsClient.md#listliquidations), per SDK-TYPE-006. Forwards verbatim. #### Throws [IndexerError](../classes/IndexerError.md) As [SomniaMarketsClient.listLiquidations](SomniaMarketsClient.md#listliquidations). The union is [SomniaMarketsClientGetLiquidationsError](../type-aliases/SomniaMarketsClientGetLiquidationsError.md). #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiquidations`](SomniaMarketsClient.md#getliquidations) *** ### listFundingRateHistory() > **listFundingRateHistory**(`pool`, `opts?`): `Promise`\<[`FundingRateUpdate`](../type-aliases/FundingRateUpdate.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1598 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`](../type-aliases/FundingRateUpdate.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listFundingRateHistory`](SomniaMarketsClient.md#listfundingratehistory) *** ### listFundingRateCandles() > **listFundingRateCandles**(`pool`, `intervalSeconds`, `opts?`): `Promise`\<[`FundingRateCandle`](../type-aliases/FundingRateCandle.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1620 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`](../type-aliases/FundingRateCandle.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listFundingRateCandles`](SomniaMarketsClient.md#listfundingratecandles) *** ### listPerpFees() > **listPerpFees**(`opts?`): `Promise`\<[`PerpFeeRecord`](../type-aliases/PerpFeeRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1634 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`](../type-aliases/PerpFeeRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpFees`](SomniaMarketsClient.md#listperpfees) *** ### listPerpOrderRejections() > **listPerpOrderRejections**(`opts?`): `Promise`\<[`PerpOrderRejection`](../type-aliases/PerpOrderRejection.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1655 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`](../type-aliases/PerpOrderRejection.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpOrderRejections`](SomniaMarketsClient.md#listperporderrejections) *** ### ~~getFundingRateHistory()~~ > **getFundingRateHistory**(`pool`, `opts?`): `Promise`\<[`FundingRateUpdate`](../type-aliases/FundingRateUpdate.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1668 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`](../type-aliases/FundingRateUpdate.md)[]\> #### Deprecated Use [listFundingRateHistory](SomniaMarketsClient.md#listfundingratehistory) instead. This alias forwards verbatim. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getFundingRateHistory`](SomniaMarketsClient.md#getfundingratehistory) *** ### getOpenInterestHistory() > **getOpenInterestHistory**(`pool`, `opts?`): `Promise`\<[`OpenInterestSnapshot`](../type-aliases/OpenInterestSnapshot.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1674 A perp pool's open-interest history, newest first — paginated. #### Parameters ##### pool `string` ##### opts? ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`OpenInterestSnapshot`](../type-aliases/OpenInterestSnapshot.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOpenInterestHistory`](SomniaMarketsClient.md#getopeninteresthistory) *** ### listPerpPositions() > **listPerpPositions**(`account`, `opts?`): `Promise`\<[`IndexedPerpPosition`](../type-aliases/IndexedPerpPosition.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1689 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](SomniaMarketsClient.md#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`](../type-aliases/IndexedPerpPosition.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpPositions`](SomniaMarketsClient.md#listperppositions) *** ### getBinaryOrderBook() > **getBinaryOrderBook**(`pool`, `opts?`): `Promise`\<[`BinaryOrderBook`](BinaryOrderBook.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1716 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](SomniaMarketsClient.md#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? [`GetBinaryOrderBookOptions`](GetBinaryOrderBookOptions.md) #### Returns `Promise`\<[`BinaryOrderBook`](BinaryOrderBook.md)\> #### Throws [InvalidInputError](../classes/InvalidInputError.md) If depth or the block pin is invalid. #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [RpcError](../classes/RpcError.md) If selecting the head or reading either side fails. #### Throws [ContractRevertError](../classes/ContractRevertError.md) If the contract rejects either read. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBinaryOrderBook`](SomniaMarketsClient.md#getbinaryorderbook) *** ### getSpotOrderBook() > **getSpotOrderBook**(`pool`, `opts?`): `Promise`\<[`SpotOrderBook`](SpotOrderBook.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1733 Read a spot OR perp pool's resting book from the contract (both ride the shared OrderBook base). Live variant: [getLiveSpotOrderBook](SomniaMarketsClient.md#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? [`GetSpotOrderBookOptions`](GetSpotOrderBookOptions.md) #### Returns `Promise`\<[`SpotOrderBook`](SpotOrderBook.md)\> #### Throws [InvalidInputError](../classes/InvalidInputError.md) If depth or the block pin is invalid. #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [RpcError](../classes/RpcError.md) If selecting the head or reading either side fails. #### Throws [ContractRevertError](../classes/ContractRevertError.md) If the contract rejects either read. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSpotOrderBook`](SomniaMarketsClient.md#getspotorderbook) *** ### getOrderOnchain() > **getOrderOnchain**(`pool`, `orderId`, `opts?`): `Promise`\<[`OnchainOrder`](OnchainOrder.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1778 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](SomniaMarketsClient.md#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. ```ts // 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? [`GetOrderOnchainOptions`](GetOrderOnchainOptions.md) #### Returns `Promise`\<[`OnchainOrder`](OnchainOrder.md) \| `null`\> #### Throws [InvalidInputError](../classes/InvalidInputError.md) If `opts.blockNumber` is negative. #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) If the owner has no chain endpoint. #### Throws [RpcError](../classes/RpcError.md) If the read fails. #### Throws [ContractRevertError](../classes/ContractRevertError.md) If the contract rejects the read for any reason other than the id having no active order. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOrderOnchain`](SomniaMarketsClient.md#getorderonchain) *** ### getOwnOpenOrdersOnchain() > **getOwnOpenOrdersOnchain**(`pool`, `owner`): `Promise`\<`bigint`[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1786 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](SomniaMarketsClient.md#getopenorders). #### Parameters ##### pool `` `0x${string}` `` ##### owner `` `0x${string}` `` #### Returns `Promise`\<`bigint`[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOwnOpenOrdersOnchain`](SomniaMarketsClient.md#getownopenordersonchain) *** ### getAllOpenOrdersOnchain() > **getAllOpenOrdersOnchain**(`pool`, `opts`): `Promise`\<\{ `orders`: [`OnchainOrder`](OnchainOrder.md)[]; `hasMore`: `boolean`; `nextCursor`: `bigint`; \}\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1800 One page of every open order on one side, at chain head — the per-order detail the aggregated book reads ([getBinaryOrderBook](SomniaMarketsClient.md#getbinaryorderbook), [getSpotOrderBook](SomniaMarketsClient.md#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). #### Parameters ##### pool `` `0x${string}` `` ##### opts ###### isBid `boolean` ###### maxCount? `number` ###### cursor? `bigint` #### Returns `Promise`\<\{ `orders`: [`OnchainOrder`](OnchainOrder.md)[]; `hasMore`: `boolean`; `nextCursor`: `bigint`; \}\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getAllOpenOrdersOnchain`](SomniaMarketsClient.md#getallopenordersonchain) *** ### getPerpState() > **getPerpState**(`pool`): `Promise`\<[`PerpStateOnchain`](PerpStateOnchain.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1810 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`](PerpStateOnchain.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpState`](SomniaMarketsClient.md#getperpstate) *** ### getPerpFeedStatus() > **getPerpFeedStatus**(`pool`): `Promise`\<[`PerpFeedStatus`](PerpFeedStatus.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1835 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](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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`](PerpFeedStatus.md)\> #### Throws [NotConfiguredError](../classes/NotConfiguredError.md) 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](../classes/RpcError.md) A chain read did not complete — the block pin included. #### Throws [ContractRevertError](../classes/ContractRevertError.md) 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](../type-aliases/SomniaMarketsClientGetPerpFeedStatusError.md). #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpFeedStatus`](SomniaMarketsClient.md#getperpfeedstatus) *** ### getPerpFundingPremium() > **getPerpFundingPremium**(`pool`): `Promise`\<[`PerpFundingPremium`](PerpFundingPremium.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1850 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](SomniaMarketsClient.md#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`](PerpFundingPremium.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpFundingPremium`](SomniaMarketsClient.md#getperpfundingpremium) *** ### getPerpPosition() > **getPerpPosition**(`ref`): `Promise`\<[`PerpPosition`](PerpPosition.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1856 An account's position in one perp pool, from the MarginBank (signed size: positive = long). `ref.marginBank` comes off the [PerpMarket](../type-aliases/PerpMarket.md) row. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<[`PerpPosition`](PerpPosition.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpPosition`](SomniaMarketsClient.md#getperpposition) *** ### getMarginAccount() > **getMarginAccount**(`marginBank`, `account`): `Promise`\<[`MarginAccount`](MarginAccount.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1863 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`. #### Parameters ##### marginBank `` `0x${string}` `` ##### account `` `0x${string}` `` #### Returns `Promise`\<[`MarginAccount`](MarginAccount.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarginAccount`](SomniaMarketsClient.md#getmarginaccount) *** ### getAccountHealth() > **getAccountHealth**(`marginBank`, `account`): `Promise`\<[`AccountHealth`](AccountHealth.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1869 An account's cross-margin health alone (equity vs IM/MM/CM + the derived status) — a lighter read than [getMarginAccount](SomniaMarketsClient.md#getmarginaccount) when only health matters. #### Parameters ##### marginBank `` `0x${string}` `` ##### account `` `0x${string}` `` #### Returns `Promise`\<[`AccountHealth`](AccountHealth.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getAccountHealth`](SomniaMarketsClient.md#getaccounthealth) *** ### getLiquidationPrice() > **getLiquidationPrice**(`ref`): `Promise`\<`bigint` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1881 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](SomniaMarketsClient.md#getbankruptcyprice). #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<`bigint` \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiquidationPrice`](SomniaMarketsClient.md#getliquidationprice) *** ### getPerpLeverage() > **getPerpLeverage**(`ref`): `Promise`\<[`PerpLeverage`](PerpLeverage.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1896 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](PerpLeverage.md#voucherleveragecapx). For whether a specific order passes, use `previewPerpOrderMargin`. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<[`PerpLeverage`](PerpLeverage.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpLeverage`](SomniaMarketsClient.md#getperpleverage) *** ### getPerpPositionAnalytics() > **getPerpPositionAnalytics**(`ref`): `Promise`\<[`PerpPositionAnalytics`](../type-aliases/PerpPositionAnalytics.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1912 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 [`PerpPositionRef`](PerpPositionRef.md) #### Returns `Promise`\<[`PerpPositionAnalytics`](../type-aliases/PerpPositionAnalytics.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpPositionAnalytics`](SomniaMarketsClient.md#getperppositionanalytics) *** ### listPerpPositionAnalytics() > **listPerpPositionAnalytics**(`p`): `Promise`\<[`PerpPositionAnalytics`](../type-aliases/PerpPositionAnalytics.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1925 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 `equityContribution`s 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`](../type-aliases/PerpPositionAnalytics.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpPositionAnalytics`](SomniaMarketsClient.md#listperppositionanalytics) *** ### getMaxPerpOrderSize() > **getMaxPerpOrderSize**(`p`): `Promise`\<[`PerpMaxOrderSize`](../type-aliases/PerpMaxOrderSize.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1946 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`](../type-aliases/PerpMaxOrderSize.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMaxPerpOrderSize`](SomniaMarketsClient.md#getmaxperpordersize) *** ### previewPerpClosePnl() > **previewPerpClosePnl**(`p`): `Promise`\<[`PerpClosePreview`](../type-aliases/PerpClosePreview.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1969 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`](../type-aliases/PerpClosePreview.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`previewPerpClosePnl`](SomniaMarketsClient.md#previewperpclosepnl) *** ### previewPerpLiquidationPrice() > **previewPerpLiquidationPrice**(`p`): `Promise`\<[`PerpLiquidationPreview`](../type-aliases/PerpLiquidationPreview.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:1988 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](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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`](../type-aliases/PerpLiquidationPreview.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`previewPerpLiquidationPrice`](SomniaMarketsClient.md#previewperpliquidationprice) *** ### getPerpSideHolders() > **getPerpSideHolders**(`ref`, `opts?`): `Promise`\<[`PerpSideHolders`](PerpSideHolders.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2020 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](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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 head - `opts.pageSize`: holders per contract call (default 1000) #### Parameters ##### ref [`PerpSideHoldersRef`](PerpSideHoldersRef.md) ##### opts? [`GetPerpSideHoldersOptions`](GetPerpSideHoldersOptions.md) #### Returns `Promise`\<[`PerpSideHolders`](PerpSideHolders.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpSideHolders`](SomniaMarketsClient.md#getperpsideholders) *** ### getBankruptcyPrice() > **getBankruptcyPrice**(`ref`, `opts?`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2041 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](SomniaMarketsClient.md#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](../classes/ContractRevertError.md) 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's `asOfBlock` — at head, a holder that closed after the snapshot reverts `NoOpenPosition`. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) ##### opts? [`GetBankruptcyPriceOptions`](GetBankruptcyPriceOptions.md) #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBankruptcyPrice`](SomniaMarketsClient.md#getbankruptcyprice) *** ### getPerpSystemConfig() > **getPerpSystemConfig**(`marginBank`): `Promise`\<[`PerpSystemConfig`](PerpSystemConfig.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2056 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`](PerpSystemConfig.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpSystemConfig`](SomniaMarketsClient.md#getperpsystemconfig) *** ### getInsuranceFundState() > **getInsuranceFundState**(`fund`): `Promise`\<[`InsuranceFundState`](InsuranceFundState.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2062 The InsuranceFund's per-tier balances and the total bad debt it can absorb. Point it at `insuranceFund` from [getPerpSystemConfig](SomniaMarketsClient.md#getperpsystemconfig). #### Parameters ##### fund `` `0x${string}` `` #### Returns `Promise`\<[`InsuranceFundState`](InsuranceFundState.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getInsuranceFundState`](SomniaMarketsClient.md#getinsurancefundstate) *** ### listPerpInsuranceFundEvents() > **listPerpInsuranceFundEvents**(`opts?`): `Promise`\<[`PerpInsuranceFundEvent`](../type-aliases/PerpInsuranceFundEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2073 The InsuranceFund's tier ledger, newest first — how each tier reached the balance [getInsuranceFundState](SomniaMarketsClient.md#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`](../type-aliases/PerpInsuranceFundEvent.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpInsuranceFundEvents`](SomniaMarketsClient.md#listperpinsurancefundevents) *** ### getLiquidationEngineConfig() > **getLiquidationEngineConfig**(`engine`): `Promise`\<[`LiquidationEngineConfig`](LiquidationEngineConfig.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2090 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`](LiquidationEngineConfig.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLiquidationEngineConfig`](SomniaMarketsClient.md#getliquidationengineconfig) *** ### tryGetPerpAccountEquity() > **tryGetPerpAccountEquity**(`marginBank`, `account`): `Promise`\<`bigint` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2099 An account's equity, or `null` when it could not be computed. [getAccountHealth](SomniaMarketsClient.md#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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`tryGetPerpAccountEquity`](SomniaMarketsClient.md#trygetperpaccountequity) *** ### getPerpCollateralBasis() > **getPerpCollateralBasis**(`marginBank`, `account`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2108 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpCollateralBasis`](SomniaMarketsClient.md#getperpcollateralbasis) *** ### listPerpPoolStatuses() > **listPerpPoolStatuses**(`p`): `Promise`\<[`PerpPoolStatus`](../type-aliases/PerpPoolStatus.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2131 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](SomniaMarketsClient.md#getmarginaccount) / [getPerpPosition](SomniaMarketsClient.md#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`](../type-aliases/PerpPoolStatus.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpPoolStatuses`](SomniaMarketsClient.md#listperppoolstatuses) *** ### listTradeablePerpPools() > **listTradeablePerpPools**(`p`): `Promise`\<`` `0x${string}` ``[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2134 Just the tradeable perp pools, filtered from [listPerpPoolStatuses](SomniaMarketsClient.md#listperppoolstatuses). #### Parameters ##### p ###### factory `` `0x${string}` `` #### Returns `Promise`\<`` `0x${string}` ``[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listTradeablePerpPools`](SomniaMarketsClient.md#listtradeableperppools) *** ### readPerpMarketFromChain() > **readPerpMarketFromChain**(`p`): `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2150 One factory-deployed perp market as a native [PerpMarket](../type-aliases/PerpMarket.md) 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](UnifiedMarket.md#indexed) for which ones and what they mean. **Gotchas** - Throws [RpcError](../classes/RpcError.md) when a read cannot be completed, and [ContractRevertError](../classes/ContractRevertError.md) 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()` yields `baseSymbol: null`, and a factory predating `IPerpPoolFactoryStopRegistry` yields `stopRegistry: null`. #### Parameters ##### p ###### status [`PerpPoolStatus`](../type-aliases/PerpPoolStatus.md) ###### collateralToken `` `0x${string}` `` ###### collateralDecimals `number` ###### collateralSymbol `string` \| `null` ###### factory `` `0x${string}` `` #### Returns `Promise`\<[`PerpMarket`](../type-aliases/PerpMarket.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`readPerpMarketFromChain`](SomniaMarketsClient.md#readperpmarketfromchain) *** ### isPerpPoolRegistered() > **isPerpPoolRegistered**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2167 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`isPerpPoolRegistered`](SomniaMarketsClient.md#isperppoolregistered) *** ### previewPerpOrderMargin() > **previewPerpOrderMargin**(`p`): `Promise`\<[`PerpOrderMarginPreview`](../type-aliases/PerpOrderMarginPreview.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2216 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`](../type-aliases/PerpOrderMarginPreview.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`previewPerpOrderMargin`](SomniaMarketsClient.md#previewperpordermargin) *** ### meetsPerpImForFill() > **meetsPerpImForFill**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2235 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](SomniaMarketsClient.md#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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`meetsPerpImForFill`](SomniaMarketsClient.md#meetsperpimforfill) *** ### quoteMeetsPerpImForOrder() > **quoteMeetsPerpImForOrder**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2252 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](SomniaMarketsClient.md#previewperpordermargin). #### Parameters ##### p ###### marginBank `` `0x${string}` `` ###### account `` `0x${string}` `` ###### pool `` `0x${string}` `` ###### additionalSize `bigint` ###### price `bigint` #### Returns `Promise`\<`boolean`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`quoteMeetsPerpImForOrder`](SomniaMarketsClient.md#quotemeetsperpimfororder) *** ### quotePerpOrderTopUp() > **quotePerpOrderTopUp**(`p`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2274 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`quotePerpOrderTopUp`](SomniaMarketsClient.md#quoteperpordertopup) *** ### getPerpLeverageImSurcharge() > **getPerpLeverageImSurcharge**(`marginBank`, `account`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2299 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](SomniaMarketsClient.md#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](SomniaMarketsClient.md#trygetperpleverageimsurcharge) in a sweep. #### Parameters ##### marginBank `` `0x${string}` `` ##### account `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpLeverageImSurcharge`](SomniaMarketsClient.md#getperpleverageimsurcharge) *** ### tryGetPerpLeverageImSurcharge() > **tryGetPerpLeverageImSurcharge**(`marginBank`, `account`): `Promise`\<`bigint` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2313 [getPerpLeverageImSurcharge](SomniaMarketsClient.md#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](../classes/RpcError.md) The chain read did not complete, or `marginBank` does not declare the view. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`tryGetPerpLeverageImSurcharge`](SomniaMarketsClient.md#trygetperpleverageimsurcharge) *** ### getPerpMaxLeverage() > **getPerpMaxLeverage**(`ref`, `opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2334 One account's own leverage cap for one perp pool, as the MarginBank stores it — the cheap path to the number [getPerpLeverage](SomniaMarketsClient.md#getperpleverage) reports as `accountMaxLeverageX`. Chain tier, exactly one storage read. Unlike [getPerpLeverage](SomniaMarketsClient.md#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](SomniaMarketsClient.md#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) triple - `opts.blockNumber`: read at this block instead of head. Combining the cap with an enumeration's or analytics row's figures? Pass that row's `asOfBlock` so both describe one moment. #### Parameters ##### ref [`PerpPositionRef`](PerpPositionRef.md) ##### opts? [`GetPerpMaxLeverageOptions`](GetPerpMaxLeverageOptions.md) #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpMaxLeverage`](SomniaMarketsClient.md#getperpmaxleverage) *** ### getPerpLinkedWalletRegistry() > **getPerpLinkedWalletRegistry**(`marginBank`): `Promise`\<`` `0x${string}` `` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2344 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpLinkedWalletRegistry`](SomniaMarketsClient.md#getperplinkedwalletregistry) *** ### quotePerpFundingPayer() > **quotePerpFundingPayer**(`marginBank`, `account`): `Promise`\<[`PerpFundingPayer`](../type-aliases/PerpFundingPayer.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2354 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`](../type-aliases/PerpFundingPayer.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`quotePerpFundingPayer`](SomniaMarketsClient.md#quoteperpfundingpayer) *** ### getPerpMainFunding() > **getPerpMainFunding**(`marginBank`, `account`): `Promise`\<[`PerpMainFunding`](PerpMainFunding.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2364 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`](PerpMainFunding.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpMainFunding`](SomniaMarketsClient.md#getperpmainfunding) *** ### getPerpWalletPullCapacity() > **getPerpWalletPullCapacity**(`marginBank`, `wallet`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2373 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpWalletPullCapacity`](SomniaMarketsClient.md#getperpwalletpullcapacity) *** ### getPerpWalletLinkage() > **getPerpWalletLinkage**(`registry`, `wallet`): `Promise`\<[`PerpWalletLinkage`](PerpWalletLinkage.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2383 A wallet's link group and its ADL-netting maturity. Takes the REGISTRY address — resolve it with [getPerpLinkedWalletRegistry](SomniaMarketsClient.md#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`](PerpWalletLinkage.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpWalletLinkage`](SomniaMarketsClient.md#getperpwalletlinkage) *** ### listPerpLinkedChildren() > **listPerpLinkedChildren**(`registry`, `main`): `Promise`\ Defined in: packages/sdk/src/somniaMarketsClient.ts:2389 Every child of a main, excluding the main — the isolated buckets one treasury currently serves. #### Parameters ##### registry `` `0x${string}` `` ##### main `` `0x${string}` `` #### Returns `Promise`\ #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpLinkedChildren`](SomniaMarketsClient.md#listperplinkedchildren) *** ### getPerpMaxLinkedChildren() > **getPerpMaxLinkedChildren**(`registry`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2395 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpMaxLinkedChildren`](SomniaMarketsClient.md#getperpmaxlinkedchildren) *** ### listPerpWalletLinkEvents() > **listPerpWalletLinkEvents**(`opts?`): `Promise`\<[`PerpWalletLinkEvent`](../type-aliases/PerpWalletLinkEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2406 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](SomniaMarketsClient.md#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`](../type-aliases/PerpWalletLinkEvent.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpWalletLinkEvents`](SomniaMarketsClient.md#listperpwalletlinkevents) *** ### listPerpMarginPulls() > **listPerpMarginPulls**(`opts?`): `Promise`\<[`PerpMarginPull`](../type-aliases/PerpMarginPull.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2425 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](SomniaMarketsClient.md#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`](../type-aliases/PerpMarginPull.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpMarginPulls`](SomniaMarketsClient.md#listperpmarginpulls) *** ### listPerpMainFundingEvents() > **listPerpMainFundingEvents**(`opts?`): `Promise`\<[`PerpMainFundingEvent`](../type-aliases/PerpMainFundingEvent.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2444 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](SomniaMarketsClient.md#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](SomniaMarketsClient.md#listperpmarginpulls)** — same wei, two sides. #### Parameters ##### opts? ###### account? `string` ###### payer? `string` ###### kind? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`PerpMainFundingEvent`](../type-aliases/PerpMainFundingEvent.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listPerpMainFundingEvents`](SomniaMarketsClient.md#listperpmainfundingevents) *** ### getPerpRiskParams() > **getPerpRiskParams**(`pool`): `Promise`\<[`PerpRiskParams`](PerpRiskParams.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2452 #### Parameters ##### pool `` `0x${string}` `` #### Returns `Promise`\<[`PerpRiskParams`](PerpRiskParams.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpRiskParams`](SomniaMarketsClient.md#getperpriskparams) *** ### getPerpHealthSnapshot() > **getPerpHealthSnapshot**(`pool`): `Promise`\<[`PerpHealthSnapshot`](../type-aliases/PerpHealthSnapshot.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2465 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`](../type-aliases/PerpHealthSnapshot.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPerpHealthSnapshot`](SomniaMarketsClient.md#getperphealthsnapshot) *** ### getEffectiveImfBps() > **getEffectiveImfBps**(`pool`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2477 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](SomniaMarketsClient.md#getperphealthsnapshot) returns this alongside the rest for one round-trip. #### Parameters ##### pool `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getEffectiveImfBps`](SomniaMarketsClient.md#geteffectiveimfbps) *** ### getVaultBalance() > **getVaultBalance**(`p`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2494 Claimable balance an owner can withdraw from a pool's internal ERC20Vault for `token`, raw units — the value behind the append-only [getVaultPayoutFallbacks](SomniaMarketsClient.md#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. ```ts 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 [`GetVaultBalanceParams`](GetVaultBalanceParams.md) #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getVaultBalance`](SomniaMarketsClient.md#getvaultbalance) *** ### getManualVaultMode() > **getManualVaultMode**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2501 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 [`GetManualVaultModeParams`](GetManualVaultModeParams.md) #### Returns `Promise`\<`boolean`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getManualVaultMode`](SomniaMarketsClient.md#getmanualvaultmode) *** ### getAutoPullRequirement() > **getAutoPullRequirement**(`p`): `Promise`\<[`AutoPullRequirement`](AutoPullRequirement.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2509 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 [`GetAutoPullRequirementParams`](GetAutoPullRequirementParams.md) #### Returns `Promise`\<[`AutoPullRequirement`](AutoPullRequirement.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getAutoPullRequirement`](SomniaMarketsClient.md#getautopullrequirement) *** ### isOperatorAuthorized() > **isOperatorAuthorized**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2516 Whether `owner` authorized `operator` for `selector` on this SpotPool, at chain head — resolved through the pool's OperatorPermissionsRegistry, so no indexer lag. #### Parameters ##### p [`IsOperatorAuthorizedParams`](IsOperatorAuthorizedParams.md) #### Returns `Promise`\<`boolean`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`isOperatorAuthorized`](SomniaMarketsClient.md#isoperatorauthorized) *** ### isGloballyApproved() > **isGloballyApproved**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2526 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](SomniaMarketsClient.md#isoperatorauthorized). #### Parameters ##### p [`IsGloballyApprovedParams`](IsGloballyApprovedParams.md) #### Returns `Promise`\<`boolean`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`isGloballyApproved`](SomniaMarketsClient.md#isgloballyapproved) *** ### isApprovedForPool() > **isApprovedForPool**(`p`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2535 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](SomniaMarketsClient.md#isoperatorauthorized). #### Parameters ##### p [`IsApprovedForPoolParams`](IsApprovedForPoolParams.md) #### Returns `Promise`\<`boolean`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`isApprovedForPool`](SomniaMarketsClient.md#isapprovedforpool) *** ### getOperatorPermissionsRegistry() > **getOperatorPermissionsRegistry**(`pool`): `Promise`\<`` `0x${string}` `` \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2559 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](../classes/NotConfiguredError.md), 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](../classes/NotConfiguredError.md) when neither `wsRpcUrl` nor the chain definition's own WebSocket endpoint exists. It throws [ContractRevertError](../classes/ContractRevertError.md) when the pool rejects the call, and [RpcError](../classes/RpcError.md) 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOperatorPermissionsRegistry`](SomniaMarketsClient.md#getoperatorpermissionsregistry) *** ### getOwnLockedBalance() > **getOwnLockedBalance**(`p`): `Promise`\<[`LockedBalance`](LockedBalance.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2565 Base/quote `owner` has locked in this pool's resting orders. Pair with [getVaultBalance](SomniaMarketsClient.md#getvaultbalance) to account for everything the pool holds for them. #### Parameters ##### p ###### pool `` `0x${string}` `` ###### owner `` `0x${string}` `` #### Returns `Promise`\<[`LockedBalance`](LockedBalance.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOwnLockedBalance`](SomniaMarketsClient.md#getownlockedbalance) *** ### getLockedTokenBreakdown() > **getLockedTokenBreakdown**(`pool`): `Promise`\<[`LockedTokenBreakdown`](LockedTokenBreakdown.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2571 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`](LockedTokenBreakdown.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getLockedTokenBreakdown`](SomniaMarketsClient.md#getlockedtokenbreakdown) *** ### convertToQuoteAtPriceCeil() > **convertToQuoteAtPriceCeil**(`p`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2577 Base→quote at a price using the pool's OWN ceil rounding — for interpreting [getLockedTokenBreakdown](SomniaMarketsClient.md#getlockedtokenbreakdown) without reimplementing it. #### Parameters ##### p ###### pool `` `0x${string}` `` ###### baseQuantity `bigint` ###### price `bigint` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`convertToQuoteAtPriceCeil`](SomniaMarketsClient.md#converttoquoteatpriceceil) *** ### getMarketOnchain() > **getMarketOnchain**(`marketId`): `Promise`\<[`MarketOnchain`](MarketOnchain.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2590 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`](MarketOnchain.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketOnchain`](SomniaMarketsClient.md#getmarketonchain) *** ### getPoolCreator() > **getPoolCreator**(`pool`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2598 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}` ``\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPoolCreator`](SomniaMarketsClient.md#getpoolcreator) *** ### getFreePools() > **getFreePools**(`creator`, `collateral`): `Promise`\<`` `0x${string}` ``[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2606 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}` ``[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getFreePools`](SomniaMarketsClient.md#getfreepools) *** ### getPoolBindings() > **getPoolBindings**(`pool`): `Promise`\<[`PoolBindingRecord`](PoolBindingRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2615 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`](PoolBindingRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPoolBindings`](SomniaMarketsClient.md#getpoolbindings) *** ### getPool() > **getPool**(`address`): `Promise`\<[`IndexedPool`](IndexedPool.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2622 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`](IndexedPool.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getPool`](SomniaMarketsClient.md#getpool) *** ### getErc20Balance() > **getErc20Balance**(`token`, `account`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2628 ERC-20 `balanceOf(account)`, raw units. For outcome positions use [getOutcomeBalance](SomniaMarketsClient.md#getoutcomebalance) (ERC-6909), not this. #### Parameters ##### token `` `0x${string}` `` ##### account `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getErc20Balance`](SomniaMarketsClient.md#geterc20balance) *** ### getErc20Metadata() > **getErc20Metadata**(`token`): `Promise`\<[`Erc20Metadata`](Erc20Metadata.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2634 ERC-20 `symbol`/`name`/`decimals` in one fan-out — label a token the indexer hasn't denormalized. #### Parameters ##### token `` `0x${string}` `` #### Returns `Promise`\<[`Erc20Metadata`](Erc20Metadata.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getErc20Metadata`](SomniaMarketsClient.md#geterc20metadata) *** ### getErc20Allowance() > **getErc20Allowance**(`token`, `owner`, `spender`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2640 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getErc20Allowance`](SomniaMarketsClient.md#geterc20allowance) *** ### getOutcomeBalance() > **getOutcomeBalance**(`p`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2647 ERC-6909 `balanceOf(account, id)` on the outcome-token singleton, raw units. `p.outcomeToken` is the singleton (from [getMarketOnchain](SomniaMarketsClient.md#getmarketonchain)); `p.id` is the market's `yesId`/`noId`. #### Parameters ##### p [`GetOutcomeBalanceParams`](GetOutcomeBalanceParams.md) #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOutcomeBalance`](SomniaMarketsClient.md#getoutcomebalance) *** ### getBalances() > **getBalances**(`tokens`, `account`): `Promise`\<`bigint`[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2657 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`](BalanceQuery.md)[] ##### account `` `0x${string}` `` #### Returns `Promise`\<`bigint`[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBalances`](SomniaMarketsClient.md#getbalances) *** ### getStopOrderSomiPayment() > **getStopOrderSomiPayment**(`registry`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2663 SOMI a SpotStopOrderRegistry charges per pending stop order (funds the trigger gas; refunded on cancel). Raw wei. #### Parameters ##### registry `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getStopOrderSomiPayment`](SomniaMarketsClient.md#getstopordersomipayment) *** ### getMaxBuilderFeeBpsTimes1k() > **getMaxBuilderFeeBpsTimes1k**(`pool`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2669 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMaxBuilderFeeBpsTimes1k`](SomniaMarketsClient.md#getmaxbuilderfeebpstimes1k) *** ### getBuilderApproval() > **getBuilderApproval**(`ref`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2672 A user's raw per-builder approval cap on a pool (pool bps×1000; 0 = none). #### Parameters ##### ref [`BuilderApprovalRef`](BuilderApprovalRef.md) #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getBuilderApproval`](SomniaMarketsClient.md#getbuilderapproval) *** ### getEffectiveBuilderApproval() > **getEffectiveBuilderApproval**(`ref`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2679 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 [`BuilderApprovalRef`](BuilderApprovalRef.md) #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getEffectiveBuilderApproval`](SomniaMarketsClient.md#geteffectivebuilderapproval) *** ### getContractMeta() > **getContractMeta**(`address`, `opts?`): `Promise`\<[`ContractMeta`](ContractMeta.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2685 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`](ContractMeta.md)\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getContractMeta`](SomniaMarketsClient.md#getcontractmeta) *** ### getNativeBalance() > **getNativeBalance**(`address`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2688 Native (SOMI/STT) balance, raw wei. #### Parameters ##### address `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getNativeBalance`](SomniaMarketsClient.md#getnativebalance) *** ### getTransactionSummary() > **getTransactionSummary**(`hash`): `Promise`\<[`TransactionSummary`](TransactionSummary.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2700 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`](TransactionSummary.md) \| `null`\> #### Throws [RpcError](../classes/RpcError.md) The chain read did not complete. #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getTransactionSummary`](SomniaMarketsClient.md#gettransactionsummary) *** ### createNetworkTape() > **createNetworkTape**(`opts?`): [`NetworkTape`](../classes/NetworkTape.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2709 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? [`NetworkTapeOptions`](NetworkTapeOptions.md) #### Returns [`NetworkTape`](../classes/NetworkTape.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`createNetworkTape`](SomniaMarketsClient.md#createnetworktape) *** ### getHeadBlock() > **getHeadBlock**(): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2712 Latest block number as the RPC sees it. #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getHeadBlock`](SomniaMarketsClient.md#getheadblock) *** ### getSystemInfo() > **getSystemInfo**(): `Promise`\<[`SystemInfo`](SystemInfo.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2724 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`](SystemInfo.md)\> #### Throws [RpcError](../classes/RpcError.md) A chain read did not complete. #### Throws [ContractRevertError](../classes/ContractRevertError.md) A configured contract rejected its read (usually an ABI mismatch). #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSystemInfo`](SomniaMarketsClient.md#getsysteminfo) *** ### listOperators() > **listOperators**(`opts?`): `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2735 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`](../type-aliases/OperatorFilter.md) & `object` #### Returns `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listOperators`](SomniaMarketsClient.md#listoperators) *** ### countOperators() > **countOperators**(`opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2745 Server-side COUNT of operators matching a filter (for directory pagination). Needs the privileged `_aggregate` role (server-only), like [countBinaryMarkets](SomniaMarketsClient.md#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? [`OperatorFilter`](../type-aliases/OperatorFilter.md) #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countOperators`](SomniaMarketsClient.md#countoperators) *** ### getOperator() > **getOperator**(`operatorId`): `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2747 One operator by id, or null if never registered. Indexer read. #### Parameters ##### operatorId `number` #### Returns `Promise`\<[`IndexedOperator`](../type-aliases/IndexedOperator.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOperator`](SomniaMarketsClient.md#getoperator) *** ### listVenues() > **listVenues**(`opts?`): `Promise`\<[`IndexedVenue`](../type-aliases/IndexedVenue.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2752 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`](../type-aliases/IndexedVenue.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listVenues`](SomniaMarketsClient.md#listvenues) *** ### countVenues() > **countVenues**(`opts?`): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2767 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](SomniaMarketsClient.md#countoperators); `Venue` is far below the cap, so no bounded variant exists. #### Parameters ##### opts? ###### operatorId? `number` ###### marketType? `string` #### Returns `Promise`\<`number`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`countVenues`](SomniaMarketsClient.md#countvenues) *** ### getVenue() > **getVenue**(`venueId`): `Promise`\<[`IndexedVenue`](../type-aliases/IndexedVenue.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2769 One venue by its opaque bytes32 id, or null. Indexer read. #### Parameters ##### venueId `string` #### Returns `Promise`\<[`IndexedVenue`](../type-aliases/IndexedVenue.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getVenue`](SomniaMarketsClient.md#getvenue) *** ### encodeBinaryVenueFeeParams() > **encodeBinaryVenueFeeParams**(`vp`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2776 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 [`BinaryVenueParams`](BinaryVenueParams.md) #### Returns `Promise`\<`` `0x${string}` ``\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`encodeBinaryVenueFeeParams`](SomniaMarketsClient.md#encodebinaryvenuefeeparams) *** ### getMaxVenueFeeBps() > **getMaxVenueFeeBps**(): `Promise`\<`number`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2781 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMaxVenueFeeBps`](SomniaMarketsClient.md#getmaxvenuefeebps) *** ### listMarketCreators() > **listMarketCreators**(`opts?`): `Promise`\<[`IndexedMarketCreator`](../type-aliases/IndexedMarketCreator.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2795 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`](../type-aliases/MarketCreatorFilter.md) & `object` #### Returns `Promise`\<[`IndexedMarketCreator`](../type-aliases/IndexedMarketCreator.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listMarketCreators`](SomniaMarketsClient.md#listmarketcreators) *** ### getMarketCreator() > **getMarketCreator**(`creator`): `Promise`\<[`IndexedMarketCreator`](../type-aliases/IndexedMarketCreator.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2797 One MarketCreator by address (with its series), or null. Indexer read. #### Parameters ##### creator `string` #### Returns `Promise`\<[`IndexedMarketCreator`](../type-aliases/IndexedMarketCreator.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getMarketCreator`](SomniaMarketsClient.md#getmarketcreator) *** ### listOracleAdapters() > **listOracleAdapters**(`opts?`): `Promise`\<[`IndexedOracleAdapter`](../type-aliases/IndexedOracleAdapter.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2804 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`](../type-aliases/IndexedOracleAdapter.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listOracleAdapters`](SomniaMarketsClient.md#listoracleadapters) *** ### getOracleAdapter() > **getOracleAdapter**(`adapter`): `Promise`\<[`IndexedOracleAdapter`](../type-aliases/IndexedOracleAdapter.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2811 One oracle adapter by address, or null. Indexer read. #### Parameters ##### adapter `string` #### Returns `Promise`\<[`IndexedOracleAdapter`](../type-aliases/IndexedOracleAdapter.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOracleAdapter`](SomniaMarketsClient.md#getoracleadapter) *** ### listSeries() > **listSeries**(`opts?`): `Promise`\<[`IndexedSeries`](../type-aliases/IndexedSeries.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2813 List series, creation-order, optionally scoped to one creator. Indexer read. #### Parameters ##### opts? ###### creator? `string` ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`IndexedSeries`](../type-aliases/IndexedSeries.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listSeries`](SomniaMarketsClient.md#listseries) *** ### getSeries() > **getSeries**(`creator`, `seriesId`): `Promise`\<[`IndexedSeries`](../type-aliases/IndexedSeries.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2820 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`](../type-aliases/IndexedSeries.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSeries`](SomniaMarketsClient.md#getseries) *** ### getSchedulingCost() > **getSchedulingCost**(`def`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2836 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 [`QuestionDefinitionInput`](QuestionDefinitionInput.md) #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getSchedulingCost`](SomniaMarketsClient.md#getschedulingcost) *** ### earmarkedOf() > **earmarkedOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2841 Native LOCKED for an operator's outstanding markets (wei; never withdrawable). Chain read; needs `config.addresses.oracleHub`. #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`earmarkedOf`](SomniaMarketsClient.md#earmarkedof) *** ### creditOf() > **creditOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2846 An operator's accrued WITHDRAWABLE surplus credit on the hub (wei). Chain read; needs `config.addresses.oracleHub`. #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`creditOf`](SomniaMarketsClient.md#creditof) *** ### outstandingOf() > **outstandingOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2851 Count of an operator's bound-but-unresolved markets. Chain read; needs `config.addresses.oracleHub`. #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`outstandingOf`](SomniaMarketsClient.md#outstandingof) *** ### withdrawableOf() > **withdrawableOf**(`operatorId`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2856 Wei an operator's owner may withdraw right now (== `creditOf`). Chain read; needs `config.addresses.oracleHub`. #### Parameters ##### operatorId `number` #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`withdrawableOf`](SomniaMarketsClient.md#withdrawableof) *** ### payerCreditOf() > **payerCreditOf**(`payer`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2863 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`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`payerCreditOf`](SomniaMarketsClient.md#payercreditof) *** ### payerOf() > **payerOf**(`marketId`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2868 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}` ``\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`payerOf`](SomniaMarketsClient.md#payerof) *** ### resolveReserve() > **resolveReserve**(): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2873 The hub's `resolveReserve()` — the per-market reserve attached+locked at onBind (wei). Chain read; needs `config.addresses.oracleHub`. #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`resolveReserve`](SomniaMarketsClient.md#resolvereserve) *** ### quoteCreateMarketValue() > **quoteCreateMarketValue**(`def`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2880 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 [`QuestionDefinitionInput`](QuestionDefinitionInput.md) #### Returns `Promise`\<`bigint`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`quoteCreateMarketValue`](SomniaMarketsClient.md#quotecreatemarketvalue) *** ### getOracleQuestion() > **getOracleQuestion**(`oracleQuestionId`): `Promise`\<[`OracleQuestionRecord`](../type-aliases/OracleQuestionRecord.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2885 One hub-scheduled oracle question (dedup key, scheduler, bind count) by its oracleQuestionId, or null. Indexer read. #### Parameters ##### oracleQuestionId `string` #### Returns `Promise`\<[`OracleQuestionRecord`](../type-aliases/OracleQuestionRecord.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOracleQuestion`](SomniaMarketsClient.md#getoraclequestion) *** ### listOracleQuestions() > **listOracleQuestions**(`opts?`): `Promise`\<[`OracleQuestionRecord`](../type-aliases/OracleQuestionRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2890 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`](../type-aliases/OracleQuestionRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listOracleQuestions`](SomniaMarketsClient.md#listoraclequestions) *** ### getOperatorHubAccount() > **getOperatorHubAccount**(`operatorId`): `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2900 One operator's hub account (earmarked / credit / outstanding) by operatorId, or null. Indexer read. #### Parameters ##### operatorId `string` \| `number` #### Returns `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md) \| `null`\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`getOperatorHubAccount`](SomniaMarketsClient.md#getoperatorhubaccount) *** ### listOperatorHubAccounts() > **listOperatorHubAccounts**(`opts?`): `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2905 Operator hub-account records, most-recently-updated first, paginated. Indexer read. #### Parameters ##### opts? ###### limit? `number` ###### offset? `number` #### Returns `Promise`\<[`OperatorHubAccountRecord`](../type-aliases/OperatorHubAccountRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listOperatorHubAccounts`](SomniaMarketsClient.md#listoperatorhubaccounts) *** ### listOracleBinds() > **listOracleBinds**(`opts?`): `Promise`\<[`OracleBindRecord`](../type-aliases/OracleBindRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2911 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`](../type-aliases/OracleBindRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listOracleBinds`](SomniaMarketsClient.md#listoraclebinds) *** ### listOracleCallbacks() > **listOracleCallbacks**(`opts?`): `Promise`\<[`OracleCallbackRecord`](../type-aliases/OracleCallbackRecord.md)[]\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2923 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`](../type-aliases/OracleCallbackRecord.md)[]\> #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`listOracleCallbacks`](SomniaMarketsClient.md#listoraclecallbacks) *** ### createTrader() > **createTrader**(`traderConfig`): [`Trader`](Trader.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2937 Build a [Trader](Trader.md) 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. #### Parameters ##### traderConfig [`TraderConfig`](TraderConfig.md) #### Returns [`Trader`](Trader.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`createTrader`](SomniaMarketsClient.md#createtrader) *** ### createOperatorAdmin() > **createOperatorAdmin**(`config`): [`OperatorAdmin`](OperatorAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2944 Build an [OperatorAdmin](OperatorAdmin.md) bound to a signer — registers/updates operators and creates/updates venues on MarketsCore. Same signer doctrine as [createTrader](SomniaMarketsClient.md#createtrader) (privateKey/local account, or a browser walletClient). #### Parameters ##### config [`OperatorAdminConfig`](OperatorAdminConfig.md) #### Returns [`OperatorAdmin`](OperatorAdmin.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`createOperatorAdmin`](SomniaMarketsClient.md#createoperatoradmin) *** ### createOracleHubAdmin() > **createOracleHubAdmin**(`config`): [`OracleHubAdmin`](OracleHubAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2955 Build an [OracleHubAdmin](OracleHubAdmin.md) 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](SomniaMarketsClient.md#createoperatoradmin). Needs `config.addresses.oracleHub`. #### Parameters ##### config [`OracleHubAdminConfig`](OracleHubAdminConfig.md) #### Returns [`OracleHubAdmin`](OracleHubAdmin.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`createOracleHubAdmin`](SomniaMarketsClient.md#createoraclehubadmin) *** ### createGovernanceAdmin() > **createGovernanceAdmin**(`config`): [`GovernanceAdmin`](GovernanceAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2963 Build a [GovernanceAdmin](GovernanceAdmin.md) 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](GovernanceAdmin.md#ismoduleowner). #### Parameters ##### config [`OracleHubAdminConfig`](OracleHubAdminConfig.md) #### Returns [`GovernanceAdmin`](GovernanceAdmin.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`createGovernanceAdmin`](SomniaMarketsClient.md#creategovernanceadmin) *** ### createMarketCreatorAdmin() > **createMarketCreatorAdmin**(`config`): [`MarketCreatorAdmin`](MarketCreatorAdmin.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:2970 Build a [MarketCreatorAdmin](MarketCreatorAdmin.md) 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](SomniaMarketsClient.md#createoperatoradmin). #### Parameters ##### config [`OracleHubAdminConfig`](OracleHubAdminConfig.md) #### Returns [`MarketCreatorAdmin`](MarketCreatorAdmin.md) #### Inherited from [`SomniaMarketsClient`](SomniaMarketsClient.md).[`createMarketCreatorAdmin`](SomniaMarketsClient.md#createmarketcreatoradmin) *** ### getIndexerFreshness() > **getIndexerFreshness**(`chainId`): `Promise`\<[`IndexerFreshness`](../type-aliases/IndexerFreshness.md) \| `null`\> Defined in: packages/sdk/src/somniaMarketsClient.ts:2984 Compare main-indexer progress with this owner's independently read chain head. Missing metadata returns null. Lag is raw blocks and chain-time seconds, without a stale threshold. Use getSyncStatus for metadata-only availability checks. #### Parameters ##### chainId `number` #### Returns `Promise`\<[`IndexerFreshness`](../type-aliases/IndexerFreshness.md) \| `null`\> #### Throws chainId does not match the owner or a variable is invalid. #### Throws Metadata request failed. #### Throws The owner's chain transport is unavailable. #### Throws A latest or processed block read failed. *** ### createObservedReads() > **createObservedReads**(): `Promise`\<[`ObservedReads`](ObservedReads.md)\> Defined in: packages/sdk/src/somniaMarketsClient.ts:3005 Observe one independent head and derive response-associated main-indexer reads. Reuse the returned capability for a batch; create another to refresh the comparison head. The capability shares this owner's cancellation and transports. No polling is started. **Example** ```ts const observed = await exchange.client.createObservedReads(); const [markets, count] = await observed.batch([ { operation: "listMarkets", args: [{ limit: 20 }] }, { operation: "countMarkets", args: [] }, ]); console.log(markets.data, markets.observation.latestProcessedBlock); console.log(count.data, count.observation.independentHead.blockNumber); const freshness = await exchange.client.getIndexerFreshness(exchange.client.config.chain.id); console.log(freshness?.lagBlocks, freshness?.lagSeconds); ``` #### Returns `Promise`\<[`ObservedReads`](ObservedReads.md)\> #### Throws The owner has no chain transport. #### Throws The head read failed. *** ### getPriceHealth() > **getPriceHealth**(`asset`): [`PriceFeedHealth`](../type-aliases/PriceFeedHealth.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:3008 Read precise delivery health without I/O. Unwatched assets return "unwatched". Shares the existing price watch and subscribePrices notifications. #### Parameters ##### asset `string` #### Returns [`PriceFeedHealth`](../type-aliases/PriceFeedHealth.md) *** ### listPriceHealth() > **listPriceHealth**(): `object`[] Defined in: packages/sdk/src/somniaMarketsClient.ts:3010 Read precise health for each retained asset without I/O or new watches. #### Returns `object`[] --- # /docs/typescript/api/index/interfaces/Span [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Span # Interface: Span Defined in: packages/sdk/src/debug.ts:115 Handle for an open span, passed to the `span`/`traced` callback so a call site can parent a nested span explicitly or annotate it mid-flight. ## Properties ### id > `readonly` **id**: `number` Defined in: packages/sdk/src/debug.ts:120 The span's event id — `0` when debugging is disabled (an inert handle: no event was emitted for it, and annotating it is a no-op). *** ### name > `readonly` **name**: `string` Defined in: packages/sdk/src/debug.ts:122 The name the span was started with (empty on the inert disabled handle). --- # /docs/typescript/api/index/interfaces/SpotOrderBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotOrderBook # Interface: SpotOrderBook Defined in: packages/sdk/src/orders.ts:871 A plain two-sided spot order book (no YES/NO inversion). Prices are raw quote units per whole base; quantities are raw base units. ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/orders.ts:873 Pinned chain block or scope applied-event watermark; absent without provenance. *** ### bids > **bids**: [`BookLevel`](BookLevel.md)[] Defined in: packages/sdk/src/orders.ts:875 Resting buys, best (highest price) first. *** ### asks > **asks**: [`BookLevel`](BookLevel.md)[] Defined in: packages/sdk/src/orders.ts:877 Resting sells, best (lowest price) first. --- # /docs/typescript/api/index/interfaces/SpotOrderRequest [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotOrderRequest # Interface: SpotOrderRequest Defined in: packages/sdk/src/trade.ts:502 One order inside a [Trader.placeSpotOrders](Trader.md#placespotorders) batch — the per-order fields of [PlaceSpotOrderParams](PlaceSpotOrderParams.md), minus everything the batch supplies once (`pool`, token context, gas). ## Properties ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:504 True = buy the base asset (pay quote); false = sell base (pay base/native). *** ### price > **price**: `bigint` Defined in: packages/sdk/src/trade.ts:509 Limit price — raw quote units per whole base token. For a MARKET order pass a crossing price (best opposite level ± slippage); it bounds the escrow. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/trade.ts:511 Base quantity, raw base units. *** ### orderType? > `optional` **orderType?**: `number` Defined in: packages/sdk/src/trade.ts:513 0 limit (default) or 2 market (IOC). See [ORDER\_TYPE](../variables/ORDER_TYPE.md). *** ### selfMatchingOption? > `optional` **selfMatchingOption?**: `number` Defined in: packages/sdk/src/trade.ts:520 Self-match behaviour when this order crosses your OWN resting order, default 0 (`CANCEL_TAKER`). Set per rung: a ladder that crosses its own quotes can keep the incoming order and drop the resting one instead. See [SELF\_MATCHING\_OPTION](../variables/SELF_MATCHING_OPTION.md). *** ### expireTimestampNs? > `optional` **expireTimestampNs?**: `bigint` Defined in: packages/sdk/src/trade.ts:522 Order expiry in ns. Defaults to ~50y (GTC). *** ### userData? > `optional` **userData?**: `bigint` Defined in: packages/sdk/src/trade.ts:524 Opaque 64-bit tag carried on the order — for market-maker bookkeeping. *** ### builder? > `optional` **builder?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:530 Routing/builder frontend address to attribute this rung to. Requires the trader to have opted this builder in via [Trader.approveBuilder](Trader.md#approvebuilder) on the batch's pool. Omit (or zero) for no routing fee. *** ### builderFeeBpsTimes1k? > `optional` **builderFeeBpsTimes1k?**: `bigint` Defined in: packages/sdk/src/trade.ts:535 Per-order builder/routing fee in the pool's native bps×1000 unit (≤ the pool's `maxBuilderFee` ceiling AND ≤ the trader's approval). 0 = none. --- # /docs/typescript/api/index/interfaces/SwapCreatorParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SwapCreatorParams # Interface: SwapCreatorParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:258 Params for [MarketCreatorAdmin.swapCreator](MarketCreatorAdmin.md#swapcreator). ## Properties ### policy > **policy**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:260 The venue's MarketCreatorPolicy. Caller must be its owner. *** ### from > **from**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:262 Outgoing creator to revoke. *** ### to > **to**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:264 Incoming creator to authorize. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:266 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/SweepExpiredAtLevelParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SweepExpiredAtLevelParams # Interface: SweepExpiredAtLevelParams Defined in: packages/sdk/src/trade.ts:344 Permissionless keeper drain: walk ONE price level from the best order on a side, cleaning up to `maxCount` expired orders. The complement of [CancelExpiredOrdersParams](CancelExpiredOrdersParams.md) when you have a price level rather than a list of ids (e.g. draining a locked market's book so its pool can be released). Each cleaned order's escrow returns to its owner. ## Properties ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:346 BinaryPool (or SpotPool) address to sweep. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/trade.ts:348 True to sweep the bid side, false the ask side. *** ### price > **price**: `bigint` Defined in: packages/sdk/src/trade.ts:350 The exact price level to sweep (raw pool price units). *** ### maxCount > **maxCount**: `bigint` Defined in: packages/sdk/src/trade.ts:352 Max number of expired orders to clean in this call. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:358 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/SyncSettlementParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SyncSettlementParams # Interface: SyncSettlementParams Defined in: packages/sdk/src/trade.ts:1794 Permissionless earmark reconcile: release the oracle earmark of a market that was voided via the `BinaryMarket.voidExpired()` escape hatch (which bypasses the module, so the hub's earmark release never fired). ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1796 bytes32 marketId to reconcile; the market must be resolved or voided. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1798 BinaryMarketsModule address; resolved from `config.addresses.binaryModule` when omitted. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1804 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/SystemInfo [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SystemInfo # Interface: SystemInfo Defined in: packages/sdk/src/system.ts:45 Live snapshot of the deployed CLOB-family contract state, as read by [SomniaMarketsClient.getSystemInfo](SomniaMarketsClient.md#getsysteminfo). `null` means the contract is not configured or not wired. A live read that FAILS throws — this snapshot never reports a value the chain did not answer, because a dashboard cannot tell a fabricated zero from a real one. ## Properties ### clobFactory > **clobFactory**: `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/system.ts:47 BinaryMarketsModule.clobFactory() (authoritative) or the configured fallback. *** ### binaryMarketImpl > **binaryMarketImpl**: `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/system.ts:53 ClobFactory.binaryMarketImpl(), or null when no ClobFactory resolved (there is no configured market-impl fallback; `binaryPoolImpl` is a different contract). *** ### factoryMismatch > **factoryMismatch**: `boolean` Defined in: packages/sdk/src/system.ts:55 True when the live ClobFactory differs from the configured one. *** ### settlement > **settlement**: `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/system.ts:62 The BinarySettlement singleton the module is wired to (live `BinaryMarketsModule.settlement()`, falling back to the configured `addresses.binarySettlement`). Null pre-wire, on a pre-v2 module that does not declare the view, and when neither is configured. A failed read throws. *** ### settlementMismatch > **settlementMismatch**: `boolean` Defined in: packages/sdk/src/system.ts:64 True when the module's live settlement differs from the configured one. *** ### marketCreator > **marketCreator**: [`MarketCreatorInfo`](MarketCreatorInfo.md) \| `null` Defined in: packages/sdk/src/system.ts:66 The configured MarketCreator's state; null when `addresses.marketCreator` is unset. *** ### oracle > **oracle**: \{ `owner`: `` `0x${string}` ``; `binaryModule`: `` `0x${string}` ``; \} \| `null` Defined in: packages/sdk/src/system.ts:68 FakeOracle wiring; null when `addresses.fakeOracle` is unset. #### Union Members ##### Type Literal \{ `owner`: `` `0x${string}` ``; `binaryModule`: `` `0x${string}` ``; \} ##### owner > **owner**: `` `0x${string}` `` FakeOracle owner (the resolve/void signer). ##### binaryModule > **binaryModule**: `` `0x${string}` `` The module the oracle delivers to (its `RECEIVER`). *** `null` *** ### usdc > **usdc**: \{ `symbol`: `string`; `decimals`: `number`; \} \| `null` Defined in: packages/sdk/src/system.ts:78 Collateral ERC-20 metadata (from `addresses.collateral`, falling back to the legacy `testUsdc`); null when neither is configured. #### Union Members ##### Type Literal \{ `symbol`: `string`; `decimals`: `number`; \} ##### symbol > **symbol**: `string` Token symbol. ##### decimals > **decimals**: `number` Token decimals. *** `null` --- # /docs/typescript/api/index/interfaces/TailDivergence [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TailDivergence # Interface: TailDivergence Defined in: packages/sdk/src/store.ts:120 Raw native levels differing at a fixed chain checkpoint. ## Properties ### pool > **pool**: `string` Defined in: packages/sdk/src/store.ts:122 Pool compared. *** ### blockNumber > **blockNumber**: `bigint` Defined in: packages/sdk/src/store.ts:124 Both chain sides and the local capture describe this target. *** ### depth > **depth**: `number` Defined in: packages/sdk/src/store.ts:126 Maximum compared levels per side. *** ### local > **local**: `object` Defined in: packages/sdk/src/store.ts:128 Event-derived levels filtered using the target chain timestamp. #### bids > **bids**: [`BookLevel`](BookLevel.md)[] #### asks > **asks**: [`BookLevel`](BookLevel.md)[] *** ### chain > **chain**: `object` Defined in: packages/sdk/src/store.ts:130 Contract levels read at the same target. #### bids > **bids**: [`BookLevel`](BookLevel.md)[] #### asks > **asks**: [`BookLevel`](BookLevel.md)[] --- # /docs/typescript/api/index/interfaces/TailFailure [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TailFailure # Interface: TailFailure Defined in: packages/sdk/src/store.ts:112 An observable background operation failure. ## Properties ### operation > **operation**: `"recovery"` \| `"reconciliation"` \| `"subscription"` Defined in: packages/sdk/src/store.ts:114 Failed operation; reconciliation is diagnostic and does not replace the book. *** ### error > **error**: [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/store.ts:116 Semantic SDK failure with the original cause. --- # /docs/typescript/api/index/interfaces/TailReconciliationConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TailReconciliationConfig # Interface: TailReconciliationConfig Defined in: packages/sdk/src/config.ts:418 Opt-in live-book diagnostic bounds. ## Properties ### blockInterval > **blockInterval**: `bigint` Defined in: packages/sdk/src/config.ts:420 Positive block interval. Heads coalesce while a comparison is pending. *** ### depth > **depth**: `number` Defined in: packages/sdk/src/config.ts:422 Top levels per side, an integer from 1 to 100. --- # /docs/typescript/api/index/interfaces/TailStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TailStatus # Interface: TailStatus Defined in: packages/sdk/src/store.ts:84 Live-tail health snapshot — how current the store's `getLive*` reads are: block coverage (snapshot/last/head), socket state, and active watch count. ## Properties ### healedGaps > **healedGaps**: `number` Defined in: packages/sdk/src/store.ts:86 Nonempty intervening ranges successfully recovered. Empty probes do not count. *** ### lastDivergence > **lastDivergence**: [`TailDivergence`](TailDivergence.md) \| `null` Defined in: packages/sdk/src/store.ts:88 Last observed divergence, retained after later matching checks. *** ### failure > **failure**: [`TailFailure`](TailFailure.md) \| `null` Defined in: packages/sdk/src/store.ts:90 Background failure; cleared only after the failed work succeeds. *** ### mode > **mode**: [`TailMode`](../type-aliases/TailMode.md) Defined in: packages/sdk/src/store.ts:92 Current data-source mode ("init" until the first watch is hydrated). *** ### snapshotBlock > **snapshotBlock**: `number` Defined in: packages/sdk/src/store.ts:97 Block the most recent indexer snapshot was consistent to (a watch's seam covers snapshotBlock+1..) *** ### lastBlock > **lastBlock**: `number` Defined in: packages/sdk/src/store.ts:99 Highest applied event or sealed scope block; heads alone do not advance it. *** ### headBlock > **headBlock**: `number` Defined in: packages/sdk/src/store.ts:101 Latest chain head observed over the WS *** ### wsConnected > **wsConnected**: `boolean` Defined in: packages/sdk/src/store.ts:103 Whether the chain WS subscriptions are currently delivering *** ### watchCount > **watchCount**: `number` Defined in: packages/sdk/src/store.ts:108 Active market watches (pools currently subscribed, incl. an all-markets watch's set). 0 → the tail is idle and no socket is held for it. --- # /docs/typescript/api/index/interfaces/TapeFill [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TapeFill # Interface: TapeFill Defined in: packages/sdk/src/networkTape.ts:75 An executed fill as the tape saw it. ## Properties ### key > **key**: `string` Defined in: packages/sdk/src/networkTape.ts:77 Stable row key: `${blockNumber}_${logIndex}_${pool}`. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/networkTape.ts:78 *** ### takerOrderId > **takerOrderId**: `bigint` Defined in: packages/sdk/src/networkTape.ts:79 *** ### makerOrderId > **makerOrderId**: `bigint` Defined in: packages/sdk/src/networkTape.ts:80 *** ### price > **price**: `bigint` Defined in: packages/sdk/src/networkTape.ts:82 Execution price, raw quote units per whole base. *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/networkTape.ts:84 Quantity filled, raw base/outcome units. *** ### taker > **taker**: `string` \| `null` Defined in: packages/sdk/src/networkTape.ts:91 Resolved from the session's OrderPlaced stream. The taker's placement follows its fills in the same tx, so this back-fills within one message batch; null until then (and forever, for a maker quoted before the tape started — resolve those via [SomniaMarketsClient.getFill](SomniaMarketsClient.md#getfill) if needed). *** ### maker > **maker**: `string` \| `null` Defined in: packages/sdk/src/networkTape.ts:92 *** ### blockNumber > **blockNumber**: `number` Defined in: packages/sdk/src/networkTape.ts:93 *** ### logIndex > **logIndex**: `number` Defined in: packages/sdk/src/networkTape.ts:94 *** ### at > **at**: `number` Defined in: packages/sdk/src/networkTape.ts:95 --- # /docs/typescript/api/index/interfaces/TapeOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TapeOrder # Interface: TapeOrder Defined in: packages/sdk/src/networkTape.ts:54 An order placement as the tape saw it (either side of the book). ## Properties ### key > **key**: `string` Defined in: packages/sdk/src/networkTape.ts:56 Stable row key: `${blockNumber}_${logIndex}_${pool}`. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/networkTape.ts:58 Lowercased pool address the order landed on. *** ### orderId > **orderId**: `bigint` Defined in: packages/sdk/src/networkTape.ts:60 uint128 order id — with `pool`, a permanent identity (ids never reuse). *** ### owner > **owner**: `string` Defined in: packages/sdk/src/networkTape.ts:62 Order owner, lowercased. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/networkTape.ts:63 *** ### price > **price**: `bigint` Defined in: packages/sdk/src/networkTape.ts:65 Limit price, raw quote units per whole base (binary: YES-probability scale). *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/networkTape.ts:67 Full order size, raw base/outcome units. *** ### blockNumber > **blockNumber**: `number` Defined in: packages/sdk/src/networkTape.ts:68 *** ### logIndex > **logIndex**: `number` Defined in: packages/sdk/src/networkTape.ts:69 *** ### at > **at**: `number` Defined in: packages/sdk/src/networkTape.ts:71 Arrival time (ms since epoch) — Somnia logs carry no timestamp. --- # /docs/typescript/api/index/interfaces/TokenLockBreakdown [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TokenLockBreakdown # Interface: TokenLockBreakdown Defined in: packages/sdk/src/spot/poolReads.ts:180 How one token's reserves in a pool divide up — see [SomniaMarketsClient.getLockedTokenBreakdown](SomniaMarketsClient.md#getlockedtokenbreakdown). ## Properties ### principalLocked > **principalLocked**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:182 Tradeable principal backing resting orders. *** ### lockedSurplus > **lockedSurplus**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:184 Locked above principal (rounding + fee headroom the orders reserved). *** ### leftover > **leftover**: `bigint` Defined in: packages/sdk/src/spot/poolReads.ts:186 Reserves backing NO resting order — accrued fees and stray balance. --- # /docs/typescript/api/index/interfaces/Tradable [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Tradable # Interface: Tradable Defined in: packages/sdk/src/unified/symbols.ts:27 A parsed + resolved tradable: the market it lives on, and (for outcome markets) which outcome book it addresses. ## Properties ### market > **market**: [`Market`](../type-aliases/Market.md) Defined in: packages/sdk/src/unified/symbols.ts:29 The native market row this tradable lives on (union — narrow by `marketType`). *** ### marketSymbol > **marketSymbol**: `string` Defined in: packages/sdk/src/unified/symbols.ts:31 Canonical MARKET symbol (no outcome suffix). *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/symbols.ts:33 Canonical tradable symbol (with outcome suffix where applicable). *** ### outcome? > `optional` **outcome?**: `string` Defined in: packages/sdk/src/unified/symbols.ts:35 Outcome label (binary: "YES" | "NO"); undefined for spot. *** ### outcomeIndex? > `optional` **outcomeIndex?**: `number` Defined in: packages/sdk/src/unified/symbols.ts:37 Outcome index (binary: 0 = YES, 1 = NO); undefined for spot. *** ### pool > **pool**: `` `0x${string}` `` Defined in: packages/sdk/src/unified/symbols.ts:42 The pool the tradable's orders go to — always `market.poolAddress`, so it carries that field's type rather than widening it back to `string`. --- # /docs/typescript/api/index/interfaces/Trader [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Trader # Interface: Trader Defined in: packages/sdk/src/trade.ts:2122 The SDK's write tier — every pool/market transaction it can sign and send, bound to one signer. Built via `client.createTrader(config)` (see [TraderConfig](TraderConfig.md)); shares that client's chain, addresses, and WebSocket. Every write AWAITS its receipt before resolving — there is no bare-hash return to babysit. Order placements additionally resolve to the decoded order id + fills. ## Methods ### placeOrder() > **placeOrder**(`params`): `Promise`\<[`PlaceOrderResult`](PlaceOrderResult.md)\> Defined in: packages/sdk/src/trade.ts:2148 Place a limit order (auto-approving the escrow token by default). Resolves once mined, with the resting order id and any fills. **Gotchas** - Throws [InvalidInputError](../classes/InvalidInputError.md) - `price` or `quantity` was not > 0. - Throws [ContractRevertError](../classes/ContractRevertError.md) - the pool rejected the order; `errorName` carries the protocol's own error (e.g. `InsufficientBalance`). Also thrown when the transaction mines with a reverted status — the SDK replays the call to recover the reason, so you get a name rather than a failed receipt. - Throws [RpcError](../classes/RpcError.md) - the send never got an answer from the node. **Example** (Placing a binary bid) Bid 0.62 for 10 YES, bigint-exact (6-decimal collateral). ```ts const trader = client.createTrader({ privateKey }); const res = await trader.placeOrder({ pool, side: "BUY_YES", price: 620_000n, // 0.62 × 10^6 quantity: 10_000_000n, // 10 outcome tokens × 10^6 }); console.log(res.orderId, res.fills.length); // resting id (if it rested) + immediate fills ``` #### Parameters ##### params [`PlaceOrderParams`](PlaceOrderParams.md) #### Returns `Promise`\<[`PlaceOrderResult`](PlaceOrderResult.md)\> *** ### cancelOrder() > **cancelOrder**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2157 Cancel a resting order on its pool (works for spot + binary). **Gotchas** - Throws [ContractRevertError](../classes/ContractRevertError.md) - the cancel did not land (already filled, already canceled, not the owner — `errorName` distinguishes them). - Throws [RpcError](../classes/RpcError.md) - the send never got an answer from the node. #### Parameters ##### params [`CancelOrderParams`](CancelOrderParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### reduceOrder() > **reduceOrder**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2163 Shrink a resting order's remaining quantity in place, keeping its price-time queue priority (works for spot + binary). Reverts on-chain for an expired order — use [Trader.cancelOrder](#cancelorder) there. #### Parameters ##### params [`ReduceOrderParams`](ReduceOrderParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### cancelExpiredOrders() > **cancelExpiredOrders**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2169 Permissionless keeper drain: clean an explicit list of expired resting orders on a pool, returning each order's escrow to its owner (best-effort; skips non-expired / stale ids). #### Parameters ##### params [`CancelExpiredOrdersParams`](CancelExpiredOrdersParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### sweepExpiredAtLevel() > **sweepExpiredAtLevel**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2174 Permissionless keeper drain: clean up to `maxCount` expired orders at one price level on a side. #### Parameters ##### params [`SweepExpiredAtLevelParams`](SweepExpiredAtLevelParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### captureClose() > **captureClose**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2181 Permissionless closing-price capture on a BinaryPool (post-expiry): stores the closing mid and lifts the closing-book lock. Required before sweeping a pre-terminal closing book — a `CloseNotCaptured` revert on a cancel/sweep means "capture first, then retry". #### Parameters ##### params [`CaptureCloseParams`](CaptureCloseParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### approveBuilder() > **approveBuilder**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2197 Opt a routing/builder frontend in on a pool so orders the trader places with that builder code may charge up to `maxFeeBpsTimes1k` (0 revokes). Required before a non-zero `builder`/`builderFeeBpsTimes1k` on [Trader.placeOrder](#placeorder), [Trader.placeSpotOrder](#placespotorder) or [Trader.placePerpOrder](#placeperporder). Binary, spot and perp pools each implement this interface, but the approval is stored PER POOL: approving a builder on one pool grants nothing on another. Call it once per pool the trader will place attributed orders on, or the placement reverts. Each pool declares the whole builder-error set; which one fires depends on the check that trips first. With NO approval at all that is `BuilderNotApproved` on a SpotPool (it guards `approved > 0`), `BuilderFeeExceedsApproval` on a PerpPool, and `BuilderFeeExceedsCap` on a BinaryPool — whose ceiling, unlike the other two, is frozen at init. #### Parameters ##### params [`ApproveBuilderParams`](ApproveBuilderParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### getBuilderApproval() > **getBuilderApproval**(`ref`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/trade.ts:2199 Read a trader's per-builder approval cap on a pool (pool bps×1000; 0 = none). #### Parameters ##### ref [`BuilderApprovalRef`](BuilderApprovalRef.md) #### Returns `Promise`\<`bigint`\> *** ### getEffectiveBuilderApproval() > **getEffectiveBuilderApproval**(`ref`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/trade.ts:2205 Effective builder approval on a pool: the trader's raw cap clamped by the pool's protocol-wide `getMaxBuilderFeeBpsTimes1k` ceiling — the actual enforced limit a `builderFeeBpsTimes1k` on any place-order verb must not exceed. #### Parameters ##### ref [`BuilderApprovalRef`](BuilderApprovalRef.md) #### Returns `Promise`\<`bigint`\> *** ### getMaxBuilderFeeBpsTimes1k() > **getMaxBuilderFeeBpsTimes1k**(`pool`): `Promise`\<`bigint`\> Defined in: packages/sdk/src/trade.ts:2207 Read a pool's protocol-wide builder-fee ceiling (bps×1000). #### Parameters ##### pool `` `0x${string}` `` #### Returns `Promise`\<`bigint`\> *** ### placeSpotOrder() > **placeSpotOrder**(`params`): `Promise`\<[`PlaceOrderResult`](PlaceOrderResult.md)\> Defined in: packages/sdk/src/trade.ts:2218 Place a spot limit/market order on a SpotPool (auto-approves the escrow token, or sends native msg.value on a native-base sell). An ERC-20 approval check uses `requiredAmount`, which is the pool's worst-case reserve including fee headroom. A native sell sends `delta`, which subtracts the owner's current vault balance from that reserve. The SDK reads the requirement once per uncached token/pool approval and on each native-base sell. #### Parameters ##### params [`PlaceSpotOrderParams`](PlaceSpotOrderParams.md) #### Returns `Promise`\<[`PlaceOrderResult`](PlaceOrderResult.md)\> *** ### placeSpotOrders() > **placeSpotOrders**(`params`): `Promise`\<[`PlaceSpotOrdersResult`](PlaceSpotOrdersResult.md)\> Defined in: packages/sdk/src/trade.ts:2267 Place several orders on one SpotPool in a single transaction — a market maker's ladder in one tx instead of a loop of sends. **Gotchas** This write is NON-PAYABLE: unlike [Trader.placeSpotOrder](#placespotorder), it takes no `msg.value`. A native-base sell in a batch therefore funds from the pool's VAULT balance — pre-deposit native to the vault and auto-pull consumes it. ERC-20 auto-pull works normally per request, and the batch approves each escrow token once for the whole batch's total. SPOT ONLY. A binary pool reverts `UseBinaryPlacement` on generic placement — the YES/NO kind must be explicit, so use [Trader.placeOrder](#placeorder) there. A request that does not place is NOT an error: `outcomes[i].success` is false with no id for a PostOnly that would cross, an unfilled FillOrKill, an IOC that found no liquidity, an already-expired expiry, or a CancelTaker self-match. A hard validation error (bad lot size, insufficient funds) reverts the whole batch. Outcome attribution matches each `OrderPlaced` event to its request on every field the event echoes (side, price, quantity, userData, expiry), in order. Two byte-identical adjacent requests with different outcomes are therefore indistinguishable from logs — the earlier index gets the credit. Tag rungs with distinct `userData` when exact attribution matters. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `orders` was empty, or a request had a non-positive price or quantity. - Throws [ContractRevertError](../classes/ContractRevertError.md) - the batch was rejected; `errorName` carries the protocol's error (`EmptyBatch`, `UseBinaryPlacement` on a binary pool, or a per-order validation failure). **Example** (Placing a spot-order batch) ```ts // Place a three-rung sell ladder in one transaction. const trader = client.createTrader({ privateKey }); const res = await trader.placeSpotOrders({ pool, quoteToken, baseToken, orders: [1_010_000n, 1_020_000n, 1_030_000n].map((price) => ({ isBid: false, price, quantity: 1_000_000n, })), }); // Index-aligned with `orders`; a rung that did not place is success:false. const ids = res.outcomes.flatMap((o) => (o.success ? [o.orderId!] : [])); ``` #### Parameters ##### params [`PlaceSpotOrdersParams`](PlaceSpotOrdersParams.md) #### Returns `Promise`\<[`PlaceSpotOrdersResult`](PlaceSpotOrdersResult.md)\> *** ### cancelOrders() > **cancelOrders**(`params`): `Promise`\<[`CancelOrdersResult`](CancelOrdersResult.md)\> Defined in: packages/sdk/src/trade.ts:2293 Cancel several resting orders on one pool in a single transaction — pull a whole ladder without leaving the remaining rungs exposed. Works on spot AND binary pools (cancel is inherited from the OrderBook base, not placement-gated). **Gotchas** BEST-EFFORT by design: an id that can no longer be cancelled (already filled, already cancelled, expired-and-swept, not owned by the signer) is SKIPPED on-chain instead of reverting the batch — which is the point in a fast market. Each `outcomes[i].cancelled` is inferred from whether the id emitted a cancel event, so a `false` does NOT tell you WHY: a benign fill race and a wrong id look identical here. Reconcile against the book if you need to know. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `orderIds` was empty. - Throws [ContractRevertError](../classes/ContractRevertError.md) - `errorName` `EmptyBatch` when the contract rejects the payload. **Example** (Inspecting batch cancellations) ```ts const trader = client.createTrader({ privateKey }); const res = await trader.cancelOrders({ pool, orderIds: ladderIds }); const skipped = res.outcomes.filter((o) => !o.cancelled).map((o) => o.orderId); ``` #### Parameters ##### params [`CancelOrdersParams`](CancelOrdersParams.md) #### Returns `Promise`\<[`CancelOrdersResult`](CancelOrdersResult.md)\> *** ### reduceOrders() > **reduceOrders**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2309 Shrink several resting orders in place in a single transaction, each keeping its price-time queue priority. Works on spot AND binary pools. **Gotchas** ATOMIC, unlike [Trader.cancelOrders](#cancelorders): the FIRST invalid reduction reverts the entire batch and no order changes. A reduction is invalid if the new quantity is not a `lotSize` multiple, is below `minQuantity`, is not strictly less than the current remaining, or the order has expired (cancel those instead). Size the batch accordingly — one stale id loses the whole tx. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `reductions` was empty. - Throws [ContractRevertError](../classes/ContractRevertError.md) - a reduction was rejected; `errorName` carries the protocol's error. #### Parameters ##### params [`ReduceOrdersParams`](ReduceOrdersParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### placePerpOrder() > **placePerpOrder**(`params`): `Promise`\<[`PlaceOrderResult`](PlaceOrderResult.md)\> Defined in: packages/sdk/src/trade.ts:2314 Place a perp limit/market order on a PerpPool. Margin is locked from the signer's MarginBank balance — [Trader.depositMargin](#depositmargin) first. #### Parameters ##### params [`PlacePerpOrderParams`](PlacePerpOrderParams.md) #### Returns `Promise`\<[`PlaceOrderResult`](PlaceOrderResult.md)\> *** ### amendOrder() > **amendOrder**(`params`): `Promise`\<[`AmendOrderResult`](AmendOrderResult.md)\> Defined in: packages/sdk/src/trade.ts:2358 Cancel ONE resting order and place its replacement atomically — the re-quote primitive, with no gap on the book. **When to use** Re-pricing a single quote. For a whole ladder use [Trader.amendOrders](#amendorders), which cancels every old order before placing any replacement. To shrink an order without losing its place in the queue use [Trader.reduceOrder](#reduceorder) — amend is not priority-preserving. **Details** Prefer this over [Trader.amendOrders](#amendorders) with a one-element array: this raises the replacement's own landing-time reason (`PostOnlyWouldCross`, `SelfMatchCancelTaker`, `ImmediateOrCancelNoFill`, `FillOrKillNotFillable`, `OrderAlreadyExpired`), where the batch wraps it as `AmendReplacementRejected(requestIndex, reason)` and leaves the caller unwrapping an index it already knew. **Gotchas** SpotPool and PerpPool only — a BinaryPool reverts `UseBinaryPlacement`, since binary placement is its own entry point. The replacement gets a NEW order id, so update local tracking. Non-payable: a native auto-pull amend reverts, because the cancel leg delivers the freed native to the wallet and the place leg cannot reach it — fund native replacements from a manual-vault balance. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `price` or `quantity` was not > 0. - Throws [ContractRevertError](../classes/ContractRevertError.md) - the old order was gone and `alwaysPlace` was not set (`AmendOldOrderGone`), it belongs to someone else (`IncorrectSender`), or the replacement did not rest or fill; `errorName` carries the protocol's error. **Example** (Amending an order) Re-quote one bid a tick lower, and keep the new id. ```ts const { newOrderId } = await trader.amendOrder({ pool, oldOrderId: resting, newOrder: { isBid: true, price: 1_990_000n, quantity: 5_000_000n }, }); ``` #### Parameters ##### params [`AmendOrderParams`](AmendOrderParams.md) #### Returns `Promise`\<[`AmendOrderResult`](AmendOrderResult.md)\> *** ### amendOrders() > **amendOrders**(`params`): `Promise`\<[`AmendOrdersResult`](AmendOrdersResult.md)\> Defined in: packages/sdk/src/trade.ts:2363 Cancel N orders and place their replacements atomically. All-or-nothing, and it places — so the same BinaryPool restriction applies. #### Parameters ##### params [`AmendOrdersParams`](AmendOrdersParams.md) #### Returns `Promise`\<[`AmendOrdersResult`](AmendOrdersResult.md)\> *** ### buildPlaceOrder() > **buildPlaceOrder**(`params`): `Promise`\<[`UnsignedOrder`](UnsignedOrder.md)\> Defined in: packages/sdk/src/trade.ts:2404 Build a binary placement WITHOUT sending it — the same inputs as [Trader.placeOrder](#placeorder), handed back as unsigned calls. **When to use** Reach for this when the signing and the sending are not the same moment: to pre-sign an ERC-4337 UserOp while the user is still filling in the form, to batch the order into a multicall, to hand it to a relayer, or to simulate it. For ordinary "place this order now", use [Trader.placeOrder](#placeorder) — it is one call and it handles the approval for you. **Gotchas** The approval is RETURNED, not sent. `placeOrder` approves as a side effect; this cannot, because sending is exactly what it must not do. Send `approval` first when it is present, or the order reverts on-chain. Still `async`: a binary placement reads the pool's market expiry when the caller does not pass `expireTimestampNs`, and resolves the pool's escrow tokens to work out which approval is needed. Pass `expireTimestampNs`, `outcomeToken`, `yesId`, `noId`, and `collateral` to keep it off the network. No gas estimate and no nonce ride along — those belong to the signer, and pinning them here would stale the moment the call is cached. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `price` or `quantity` was not > 0. **Example** (Building an unsigned order) Pre-sign off the form, send on the click. ```ts const { order, approval } = await trader.buildPlaceOrder({ pool, side: "BUY_YES", price: 620_000n, quantity: 10_000_000n, }); if (approval) await walletClient.sendTransaction({ ...approval, account }); const signed = await account.signTransaction({ ...order, nonce, ...fees }); ``` #### Parameters ##### params [`PlaceOrderParams`](PlaceOrderParams.md) #### Returns `Promise`\<[`UnsignedOrder`](UnsignedOrder.md)\> *** ### buildPlaceSpotOrder() > **buildPlaceSpotOrder**(`params`): `Promise`\<[`UnsignedOrder`](UnsignedOrder.md)\> Defined in: packages/sdk/src/trade.ts:2428 Build a spot placement WITHOUT sending it — see [Trader.buildPlaceOrder](#buildplaceorder) for when to reach for this and how the returned approval works. A native-base sell pays via `msg.value`, so it comes back with no `approval` and a non-zero `order.value`: the pool's vault shortfall for this order, fee headroom included, as read when the call is built. A vault that gains funds before the send only shrinks the requirement (the pool refunds the overage); one that loses them makes the pool reject the call. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `price` or `quantity` is not positive. - Throws [ContractRevertError](../classes/ContractRevertError.md) - the native-sell funding read reverted. - Throws [RpcError](../classes/RpcError.md) - the native-sell funding read did not complete. **Gotchas** A spot placement that DEFAULTS its expiry pins it to ~50 years from *now*, so two builds a second apart differ in that one argument. Harmless against a 50-year horizon, but it means such a build is not byte-reproducible: sign and send the `order` you were handed rather than rebuilding and expecting the same bytes. Pass [PlaceSpotOrderParams.expireTimestampNs](PlaceSpotOrderParams.md#expiretimestampns) explicitly and the build is reproducible, as binary and perp already are. #### Parameters ##### params [`PlaceSpotOrderParams`](PlaceSpotOrderParams.md) #### Returns `Promise`\<[`UnsignedOrder`](UnsignedOrder.md)\> *** ### buildPlacePerpOrder() > **buildPlacePerpOrder**(`params`): `Promise`\<[`UnsignedOrder`](UnsignedOrder.md)\> Defined in: packages/sdk/src/trade.ts:2436 Build a perp placement WITHOUT sending it — see [Trader.buildPlaceOrder](#buildplaceorder) for when to reach for this. Never carries an `approval`: margin is locked from the MarginBank balance rather than escrowed per order ([Trader.depositMargin](#depositmargin) first). #### Parameters ##### params [`PlacePerpOrderParams`](PlacePerpOrderParams.md) #### Returns `Promise`\<[`UnsignedOrder`](UnsignedOrder.md)\> *** ### depositMargin() > **depositMargin**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2441 Deposit collateral into the MarginBank (auto-approving the collateral token to the bank by default). One cross-margin balance covers every perp pool. #### Parameters ##### params [`DepositMarginParams`](DepositMarginParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### withdrawMargin() > **withdrawMargin**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2443 Withdraw free collateral from the MarginBank (margin-checked on-chain). #### Parameters ##### params [`WithdrawMarginParams`](WithdrawMarginParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### withdrawVault() > **withdrawVault**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2451 Claim a payout that fell back to a pool's internal ERC20Vault (a `PayoutFallbackToVault` credit) back to the wallet. Read the claimable amount first with `client.getVaultBalance({ vault, owner, token })`. Also how funds leave a manual-mode balance — see [setManualVaultMode](#setmanualvaultmode). #### Parameters ##### params [`WithdrawVaultParams`](WithdrawVaultParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### depositVault() > **depositVault**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2458 Pre-fund an ERC-20 balance in a pool's internal vault (approves the pool when needed). Ordinary placement needs no deposit — auto-pull covers it; deposit when funding must precede the order. Native goes in via [depositVaultNative](#depositvaultnative). #### Parameters ##### params [`DepositVaultParams`](DepositVaultParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### depositVaultNative() > **depositVaultNative**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2472 Pre-fund a native (SOMI) vault balance for the signer, or for another account when `owner` is set. The amount travels as `msg.value`. A binary pool's vault takes exactly one token, so the SDK reads the pool's `collateralToken()` first and refuses a native deposit into a pool whose collateral is not native rather than spending a failed transaction. A pool without that view (a SpotPool) goes straight to the chain. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `amount` is not positive, or the pool is a binary pool whose collateral is not native. - Throws [RpcError](../classes/RpcError.md) - the preflight read or the deposit did not complete. A failed preflight never broadcasts. - Throws [ContractRevertError](../classes/ContractRevertError.md) - the pool rejected the deposit (`InvalidDepositOrWithdrawal` when native is not one of its tokens). #### Parameters ##### params [`DepositVaultNativeParams`](DepositVaultNativeParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### depositVaultNativeFor() > **depositVaultNativeFor**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2477 Pre-fund ANOTHER account's native vault balance — [depositVaultNative](#depositvaultnative) with `owner` required (an operator funding a bot wallet). Same errors. #### Parameters ##### params [`DepositVaultNativeParams`](DepositVaultNativeParams.md) & `object` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setManualVaultMode() > **setManualVaultMode**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2483 Opt out of (or back into) wallet auto-pull on one SpotPool. While enabled, orders draw only on pre-deposited vault balance AND payouts stay as vault credit — claim them with [withdrawVault](#withdrawvault). Scoped per user per pool. #### Parameters ##### params [`SetManualVaultModeParams`](SetManualVaultModeParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setOperatorApprovalForPool() > **setOperatorApprovalForPool**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2489 Grant or revoke an operator on ONE SpotPool — the tighter way to let a bot trade for you. The signer is the granting owner; `approved: false` revokes. Read it back with [SomniaMarketsClient.isApprovedForPool](SomniaMarketsClient.md#isapprovedforpool). #### Parameters ##### params [`SetOperatorApprovalForPoolParams`](SetOperatorApprovalForPoolParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setOperatorApprovalGlobal() > **setOperatorApprovalGlobal**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2495 Grant or revoke an operator across EVERY registered pool. Required for `SpotRouter` (not on any pool's allowlist); prefer [setOperatorApprovalForPool](#setoperatorapprovalforpool) for a single-venue bot. #### Parameters ##### params [`SetOperatorApprovalGlobalParams`](SetOperatorApprovalGlobalParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### setPerpLeverage() > **setPerpLeverage**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2497 Set the signer's max leverage for one perp pool (caps position size vs margin). #### Parameters ##### params [`SetPerpLeverageParams`](SetPerpLeverageParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### proposePerpWalletLink() > **proposePerpWalletLink**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2517 Offer a child wallet a link to the signer as its main — the first half of the handshake that gives a perp sub-account access to the signer's wallet. Isolated margin on perps is one wallet per position, so a trader running N isolated positions runs N wallets. Linking them lets each child's position-increasing order draw its shortfall from this main's wallet, so one funded treasury serves all N. The signer is the MAIN and this moves no money. The child must send [acceptPerpWalletLink](#acceptperpwalletlink) next, and it is the only party that can: read the offer from `client.listPerpWalletLinkEvents({ child })`, which is the ONLY record of a pending proposal. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `registry` is the zero address, or none of `registry`, `marginBank` and `pool` was passed. - Throws [NotConfiguredError](../classes/NotConfiguredError.md) - the bank holds no registry, so the rail is dormant on this deployment. - Throws [RpcError](../classes/RpcError.md) - the registry or bank resolution read did not complete. A failed resolution never broadcasts. - Throws [ContractRevertError](../classes/ContractRevertError.md) - `CannotLinkSelf`, `CallerIsChild` (the signer is already someone's child), `AlreadyLinked` (`child` already has a main), `NoStateChange` (this offer already stands), or `ZeroAddress`. #### Parameters ##### params [`ProposePerpWalletLinkParams`](ProposePerpWalletLinkParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### acceptPerpWalletLink() > **acceptPerpWalletLink**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2531 Accept a main's standing offer, as the child — the second half of the handshake. From here the signer's position-increasing orders pull their shortfall from `main`'s wallet. Funding does not wait for link maturity; `maturesAt` gates ADL netting only. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `registry` is the zero address, or none of `registry`, `marginBank` and `pool` was passed. - Throws [NotConfiguredError](../classes/NotConfiguredError.md) - the bank holds no registry, so the rail is dormant on this deployment. - Throws [RpcError](../classes/RpcError.md) - the registry or bank resolution read did not complete. A failed resolution never broadcasts. - Throws [ContractRevertError](../classes/ContractRevertError.md) - `NoProposalPending`, `CallerIsChild` (`main` has itself become a child), `CallerIsMain` (the signer already has children), `AlreadyLinked`, or `MaxChildrenReached`. #### Parameters ##### params [`AcceptPerpWalletLinkParams`](AcceptPerpWalletLinkParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### cancelPerpWalletLinkProposal() > **cancelPerpWalletLinkProposal**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2541 Withdraw an offer the signer made and the child has not accepted. An ACCEPTED link comes down with [unlinkPerpWallet](#unlinkperpwallet) instead. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `registry` is the zero address, or none of `registry`, `marginBank` and `pool` was passed. - Throws [NotConfiguredError](../classes/NotConfiguredError.md) - the bank holds no registry, so the rail is dormant on this deployment. - Throws [RpcError](../classes/RpcError.md) - the registry or bank resolution read did not complete. A failed resolution never broadcasts. - Throws [ContractRevertError](../classes/ContractRevertError.md) - `NoProposalPending` (nothing pending for this pair, including an offer already accepted). #### Parameters ##### params [`CancelPerpWalletLinkProposalParams`](CancelPerpWalletLinkProposalParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### unlinkPerpWallet() > **unlinkPerpWallet**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2554 Dissolve an accepted link, from either end — pass the other party. Settles no money: a claim the main funded survives the unlink and still gates the child's withdrawals. `PerpsUnlinkGuard` vetoes it while the leaver holds open positions and is liquidatable. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `registry` is the zero address, or none of `registry`, `marginBank` and `pool` was passed. - Throws [NotConfiguredError](../classes/NotConfiguredError.md) - the bank holds no registry, so the rail is dormant on this deployment. - Throws [RpcError](../classes/RpcError.md) - the registry or bank resolution read did not complete. A failed resolution never broadcasts. - Throws [ContractRevertError](../classes/ContractRevertError.md) - `NotLinked` (the two are not a linked pair) or `UnlinkBlockedByGuard` (the leaver is liquidatable with open positions). #### Parameters ##### params [`UnlinkPerpWalletParams`](UnlinkPerpWalletParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### repayPerpMainFunding() > **repayPerpMainFunding**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2567 Return principal the signer's main funded, as the child. Over-asking is clamped to `min(amount, outstanding, balance)` rather than rejected, so the outstanding figure from `client.getPerpMainFunding` cannot be stale-high. Repaying is what unlocks the child's own money: `withdraw` frees at most `balance - outstanding`. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `amount` is not positive, `marginBank` is the zero address, or neither `marginBank` nor `pool` was passed. - Throws [RpcError](../classes/RpcError.md) - the bank resolution read did not complete. A failed resolution never broadcasts. - Throws [ContractRevertError](../classes/ContractRevertError.md) - `NoFundedPrincipal` (nothing outstanding), `NothingToReturn` (the clamp reached zero, so the balance is gone), or `InsufficientMarginAfterWithdrawal`. #### Parameters ##### params [`RepayPerpMainFundingParams`](RepayPerpMainFundingParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### recallPerpMainFunding() > **recallPerpMainFunding**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2579 Pull principal back out of a child, as the payer. The signer must be the payer the bank recorded at funding time. Recovers principal, never winnings, and performs no unlink — the child can be funded again without a fresh handshake. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `amount` is not positive, `marginBank` is the zero address, or neither `marginBank` nor `pool` was passed. - Throws [RpcError](../classes/RpcError.md) - the bank resolution read did not complete. A failed resolution never broadcasts. - Throws [ContractRevertError](../classes/ContractRevertError.md) - `OnlyFundingPayer` (the signer is not the recorded payer), `NoFundedPrincipal`, `NothingToReturn`, or `InsufficientMarginAfterWithdrawal`. #### Parameters ##### params [`RecallPerpMainFundingParams`](RecallPerpMainFundingParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### pokeFunding() > **pokeFunding**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2581 Permissionlessly poke a perp pool's funding settlement (updateFunding). #### Parameters ##### params ###### pool `` `0x${string}` `` ###### gas? `bigint` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### placeSpotStopOrder() > **placeSpotStopOrder**(`params`): `Promise`\<[`PlaceStopOrderResult`](PlaceStopOrderResult.md)\> Defined in: packages/sdk/src/trade.ts:2586 Place a spot stop-loss / take-profit pending order on a SpotStopOrderRegistry (funds the trigger via SOMI msg.value). #### Parameters ##### params [`PlaceSpotStopOrderParams`](PlaceSpotStopOrderParams.md) #### Returns `Promise`\<[`PlaceStopOrderResult`](PlaceStopOrderResult.md)\> *** ### cancelStopOrder() > **cancelStopOrder**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2588 Cancel a pending stop order on its registry. #### Parameters ##### params [`CancelStopOrderParams`](CancelStopOrderParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### placePerpStopOrder() > **placePerpStopOrder**(`params`): `Promise`\<[`PlacePerpStopOrderResult`](PlacePerpStopOrderResult.md)\> Defined in: packages/sdk/src/trade.ts:2599 Place a perp take-profit / stop-loss on a PerpStopOrderRegistry (funds the trigger via SOMI msg.value), granting the registry's one-time operator approval first if the signer has not already. The single perp-stop create entry: pass `pair` for a linked one-cancels-other set, or `intent: "opening"` for a stop-entry. Both default off, so an existing call is an ordinary reduce-only stop and produces the same transaction it always did. #### Parameters ##### params [`PlacePerpStopOrderParams`](PlacePerpStopOrderParams.md) #### Returns `Promise`\<[`PlacePerpStopOrderResult`](PlacePerpStopOrderResult.md)\> *** ### linkPerpStopOrders() > **linkPerpStopOrders**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2604 Link two existing perp stops into a one-cancels-other pair — the after-the-fact form of `placePerpStopOrder({ pair })`, and how a survivor is re-paired. #### Parameters ##### params [`LinkPerpStopOrdersParams`](LinkPerpStopOrdersParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### cancelPerpStopOrder() > **cancelPerpStopOrder**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2609 Cancel a pending perp stop. If it is one leg of a pair the other stays armed and is unlinked — use [cancelPerpStopOrders](#cancelperpstoporders) to tear down both. #### Parameters ##### params [`CancelStopOrderParams`](CancelStopOrderParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### cancelPerpStopOrders() > **cancelPerpStopOrders**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2611 Cancel several of the signer's pending perp stops in one tx, one refund transfer. #### Parameters ##### params [`CancelPerpStopOrdersParams`](CancelPerpStopOrdersParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### claimPerpStopSomi() > **claimPerpStopSomi**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2616 Claim SOMI the perp stop registry owes the signer — the refund path for an owner that cannot receive native. Reverts `NothingToClaim` on a zero balance. #### Parameters ##### params [`ClaimPerpStopSomiParams`](ClaimPerpStopSomiParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### buildPlacePerpStopOrder() > **buildPlacePerpStopOrder**(`params`): `Promise`\<[`UnsignedPerpStopOrder`](UnsignedPerpStopOrder.md)\> Defined in: packages/sdk/src/trade.ts:2636 Build [placePerpStopOrder](#placeperpstoporder) without sending it — the stop-registry call plus, unless skipped, the operator grant the trigger needs first. Recover the created ids from your own receipt with `decodePerpStopOrderIds`. #### Parameters ##### params [`PlacePerpStopOrderParams`](PlacePerpStopOrderParams.md) #### Returns `Promise`\<[`UnsignedPerpStopOrder`](UnsignedPerpStopOrder.md)\> *** ### buildCancelPerpStopOrder() > **buildCancelPerpStopOrder**(`params`): [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/trade.ts:2638 Build [cancelPerpStopOrder](#cancelperpstoporder) without sending it. #### Parameters ##### params [`CancelStopOrderParams`](CancelStopOrderParams.md) #### Returns [`UnsignedCall`](UnsignedCall.md) *** ### buildCancelPerpStopOrders() > **buildCancelPerpStopOrders**(`params`): [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/trade.ts:2640 Build [cancelPerpStopOrders](#cancelperpstoporders) without sending it. #### Parameters ##### params [`CancelPerpStopOrdersParams`](CancelPerpStopOrdersParams.md) #### Returns [`UnsignedCall`](UnsignedCall.md) *** ### buildDepositMargin() > **buildDepositMargin**(`params`): `Promise`\<[`UnsignedMarginDeposit`](UnsignedMarginDeposit.md)\> Defined in: packages/sdk/src/trade.ts:2645 Build [depositMargin](#depositmargin) without sending it — the `deposit` call plus, unless `autoApprove: false`, the ERC-20 approval the bank needs first. #### Parameters ##### params [`DepositMarginParams`](DepositMarginParams.md) #### Returns `Promise`\<[`UnsignedMarginDeposit`](UnsignedMarginDeposit.md)\> *** ### buildWithdrawMargin() > **buildWithdrawMargin**(`params`): `Promise`\<[`UnsignedCall`](UnsignedCall.md)\> Defined in: packages/sdk/src/trade.ts:2647 Build [withdrawMargin](#withdrawmargin) without sending it. Nothing to approve. #### Parameters ##### params [`WithdrawMarginParams`](WithdrawMarginParams.md) #### Returns `Promise`\<[`UnsignedCall`](UnsignedCall.md)\> *** ### buildAcceptPerpWalletLink() > **buildAcceptPerpWalletLink**(`params`): `Promise`\<[`UnsignedCall`](UnsignedCall.md)\> Defined in: packages/sdk/src/trade.ts:2657 Build [acceptPerpWalletLink](#acceptperpwalletlink) without sending it, so the accept and the child's first isolated placement go out as ONE transaction. The accept must execute first, or the placement finds no main. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `registry` is the zero address, or none of `registry`, `marginBank` and `pool` was passed. - Throws [NotConfiguredError](../classes/NotConfiguredError.md) - the bank holds no registry, so the rail is dormant on this deployment. - Throws [RpcError](../classes/RpcError.md) - the registry or bank resolution read did not complete. A failed resolution never broadcasts. #### Parameters ##### params [`AcceptPerpWalletLinkParams`](AcceptPerpWalletLinkParams.md) #### Returns `Promise`\<[`UnsignedCall`](UnsignedCall.md)\> *** ### buildRepayPerpMainFunding() > **buildRepayPerpMainFunding**(`params`): `Promise`\<[`UnsignedCall`](UnsignedCall.md)\> Defined in: packages/sdk/src/trade.ts:2666 Build [repayPerpMainFunding](#repayperpmainfunding) without sending it, so the repayment and the withdrawal it unlocks go out as ONE transaction. The repayment must execute first — the withdrawal's gate reads the claim it clears. - Throws [InvalidInputError](../classes/InvalidInputError.md) - `amount` is not positive, `marginBank` is the zero address, or neither `marginBank` nor `pool` was passed. - Throws [RpcError](../classes/RpcError.md) - the bank resolution read did not complete. #### Parameters ##### params [`RepayPerpMainFundingParams`](RepayPerpMainFundingParams.md) #### Returns `Promise`\<[`UnsignedCall`](UnsignedCall.md)\> *** ### mintSet() > **mintSet**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2669 Mint a YES+NO set: deposit collateral, receive equal YES + NO. #### Parameters ##### params [`MintSetParams`](MintSetParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### burnSet() > **burnSet**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2671 Burn a YES+NO set: surrender both halves, receive collateral back. #### Parameters ##### params [`BurnSetParams`](BurnSetParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### redeem() > **redeem**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2678 Burn winning outcome tokens for collateral (resolved/voided markets). Settlement-extraction v2: module-routed — the module pulls the caller's winning tokens, finalizes-if-needed, and redeems through BinarySettlement. Takes `marketId` (not a pool address — a pool serves successive markets). #### Parameters ##### params [`RedeemParams`](RedeemParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### signRedeemAuth() > **signRedeemAuth**(`params`): `Promise`\<[`RedeemAuthorization`](RedeemAuthorization.md)\> Defined in: packages/sdk/src/trade.ts:2686 Produce an EIP-712 [RedeemAuthorization](RedeemAuthorization.md) the connected signer (the position owner) hands to a relayer, so the relayer can call [Trader.redeemFor](#redeemfor) and pay the gas while the OWNER receives the payout. Signs over the module's `REDEEM_AUTH_TYPEHASH` in the `SomniaMarkets` domain; no transaction is sent. #### Parameters ##### params [`SignRedeemAuthParams`](SignRedeemAuthParams.md) #### Returns `Promise`\<[`RedeemAuthorization`](RedeemAuthorization.md)\> *** ### redeemFor() > **redeemFor**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2692 Relayer path: submit a position owner's pre-signed [RedeemAuthorization](RedeemAuthorization.md) (from [Trader.signRedeemAuth](#signredeemauth)). The caller pays gas; the module pays the OWNER the collateral (payout is hard-pinned to `owner`, never the relayer). #### Parameters ##### params [`RedeemForParams`](RedeemForParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### redeemMany() > **redeemMany**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2694 Claim winnings from many settled markets in one transaction (batch redeem). #### Parameters ##### params [`RedeemManyParams`](RedeemManyParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### redeemDirect() > **redeemDirect**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2699 Low-level direct redemption against the BinarySettlement singleton (bypasses the module; no operator attribution). Takes the raw ERC-6909 `outcomeId`. #### Parameters ##### params [`RedeemDirectParams`](RedeemDirectParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### claimOwed() > **claimOwed**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2701 Claim an accrued push-fallback (`owed`) balance on the settlement singleton. #### Parameters ##### params [`ClaimOwedParams`](ClaimOwedParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### pokeOracle() > **pokeOracle**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2723 Permissionless oracle retry — the FIRST move when a market is past expiry with no resolution: ask the module to re-pull the answer for its oracle question. **When to use** Use before [Trader.voidExpired](#voidexpired). A poke that succeeds resolves the market normally (winners paid in full); voiding pays everyone 1/N instead, so it is the fallback, not the first resort. **Gotchas** Keyed by ORACLE QUESTION, not market: the module fans out to every market bound to that question and resolves the ones whose adapter answers. Unanswered adapters are skipped, so this can resolve some markets and leave others — a success is not "all bound markets resolved". Reverts `OracleNotAnswered` only when none answered, `UnknownOracleQuestion` when no market is bound; both decode as [ContractRevertError](../classes/ContractRevertError.md), so a keeper loop can branch on `errorName`. #### Parameters ##### params [`PokeOracleParams`](PokeOracleParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### voidExpired() > **voidExpired**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2749 Permissionless dead-oracle escape hatch: void a market whose oracle never answered, so both sides can redeem at 1/N collateral. **When to use** Use only after [Trader.pokeOracle](#pokeoracle) has failed and `expiry + settlementWindow` has elapsed — this is the funds-unstranding backstop, and it pays 1/N rather than the real outcome. **Gotchas** This writes to the MARKET contract, bypassing the module — so the oracle hub's earmark release never fires. Follow with [Trader.syncSettlement](#syncsettlement), then [Trader.finalizeMarket](#finalizemarket) and [Trader.releasePool](#releasepool), to leave the market fully reconciled. Before sending, this reads the market's status, expiry, and settlement window and throws [InvalidInputError](../classes/InvalidInputError.md) naming the gate time if the window is still open — the on-chain `SettlementWindowOpen` revert carries no timestamp, and "when can I retry" is the operator's real question. The comparison uses the chain's `block.timestamp`, matching the contract, so a skewed local clock neither lets a doomed call through nor blocks a valid one. Pass `skipPreflight` to send blind and let the contract judge. #### Parameters ##### params [`VoidExpiredParams`](VoidExpiredParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### finalizeMarket() > **finalizeMarket**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2754 Permissionless keeper: finalize a settled market (sweep its pool's backing + resolution snapshot to the settlement singleton). No-op-guarded on repeat. #### Parameters ##### params [`FinalizeMarketParams`](FinalizeMarketParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### syncSettlement() > **syncSettlement**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2760 Permissionless earmark reconcile: release the oracle earmark of a market voided via `BinaryMarket.voidExpired()` (which bypasses the module, so the hub's earmark release never fired). Idempotent; reverts `MarketNotSettled` while still live. #### Parameters ##### params [`SyncSettlementParams`](SyncSettlementParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### releasePool() > **releasePool**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2765 Permissionless keeper: release a finalized, drained pool back to its creator's free list for recycle onto the next market. #### Parameters ##### params [`ReleasePoolParams`](ReleasePoolParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### getSettlement() > **getSettlement**(`marketId`, `opts?`): `Promise`\<[`SettlementRecord`](SettlementRecord.md) \| `null`\> Defined in: packages/sdk/src/trade.ts:2771 Read a market's settlement record from the BinarySettlement singleton (by bytes32 marketId — resolves the marketKey via the module's yesId). Returns null when the market has never been finalized. #### Parameters ##### marketId `` `0x${string}` `` ##### opts? ###### module? `` `0x${string}` `` ###### settlement? `` `0x${string}` `` #### Returns `Promise`\<[`SettlementRecord`](SettlementRecord.md) \| `null`\> *** ### getFreePools() > **getFreePools**(`creator`, `collateral`, `opts?`): `Promise`\<`` `0x${string}` ``[]\> Defined in: packages/sdk/src/trade.ts:2773 Read a creator's free (finalized + released, reusable) pools for a collateral. #### Parameters ##### creator `` `0x${string}` `` ##### collateral `` `0x${string}` `` ##### opts? ###### module? `` `0x${string}` `` #### Returns `Promise`\<`` `0x${string}` ``[]\> *** ### poolCreator() > **poolCreator**(`pool`, `opts?`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/trade.ts:2775 Read a pool's creator (its first-deploy creator — the only party that can reuse it). #### Parameters ##### pool `` `0x${string}` `` ##### opts? ###### module? `` `0x${string}` `` #### Returns `Promise`\<`` `0x${string}` ``\> *** ### mintSetNative() > **mintSetNative**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2780 Mint a complete YES+NO set paying with NATIVE token via the CollateralRouter (wraps `msg.value` → wNative). The market's collateral must be wNative. #### Parameters ##### params [`MintSetNativeParams`](MintSetNativeParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### mintSetPermit2() > **mintSetPermit2**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2785 Mint a complete YES+NO set pulling collateral via a Permit2 signature through the CollateralRouter (no prior ERC-20 `approve`). #### Parameters ##### params [`MintSetPermit2Params`](MintSetPermit2Params.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### redeemNative() > **redeemNative**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2790 Redeem winning outcome tokens for a NATIVE payout via the CollateralRouter (unwraps wNative → native). Approve the router for the winning outcome first. #### Parameters ##### params [`RedeemNativeParams`](RedeemNativeParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### faucet() > **faucet**(`params?`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2792 Mint TestUSDC from the faucet to the signer. #### Parameters ##### params? [`FaucetParams`](FaucetParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### resolve() > **resolve**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2794 Resolve a market via the FakeOracle (demo resolver). #### Parameters ##### params [`ResolveParams`](ResolveParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### voidMarket() > **voidMarket**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2796 Void a market via the FakeOracle (demo resolver). #### Parameters ##### params [`VoidMarketParams`](VoidMarketParams.md) #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### poke() > **poke**(`params`): `Promise`\<[`TxResult`](TxResult.md)\> Defined in: packages/sdk/src/trade.ts:2798 Poke a market to advance its lifecycle. No-op since status is derived; kept for ABI stability. #### Parameters ##### params ###### market `` `0x${string}` `` ###### gas? `bigint` #### Returns `Promise`\<[`TxResult`](TxResult.md)\> *** ### clearApprovalCache() > **clearApprovalCache**(`token?`, `spender?`): `void` Defined in: packages/sdk/src/trade.ts:2804 Forget cached token approvals so the next escrowing write re-checks allowance. Pass a (token, spender) to clear one pair, or nothing to clear all. Rarely needed — maxUint256 approvals don't decrement. #### Parameters ##### token? `` `0x${string}` `` ##### spender? `` `0x${string}` `` #### Returns `void` --- # /docs/typescript/api/index/interfaces/TraderConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TraderConfig # Interface: TraderConfig Defined in: packages/sdk/src/trade.ts:62 Signer + defaults for `client.createTrader` — how a [Trader](Trader.md) signs. Provide at least one signing source: `privateKey`, a local `account`, or a `walletClient`. ## Properties ### walletClient? > `optional` **walletClient?**: `object` Defined in: packages/sdk/src/trade.ts:69 A pre-built signer (e.g. a browser/wagmi wallet over an injected provider). Only needed when the SDK can't sign locally — with `privateKey` / a local `account`, the SDK signs itself and sends over the client's WebSocket via realtime_sendRawTransaction (send + confirm in one round-trip). *** ### account? > `optional` **account?**: `` `0x${string}` `` \| `Account` Defined in: packages/sdk/src/trade.ts:71 A local signing account (e.g. from viem's privateKeyToAccount). *** ### privateKey? > `optional` **privateKey?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:73 Private key — the SDK derives the account. *** ### publicClient? > `optional` **publicClient?**: `object` Defined in: packages/sdk/src/trade.ts:75 Read client for allowance/receipts. Defaults to the client's WebSocket client. *** ### decimals? > `optional` **decimals?**: `number` Defined in: packages/sdk/src/trade.ts:77 Outcome/collateral decimals (default 6). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:82 Default gas ceiling per tx (10,000,000 when unset); each write can override per-call via its params' `gas`. --- # /docs/typescript/api/index/interfaces/TransactionSummary [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TransactionSummary # Interface: TransactionSummary Defined in: packages/sdk/src/system.ts:218 Chain-direct summary of one transaction — sender, gas spent, fee paid, status — for enriching an order/fill view with what the tx cost. One `eth_getTransactionByHash` + one `eth_getTransactionReceipt`, in parallel. ## Properties ### from > **from**: `string` Defined in: packages/sdk/src/system.ts:220 Sender (the wallet that paid gas), lowercased. *** ### to > **to**: `string` \| `null` Defined in: packages/sdk/src/system.ts:222 Target contract, lowercased; null on a deployment. *** ### nonce > **nonce**: `number` Defined in: packages/sdk/src/system.ts:223 *** ### status > **status**: `"success"` \| `"reverted"` Defined in: packages/sdk/src/system.ts:224 *** ### gasUsed > **gasUsed**: `bigint` Defined in: packages/sdk/src/system.ts:225 *** ### gasLimit > **gasLimit**: `bigint` Defined in: packages/sdk/src/system.ts:227 The sender's gas limit for the tx. *** ### effectiveGasPrice > **effectiveGasPrice**: `bigint` Defined in: packages/sdk/src/system.ts:228 *** ### feeWei > **feeWei**: `bigint` Defined in: packages/sdk/src/system.ts:230 gasUsed × effectiveGasPrice — the fee paid, wei of the native token. *** ### value > **value**: `bigint` Defined in: packages/sdk/src/system.ts:232 Native value sent with the tx (wei). *** ### logCount > **logCount**: `number` Defined in: packages/sdk/src/system.ts:234 Log records in the receipt — how much the tx did (batch orders emit many). --- # /docs/typescript/api/index/interfaces/TransferOperatorOwnershipParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TransferOperatorOwnershipParams # Interface: TransferOperatorOwnershipParams Defined in: packages/sdk/src/operatorAdmin.ts:155 Params for [OperatorAdmin.transferOperatorOwnership](OperatorAdmin.md#transferoperatorownership). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:157 The operator whose ownership is staged. Caller must be its owner. *** ### newOwner > **newOwner**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:162 The staged new owner — must later call [OperatorAdmin.acceptOperatorOwnership](OperatorAdmin.md#acceptoperatorownership) to complete the transfer. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:164 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/TriggerRollParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TriggerRollParams # Interface: TriggerRollParams Defined in: packages/sdk/src/marketCreatorAdmin.ts:146 Params for [MarketCreatorAdmin.triggerRoll](MarketCreatorAdmin.md#triggerroll). ## Properties ### creator > **creator**: `` `0x${string}` `` Defined in: packages/sdk/src/marketCreatorAdmin.ts:148 The MarketCreator owning the series. Caller must be its owner. *** ### seriesId > **seriesId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:150 The series to roll. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/marketCreatorAdmin.ts:152 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/TxResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TxResult # Interface: TxResult Defined in: packages/sdk/src/trade.ts:90 Base result of a confirmed write — the SDK waits for the receipt before resolving. ## Extended by - [`PlaceOrderResult`](PlaceOrderResult.md) - [`PlaceStopOrderResult`](PlaceStopOrderResult.md) - [`PlacePerpStopOrderResult`](PlacePerpStopOrderResult.md) - [`PlaceSpotOrdersResult`](PlaceSpotOrdersResult.md) - [`CancelOrdersResult`](CancelOrdersResult.md) - [`AmendOrderResult`](AmendOrderResult.md) - [`AmendOrdersResult`](AmendOrdersResult.md) - [`RegisterOperatorResult`](RegisterOperatorResult.md) - [`CreateVenueResult`](CreateVenueResult.md) - [`ScheduleQuestionResult`](ScheduleQuestionResult.md) - [`CreateMarketCreatorResult`](CreateMarketCreatorResult.md) ## Properties ### hash > **hash**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:92 The transaction hash. *** ### receipt > **receipt**: `TransactionReceipt` Defined in: packages/sdk/src/trade.ts:94 The mined receipt (status, gas used, logs). --- # /docs/typescript/api/index/interfaces/UnifiedBalance [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedBalance # Interface: UnifiedBalance Defined in: packages/sdk/src/unified/structs.ts:305 One currency's balance, human units (ccxt shape). For spot/binary, funds escrowed in resting orders live in the pools — not the wallet — so `used` is 0 and `free === total`. NOTE: this "used is 0" property is a fact about wallet-held tokens, not a law of the venue — perp collateral IS locked (MarginBank margin against open positions), and a margin-aware `fetchBalance` arm must report it through `used` rather than pretending the invariant generalizes. ## Properties ### free > **free**: `number` Defined in: packages/sdk/src/unified/structs.ts:307 Spendable balance. *** ### used > **used**: `number` Defined in: packages/sdk/src/unified/structs.ts:309 Locked balance (0 for wallet-held spot/binary tokens; perp margin when reported). *** ### total > **total**: `number` Defined in: packages/sdk/src/unified/structs.ts:311 `free + used`, human units. --- # /docs/typescript/api/index/interfaces/UnifiedBalances [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedBalances # Interface: UnifiedBalances Defined in: packages/sdk/src/unified/structs.ts:319 Balances keyed by currency code, plus the raw reads under `info`. ## Indexable > \[`code`: `string`\]: [`UnifiedBalance`](UnifiedBalance.md) --- # /docs/typescript/api/index/interfaces/UnifiedFundingRate [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedFundingRate # Interface: UnifiedFundingRate Defined in: packages/sdk/src/unified/structs.ts:407 A perp funding-rate snapshot (live chain read; rates are fractions, not %). ## Properties ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:409 The perp's tradable symbol, e.g. "BTC/USDSO:USDSO". *** ### markPrice > **markPrice**: `number` \| `undefined` Defined in: packages/sdk/src/unified/structs.ts:417 Mark price, human quote units. Undefined when the mark feed is stale — a live read reports that explicitly, and a historical row carries the contract's 0 sentinel, neither of which should be flattened to a price of zero. *** ### indexPrice > **indexPrice**: `number` Defined in: packages/sdk/src/unified/structs.ts:419 Oracle index price, human quote units. *** ### fundingRate > **fundingRate**: `number` Defined in: packages/sdk/src/unified/structs.ts:435 Funding rate per 8 HOURS as a plain fraction (0.0001 = 0.01%). Normalized to a fixed 8h axis (the Hyperliquid/Binance convention) from the chain's per-calculation-window value, so it stays comparable across a parameter change. NOT the amount charged at each settlement: that is this divided by `n = fundingWindowSec / fundingIntervalSec`, which is 8 on every live pool and has been 96 at a 300s cadence. `info` carries both figures. On a HISTORICAL row that caught up over several intervals, `rate / n` is only ONE interval's worth: the amount that settlement actually charged is `rate * intervalsAccrued / n`. Rows at the deployed one-interval horizon have `intervalsAccrued` of 1, so the two agree there and disagree only on older catch-up rows. *** ### fundingTimestamp? > `optional` **fundingTimestamp?**: `number` Defined in: packages/sdk/src/unified/structs.ts:443 When funding next settles, or when this row settled (ms). For a live read this is the last settlement anchor plus the settlement interval; because settlement is permissionless and LAZY it can be in the past, which means a settlement is due rather than that anything is wrong. *** ### timestamp > **timestamp**: `number` Defined in: packages/sdk/src/unified/structs.ts:445 When this snapshot was read (ms, local clock). *** ### datetime > **datetime**: `string` Defined in: packages/sdk/src/unified/structs.ts:447 ISO-8601 of `timestamp`. *** ### info > **info**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:449 The native on-chain perp state (raw 1e18/quote-unit bigints). --- # /docs/typescript/api/index/interfaces/UnifiedMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedMarket # Interface: UnifiedMarket Defined in: packages/sdk/src/unified/structs.ts:31 A unified market object. `info` is the native `Market` union row. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/unified/structs.ts:33 Venue-internal id (the native market id: bytes32 for binary, pool for spot). *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:38 Canonical MARKET symbol (no outcome suffix), e.g. "SOMI/USDC" or "BTC-95000-31DEC26/USDC". Key into `exchange.markets`. *** ### type > **type**: [`UnifiedMarketType`](../type-aliases/UnifiedMarketType.md) Defined in: packages/sdk/src/unified/structs.ts:40 Market kind — see [UnifiedMarketType](../type-aliases/UnifiedMarketType.md). *** ### base > **base**: `string` Defined in: packages/sdk/src/unified/structs.ts:45 Base currency code — for outcome markets, the market's asset-strike-expiry stem (everything before the slash). *** ### quote > **quote**: `string` Defined in: packages/sdk/src/unified/structs.ts:47 Quote currency code (outcome markets: the collateral token's code). *** ### settle? > `optional` **settle?**: `string` Defined in: packages/sdk/src/unified/structs.ts:52 Settlement currency code. Set on swap (== quote for a linear perp) and outcome markets; absent on spot. *** ### active > **active**: `boolean` Defined in: packages/sdk/src/unified/structs.ts:54 Derived from live/indexed lifecycle — false once trading is impossible. *** ### contract > **contract**: `boolean` Defined in: packages/sdk/src/unified/structs.ts:56 ccxt's derivative flag: true only for swap (perp) markets. *** ### precision > **precision**: `object` Defined in: packages/sdk/src/unified/structs.ts:61 Decimal places implied by the market's tick (price) and lot (amount) grids — what [SomniaMarkets.priceToPrecision](../classes/SomniaMarkets.md#pricetoprecision) snaps to. #### price > **price**: `number` Price decimal places (from the tick grid). #### amount > **amount**: `number` Amount decimal places (from the lot grid). *** ### limits > **limits**: `object` Defined in: packages/sdk/src/unified/structs.ts:68 Order-size floors, human units; `min` is absent when the pool sets none. #### amount > **amount**: `object` Amount (order size) bounds. ##### amount.min? > `optional` **min?**: `number` Minimum order size, human base units. *** ### outcomes? > `optional` **outcomes?**: `object`[] Defined in: packages/sdk/src/unified/structs.ts:76 Outcome tradables (binary/categorical). Absent on spot/swap. #### symbol > **symbol**: `string` The outcome's tradable symbol, e.g. "BTC-95000-31DEC26/USDC#YES". #### label > **label**: `string` Outcome label ("YES" / "NO"). #### index > **index**: `number` Outcome index on the ERC-6909 singleton (0 = YES, 1 = NO). *** ### indexed > **indexed**: `boolean` Defined in: packages/sdk/src/unified/structs.ts:115 Whether the indexer has a row for this market. True for every spot and outcome market — those are discovered through the indexer, so a row is the only way they appear at all. It can be **false only on a perp**, which `loadMarkets()` also discovers from the PerpPoolFactory: a market deployed after the indexer's perp manifest was written is present on the chain and absent from the indexer. **Branch on this before reading anything history-derived.** On a market with `indexed: false`, `info.cumulativeBaseVolume`, `info.cumulativeQuoteVolume`, `info.tradeCount`, `info.createdAtTimestamp` and `info.createdAtBlock` are `"0"` placeholders meaning UNKNOWN — not "never traded" — and every funding, mark-price and open-interest field is null. `info.lastPrice` and `info.lastTradeAt` need care of their own. They are null here for the same reason, but on an INDEXED market null carries the narrower meaning "no fill yet". So null on a market with `indexed: false` says nothing about whether it has traded, and rendering it as "no trades" is wrong. The chain-backed reads work in full — positions, collateral, the order book — and the indexer-backed ones (candles, fills, order history, portfolio) return empty. TP/SL depends on `info.stopRegistry`, which comes from the factory and is null when it records none. **Placement is a separate question from `indexed`.** Discovery reports every factory pool, including restricted and unregistered ones, so a market being present here does not mean an order will be accepted: check [UnifiedMarket.active](#active) or [UnifiedMarket.perpStatus](#perpstatus). A restricted market takes closes and cancels but reverts anything position-increasing. *** ### perpStatus? > `optional` **perpStatus?**: `Pick`\<[`PerpPoolStatus`](../type-aliases/PerpPoolStatus.md), `"restricted"` \| `"registered"` \| `"tradeable"`\> Defined in: packages/sdk/src/unified/structs.ts:130 Live tradeability gates, perp markets only. Absent on spot and outcome markets; on every market when no PerpPoolFactory could be reached (see `SomniaMarkets.perpDiscoveryError`); and per-market on an indexed perp the reachable factory does not list — which happens after a factory rotation, and leaves that market's `active` falling back to `true`. Read from the chain on each `loadMarkets()`, because "deployed" is not "tradeable" and the two gates fail for unrelated reasons — see [PerpPoolStatus](../type-aliases/PerpPoolStatus.md). [UnifiedMarket.active](#active) folds them together; these are here for a consumer that must tell a wound-down market from one that was never activated. *** ### info > **info**: [`Market`](../type-aliases/Market.md) Defined in: packages/sdk/src/unified/structs.ts:132 The native `Market` union row (raw strings/bigint-scale fields). --- # /docs/typescript/api/index/interfaces/UnifiedOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedOrder # Interface: UnifiedOrder Defined in: packages/sdk/src/unified/structs.ts:203 An order, in the tradable's own terms (prices/amounts human units). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/unified/structs.ts:208 On-chain order id (decimal string) — pass to [SomniaMarkets.cancelOrder](../classes/SomniaMarkets.md#cancelorder). Falls back to the tx hash for a write that left nothing resting. *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:210 The tradable symbol the order is viewed on. *** ### type? > `optional` **type?**: `"limit"` \| `"market"` Defined in: packages/sdk/src/unified/structs.ts:226 Requested execution style ("market" computed a crossing IOC limit). **Absent on orders read back from the indexer** — `fetchOrders`, `fetchOpenOrders` and `watchOrders` all leave it undefined. The pools do not emit the order type: `OrderPlaced` carries a `placedOrder` struct with no order-type member, and binary pools emit only the YES/NO side, so the indexer has nothing to store and the SDK has nothing to read. Populating it needs a contract change. Present only where the value is genuinely known: on the result of [SomniaMarkets.createOrder](../classes/SomniaMarkets.md#createorder), which echoes the caller's own argument. ([UnifiedStopOrder.type](UnifiedStopOrder.md#type) is always known — the stop registry does emit the order type.) *** ### side > **side**: `"buy"` \| `"sell"` Defined in: packages/sdk/src/unified/structs.ts:228 Direction on this tradable's book (a NO buy is a YES sell internally). *** ### price? > `optional` **price?**: `number` Defined in: packages/sdk/src/unified/structs.ts:230 Limit price, human units; absent when unknown. *** ### amount > **amount**: `number` Defined in: packages/sdk/src/unified/structs.ts:232 Full order size, human base units. *** ### filled > **filled**: `number` Defined in: packages/sdk/src/unified/structs.ts:234 Quantity filled so far, human base units. *** ### remaining > **remaining**: `number` Defined in: packages/sdk/src/unified/structs.ts:236 Quantity still open (`amount − filled`), human base units. *** ### status > **status**: [`UnifiedOrderStatus`](../type-aliases/UnifiedOrderStatus.md) Defined in: packages/sdk/src/unified/structs.ts:238 Lifecycle state — see [UnifiedOrderStatus](../type-aliases/UnifiedOrderStatus.md). *** ### txHash? > `optional` **txHash?**: `string` Defined in: packages/sdk/src/unified/structs.ts:240 Tx hash the order was placed in, when known. *** ### timestamp? > `optional` **timestamp?**: `number` Defined in: packages/sdk/src/unified/structs.ts:242 Placement time (ms); write results stamp the local clock. *** ### datetime? > `optional` **datetime?**: `string` Defined in: packages/sdk/src/unified/structs.ts:244 ISO-8601 of `timestamp`. *** ### info > **info**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:246 The native order row / [PlaceOrderResult](PlaceOrderResult.md). --- # /docs/typescript/api/index/interfaces/UnifiedOrderBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedOrderBook # Interface: UnifiedOrderBook Defined in: packages/sdk/src/unified/structs.ts:140 An L2 book: [price, amount] pairs, best first, human units. ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/unified/structs.ts:142 Pinned chain block or scope applied-event watermark; absent without provenance. *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:147 The tradable symbol this book view addresses (a NO book is the YES book inverted into NO terms). *** ### bids > **bids**: \[`number`, `number`\][] Defined in: packages/sdk/src/unified/structs.ts:149 Buy side, best (highest) bid first. *** ### asks > **asks**: \[`number`, `number`\][] Defined in: packages/sdk/src/unified/structs.ts:151 Sell side, best (lowest) ask first. *** ### timestamp? > `optional` **timestamp?**: `number` Defined in: packages/sdk/src/unified/structs.ts:153 When this view was assembled (ms) — local clock, not a block timestamp. *** ### info? > `optional` **info?**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:155 The native book (raw bigint levels; YES terms for binary). --- # /docs/typescript/api/index/interfaces/UnifiedPosition [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedPosition # Interface: UnifiedPosition Defined in: packages/sdk/src/unified/structs.ts:457 An open perp position, human units. ## Properties ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:459 The perp's tradable symbol. *** ### side > **side**: `"short"` \| `"long"` Defined in: packages/sdk/src/unified/structs.ts:461 Position direction (from the sign of the on-chain size). *** ### contracts > **contracts**: `number` Defined in: packages/sdk/src/unified/structs.ts:463 Absolute position size in base units. *** ### entryPrice > **entryPrice**: `number` Defined in: packages/sdk/src/unified/structs.ts:465 Average entry price, human quote units. *** ### markPrice? > `optional` **markPrice?**: `number` Defined in: packages/sdk/src/unified/structs.ts:467 Current EMA mark price, human quote units. *** ### unrealizedPnl? > `optional` **unrealizedPnl?**: `number` Defined in: packages/sdk/src/unified/structs.ts:469 (mark − entry) × signed size, human quote units. Excludes pending funding. *** ### liquidationPrice? > `optional` **liquidationPrice?**: `number` Defined in: packages/sdk/src/unified/structs.ts:480 Estimated liquidation price, human quote units — the price at which THIS market's move alone would trip the account's cross-margin maintenance requirement. `undefined` when it can't be derived (a stale mark anywhere in the account reverts the health read this needs). Solved with both sides of `equity == mmReq` moving against the mark; see `perpLiquidationPrice` for the identity and what is held constant. For the price a proposed order would move this to, use `client.previewPerpLiquidationPrice`. *** ### timestamp? > `optional` **timestamp?**: `number` Defined in: packages/sdk/src/unified/structs.ts:482 When the position last changed on-chain (ms). *** ### datetime? > `optional` **datetime?**: `string` Defined in: packages/sdk/src/unified/structs.ts:484 ISO-8601 of `timestamp`. *** ### info > **info**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:486 The native reads: `{ position, state }` (raw bigints). --- # /docs/typescript/api/index/interfaces/UnifiedPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedPrice # Interface: UnifiedPrice Defined in: packages/sdk/src/unified/structs.ts:494 A realtime price snapshot for one asset (the on-chain EMA oracle feed). ## Properties ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:496 Asset symbol, e.g. "BTC", "ETH". *** ### price > **price**: `number` Defined in: packages/sdk/src/unified/structs.ts:498 Latest price, human units. *** ### ema > **ema**: `number` Defined in: packages/sdk/src/unified/structs.ts:500 Latest EMA (exponential moving average) price, human units. *** ### timestamp > **timestamp**: `number` Defined in: packages/sdk/src/unified/structs.ts:502 Block timestamp of the latest observation (ms). *** ### datetime > **datetime**: `string` Defined in: packages/sdk/src/unified/structs.ts:504 ISO-8601 of `timestamp`. *** ### info > **info**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:506 The native [LivePrice](LivePrice.md) row (raw 1e18 strings + block metadata). --- # /docs/typescript/api/index/interfaces/UnifiedStopOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedStopOrder # Interface: UnifiedStopOrder Defined in: packages/sdk/src/unified/structs.ts:263 A stop / take-profit order resting OFF the book on the market's SpotStopOrderRegistry, human units. Fires as a market or limit order when the pool's mark price crosses `triggerPrice`. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/unified/structs.ts:265 Registry order id (decimal string) — pass to [SomniaMarkets.cancelStopOrder](../classes/SomniaMarkets.md#cancelstoporder). *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:267 The spot tradable the stop targets. *** ### type > **type**: `"limit"` \| `"market"` Defined in: packages/sdk/src/unified/structs.ts:269 Execution style at trigger time. *** ### side > **side**: `"buy"` \| `"sell"` Defined in: packages/sdk/src/unified/structs.ts:271 Direction of the triggered order. *** ### amount > **amount**: `number` Defined in: packages/sdk/src/unified/structs.ts:273 Order size, human base units. *** ### triggerPrice > **triggerPrice**: `number` Defined in: packages/sdk/src/unified/structs.ts:275 Mark price that arms the trigger, human quote units. *** ### triggerDirection > **triggerDirection**: `"above"` \| `"below"` Defined in: packages/sdk/src/unified/structs.ts:277 Which side of the mark the trigger arms on. *** ### price? > `optional` **price?**: `number` Defined in: packages/sdk/src/unified/structs.ts:279 Limit price of the triggered order (limit stops only), human quote units. *** ### status > **status**: [`UnifiedStopOrderStatus`](../type-aliases/UnifiedStopOrderStatus.md) Defined in: packages/sdk/src/unified/structs.ts:281 Lifecycle state — see [UnifiedStopOrderStatus](../type-aliases/UnifiedStopOrderStatus.md). *** ### triggeredOrderId? > `optional` **triggeredOrderId?**: `string` Defined in: packages/sdk/src/unified/structs.ts:283 The spot order id the trigger produced, once it fired. *** ### timestamp? > `optional` **timestamp?**: `number` Defined in: packages/sdk/src/unified/structs.ts:285 Creation time (ms). *** ### datetime? > `optional` **datetime?**: `string` Defined in: packages/sdk/src/unified/structs.ts:287 ISO-8601 of `timestamp`. *** ### txHash? > `optional` **txHash?**: `string` Defined in: packages/sdk/src/unified/structs.ts:289 Tx hash of the create, when known (write results only). *** ### info > **info**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:291 The native registry row / write result. --- # /docs/typescript/api/index/interfaces/UnifiedTicker [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedTicker # Interface: UnifiedTicker Defined in: packages/sdk/src/unified/structs.ts:336 A rolling 24h market snapshot (ccxt ticker shape), human units. Absent fields mean the window had no trades to derive them from. ## Properties ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:338 The tradable symbol the ticker describes. *** ### timestamp > **timestamp**: `number` Defined in: packages/sdk/src/unified/structs.ts:340 When this snapshot was computed (ms, local clock). *** ### datetime > **datetime**: `string` Defined in: packages/sdk/src/unified/structs.ts:342 ISO-8601 of `timestamp`. *** ### high? > `optional` **high?**: `number` Defined in: packages/sdk/src/unified/structs.ts:344 Highest fill price in the window. *** ### low? > `optional` **low?**: `number` Defined in: packages/sdk/src/unified/structs.ts:346 Lowest fill price in the window. *** ### open? > `optional` **open?**: `number` Defined in: packages/sdk/src/unified/structs.ts:348 First fill price in the window. *** ### last? > `optional` **last?**: `number` Defined in: packages/sdk/src/unified/structs.ts:350 Most recent fill price (may predate the window on quiet markets). *** ### change? > `optional` **change?**: `number` Defined in: packages/sdk/src/unified/structs.ts:352 `last − open`, when both are known. *** ### percentage? > `optional` **percentage?**: `number` Defined in: packages/sdk/src/unified/structs.ts:354 `change / open` as a plain fraction (0.05 = +5%), when derivable. *** ### baseVolume > **baseVolume**: `number` Defined in: packages/sdk/src/unified/structs.ts:356 Σ base-asset volume over the window. *** ### quoteVolume > **quoteVolume**: `number` Defined in: packages/sdk/src/unified/structs.ts:358 Σ quote-asset volume over the window. *** ### markPrice? > `optional` **markPrice?**: `number` Defined in: packages/sdk/src/unified/structs.ts:367 PERP ONLY — mark price, human quote units. Undefined on spot/binary, and undefined on a perp whose mark is unusable — either the feed reported stale, or the price is zero. A zero mark is never published: flattened to a number it reads as a real price, and downstream an unguarded `markPrice - entryPrice` becomes a 100% loss on every open position. *** ### indexPrice? > `optional` **indexPrice?**: `number` Defined in: packages/sdk/src/unified/structs.ts:369 PERP ONLY — oracle index price, human quote units. Undefined on spot/binary. *** ### fundingRate? > `optional` **fundingRate?**: `number` Defined in: packages/sdk/src/unified/structs.ts:381 PERP ONLY — funding rate per **8 HOURS** as a plain fraction (0.0001 = 0.01%). The same axis [UnifiedFundingRate.fundingRate](UnifiedFundingRate.md#fundingrate) and `fetchFundingRateHistory` use, deliberately: a header reading one basis while the chart beside it reads another is a wrong number that looks right. NOT the amount charged per settlement — that is this divided by `fundingWindowSec / fundingIntervalSec` (8 on every live pool; it has been 96 at a 300s cadence), and `info.perp` carries both figures. On a historical catch-up row, multiply by that row's `intervalsAccrued` — one settlement can charge more than one interval's worth. *** ### fundingTimestamp? > `optional` **fundingTimestamp?**: `number` Defined in: packages/sdk/src/unified/structs.ts:386 PERP ONLY — when funding next settles (ms). Settlement is permissionless and lazy, so a past value means a settlement is DUE, not that anything is broken. *** ### openInterest? > `optional` **openInterest?**: `number` Defined in: packages/sdk/src/unified/structs.ts:393 PERP ONLY — total open interest in base units. ONE counter, not a long/short pair: in a matched CLOB the short side is provably equal, so there is nothing to sum. *** ### info > **info**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:399 The raw fold this snapshot came from (raw-unit bigints). On a perp it also carries `perp`, the full on-chain state — including `fundingWindowSec` / `fundingIntervalSec` for re-basing the funding rate. --- # /docs/typescript/api/index/interfaces/UnifiedTrade [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedTrade # Interface: UnifiedTrade Defined in: packages/sdk/src/unified/structs.ts:163 A fill, in the tradable's own terms (prices/amounts human units). ## Properties ### blockNumber? > `optional` **blockNumber?**: `bigint` Defined in: packages/sdk/src/unified/structs.ts:165 Source fill block, preserved in outcome views. Absent when the input has no block provenance. *** ### logIndex? > `optional` **logIndex?**: `number` Defined in: packages/sdk/src/unified/structs.ts:167 Source log position. Absent when the input has no log provenance. *** ### id > **id**: `string` Defined in: packages/sdk/src/unified/structs.ts:169 Native fill id — unique per fill, stable across reads. *** ### symbol > **symbol**: `string` Defined in: packages/sdk/src/unified/structs.ts:171 The tradable symbol the fill is viewed on. *** ### price > **price**: `number` Defined in: packages/sdk/src/unified/structs.ts:173 Fill price, human units (binary: this outcome's probability). *** ### amount > **amount**: `number` Defined in: packages/sdk/src/unified/structs.ts:175 Filled quantity, human base units. *** ### cost > **cost**: `number` Defined in: packages/sdk/src/unified/structs.ts:177 price × amount, in quote units. *** ### side? > `optional` **side?**: `"buy"` \| `"sell"` Defined in: packages/sdk/src/unified/structs.ts:179 Taker direction on this tradable's book; undefined when unresolved. *** ### txHash? > `optional` **txHash?**: `string` Defined in: packages/sdk/src/unified/structs.ts:181 Tx hash the fill landed in, when known. *** ### timestamp > **timestamp**: `number` Defined in: packages/sdk/src/unified/structs.ts:183 Fill block timestamp (ms). *** ### datetime > **datetime**: `string` Defined in: packages/sdk/src/unified/structs.ts:185 ISO-8601 of `timestamp`. *** ### info > **info**: `unknown` Defined in: packages/sdk/src/unified/structs.ts:187 The native fill row (raw units, maker/taker addresses). --- # /docs/typescript/api/index/interfaces/UnlinkPerpWalletParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnlinkPerpWalletParams # Interface: UnlinkPerpWalletParams Defined in: packages/sdk/src/trade.ts:1020 Inputs to [Trader.unlinkPerpWallet](Trader.md#unlinkperpwallet) — dissolve an accepted link. Works from either end: pass the OTHER party and the registry resolves which side is the main. ## Extends - [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md) ## Properties ### registry? > `optional` **registry?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:958 The LinkedWalletRegistry. Skips resolution entirely. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`registry`](PerpWalletLinkTarget.md#registry) *** ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:960 MarginBank address — its `getLinkedWalletRegistry()` is read (never cached). #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`marginBank`](PerpWalletLinkTarget.md#marginbank) *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:962 A PerpPool — its `marginBank()` is read (and cached), then the registry. #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`pool`](PerpWalletLinkTarget.md#pool) *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:968 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) #### Inherited from [`PerpWalletLinkTarget`](PerpWalletLinkTarget.md).[`gas`](PerpWalletLinkTarget.md#gas) *** ### counterparty > **counterparty**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1022 The other party to the link — the signer's main, or one of its children. --- # /docs/typescript/api/index/interfaces/UnsignedCall [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnsignedCall # Interface: UnsignedCall Defined in: packages/sdk/src/writer.ts:117 One unsigned call, ready for any signer: spread into viem's `sendTransaction`, wrap as an ERC-4337 UserOp call field, or hand to a relayer. Deliberately minimal, following `BridgeTransaction` in the `/chains` bridge module: no nonce, no fees, no gas — those are the signer's job, and pinning them here would stale the moment the call is cached. `description` is a human label for a confirmation UI. Unlike `BridgeTransaction` there is no `chainId`: these calls are always on the chain the client is already connected to, whereas a bridge leg is explicitly cross-chain. Note `value` is a `bigint`, so `JSON.stringify` throws on it — convert it yourself if the call crosses a serialization boundary. ## Properties ### to > **to**: `` `0x${string}` `` Defined in: packages/sdk/src/writer.ts:119 Contract to call. *** ### data > **data**: `` `0x${string}` `` Defined in: packages/sdk/src/writer.ts:121 ABI-encoded calldata. *** ### value > **value**: `bigint` Defined in: packages/sdk/src/writer.ts:123 Native value to attach, in wei. `0n` unless the call pays native. *** ### description > **description**: `string` Defined in: packages/sdk/src/writer.ts:125 What this call does, for a UI to label a confirmation with. --- # /docs/typescript/api/index/interfaces/UnsignedMarginDeposit [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnsignedMarginDeposit # Interface: UnsignedMarginDeposit Defined in: packages/sdk/src/perp/margin.ts:1412 A MarginBank deposit expanded into the unsigned calls it actually takes. Two or one: the bank pulls the collateral, so it needs an ERC-20 allowance first — unless `autoApprove: false` says the caller manages that themselves. ## Properties ### deposit > **deposit**: [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/perp/margin.ts:1414 The `deposit` call itself. *** ### approval? > `optional` **approval?**: [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/perp/margin.ts:1416 The ERC-20 approval the bank needs first; absent when `autoApprove: false`. --- # /docs/typescript/api/index/interfaces/UnsignedOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnsignedOrder # Interface: UnsignedOrder Defined in: packages/sdk/src/writer.ts:191 A placement expanded into the unsigned calls it actually takes. Two or one: a placement that escrows an ERC-20 (or outcome tokens) needs an approval before the order call, while a native-base sell and every perp placement need only the order. `approval` is simply absent when there is nothing to approve — branching on it narrows: **Example** (Sending an unsigned order) ```ts const { order, approval } = await trader.buildPlaceOrder(params); if (approval) await walletClient.sendTransaction({ ...approval, account }); await walletClient.sendTransaction({ ...order, account }); ``` The approval is RETURNED, never sent — unlike `placeOrder`, which sends it as a side effect. A caller who skips a needed approval gets an on-chain revert, so check `approval` rather than assuming it is handled. `approval` is present whenever the placement escrows something, without checking the current allowance (that check is an `eth_call`, which a build-only verb should not make) — so it may be redundant, never short: it approves `maxUint256`, as the send path does. (A token that demands its allowance be zeroed before being re-set would reject that, same as on the send path.) Pass `autoApprove: false` to drop it and skip the escrow lookup. ## Properties ### order > **order**: [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/writer.ts:193 The placement call itself. *** ### approval? > `optional` **approval?**: [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/writer.ts:195 The approval the placement needs first; absent when nothing needs approving. --- # /docs/typescript/api/index/interfaces/UnsignedPerpStopOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnsignedPerpStopOrder # Interface: UnsignedPerpStopOrder Defined in: packages/sdk/src/perp/stops.ts:788 A perp stop placement expanded into the unsigned calls it actually takes. Two or one, and the difference matters more here than for a token approval: the registry places on the owner's behalf, so without the operator grant the trigger reverts **and the prepaid SOMI is consumed having placed nothing**. Batch both. ## Properties ### stopOrder > **stopOrder**: [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/perp/stops.ts:790 The registry call that creates the stop — or, for a `pair`, both legs at once. *** ### operatorApproval? > `optional` **operatorApproval?**: [`UnsignedCall`](UnsignedCall.md) Defined in: packages/sdk/src/perp/stops.ts:795 The one-time operator grant the trigger needs first; absent only when `skipOperatorApproval: true` was passed. --- # /docs/typescript/api/index/interfaces/UpdateOperatorParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UpdateOperatorParams # Interface: UpdateOperatorParams Defined in: packages/sdk/src/operatorAdmin.ts:121 Params for [OperatorAdmin.updateOperator](OperatorAdmin.md#updateoperator). Every mutable field is replaced — pass the full desired state, not a delta. ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:123 The operator to update. Caller must be its owner. *** ### feeRecipient > **feeRecipient**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:125 New default recipient of the operator's venue fees. *** ### enabled > **enabled**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:127 New enabled flag (the operator-wide kill switch). *** ### policy > **policy**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:129 New IVenuePolicy address; zero clears the operator-wide gate. *** ### context? > `optional` **context?**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:131 Opaque metadata bytes; replaces the prior value (empty `0x` clears it). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:133 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/UpdateVenueParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UpdateVenueParams # Interface: UpdateVenueParams Defined in: packages/sdk/src/operatorAdmin.ts:210 Params for [OperatorAdmin.updateVenue](OperatorAdmin.md#updatevenue). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:212 The operator owning the venue. Caller must be its owner. *** ### venueId > **venueId**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:214 The venue to update (within the operator). *** ### config > **config**: [`VenueConfigInput`](VenueConfigInput.md) Defined in: packages/sdk/src/operatorAdmin.ts:219 Replacement config — the full desired state, not a delta. `marketType` stays whatever it was at creation. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/operatorAdmin.ts:221 Gas ceiling for this tx; overrides the config default. --- # /docs/typescript/api/index/interfaces/ValidAnswersInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ValidAnswersInput # Interface: ValidAnswersInput Defined in: packages/sdk/src/oracleHub.ts:94 The set of valid answers a question may resolve to. ## Properties ### answerType > **answerType**: `number` Defined in: packages/sdk/src/oracleHub.ts:96 [ANSWER\_TYPE](../variables/ANSWER_TYPE.md) value (uint8 on the wire). *** ### discreteOutcomes > **discreteOutcomes**: `string`[] Defined in: packages/sdk/src/oracleHub.ts:98 Outcome labels for a Discrete question; empty for Numeric. *** ### numericIntervals > **numericIntervals**: [`QuestionIntervalInput`](QuestionIntervalInput.md)[] Defined in: packages/sdk/src/oracleHub.ts:100 Value buckets for a Numeric question (one outcome slot each); empty for Discrete. *** ### numericDecimals > **numericDecimals**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:102 Fixed-point decimals the numeric answer and interval bounds are scaled by. --- # /docs/typescript/api/index/interfaces/VenueConfigInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / VenueConfigInput # Interface: VenueConfigInput Defined in: packages/sdk/src/operatorAdmin.ts:56 A venue's mutable config (mirror of MarketsCore's `VenueConfig` input tuple) — passed whole to [OperatorAdmin.createVenue](OperatorAdmin.md#createvenue) and [OperatorAdmin.updateVenue](OperatorAdmin.md#updatevenue). ## Properties ### feeParams > **feeParams**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:61 Type-specific fee parameters, abi-encoded (see `encodeBinaryVenueFeeParams` for BINARY_V1). Opaque to the registry. *** ### feeRecipientOverride > **feeRecipientOverride**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:63 Per-venue fee recipient; zero falls back to the operator's default. *** ### policy > **policy**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:69 IVenuePolicy address; zero means no per-venue gate (the operator-wide policy still applies). Creation needs SOME create-side policy set — point this at the deployed OpenPolicy to make the venue open. *** ### signer > **signer**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:71 EIP-712 signer; non-zero requires a venue-signed authorization to create. *** ### creationEnabled > **creationEnabled**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:76 Whether market creation on this venue is live. Trading/settlement on existing markets is unaffected. *** ### context? > `optional` **context?**: `` `0x${string}` `` Defined in: packages/sdk/src/operatorAdmin.ts:81 Opaque metadata bytes attached to the venue; the registry attaches no semantics (indexed as-is). Defaults to `0x` (empty). Capped at 4 KiB. --- # /docs/typescript/api/index/interfaces/VenuePreflightInput [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / VenuePreflightInput # Interface: VenuePreflightInput Defined in: packages/sdk/src/preflight.ts:126 The venue fields the venue-step preflight inspects (subset of [IndexedVenue](../type-aliases/IndexedVenue.md)) plus whether the venue's market type is bound to a module in MarketsCore. ## Properties ### caller > **caller**: `` `0x${string}` `` Defined in: packages/sdk/src/preflight.ts:128 The connected signer — must own the venue's operator. *** ### operatorOwner > **operatorOwner**: `string` Defined in: packages/sdk/src/preflight.ts:130 The owner of the operator the venue belongs to. *** ### creationEnabled > **creationEnabled**: `boolean` Defined in: packages/sdk/src/preflight.ts:132 The venue's creation flag — off blocks new markets on the venue. *** ### moduleBound > **moduleBound**: `boolean` Defined in: packages/sdk/src/preflight.ts:137 Whether MarketsCore has a module bound for the venue's market type (`moduleOf(marketType) != 0`). --- # /docs/typescript/api/index/interfaces/VoidExpiredParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / VoidExpiredParams # Interface: VoidExpiredParams Defined in: packages/sdk/src/trade.ts:1855 Permissionless dead-oracle escape hatch: void a market whose settlement window has lapsed without a resolution. ## Properties ### marketId > **marketId**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1857 bytes32 marketId to void; its market contract is resolved from the module. *** ### module? > `optional` **module?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1859 BinaryMarketsModule address; resolved from `config.addresses.binaryModule` when omitted. *** ### skipPreflight? > `optional` **skipPreflight?**: `boolean` Defined in: packages/sdk/src/trade.ts:1865 Skip the pre-send status/window check. The on-chain guards still apply — this only gives up the clearer client-side error (and its three reads). #### Default ```ts false ``` *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1871 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/VoidMarketParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / VoidMarketParams # Interface: VoidMarketParams Defined in: packages/sdk/src/trade.ts:2092 Inputs to [Trader.voidMarket](Trader.md#voidmarket) — void a market via the FakeOracle (demo/dev resolver only). Each side then redeems against the payout vector the market stores: a half per side under the `UNIFORM` void policy, and `[p, D−p]` at the closing YES price on a `CLOB_SNAPSHOT` void that captured a two-sided close. ## Properties ### market > **market**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2094 BinaryMarket address to void. *** ### fakeOracle? > `optional` **fakeOracle?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:2096 FakeOracle address; defaults to the configured one. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:2102 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/WatchHandle [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / WatchHandle # Interface: WatchHandle Defined in: packages/sdk/src/liveTail.ts:62 A live watch. `stop()` releases it (idempotent); the underlying subscription is shared and torn down when the last handle stops. ## Methods ### stop() > **stop**(): `void` Defined in: packages/sdk/src/liveTail.ts:71 Release this handle's reference on its watch scope (idempotent — extra calls are no-ops). Handles on the same scope share one subscription; stopping the LAST one tears down the scope's local materialization after a short linger (which absorbs unmount/remount without re-snapshotting): the subscription is dropped and the market's fills/orders are purged, so `getLive*` reads for it return empty again. The market row itself is kept for list views. #### Returns `void` --- # /docs/typescript/api/index/interfaces/WithdrawMarginParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / WithdrawMarginParams # Interface: WithdrawMarginParams Defined in: packages/sdk/src/trade.ts:926 Inputs to [Trader.withdrawMargin](Trader.md#withdrawmargin) — pull free collateral back out of the MarginBank (the bank margin-checks the withdrawal on-chain). ## Properties ### marginBank? > `optional` **marginBank?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:928 MarginBank address (from the PerpMarket row), or pass `pool` to resolve it. *** ### pool? > `optional` **pool?**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:930 A PerpPool — its `marginBank()` is read (and cached) when `marginBank` is omitted. *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:932 Collateral amount to withdraw, raw units. Must be ≤ withdrawable (margin-checked on-chain). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:938 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/WithdrawMyCreditParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / WithdrawMyCreditParams # Interface: WithdrawMyCreditParams Defined in: packages/sdk/src/oracleHub.ts:416 Parameters for [OracleHubAdmin.withdrawMyCredit](OracleHubAdmin.md#withdrawmycredit). ## Properties ### amountWei > **amountWei**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:422 Wei to withdraw from the CALLER's own accrued A1 payer credit (must be ≤ `payerCreditOf(caller)`, else the hub reverts). msg.sender-gated — the connected signer draws only its own credit. *** ### to > **to**: `` `0x${string}` `` Defined in: packages/sdk/src/oracleHub.ts:424 Recipient of the native transfer. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:426 Gas-limit override for this tx (defaults to the admin config's `gas`). --- # /docs/typescript/api/index/interfaces/WithdrawParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / WithdrawParams # Interface: WithdrawParams Defined in: packages/sdk/src/oracleHub.ts:397 Parameters for [OracleHubAdmin.withdraw](OracleHubAdmin.md#withdraw). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/oracleHub.ts:399 Operator whose WITHDRAWABLE credit to draw down. OWNER-gated on-chain. *** ### amountWei > **amountWei**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:404 Wei to withdraw from the operator's accrued surplus credit (must be ≤ `withdrawableOf(operatorId)`, else the hub reverts `InsufficientCredit`). *** ### to > **to**: `` `0x${string}` `` Defined in: packages/sdk/src/oracleHub.ts:406 Recipient of the native transfer. *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/oracleHub.ts:408 Gas-limit override for this tx (defaults to the admin config's `gas`). --- # /docs/typescript/api/index/interfaces/WithdrawVaultParams [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / WithdrawVaultParams # Interface: WithdrawVaultParams Defined in: packages/sdk/src/trade.ts:1075 Claim a payout that fell back to a pool's internal ERC20Vault (a `PayoutFallbackToVault` credit) back to the caller's wallet. ## Properties ### vault > **vault**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1080 The ERC20Vault to withdraw from — the pool address (BinaryPool/SpotPool ARE ERC20Vaults). *** ### token > **token**: `` `0x${string}` `` Defined in: packages/sdk/src/trade.ts:1082 Token to withdraw (ERC-20 address, or the vault's native sentinel). *** ### amount > **amount**: `bigint` Defined in: packages/sdk/src/trade.ts:1087 Amount to withdraw, raw units. Must be ≤ the vault's withdrawable balance (read it with `client.getVaultBalance`). *** ### gas? > `optional` **gas?**: `bigint` Defined in: packages/sdk/src/trade.ts:1093 Gas ceiling for this tx. #### Default [TraderConfig.gas](TraderConfig.md#gas) (10,000,000) --- # /docs/typescript/api/index/interfaces/YesBookTop [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / YesBookTop # Interface: YesBookTop Defined in: packages/sdk/src/units.ts:133 Best YES bid/ask of a binary book (raw quote units), for marking a position. Either side may be absent on a one-sided book. Feed it the top level of `getBinaryOrderBook` / `getLiveBinaryOrderBook`. ## Properties ### bestBid? > `optional` **bestBid?**: `bigint` Defined in: packages/sdk/src/units.ts:135 Best resting YES bid (raw), if any. *** ### bestAsk? > `optional` **bestAsk?**: `bigint` Defined in: packages/sdk/src/units.ts:137 Best resting YES ask (raw), if any. --- # /docs/typescript/api/index/type-aliases/BaseMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BaseMarket # Type Alias: BaseMarket > **BaseMarket** = `object` Defined in: packages/sdk/src/markets.ts:54 Fields every market has, regardless of type. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/markets.ts:56 Primary key (lowercased): bytes32 marketId for binary, pool address for spot. *** ### marketType > **marketType**: [`MarketType`](MarketType.md) Defined in: packages/sdk/src/markets.ts:58 Discriminator — narrow on this (or the `is*Market` guards). *** ### poolAddress > **poolAddress**: `Address` Defined in: packages/sdk/src/markets.ts:63 The pool serving this market (lowercased; == id for SPOT/PERP). For binary, a TIME-VARYING binding — see the recycle caveat on [BinaryMarket.nonce](BinaryMarket.md). *** ### lastPrice > **lastPrice**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:65 Last fill price (raw). For binary, ≈ YES probability × 10^decimals. Null until first fill. *** ### lastTradeAt > **lastTradeAt**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:67 Timestamp (unix seconds) of the last fill; null until first fill. *** ### cumulativeBaseVolume > **cumulativeBaseVolume**: `string` Defined in: packages/sdk/src/markets.ts:69 Cumulative base/outcome-token volume (raw, decimal string). *** ### cumulativeQuoteVolume > **cumulativeQuoteVolume**: `string` Defined in: packages/sdk/src/markets.ts:71 Cumulative quote/collateral volume (raw, decimal string). *** ### tradeCount > **tradeCount**: `string` Defined in: packages/sdk/src/markets.ts:73 Lifetime fill count (decimal string). *** ### baseDecimals > **baseDecimals**: `number` Defined in: packages/sdk/src/markets.ts:75 Base-token decimals (binary: outcome tokens mirror the collateral's decimals). *** ### quoteDecimals > **quoteDecimals**: `number` Defined in: packages/sdk/src/markets.ts:80 Quote-token decimals (binary: the collateral's — per-venue, e.g. 6dp TestUSDC vs 18dp USDso). Format prices/amounts with this. *** ### createdAtTimestamp > **createdAtTimestamp**: `string` Defined in: packages/sdk/src/markets.ts:82 Timestamp (unix seconds) the market was created/indexed. *** ### createdAtBlock > **createdAtBlock**: `string` Defined in: packages/sdk/src/markets.ts:91 Block the market was created in. Carried for the same reason as `resolvedAtBlock`: a market is bracketed by two reads of an off-chain feed and only a BLOCK identifies which print each one saw — a `"fixed"`-mode market's `strike` IS the feed's spot at THIS block (see [BinaryMarket.mode](BinaryMarket.md)), and that print lands before `tradingStart` far more often than on it, so `createdAtTimestamp` cannot find it. --- # /docs/typescript/api/index/type-aliases/BinaryBuySide [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryBuySide # Type Alias: BinaryBuySide > **BinaryBuySide** = `"BUY_YES"` \| `"BUY_NO"` Defined in: packages/sdk/src/derivedReads.ts:845 The buy sides of [BinarySide](BinarySide.md) — what a stake converts into. --- # /docs/typescript/api/index/type-aliases/BinaryFillKind [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryFillKind # Type Alias: BinaryFillKind > **BinaryFillKind** = `"DIRECT_YES"` \| `"DIRECT_NO"` \| `"MINT_A_PAIR"` \| `"BURN_A_PAIR"` Defined in: packages/sdk/src/store.ts:44 How a binary fill settled: direct outcome trade, or a mint/burn of a YES+NO pair. --- # /docs/typescript/api/index/type-aliases/BinaryMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryMarket # Type Alias: BinaryMarket > **BinaryMarket** = [`BaseMarket`](BaseMarket.md) & `object` Defined in: packages/sdk/src/markets.ts:237 A binary (YES/NO outcome) order-book market — the binary CLOB. ## Type Declaration ### marketType > **marketType**: `"BINARY"` Discriminator (narrowed). ### marketId > **marketId**: `Hex` bytes32 marketId (== id). ### marketAddress > **marketAddress**: `Address` The BinaryMarket clone contract's address (lowercased). ### yesTokenId > **yesTokenId**: `string` This market's YES/NO position ids on the ERC-6909 outcome-token singleton, as decimal strings (the indexer stores uint256 ids as strings). ### noTokenId > **noTokenId**: `string` The NO position id — see BinaryMarket.yesTokenId. ### collateral > **collateral**: `Address` Collateral ERC-20 backing the market (lowercased; per-venue). ### asset > **asset**: `string` Underlying asset symbol (e.g. "BTC"). ### question > **question**: `string` Display question text. May differ from BinaryMarket.oracleQuestion. ### status > **status**: [`BinaryMarketStatus`](BinaryMarketStatus.md) Lifecycle status (aliased from the indexer's `clobStatus`). Derived from lifecycle EVENTS only — the timestamp-implicit Listed→Trading→Settling transitions emit none, so derive the live trading state from `tradingStart`/`expiry` between events rather than trusting this alone. ### oracleQuestion > **oracleQuestion**: `string` \| `null` The canonical oracle question string (as registered on-chain); may differ from the display `question`. Null on markets indexed before this field. ### oracleQuestionId? > `optional` **oracleQuestionId?**: `string` \| `null` Oracle question id the market binds to (uint256 as a decimal string, from `BinaryMarketsModule.MarketCreated`). `null` when discovered via the realtime tail or indexed before this field (filled on the next snapshot). ### strike > **strike**: `string` Strike the question resolves against (raw, in the oracle's price scale). ### mode > **mode**: [`BinaryResolutionMode`](BinaryResolutionMode.md) How this market's threshold is established — the distinction every consumer of a binary market eventually needs, served rather than sniffed. - `"reference"` — an up/down market. `strike` is 0 because the threshold IS another question's answer ("ETH closes at or above its opening price"), reached through `MarketReferenceLink` → `OracleAnswer`. Read it with `getOpeningPrices` / `getMarketResolution().openingAnswer`. - `"fixed"` — the threshold was set at creation ("at or above 77036.65") and is `strike` itself. There is no reference question, so an opening price does not exist and never will. Derived from `strike` alone (see [binaryResolutionMode](../functions/binaryResolutionMode.md)), so it costs no extra query. Before it existed consumers inferred the mode from a LOOKUP MISS — "no opening answer, so it must be fixed-strike" — which conflates "no reference question" with "the reference question has not been answered yet". That reads as working code right up until an oracle is slow. ### tradingStart > **tradingStart**: `string` Timestamp (unix seconds) trading opens. ### expiry > **expiry**: `string` Timestamp (unix seconds) trading ends and the outcome is decided. ### winningOutcome > **winningOutcome**: `number` \| `null` Winning outcome (0 = YES, 1 = NO) — DERIVED by the indexer from a one-hot payout vector (Oracle v2 resolves with vectors; a one-hot vector has a unique winner). Null until Resolved and on non-one-hot (void/partial) vectors — the binary-compat field, kept alongside the vector below. ### payoutNumerators? > `optional` **payoutNumerators?**: `string`[] \| `null` Per-outcome payout numerators the market settled to (Oracle v2 vector resolution; uint256s as decimal strings — one-hot on a win; on a void, the vector the frozen void policy produced: uniform under `UNIFORM`, and `[p, D−p]` at the closing YES price on a `CLOB_SNAPSHOT` void that captured a two-sided close. Raw Σ == payoutDenominator). This vector, not BinaryMarket.voidPolicy, is what a void actually pays: every snapshot fallback stores the uniform vector. Null until Resolved / on markets indexed before the vector fields existed. ### payoutDenominator? > `optional` **payoutDenominator?**: `string` \| `null` Denominator the numerators are scaled against (`PAYOUT_VECTOR_DENOMINATOR` = 10_000_000; decimal string). Null until Resolved. ### resolvedAtBlock > **resolvedAtBlock**: `string` \| `null` Block the market resolved at; null until Resolved. ### resolvedAtTimestamp > **resolvedAtTimestamp**: `string` \| `null` Timestamp (unix seconds) the market resolved at; null until Resolved. ### createdByTx > **createdByTx**: `Hex` \| `null` Tx hash the market was created in; null on markets indexed before this field. ### creator? > `optional` **creator?**: `Address` \| `null` Wallet that invoked createMarket (lowercased, from `BinaryMarketsModule.MarketCreated`). `null` when discovered via the realtime tail or indexed before this field (filled on the next snapshot). ### voided > **voided**: `boolean` True once the market voided (payout per the frozen void policy; `payoutNumerators` carries the actual vector). ### voidPolicy? > `optional` **voidPolicy?**: `number` \| `null` Void payout policy frozen at creation (from `BinaryMarketsModule.MarketCreated`): 0 UNIFORM (both sides redeem 1/N on a void), 2 CLOB_SNAPSHOT (a void pays `[p, D-p]` at the market's closing YES price; falls back to uniform when no two-sided close exists). `null` on pre-policy markets or tail-discovered rows. ### backing > **backing**: `string` Collateral backing complete sets on the LIVE pool (raw). Reads 0 once finalized — prefer BinaryMarket.netBacking after finalize. ### nonce? > `optional` **nonce?**: `string` \| `null` The pool's market nonce this market is bound to (settlement-extraction v2). A pool serves successive markets; `(poolAddress, nonce)` disambiguates them and encodes the outcome ids. `null` on markets indexed before v2 / discovered via a live event that doesn't carry it (filled on the next snapshot). RECYCLE CAVEAT: `poolAddress` is a TIME-VARYING 1:1 binding — the same pool address serves different markets over time (never concurrently). Always key a market by `marketId`, never by `poolAddress` alone; use `nonce` to tell which of a pool's markets a given outcome id belongs to. ### finalized? > `optional` **finalized?**: `boolean` \| `null` Whether this market's backing has been finalized onto the BinarySettlement singleton (settlement-extraction v2). True once `finalizeMarket` swept the pool's backing over; redemption is served by settlement thereafter. `null` when unknown (pre-v2 / not yet snapshotted). ### netBacking? > `optional` **netBacking?**: `string` \| `null` The NET collateral backing recorded on the settlement singleton after finalize (post fee-skim on resolution; gross on void), decimal string. This is the authoritative post-finalize backing: `BinaryMarket.backing()` reads 0 once finalized, so redemption UIs should prefer `netBacking` when set. `null` until finalize / on pre-v2 markets. ### context? > `optional` **context?**: `Hex` \| `null` Opaque creator-supplied metadata bytes (hex, 0x-prefixed; '0x' when empty). The chain attaches no semantics — off-chain data only. Set once at creation. `null` on non-binary markets / markets indexed before this field existed. ### intervalSec? > `optional` **intervalSec?**: `string` \| `null` Series cadence in seconds (60=1m, 300=5m, 900=15m, 3600=1h, 14400=4h, 86400=24h) — APPROXIMATE, see [BinaryMarketFilter.intervalSec](BinaryMarketFilter.md#intervalsec). DERIVED by the indexer from the market's own window (`expiry − tradingStart`) — a series' FIRST market is a bootstrap partial whose window is shorter than the steady-state cadence. `null` on SPOT / PERP. ### interval? > `optional` **interval?**: `string` \| `null` Human timeframe label for this series — `"1m"` / `"5m"` / `"15m"` / `"1h"` / `"4h"` / `"24h"` — DERIVED by the SDK from BinaryMarket.intervalSec (falling back to `expiry − tradingStart`) and snapped to its [CADENCE\_LADDER\_SEC](../variables/CADENCE_LADDER_SEC.md) rung, so a roll that opened late reads as the cadence it belongs to rather than as its own (`56` → `"1m"`, not `"56s"`). A window matching no rung keeps its own value. Served ready-to-render so consumers stop re-deriving it; see [marketIntervalLabel](../functions/marketIntervalLabel.md). `null` on SPOT / PERP or when no cadence is determinable. ### operatorId? > `optional` **operatorId?**: `number` \| `null` Origin operator id the market was created under (from `BinaryMarketsModule.MarketCreated`). `null` when discovered via the realtime tail (filled on the next snapshot). ### venueId? > `optional` **venueId?**: `Hex` \| `null` Origin venue id within the operator, contract-generated opaque bytes32 hex. `null` when discovered via the realtime tail (filled on the next snapshot — the live `MarketCreator.MarketCreated` event doesn't carry it). --- # /docs/typescript/api/index/type-aliases/BinaryMarketFilter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryMarketFilter # Type Alias: BinaryMarketFilter > **BinaryMarketFilter** = `object` Defined in: packages/sdk/src/markets.ts:796 Filters shared by the binary-market list queries (`listBinaryMarkets`, `listLiveBinaryMarkets`, `listPastBinaryMarkets`). Every field is optional; an omitted field does NOT constrain the query. Applied server-side (Hasura `where`), so `venueId` / `intervalSec` hit their indexes. ## Properties ### operatorId? > `optional` **operatorId?**: `number` Defined in: packages/sdk/src/markets.ts:798 Origin operator id (from `BinaryMarketsModule.MarketCreated`). *** ### venueId? > `optional` **venueId?**: `string` Defined in: packages/sdk/src/markets.ts:800 Origin venue id within the operator (contract-generated bytes32 hex). *** ### asset? > `optional` **asset?**: `string` Defined in: packages/sdk/src/markets.ts:802 Underlying asset symbol, e.g. `"BTC"` | `"ETH"`. *** ### intervalSec? > `optional` **intervalSec?**: `number` Defined in: packages/sdk/src/markets.ts:812 Series cadence in seconds — a rung of [CADENCE\_LADDER\_SEC](../variables/CADENCE_LADDER_SEC.md): `60` (1m) | `300` (5m) | `900` (15m) | `3600` (1h) | `14400` (4h) | `86400` (24h). Matched as a BAND of ± [CADENCE\_TOLERANCE\_SEC](../variables/CADENCE_TOLERANCE_SEC.md), not exactly: a rolled market's indexed window is `expiry − tradingStart` and trading routinely opens a second or two late, so a 15m series is indexed at 898s and 899s as well as 900s. Passing `900` returns all three. *** ### status? > `optional` **status?**: [`BinaryMarketStatus`](BinaryMarketStatus.md) Defined in: packages/sdk/src/markets.ts:817 Lifecycle status — `"Trading"` is active; `"Locked"` / `"Settling"` / `"Resolved"` / `"Voided"` are the not-active states. *** ### search? > `optional` **search?**: `string` Defined in: packages/sdk/src/markets.ts:823 Free-text needle matched (case-insensitive) against the asset symbol and the question text. Server-side (`_ilike`), AND-combined with the other facets so it narrows within them. *** ### creator? > `optional` **creator?**: `string` Defined in: packages/sdk/src/markets.ts:828 Wallet that invoked createMarket (from `BinaryMarketsModule.MarketCreated`). Case-insensitive (lowercased server-side). *** ### orderBy? > `optional` **orderBy?**: [`BinaryMarketOrderBy`](BinaryMarketOrderBy.md) Defined in: packages/sdk/src/markets.ts:835 Server-side sort (Hasura `order_by`). `"newest"` → createdAtTimestamp desc; `"closingSoon"` → expiry asc; `"volume"` → cumulativeQuoteVolume desc; `"tradeCount"` → tradeCount desc. Omitted → each list keeps its own default (`listBinaryMarkets` newest-first; `listLiveBinaryMarkets` closingSoon). --- # /docs/typescript/api/index/type-aliases/BinaryMarketOrderBy [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryMarketOrderBy # Type Alias: BinaryMarketOrderBy > **BinaryMarketOrderBy** = `"newest"` \| `"closingSoon"` \| `"volume"` \| `"tradeCount"` Defined in: packages/sdk/src/markets.ts:843 Sort keys for the binary-market list queries — see [BinaryMarketFilter.orderBy](BinaryMarketFilter.md#orderby). --- # /docs/typescript/api/index/type-aliases/BinaryMarketStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryMarketStatus # Type Alias: BinaryMarketStatus > **BinaryMarketStatus** = `"Listed"` \| `"Trading"` \| `"Locked"` \| `"Settling"` \| `"Resolved"` \| `"Voided"` \| `"Finalized"` Defined in: packages/sdk/src/store.ts:62 Binary-market lifecycle (mirror of the indexer's `ClobMarketStatus` enum). The first six mirror the on-chain `MarketStatus` enum; `"Finalized"` is an INDEXER-DERIVED terminal state (no on-chain enum member) set when the market's backing + resolution snapshot are swept to the BinarySettlement singleton — it supersedes Resolved/Voided once finalize lands, and redemptions are served by settlement thereafter. --- # /docs/typescript/api/index/type-aliases/BinaryResolutionMode [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinaryResolutionMode # Type Alias: BinaryResolutionMode > **BinaryResolutionMode** = `"reference"` \| `"fixed"` Defined in: packages/sdk/src/markets.ts:765 How a binary market's threshold is established. See [BinaryMarket.mode](BinaryMarket.md). Not a chain enum — it is a reading of `strike`, whose 0 is the protocol's own sentinel for "this market resolves against another question's answer". --- # /docs/typescript/api/index/type-aliases/BinarySellSide [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinarySellSide # Type Alias: BinarySellSide > **BinarySellSide** = `"SELL_YES"` \| `"SELL_NO"` Defined in: packages/sdk/src/derivedReads.ts:852 The sell sides of [BinarySide](BinarySide.md) — what unwinds a position. --- # /docs/typescript/api/index/type-aliases/BinarySide [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BinarySide # Type Alias: BinarySide > **BinarySide** = `"BUY_YES"` \| `"SELL_YES"` \| `"BUY_NO"` \| `"SELL_NO"` Defined in: packages/sdk/src/store.ts:38 A side on a binary book: buy/sell the YES or NO outcome token. --- # /docs/typescript/api/index/type-aliases/BlockActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BlockActivity # Type Alias: BlockActivity > **BlockActivity** = `object` Defined in: packages/sdk/src/activity.ts:633 Everything the protocol traded in one block, grouped by market. ## Properties ### blockNumber > **blockNumber**: `bigint` Defined in: packages/sdk/src/activity.ts:635 The block, as the caller asked for it. *** ### timestamp > **timestamp**: `bigint` Defined in: packages/sdk/src/activity.ts:637 The block timestamp the reads were anchored on (unix seconds). *** ### markets > **markets**: [`BlockMarketActivity`](BlockMarketActivity.md)[] Defined in: packages/sdk/src/activity.ts:642 The markets this block touched, in descending order of activity. EMPTY is the normal case: most blocks contain no markets activity at all. *** ### marketsById > **marketsById**: `Record`\<`string`, [`Market`](Market.md)\> Defined in: packages/sdk/src/activity.ts:647 Market rows for every id in `markets`, keyed by lowercased id — so a caller can NAME each group without a lookup per group. *** ### truncated > **truncated**: `boolean` Defined in: packages/sdk/src/activity.ts:656 True when a stream came back exactly `limit` rows and the block may hold more. A block's activity is not a bounded set — a busy block can outrun any page — so the cap is reported rather than hidden. Page with `offset` while this is true; see [BlockActivityOptions](BlockActivityOptions.md). --- # /docs/typescript/api/index/type-aliases/BlockActivityOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BlockActivityOptions # Type Alias: BlockActivityOptions > **BlockActivityOptions** = `object` Defined in: packages/sdk/src/activity.ts:659 ## Properties ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/activity.ts:661 Max rows per stream (default 500). *** ### offset? > `optional` **offset?**: `number` Defined in: packages/sdk/src/activity.ts:669 Rows to skip per stream (default 0). Paging is PER STREAM, not over the grouped result: the three streams are independent reads and a page of one does not line up with a page of another. Use it to walk a block that reports `truncated`. --- # /docs/typescript/api/index/type-aliases/BlockMarketActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BlockMarketActivity # Type Alias: BlockMarketActivity > **BlockMarketActivity** = `object` Defined in: packages/sdk/src/activity.ts:619 One market's slice of a block. ## Properties ### market > **market**: `string` Defined in: packages/sdk/src/activity.ts:621 Lowercased market id. *** ### fills > **fills**: [`MarketTradeActivity`](MarketTradeActivity.md)[] Defined in: packages/sdk/src/activity.ts:623 Trades matched on this market in this block, in log order. *** ### placed > **placed**: [`BlockOrder`](BlockOrder.md)[] Defined in: packages/sdk/src/activity.ts:625 Orders placed on this market in this block. *** ### touched > **touched**: [`BlockOrder`](BlockOrder.md)[] Defined in: packages/sdk/src/activity.ts:627 Resting orders this block filled or removed. --- # /docs/typescript/api/index/type-aliases/BlockOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BlockOrder # Type Alias: BlockOrder > **BlockOrder** = `object` Defined in: packages/sdk/src/activity.ts:585 An order event that happened in one block. Deliberately carries NO `status`, `filledQuantity` or `quantityRemaining`. `Order` is a mutable row — those three columns are as-of-now, not as-of-this block — so the query does not select them and this type cannot leak them into a historical view. The block's own traded quantity comes from `fills`. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/activity.ts:587 Indexer row id. *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/activity.ts:589 On-chain order id (decimal string). *** ### market > **market**: `string` Defined in: packages/sdk/src/activity.ts:591 Lowercased market id. *** ### owner > **owner**: `string` Defined in: packages/sdk/src/activity.ts:593 Order owner. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/activity.ts:594 *** ### side > **side**: [`BinarySide`](BinarySide.md) \| `null` Defined in: packages/sdk/src/activity.ts:595 *** ### price > **price**: `string` Defined in: packages/sdk/src/activity.ts:597 Raw quote units per whole base. *** ### fullQuantity > **fullQuantity**: `string` Defined in: packages/sdk/src/activity.ts:599 Raw base units the order was placed for. *** ### placedAtBlock > **placedAtBlock**: `bigint` Defined in: packages/sdk/src/activity.ts:605 Block the order was PLACED in. Equal to the viewed block for a `placed` row; earlier than it for most `touched` rows, since a resting order is usually quoted in one block and removed in another. *** ### placedTxHash > **placedTxHash**: `string` Defined in: packages/sdk/src/activity.ts:607 Transaction that placed the order. *** ### cancelReason > **cancelReason**: `string` \| `null` Defined in: packages/sdk/src/activity.ts:613 Why the protocol removed the order, when the protocol (not the owner) did. Null for an owner cancel and for an order that was never cancelled — so a null here does NOT mean "still open". *** ### touch > **touch**: [`BlockOrderTouch`](BlockOrderTouch.md) \| `null` Defined in: packages/sdk/src/activity.ts:615 Set on `touched` rows only; null on `placed` rows. --- # /docs/typescript/api/index/type-aliases/BlockOrderTouch [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BlockOrderTouch # Type Alias: BlockOrderTouch > **BlockOrderTouch** = `"FILLED"` \| `"REMOVED"` Defined in: packages/sdk/src/activity.ts:575 How a resting order was touched IN the block being viewed. DERIVED from the block's own fills, never read off `Order.status`: status is the row's CURRENT value, so an order placed in this block and cancelled three blocks later reads `Cancelled` here — a state from this block's future. See [BlockOrder](BlockOrder.md). - `FILLED` — the order is a maker or taker of a fill in this block. - `REMOVED` — it is not, so this block cancelled or amended it. --- # /docs/typescript/api/index/type-aliases/BlockTimestampResolver [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BlockTimestampResolver # Type Alias: BlockTimestampResolver > **BlockTimestampResolver** = (`blockNumber`) => `Promise`\<`bigint`\> Defined in: packages/sdk/src/activity.ts:562 Reads a block's timestamp from the chain. The block-scoped reads need an anchor the indexer can serve from — no block column is indexed — and the block's own timestamp is it. This module stays indexer-only, so the owner injects the one chain read it needs rather than the module reaching for a transport of its own. ## Parameters ### blockNumber `bigint` ## Returns `Promise`\<`bigint`\> --- # /docs/typescript/api/index/type-aliases/BookTop [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BookTop # Type Alias: BookTop > **BookTop** = `object` Defined in: packages/sdk/src/orders.ts:415 Top of one market's resting book — ANY market kind. Prices are RAW and in that market's own terms: quote units per whole base on SPOT and PERP, YES probability on BINARY (there, the same scale as `BinaryMarket.lastPrice`). Comparable within a market, never across kinds or against another market's quote asset. `mid` is (bestBid + bestAsk) / 2, null unless BOTH sides rest — a one-sided book has no meaningful mid. ## Properties ### bestBid > **bestBid**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:417 Best (highest) resting bid price (raw); null when no bid rests. *** ### bestAsk > **bestAsk**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:419 Best (lowest) resting ask price (raw); null when no ask rests. *** ### mid > **mid**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:421 (bestBid + bestAsk) / 2, floored (raw); null unless BOTH sides rest. --- # /docs/typescript/api/index/type-aliases/BuilderApproval [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BuilderApproval # Type Alias: BuilderApproval > **BuilderApproval** = `object` Defined in: packages/sdk/src/fees.ts:222 A user→builder fee approval (mirror of the indexer `BuilderApproval` entity) — the directory counterpart to the on-chain point read `client.getBuilderApproval`. `maxFeeBpsTimes1k` is the pool bps×1000 cap. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/fees.ts:224 Approval id (`${market}_${user}_${builder}` — one row per triple, upserted). *** ### market > **market**: `string` Defined in: packages/sdk/src/fees.ts:226 Market id the approval applies to (lowercased). *** ### pool > **pool**: `string` Defined in: packages/sdk/src/fees.ts:228 Pool hosting that market's book (lowercased; joined via the market row). *** ### user > **user**: `string` Defined in: packages/sdk/src/fees.ts:230 Granting user (lowercased). *** ### builder > **builder**: `string` Defined in: packages/sdk/src/fees.ts:232 Approved builder/routing frontend (lowercased). *** ### maxFeeBpsTimes1k > **maxFeeBpsTimes1k**: `string` Defined in: packages/sdk/src/fees.ts:234 Max per-order builder fee the user approved (pool bps×1000; 0 = revoked). *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/fees.ts:236 Block of the last BuilderApproved upsert (decimal string). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/fees.ts:238 Timestamp (unix seconds) of the last BuilderApproved upsert. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/fees.ts:240 Tx hash of the last BuilderApproved upsert. --- # /docs/typescript/api/index/type-aliases/BuilderFeeRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / BuilderFeeRecord # Type Alias: BuilderFeeRecord > **BuilderFeeRecord** = `object` Defined in: packages/sdk/src/fees.ts:61 A realized builder/routing-fee record (mirror of the indexer `BuilderFeeRecord` entity). Amounts are raw collateral units. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/fees.ts:63 Record id (`${blockNumber}_${logIndex}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/fees.ts:65 uint128 OrderId the fee was charged on (decimal string). *** ### builder > **builder**: `string` Defined in: packages/sdk/src/fees.ts:67 Builder/routing frontend that received the fee (lowercased). *** ### payer > **payer**: `string` \| `null` Defined in: packages/sdk/src/fees.ts:69 Order owner who paid the fee (lowercased); null on pre-payer records. *** ### token > **token**: `string` Defined in: packages/sdk/src/fees.ts:71 Fee token (lowercased). *** ### amount > **amount**: `string` Defined in: packages/sdk/src/fees.ts:73 Fee routed to the builder (raw collateral units). *** ### market > **market**: `string` \| `null` Defined in: packages/sdk/src/fees.ts:75 Market id the fee's pool belongs to (lowercased); null when unlinked. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/fees.ts:77 Pool the fee was charged on (lowercased). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/fees.ts:79 Timestamp (unix seconds) the fee was charged. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/fees.ts:81 Tx hash the charge landed in. --- # /docs/typescript/api/index/type-aliases/Candle [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Candle # Type Alias: Candle > **Candle** = `object` Defined in: packages/sdk/src/candles.ts:22 One OHLCV candle (mirror of the indexer `Candle` entity). Candles exist for ANY pool — spot or binary — so this is unprefixed, not binary-specific. Prices are raw quote units per whole base (binary: the YES-probability scale, same as `lastPrice`); volumes are raw. ## Properties ### bucketStart > **bucketStart**: `string` Defined in: packages/sdk/src/candles.ts:24 Bucket-open timestamp (unix seconds), aligned to the interval. *** ### openPrice > **openPrice**: `string` Defined in: packages/sdk/src/candles.ts:26 First fill price in the bucket (raw). *** ### high > **high**: `string` Defined in: packages/sdk/src/candles.ts:28 Highest fill price in the bucket (raw). *** ### low > **low**: `string` Defined in: packages/sdk/src/candles.ts:30 Lowest fill price in the bucket (raw). *** ### closePrice > **closePrice**: `string` Defined in: packages/sdk/src/candles.ts:32 Last fill price in the bucket (raw). *** ### baseVolume > **baseVolume**: `string` Defined in: packages/sdk/src/candles.ts:34 Base/outcome-token volume in the bucket (raw). *** ### quoteVolume > **quoteVolume**: `string` Defined in: packages/sdk/src/candles.ts:36 Quote/collateral volume in the bucket (raw). *** ### tradeCount > **tradeCount**: `number` Defined in: packages/sdk/src/candles.ts:38 Number of fills in the bucket. --- # /docs/typescript/api/index/type-aliases/ClaimableFromError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClaimableFromError # Type Alias: ClaimableFromError > **ClaimableFromError** = [`InvalidInputError`](../classes/InvalidInputError.md) Defined in: packages/sdk/src/derivedReads.ts:758 Errors raised by [claimableFrom](../functions/claimableFrom.md). --- # /docs/typescript/api/index/type-aliases/ClientQueryKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ClientQueryKey # Type Alias: ClientQueryKey > **ClientQueryKey** = readonly [`QueryKeyElement`](QueryKeyElement.md)[] Defined in: packages/sdk/src/queryKeys.ts:47 A cache key for one client read: `["somnia-markets", , …inputs]`. --- # /docs/typescript/api/index/type-aliases/ComputeBinaryPnlError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ComputeBinaryPnlError # Type Alias: ComputeBinaryPnlError > **ComputeBinaryPnlError** = [`InvalidInputError`](../classes/InvalidInputError.md) Defined in: packages/sdk/src/units.ts:501 Errors raised by [computeBinaryPnl](../functions/computeBinaryPnl.md). --- # /docs/typescript/api/index/type-aliases/ComputePortfolioAnalyticsError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ComputePortfolioAnalyticsError # Type Alias: ComputePortfolioAnalyticsError > **ComputePortfolioAnalyticsError** = [`InvalidInputError`](../classes/InvalidInputError.md) Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:377 Every error [computePortfolioAnalytics](../functions/computePortfolioAnalytics.md) can throw. The fold is pure and touches no network or chain, so a bad argument is the only way it fails. --- # /docs/typescript/api/index/type-aliases/ComputePositionPnLError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ComputePositionPnLError # Type Alias: ComputePositionPnLError > **ComputePositionPnLError** = [`InvalidInputError`](../classes/InvalidInputError.md) Defined in: packages/sdk/src/derivedReads.ts:560 Errors raised by [computePositionPnL](../functions/computePositionPnL.md). --- # /docs/typescript/api/index/type-aliases/CountResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CountResult # Type Alias: CountResult > **CountResult** = `object` Defined in: packages/sdk/src/indexerRead.ts:183 A row count plus whether the read was cut short — same `truncated` vocabulary as [FundingRateSeries](FundingRateSeries.md) and the `hasMore` pagers, so a caller reads one convention across the SDK rather than two. `truncated: false` — a real total, from Hasura `_aggregate` or from a fallback scan that finished inside the cap. `truncated: true` — `count` is a LOWER BOUND (10,000 rows, the fallback cap); the true total is at least that. Render it as "10,000+", and do not treat it as the last page when paginating: a `rows.length < count` gate goes false while rows remain. ## Properties ### count > **count**: `number` Defined in: packages/sdk/src/indexerRead.ts:185 Rows matched, or the fallback cap (10,000) when `truncated`. *** ### truncated > **truncated**: `boolean` Defined in: packages/sdk/src/indexerRead.ts:187 True when the bounded fallback hit its cap, so `count` is a lower bound. --- # /docs/typescript/api/index/type-aliases/DebugEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DebugEvent # Type Alias: DebugEvent > **DebugEvent** = \{ `kind`: `"log"`; `level`: `"debug"` \| `"warn"`; `scope`: `string`; `message`: `string`; `data?`: `Record`\<`string`, `unknown`\>; \} \| \{ `kind`: `"span"`; `phase`: `"start"`; `id`: `number`; `parentId?`: `number`; `name`: `string`; `data?`: `Record`\<`string`, `unknown`\>; \} \| \{ `kind`: `"span"`; `phase`: `"annotate"`; `id`: `number`; `name`: `string`; `data`: `Record`\<`string`, `unknown`\>; \} \| \{ `kind`: `"span"`; `phase`: `"end"`; `id`: `number`; `name`: `string`; `durationMs`: `number`; `error?`: `unknown`; \} Defined in: packages/sdk/src/debug.ts:62 One event on the client's opt-in debug channel — either a structured log line or one phase of a span. Wire a sink with [ClientConfig.debug](../interfaces/ClientConfig.md#debug) and every event the client produces flows through it. **Details** Events are data, not display strings: `data` carries raw values (counts, addresses, bigints) and rendering/filtering is entirely the sink's job — see [consoleDebugSink](../functions/consoleDebugSink.md) for a ready-made renderer and [debugCollector](../functions/debugCollector.md) for test capture. A span arrives as a `start`/`end` pair sharing an `id` (unique within one client instance), with any number of `annotate` events in between attaching data to the still-open span. The shape maps 1:1 onto OpenTelemetry, so a real tracer is just another sink: `name` ↔ span name, `data` ↔ attributes, `error` ↔ span status / recorded exception, `annotate` ↔ `setAttribute`, `parentId` ↔ context link. **Gotchas** Parenting is EXPLICIT — a span event carries `parentId` only when the call site passed the parent handle — so interleaved events from concurrent operations always attribute correctly; never infer nesting from event order. **Example** (Handling debug events) A minimal custom sink — narrow on `kind`/`phase` and the union does the rest: ```ts const sink = (e: DebugEvent): void => { if (e.kind === "log") console.log(e.scope, e.message, e.data); else if (e.phase === "end" && e.error !== undefined) console.error(e.name, e.error); else if (e.phase === "end" && e.durationMs > 500) console.log("slow:", e.name, e.durationMs); }; const exchange = new SomniaMarkets({ ...config, debug: sink }); ``` ## Union Members ### Type Literal \{ `kind`: `"log"`; `level`: `"debug"` \| `"warn"`; `scope`: `string`; `message`: `string`; `data?`: `Record`\<`string`, `unknown`\>; \} #### kind > **kind**: `"log"` #### level > **level**: `"debug"` \| `"warn"` `"warn"` for conditions worth surfacing (a failed watch); `"debug"` for tracing. #### scope > **scope**: `string` Emitting module, e.g. `"liveTail"` — filter on it in the sink. #### message > **message**: `string` Stable, human-readable event description, e.g. `"applying logs"`. #### data? > `optional` **data?**: `Record`\<`string`, `unknown`\> Raw values for the sink to render (counts, block numbers, addresses, bigints). *** ### Type Literal \{ `kind`: `"span"`; `phase`: `"start"`; `id`: `number`; `parentId?`: `number`; `name`: `string`; `data?`: `Record`\<`string`, `unknown`\>; \} #### kind > **kind**: `"span"` #### phase > **phase**: `"start"` #### id > **id**: `number` Span id — matches the `annotate`/`end` events of the same span. Unique per client. #### parentId? > `optional` **parentId?**: `number` The enclosing span's `id`; absent on a root span. Only ever set explicitly. #### name > **name**: `string` Span name, `"."` — e.g. `"trade.execute"`, `"trader.placeOrder"`. #### data? > `optional` **data?**: `Record`\<`string`, `unknown`\> The operation's input, as raw values (a trader call's params object, …). *** ### Type Literal \{ `kind`: `"span"`; `phase`: `"annotate"`; `id`: `number`; `name`: `string`; `data`: `Record`\<`string`, `unknown`\>; \} #### kind > **kind**: `"span"` #### phase > **phase**: `"annotate"` #### id > **id**: `number` The still-open span this data belongs to. #### name > **name**: `string` The annotated span's name (so sinks need no id → name lookup). #### data > **data**: `Record`\<`string`, `unknown`\> Values that only exist mid-span — e.g. the tx hash once broadcast returns. *** ### Type Literal \{ `kind`: `"span"`; `phase`: `"end"`; `id`: `number`; `name`: `string`; `durationMs`: `number`; `error?`: `unknown`; \} #### kind > **kind**: `"span"` #### phase > **phase**: `"end"` #### id > **id**: `number` Matches the span's `start` event. #### name > **name**: `string` Same name as the `start` event. #### durationMs > **durationMs**: `number` Wall-clock start-to-settle: for an async span, until the promise settles. #### error? > `optional` **error?**: `unknown` The thrown value / rejection reason when the span failed; absent on success. --- # /docs/typescript/api/index/type-aliases/EstPayoutForError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / EstPayoutForError # Type Alias: EstPayoutForError > **EstPayoutForError** = [`InvalidInputError`](../classes/InvalidInputError.md) Defined in: packages/sdk/src/derivedReads.ts:666 Errors raised by [estPayoutFor](../functions/estPayoutFor.md). --- # /docs/typescript/api/index/type-aliases/FillDetail [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FillDetail # Type Alias: FillDetail > **FillDetail** = [`OrderFillRow`](OrderFillRow.md) & `object` Defined in: packages/sdk/src/fills.ts:390 [OrderFillRow](OrderFillRow.md) plus the market it executed on — one fill, fully framed. The embed is `marketRef`, not `market`, because the name is already taken: [FillRow.market](FillRow.md#market) is the bytes32 marketId STRING (aliased from `market_id` in `FillQueryFields`, load-bearing for binary-PnL market scoping). Two fields cannot share it — GraphQL refuses to select the `market` relationship alongside the `market: market_id` alias, and the TS intersection `string & MarketRef` is uninhabitable. ## Type Declaration ### marketRef > **marketRef**: [`MarketRef`](MarketRef.md) --- # /docs/typescript/api/index/type-aliases/FillOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FillOrder # Type Alias: FillOrder > **FillOrder** = `object` Defined in: packages/sdk/src/fills.ts:476 One side's order on a fill — the resting order, or the one that crossed it. A narrower shape than [OrderRow](OrderRow.md): this describes an order in the context of a fill whose market is already known, so it carries no market labelling. Amounts are raw units. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/fills.ts:478 Order id (`${pool}_${orderId}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/fills.ts:480 uint128 OrderId as a decimal string. *** ### owner > **owner**: `string` Defined in: packages/sdk/src/fills.ts:482 Owner wallet, lowercased. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/fills.ts:487 True = bid (buy). Set on every market kind, unlike `side`, which the indexer fills in only for binary. *** ### side > **side**: [`BinarySide`](BinarySide.md) \| `null` Defined in: packages/sdk/src/fills.ts:489 BINARY only — the YES/NO side; null on spot and perp. *** ### price > **price**: `string` Defined in: packages/sdk/src/fills.ts:491 Limit price, raw quote units per whole base. *** ### fullQuantity > **fullQuantity**: `string` Defined in: packages/sdk/src/fills.ts:493 Original size, raw base/outcome units. *** ### filledQuantity > **filledQuantity**: `string` Defined in: packages/sdk/src/fills.ts:495 Cumulative filled size, raw base/outcome units. *** ### quantityRemaining > **quantityRemaining**: `string` Defined in: packages/sdk/src/fills.ts:497 Unfilled remainder, raw base/outcome units. *** ### status > **status**: [`OrderStatus`](OrderStatus.md) Defined in: packages/sdk/src/fills.ts:499 Reconciled lifecycle status (Open/Filled/Cancelled/Expired/Closed). *** ### rested > **rested**: `boolean` Defined in: packages/sdk/src/fills.ts:501 Whether the order ever rested on the book (an `OrderRested` fired). *** ### cancelReason > **cancelReason**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:507 WHY the PROTOCOL cancelled the order, when it was not the owner. Null for an owner cancel and for an order that was never cancelled — so a `Cancelled` status with a null reason means the owner did it. *** ### placedAtTimestamp > **placedAtTimestamp**: `string` Defined in: packages/sdk/src/fills.ts:509 Timestamp (unix seconds) the order was placed. *** ### placedTxHash > **placedTxHash**: `string` Defined in: packages/sdk/src/fills.ts:511 Transaction the order was PLACED in — usually not the fill's transaction. --- # /docs/typescript/api/index/type-aliases/FillRow [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FillRow # Type Alias: FillRow > **FillRow** = `object` Defined in: packages/sdk/src/fills.ts:261 One fill as the indexer recorded it (mirror of the unified `Fill` entity — spot, perp and binary fills share it). ## Properties ### blockNumber? > `optional` **blockNumber?**: `string` Defined in: packages/sdk/src/fills.ts:263 Source block as an exact decimal string. SDK reads populate it; caller-built rows may omit it. *** ### logIndex? > `optional` **logIndex?**: `number` Defined in: packages/sdk/src/fills.ts:265 Source log position. SDK reads populate it; caller-built rows may omit it. *** ### id > **id**: `string` Defined in: packages/sdk/src/fills.ts:267 Fill id (`${blockNumber}_${logIndex}`). *** ### market > **market**: `string` Defined in: packages/sdk/src/fills.ts:278 The market's bytes32 marketId — the STABLE identity of the market this fill executed in. Group and label by this, never by `pool` alone: a binary pool is recycled across successive markets, so fills from a pool's earlier life carry the same pool address as the market currently on it. On SPOT/PERP the pool address IS the market id. Pass it to [client.getMarket](../interfaces/SomniaMarketsClient.md#getmarket) for the full row. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/fills.ts:283 Lowercased pool address the fill executed on. A TIME-VARYING binding — see `market` for the identity that does not move. *** ### fillPrice > **fillPrice**: `string` Defined in: packages/sdk/src/fills.ts:288 Execution price, raw quote units per whole base (binary: YES-probability scale). SPOT/PERP: the maker's limit price. *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/fills.ts:290 Base/outcome-token quantity filled, raw units. *** ### quoteQuantity > **quoteQuantity**: `string` Defined in: packages/sdk/src/fills.ts:292 Quote/collateral value = quantity × fillPrice / 10^baseDecimals (raw, floored). *** ### maker > **maker**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:294 Maker (resting) wallet, lowercased; null when unknown. *** ### makerSide > **makerSide**: [`BinarySide`](BinarySide.md) \| `null` Defined in: packages/sdk/src/fills.ts:296 BINARY only — the maker's YES/NO side; null on SPOT/PERP. *** ### taker > **taker**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:301 Taker wallet, lowercased. Denormalized from the taker's OrderPlaced (which fires after the fill in the same tx) — null until that bridge lands. *** ### takerSide > **takerSide**: [`BinarySide`](BinarySide.md) \| `null` Defined in: packages/sdk/src/fills.ts:306 BINARY only — the taker's YES/NO side; null on SPOT/PERP or until the taker's OrderPlaced is bridged. *** ### kind > **kind**: [`BinaryFillKind`](BinaryFillKind.md) \| `null` Defined in: packages/sdk/src/fills.ts:311 BINARY only — how the fill settled (direct trade vs mint/burn of a pair); null on SPOT/PERP or until the taker side is known. *** ### takerIsBid > **takerIsBid**: `boolean` \| `null` Defined in: packages/sdk/src/fills.ts:316 True when the taker bought the base/YES (the maker was the ask); null until the taker side is known. *** ### takerOrder > **takerOrder**: \{ `owner`: `string`; `side`: [`BinarySide`](BinarySide.md) \| `null`; \} \| `null` Defined in: packages/sdk/src/fills.ts:324 The taker's ORDER (owner + side), when the indexer has it. Prefer `takerOrder.side` over [FillRow.takerSide](#takerside) on binary: the latter is a denormalized copy the taker bridge backfills, so it lags and can be null on a row that already names its taker. *** ### makerOrderId > **makerOrderId**: `string` Defined in: packages/sdk/src/fills.ts:326 uint128 id of the resting (maker) order, decimal string. *** ### takerOrderId > **takerOrderId**: `string` Defined in: packages/sdk/src/fills.ts:328 uint128 id of the aggressing (taker) order, decimal string. *** ### takerRemainingQuantity > **takerRemainingQuantity**: `string` Defined in: packages/sdk/src/fills.ts:337 The taker order's unfilled remainder AFTER this fill, raw base/outcome units. `"0"` means this fill completed the order. The chain's own number, as `OrderFilled` carries it — so a caller reconciling partial fills from the tape sees exactly what an event subscriber sees, without re-deriving it from the running quantity. *** ### makerRemainingQuantity > **makerRemainingQuantity**: `string` Defined in: packages/sdk/src/fills.ts:339 The maker order's unfilled remainder AFTER this fill, on the same terms as [FillRow.takerRemainingQuantity](#takerremainingquantity). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/fills.ts:341 Timestamp (unix seconds) of the fill. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/fills.ts:343 Tx hash the fill landed in. --- # /docs/typescript/api/index/type-aliases/FillsOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FillsOptions # Type Alias: FillsOptions > **FillsOptions** = `object` Defined in: packages/sdk/src/fills.ts:30 Options for [SomniaMarketsClient.getFills](../interfaces/SomniaMarketsClient.md#getfills) / [SomniaMarketsClient.getUserFills](../interfaces/SomniaMarketsClient.md#getuserfills). All optional. ## Properties ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/fills.ts:32 Max rows (default 50). *** ### offset? > `optional` **offset?**: `number` Defined in: packages/sdk/src/fills.ts:34 Row offset for paging the tape (default 0). *** ### since? > `optional` **since?**: `number` Defined in: packages/sdk/src/fills.ts:36 Only fills at/after this unix-seconds timestamp. *** ### until? > `optional` **until?**: `number` Defined in: packages/sdk/src/fills.ts:38 Only fills at/before this unix-seconds timestamp. --- # /docs/typescript/api/index/type-aliases/FillsScope [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FillsScope # Type Alias: FillsScope > **FillsScope** = [`FillsOptions`](FillsOptions.md) & `object` Defined in: packages/sdk/src/fills.ts:53 Scope for the per-account fill reads ([SomniaMarketsClient.getUserFills](../interfaces/SomniaMarketsClient.md#getuserfills) / [SomniaMarketsClient.countUserFills](../interfaces/SomniaMarketsClient.md#countuserfills)): a `market` (or `markets`) and/or `pool` predicate on top of [FillsOptions](FillsOptions.md). Prefer `market` on binary. A binary pool is recycled by successive markets, so `pool` selects every life of that pool, while `market` selects exactly one market. On spot/perp the market id IS the pool address, so the two agree. ## Type Declaration ### market? > `optional` **market?**: `string` Only fills in this market (bytes32 marketId, case-insensitive). ### markets? > `optional` **markets?**: readonly `string`[] Only fills in ANY of these markets (bytes32 marketIds, case-insensitive) — the batched form of `market`, for folding several markets from one read. An empty array matches nothing. Supplying `market` as well narrows to both (the intersection), so neither silently overrides the other. ### pool? > `optional` **pool?**: `string` Only fills on this pool address (case-insensitive). --- # /docs/typescript/api/index/type-aliases/FundingPayment [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundingPayment # Type Alias: FundingPayment > **FundingPayment** = `object` Defined in: packages/sdk/src/perp/history.ts:48 A signed funding payment (mirror of the indexer `FundingPayment` entity). `amount` is signed raw collateral: **positive is what the account pays**, negative is what it receives. **Details.** The sign is the on-chain one, passed straight through from `MarginBank.FundingSettled`'s `int256 payment` — the indexer does not negate it, and neither does this type. `MarginBank` debits the account when `payment > 0` and credits it when `payment < 0`, and `IMarginBank` documents the event parameter as "positive = paid by account, negative = received by account". Keeping the pass-through is what lets a caller reconcile the value against the chain and against the cumulative funding index. It is the same direction as [PerpPositionMetrics.accruedFunding](../interfaces/PerpPositionMetrics.md#accruedfunding), which is a cost subtracted from equity, and as `docs/PERPS.md`'s `fundingSettled`. **Gotchas.** To display "paid" or "received" to a user, branch on `amount > 0n` meaning paid. A row read as though positive meant received labels every funding transfer the wrong way round. ## Example **Label a settled funding row for a user** ```ts // Positive `amount` = the account PAID this much funding. const paid: Pick = { amount: "2226" }; const label = BigInt(paid.amount) > 0n ? "paid" : "received"; // label === "paid" ``` ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:50 Payment id (`${txHash}_${logIndex}`). *** ### account > **account**: `string` Defined in: packages/sdk/src/perp/history.ts:52 Account (lowercased). *** ### pool > **pool**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:54 Perp pool (lowercased); null when unlinked. *** ### amount > **amount**: `string` Defined in: packages/sdk/src/perp/history.ts:56 Signed funding payment (raw collateral; positive = paid by the account, negative = received). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/history.ts:58 Timestamp (unix seconds) the funding settled. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/history.ts:60 Tx hash the settlement landed in. --- # /docs/typescript/api/index/type-aliases/FundingRateCandle [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundingRateCandle # Type Alias: FundingRateCandle > **FundingRateCandle** = `object` Defined in: packages/sdk/src/perp/history.ts:423 A funding-rate rollup bucket (mirror of the indexer `FundingRateCandle`) — for charting ranges the raw series is too dense for. Each bucket is built by distributing every settlement across the buckets its covered span overlaps, weighted by seconds and normalized to a fixed per-8h axis. That is not an implementation detail: crediting a lazily-settled emit to the bucket containing its log renders a phantom spike of however many intervals it accrued, while the buckets the funding actually applied to render as paused. At the live hourly cadence an hourly bucket holds exactly ONE interval, so even a two-interval emit doubles one bucket and empties its neighbour. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:425 Bucket id (`${pool}_${intervalSeconds}_${bucketStart}`). *** ### pool > **pool**: `string` Defined in: packages/sdk/src/perp/history.ts:426 *** ### intervalSeconds > **intervalSeconds**: `number` Defined in: packages/sdk/src/perp/history.ts:428 3600 | 14400 | 86400. *** ### bucketStart > **bucketStart**: `string` Defined in: packages/sdk/src/perp/history.ts:430 Bucket start (unix seconds). *** ### avgFundingRate8h > **avgFundingRate8h**: `string` Defined in: packages/sdk/src/perp/history.ts:437 Seconds-weighted mean rate, already on a per-8h basis, and zero-filled: seconds no settlement covered pull the mean toward zero rather than being dropped. So a partially covered bucket reads BELOW the rate that was in force — read `coverage` to tell that apart from a genuinely small rate. *** ### minFundingRate8h > **minFundingRate8h**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:443 Extremes over CONTRIBUTING settlements only — undiluted by coverage and NOT zero-filled, so they can legitimately sit outside `avgFundingRate8h` on a thinly covered bucket. Null when no settlement's span reached this bucket. *** ### maxFundingRate8h > **maxFundingRate8h**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:444 *** ### coverage > **coverage**: `string` Defined in: packages/sdk/src/perp/history.ts:450 Covered seconds / bucket seconds, 1e18-scaled — a true ratio in [0, 1]. This is what a chart should hatch or grey on: a bucket at `avgFundingRate8h: 0` with low coverage is a PAUSE, not a measurement of zero funding. *** ### cumulativeFundingStart > **cumulativeFundingStart**: `string` Defined in: packages/sdk/src/perp/history.ts:468 Cumulative funding index at this bucket's wall-clock START and END, attributed by covered seconds — the same basis as `avgFundingRate8h`. Two exact properties follow, and both are what this pair is for: - **Sparse buckets telescope.** `cumulativeFundingEnd` equals the next existing bucket's `cumulativeFundingStart`, even across a gap no settlement covered — the index is flat over uncovered time, so there is nothing to attribute. - **Range sums are exact.** `sum(end - start)` over any set of buckets is the funding that accrued over them; see [realizedFundingPerBase](../functions/realizedFundingPerBase.md). These are ATTRIBUTION values, not chain samples. A catch-up settlement's whole span is spread across the buckets it covered rather than booked at its log, so an interior edge deliberately will NOT equal any `FundingRateUpdate.cumulativeFundingPerUnit`. Use [client.listFundingRateHistory](../interfaces/SomniaMarketsClient.md#listfundingratehistory) when you want the sampled series itself. *** ### cumulativeFundingEnd > **cumulativeFundingEnd**: `string` Defined in: packages/sdk/src/perp/history.ts:469 *** ### fundingWindowSec > **fundingWindowSec**: `number` Defined in: packages/sdk/src/perp/history.ts:471 Params at the bucket's last settlement; `paramsChangedInBucket` flags a mid-bucket change. *** ### fundingIntervalSec > **fundingIntervalSec**: `number` Defined in: packages/sdk/src/perp/history.ts:472 *** ### paramsChangedInBucket > **paramsChangedInBucket**: `boolean` Defined in: packages/sdk/src/perp/history.ts:473 *** ### indexPriceEnd > **indexPriceEnd**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:474 *** ### openInterestEnd > **openInterestEnd**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:475 *** ### updateCount > **updateCount**: `number` Defined in: packages/sdk/src/perp/history.ts:477 How many settlements contributed to this bucket. --- # /docs/typescript/api/index/type-aliases/FundingRateSeries [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundingRateSeries # Type Alias: FundingRateSeries\ > **FundingRateSeries**\<`T`\> = `object` Defined in: packages/sdk/src/funding.ts:318 Chart-ready funding buckets plus pagination evidence for the requested window. **Details** Buckets are oldest-first and gapless from the first returned real bucket. `truncated` reports whether older source rows were omitted by the page limit. **Gotchas** A truncated series can start after the requested `from` value. Use `firstBucketStart` and fetch another page instead of drawing the missing history as zero funding. ## Type Parameters ### T `T` *extends* [`FundingBucketLike`](../interfaces/FundingBucketLike.md) = [`FundingBucketLike`](../interfaces/FundingBucketLike.md) ## Properties ### buckets > **buckets**: [`FundingSeriesBucket`](FundingSeriesBucket.md)\<`T`\>[] Defined in: packages/sdk/src/funding.ts:320 Oldest-first and gapless on the interval grid — chart order. *** ### truncated > **truncated**: `boolean` Defined in: packages/sdk/src/funding.ts:325 The read hit its `limit`, so buckets older than `firstBucketStart` exist and were NOT returned. Page with `offset` for the rest. *** ### firstBucketStart > **firstBucketStart**: `number` \| `null` Defined in: packages/sdk/src/funding.ts:327 First bucketStart present, unix seconds. Above the requested `from` when truncated. --- # /docs/typescript/api/index/type-aliases/FundingRateUpdate [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundingRateUpdate # Type Alias: FundingRateUpdate > **FundingRateUpdate** = `object` Defined in: packages/sdk/src/perp/history.ts:327 A funding-rate history point (mirror of the indexer `FundingRateUpdate` entity) — the append-only counterpart to the market row's overwrite-only funding fields. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:329 Update id (`${pool}_${block}_${logIndex}`). *** ### pool > **pool**: `string` Defined in: packages/sdk/src/perp/history.ts:331 Perp pool (lowercased). *** ### fundingRate > **fundingRate**: `string` Defined in: packages/sdk/src/perp/history.ts:337 Rate applied to THIS settlement, per CALCULATION WINDOW, 1e18-scaled, signed. Normalize with `fundingWindowSec` on this same row — see [normalizeFundingRate](../functions/normalizeFundingRate.md). *** ### cumulativeFundingPerUnit > **cumulativeFundingPerUnit**: `string` Defined in: packages/sdk/src/perp/history.ts:344 Cumulative funding index AFTER this settlement (1e18 x quote units per whole base, signed, NOT monotonic). The ground truth for accrual: realized funding over any range is exactly `(end - start) / 1e18` raw quote units per whole base, with no interpolation and no gap reasoning. See [realizedFundingPerBase](../functions/realizedFundingPerBase.md). *** ### indexPrice > **indexPrice**: `string` Defined in: packages/sdk/src/perp/history.ts:346 Oracle index price at the update (raw quote per whole base, 18dp). *** ### markPrice > **markPrice**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:354 Best-effort mark-price cross-check. NULL when the contract emitted its 0 sentinel for a stale/reverting mark feed — never a price of zero. Unrelated to the premium driving the rate, which since DEX-2252 is the time-weighted IMPACT-price premium (quantity-weighted fill price at a configured notional on each side, deadbanded against the index), not a book midpoint. *** ### intervalsSettled > **intervalsSettled**: `string` Defined in: packages/sdk/src/perp/history.ts:366 Intervals SPANNED, unclamped, as emitted — the timeline the anchor advanced over, not what accrued. **This alone does not tell you whether anything was forgiven.** Compare it against `intervalsAccrued`: they are equal when the settlement charged its whole span, and `intervalsAccrued` is lower when the rest was forgiven at zero. A value above 1 is not enough on its own, because rows from before the one-interval horizon can have BOTH counts above 1 — a row spanning 264 intervals and accruing 96 forgave 168, and a row spanning 96 and accruing 96 forgave nothing. *** ### intervalsAccrued > **intervalsAccrued**: `string` Defined in: packages/sdk/src/perp/history.ts:379 What actually accrued, which is **not** `min(intervalsSettled, n)` — do not re-derive it that way. The contract's catch-up horizon charges at most **one interval** per settlement however long the gap, so a value below `intervalsSettled` means the excess was FORGIVEN at zero funding rather than deferred. The forgiven intervals are the OLDEST ones. The indexer recovers this from the cumulative-index delta the settlement actually moved, rather than reading it off `intervalsSettled`, because the horizon belongs to the deployed contract and has changed more than once. So a row is correct for the implementation that produced it, anywhere in backfilled history. *** ### fundingWindowSec > **fundingWindowSec**: `number` Defined in: packages/sdk/src/perp/history.ts:381 The rate's denominator in seconds, in force at this emit. Makes the row self-normalizing. *** ### fundingIntervalSec > **fundingIntervalSec**: `number` Defined in: packages/sdk/src/perp/history.ts:383 Settlement cadence in seconds, in force at this emit. *** ### spanStart > **spanStart**: `string` Defined in: packages/sdk/src/perp/history.ts:394 Wall-clock span this settlement's accrual covers — the last `intervalsAccrued` intervals ending at the settlement anchor. It reaches BACKWARDS from the emit, which is why a funding chart must distribute a row across the buckets its span overlaps rather than credit it to the bucket containing it. At the deployed one-interval horizon that span is usually one interval wide, so the distribution matters most for older rows: under the earlier horizons one lazily settled emit could cover a full calculation window. *** ### spanEnd > **spanEnd**: `string` Defined in: packages/sdk/src/perp/history.ts:395 *** ### anchorResynced > **anchorResynced**: `boolean` Defined in: packages/sdk/src/perp/history.ts:402 True when the settlement anchor had to be re-derived because the chain advanced it with NO event — the stale-oracle-with-zero-open-interest branch, where funding is permanently forgiven at zero and nothing is logged. A run of these means some funding time is covered by no row at all. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/history.ts:404 Timestamp (unix seconds) of the update. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/history.ts:405 *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/history.ts:406 --- # /docs/typescript/api/index/type-aliases/FundingSeriesBucket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FundingSeriesBucket # Type Alias: FundingSeriesBucket\ > **FundingSeriesBucket**\<`T`\> = `T` & `object` \| \{ `bucketStart`: `string`; `intervalSeconds`: `number`; `avgFundingRate8h`: `"0"`; `coverage`: `"0"`; `filled`: `true`; \} Defined in: packages/sdk/src/funding.ts:292 One grid slot: either a real rollup row, or a slot no settlement covered. ## Type Parameters ### T `T` *extends* [`FundingBucketLike`](../interfaces/FundingBucketLike.md) = [`FundingBucketLike`](../interfaces/FundingBucketLike.md) --- # /docs/typescript/api/index/type-aliases/GetLiquidationsOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetLiquidationsOptions # ~~Type Alias: GetLiquidationsOptions~~ > **GetLiquidationsOptions** = [`ListLiquidationsOptions`](../interfaces/ListLiquidationsOptions.md) Defined in: packages/sdk/src/perp/history.ts:699 ## Deprecated Renamed to [ListLiquidationsOptions](../interfaces/ListLiquidationsOptions.md). --- # /docs/typescript/api/index/type-aliases/GetUserFillsPageOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / GetUserFillsPageOptions # Type Alias: GetUserFillsPageOptions > **GetUserFillsPageOptions** = `Omit`\<[`FillsScope`](FillsScope.md), `"offset"`\> & `object` Defined in: packages/sdk/src/fills.ts:68 Scope and bounded continuation for [SomniaMarketsClient.getUserFillsPage](../interfaces/SomniaMarketsClient.md#getuserfillspage). ## Type Declaration ### cursor? > `optional` **cursor?**: `string` Opaque cursor from the preceding page. Omit for the newest page. --- # /docs/typescript/api/index/type-aliases/IndexedMarketCreator [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedMarketCreator # Type Alias: IndexedMarketCreator > **IndexedMarketCreator** = `object` Defined in: packages/sdk/src/marketCreatorAdmin.ts:699 A MarketCreator as the indexer sees it (mirror of the `MarketCreator` entity) — one per (operator, venue) machinery instance. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:701 MarketCreator address (== entity id, lowercased). *** ### owner > **owner**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:703 Owner address (lowercased). *** ### policy > **policy**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:705 The creator's MarketCreatorPolicy address (lowercased). *** ### core > **core**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:707 The core BinaryMarketsModule the creator binds to (lowercased). *** ### adapter > **adapter**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:709 The oracle adapter the creator's markets resolve against (lowercased). *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:711 The operator the creator is bound to. *** ### venueId > **venueId**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:713 Opaque bytes32 venue id the creator is bound to. *** ### factory > **factory**: `string` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:718 The MarketCreatorFactory that minted this creator (lowercased). `null` for a creator observed before/without its factory event. *** ### createdAtBlock > **createdAtBlock**: `number` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:720 Block the creator was deployed in (decimal string); null when not yet observed. *** ### createdAtTimestamp > **createdAtTimestamp**: `string` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:722 Timestamp (unix seconds) the creator was deployed; null when not yet observed. *** ### series > **series**: [`IndexedSeries`](IndexedSeries.md)[] Defined in: packages/sdk/src/marketCreatorAdmin.ts:724 The series registered under this creator (nested relationship). --- # /docs/typescript/api/index/type-aliases/IndexedMarketCreatorPolicy [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedMarketCreatorPolicy # Type Alias: IndexedMarketCreatorPolicy > **IndexedMarketCreatorPolicy** = `object` Defined in: packages/sdk/src/marketCreatorAdmin.ts:761 A MarketCreatorPolicy as the indexer sees it (mirror of the `MarketCreatorPolicy` entity). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:763 Policy address (== entity id, lowercased). *** ### owner > **owner**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:765 Owner address (lowercased). *** ### creator > **creator**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:767 The MarketCreator this policy gates (lowercased). *** ### createdAtTimestamp > **createdAtTimestamp**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:769 Timestamp (unix seconds) the policy was deployed. --- # /docs/typescript/api/index/type-aliases/IndexedOperator [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedOperator # Type Alias: IndexedOperator > **IndexedOperator** = `object` Defined in: packages/sdk/src/operatorAdmin.ts:437 An operator as the indexer sees it (mirror of the `Operator` entity). ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:439 operatorId (uint32) as a number — the on-chain id AND the entity primary key. *** ### owner > **owner**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:441 Owner address (lowercased). *** ### feeRecipient > **feeRecipient**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:443 Default fee recipient for the operator's venues (lowercased). *** ### enabled > **enabled**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:445 The registry-level kill switch — false disables the operator. *** ### policy > **policy**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:447 Operator-wide IVenuePolicy (lowercased); zero-address = none. *** ### context > **context**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:452 Opaque operator-supplied metadata bytes (hex, 0x-prefixed; '0x' when empty). The chain attaches no semantics — off-chain data only. *** ### pendingOwner > **pendingOwner**: `string` \| `null` Defined in: packages/sdk/src/operatorAdmin.ts:454 Pending incoming owner staged by a two-step transfer (lowercased); null if none in flight. *** ### createdAtTimestamp > **createdAtTimestamp**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:456 Timestamp (unix seconds) the operator was registered. *** ### updatedAtTimestamp > **updatedAtTimestamp**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:458 Timestamp (unix seconds) of the last update to the row. *** ### venueCount > **venueCount**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:460 Number of venues created under the operator (soft-disabled included). *** ### marketCount > **marketCount**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:462 Number of markets created under the operator. *** ### cumulativeQuoteVolume > **cumulativeQuoteVolume**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:464 Cumulative binary quote/collateral volume across the operator's markets (raw). *** ### protocolFeesCollected > **protocolFeesCollected**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:466 Cumulative protocol fees collected across the operator's markets (raw). *** ### settlementFeesCollected > **settlementFeesCollected**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:468 Cumulative settlement fees collected across the operator's markets (raw). *** ### builderFeesCollected > **builderFeesCollected**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:470 Cumulative builder fees routed across the operator's markets (raw). --- # /docs/typescript/api/index/type-aliases/IndexedOracleAdapter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedOracleAdapter # Type Alias: IndexedOracleAdapter > **IndexedOracleAdapter** = `object` Defined in: packages/sdk/src/marketCreatorAdmin.ts:732 An OracleAdapter as the indexer sees it (mirror of the `OracleAdapter` entity). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:734 Adapter address (== entity id, lowercased). *** ### owner > **owner**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:736 Owner address (lowercased). *** ### factory > **factory**: `string` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:741 The OracleAdapterFactory that minted it (lowercased); null for the protocol's shared adapter (deployed outside the factory). *** ### approved > **approved**: `boolean` Defined in: packages/sdk/src/marketCreatorAdmin.ts:743 Whether the module has approved the adapter (the inert→live gate). *** ### approvedAtTimestamp > **approvedAtTimestamp**: `string` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:745 Timestamp the adapter was approved (null if never approved). *** ### createdAtTimestamp > **createdAtTimestamp**: `string` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:752 Timestamp (unix seconds) the adapter was deployed/first indexed. `null` when the approval event was indexed BEFORE the creation event — the handler carries `prior?.createdAtTimestamp` forward, so an approve-first ordering leaves it unset (see indexer/src/handlers/machinery.ts). --- # /docs/typescript/api/index/type-aliases/IndexedPerpPosition [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedPerpPosition # Type Alias: IndexedPerpPosition > **IndexedPerpPosition** = `object` Defined in: packages/sdk/src/perp/state.ts:514 One account's position in one perp pool as the INDEXER has it — the mirror of the `PerpPosition` entity, and the batch counterpart to the per-pool chain read `client.getPerpPosition`. **This is a snapshot, not the live position.** The row is upserted on each `MarginBank.PositionUpdated`, so it is current as of [updatedAtBlock](#updatedatblock) and no fresher. Everything mark-dependent — unrealized PnL, liquidation price, margin health — needs a chain read on top; nothing here is marked to market. Numeric fields are decimal STRINGS of raw units (the indexer wire format), unlike [PerpPosition](../interfaces/PerpPosition.md), whose chain reads are `bigint`. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/state.ts:516 Row id (`${pool}_${account}`). *** ### pool > **pool**: `string` Defined in: packages/sdk/src/perp/state.ts:518 Perp pool the position is in (lowercased). *** ### account > **account**: `string` Defined in: packages/sdk/src/perp/state.ts:520 Position owner (lowercased). *** ### size > **size**: `string` Defined in: packages/sdk/src/perp/state.ts:529 SIGNED position size in raw base units: positive = long, negative = short. Normalized to match [PerpPosition.size](../interfaces/PerpPosition.md#size). The entity itself stores an absolute `size` plus a separate `isLong` flag; carrying that second field here would mean two exported position types whose `size` means different things, which reads correctly for longs and silently inverts every short. *** ### avgEntryPrice > **avgEntryPrice**: `string` \| `null` Defined in: packages/sdk/src/perp/state.ts:538 Volume-weighted average entry price, raw quote units per whole base. The same quantity as [PerpPosition.avgEntryPrice](../interfaces/PerpPosition.md#avgentryprice), written straight from the event. (The underlying entity column is named `entryPriceX18`, which is a misnomer — the value is NOT 1e18-scaled. Renamed at this boundary so the name cannot imply a rescale that never happened.) *** ### lastUpdateRealizedPnl > **lastUpdateRealizedPnl**: `string` \| `null` Defined in: packages/sdk/src/perp/state.ts:548 Realized PnL from the MOST RECENT position update only (signed; zero for opens and increases). **Not cumulative, and never summable.** There is one row per position, not one per update, and each update OVERWRITES this field — so prior values are gone and neither summing across positions nor accumulating over time yields lifetime realized PnL. It is a property of the last update, nothing more. *** ### updatedAt > **updatedAt**: `string` Defined in: packages/sdk/src/perp/state.ts:553 Unix SECONDS of the last update. ([PerpPosition](../interfaces/PerpPosition.md) is NANOseconds — the two are 1e9 apart, so never compare them without converting.) *** ### updatedAtBlock > **updatedAtBlock**: `number` \| `null` Defined in: packages/sdk/src/perp/state.ts:555 Block of the last update — the row is current as of this height, not head. --- # /docs/typescript/api/index/type-aliases/IndexedSeries [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedSeries # Type Alias: IndexedSeries > **IndexedSeries** = `object` Defined in: packages/sdk/src/marketCreatorAdmin.ts:669 A Series as the indexer sees it (mirror of the `Series` entity) — one rolling up/down market spec registered under a creator. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:671 Entity id: `${creatorLower}_${seriesId}`. *** ### creatorAddress > **creatorAddress**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:673 The MarketCreator this series belongs to (lowercased). *** ### seriesId > **seriesId**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:675 Per-creator series id (uint32). *** ### collateral > **collateral**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:677 Per-series collateral ERC-20 (lowercased). *** ### asset > **asset**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:679 Underlying asset label (e.g. "BTC/USDT"). *** ### intervalSec > **intervalSec**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:681 Roll interval in seconds (raw bigint as string). *** ### createdAtTimestamp > **createdAtTimestamp**: `string` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:688 Timestamp (unix seconds) the series was registered. `null` when the row was first written by an event that carries no creation block (the handlers pass `prior?.createdAtTimestamp` through) — the indexer schema declares it nullable, so this mirrors the wire. *** ### updatedAtTimestamp > **updatedAtTimestamp**: `string` \| `null` Defined in: packages/sdk/src/marketCreatorAdmin.ts:690 Timestamp (unix seconds) of the last update (a re-register overwrites); null until first update. --- # /docs/typescript/api/index/type-aliases/IndexedVenue [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexedVenue # Type Alias: IndexedVenue > **IndexedVenue** = `object` Defined in: packages/sdk/src/operatorAdmin.ts:478 A venue as the indexer sees it (mirror of the `Venue` entity). ## Properties ### venueId > **venueId**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:480 Opaque bytes32 venue id (== entity id); NOT a human label. *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:482 The operator the venue belongs to. *** ### marketType > **marketType**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:484 bytes4 market-type id the venue is pinned to, forever (hex). *** ### feeParams > **feeParams**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:486 Type-specific fee params, opaque to the registry (bytes hex). *** ### feeRecipientOverride > **feeRecipientOverride**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:488 Per-venue fee recipient override (lowercased); zero-address falls back to the operator's. *** ### policy > **policy**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:490 Per-venue IVenuePolicy (lowercased); zero-address = none. *** ### signer > **signer**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:492 Per-venue EIP-712 signer (lowercased); non-zero ⇒ creation requires a venue sig. *** ### creationEnabled > **creationEnabled**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:494 Whether new markets may currently be created under the venue. *** ### context > **context**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:499 Opaque venue-supplied metadata bytes (hex, 0x-prefixed; '0x' when empty). The chain attaches no semantics — off-chain data only. *** ### createdAtTimestamp > **createdAtTimestamp**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:501 Timestamp (unix seconds) the venue was created. *** ### updatedAtTimestamp > **updatedAtTimestamp**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:503 Timestamp (unix seconds) of the last update to the row. *** ### marketCount > **marketCount**: `number` Defined in: packages/sdk/src/operatorAdmin.ts:505 Number of markets created under the venue. *** ### cumulativeQuoteVolume > **cumulativeQuoteVolume**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:507 Cumulative binary quote/collateral volume across the venue's markets (raw). *** ### protocolFeesCollected > **protocolFeesCollected**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:509 Cumulative protocol fees collected across the venue's markets (raw). *** ### settlementFeesCollected > **settlementFeesCollected**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:511 Cumulative settlement fees collected across the venue's markets (raw). *** ### builderFeesCollected > **builderFeesCollected**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:513 Cumulative builder fees routed across the venue's markets (raw). --- # /docs/typescript/api/index/type-aliases/IndexerFreshness [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexerFreshness # Type Alias: IndexerFreshness > **IndexerFreshness** = [`IndexerSyncStatus`](IndexerSyncStatus.md) & `object` Defined in: packages/sdk/src/syncStatus.ts:87 Indexer metadata compared to an independently requested chain head. ## Type Declaration ### independentHead > `readonly` **independentHead**: [`IndependentHead`](../interfaces/IndependentHead.md) Independent RPC observation. RPC recency itself is not asserted. ### processedBlockTimestamp > `readonly` **processedBlockTimestamp**: `bigint` \| `null` Processed block's Unix time; null when the processed height is unknown. ### lagBlocks > `readonly` **lagBlocks**: `bigint` \| `null` Independent head minus processed height, clamped to zero. ### lagSeconds > `readonly` **lagSeconds**: `bigint` \| `null` Difference between chain timestamps in seconds, clamped to zero. ### reportedLagBlocks > `readonly` **reportedLagBlocks**: `bigint` \| `null` Indexer's own reported head minus processed height, clamped to zero. ### observedAt > `readonly` **observedAt**: `number` Wall-clock completion time in milliseconds. --- # /docs/typescript/api/index/type-aliases/IndexerSyncStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IndexerSyncStatus # Type Alias: IndexerSyncStatus > **IndexerSyncStatus** = `object` Defined in: packages/sdk/src/syncStatus.ts:19 The indexer's own sync state for one chain (envio `chain_metadata`). These self-reported heights can freeze together. Use IndexerFreshness for independent lag. ## Properties ### chainId > **chainId**: `number` Defined in: packages/sdk/src/syncStatus.ts:21 Chain id the row describes. *** ### latestProcessedBlock > **latestProcessedBlock**: `number` \| `null` Defined in: packages/sdk/src/syncStatus.ts:23 Last block the indexer fully processed; null before the first block lands. *** ### blockHeight > **blockHeight**: `number` \| `null` Defined in: packages/sdk/src/syncStatus.ts:25 Chain head height as the indexer last saw it; null until first fetched. *** ### numEventsProcessed > **numEventsProcessed**: `number` \| `null` Defined in: packages/sdk/src/syncStatus.ts:31 Lifetime count of events the indexer has processed on this chain. `null` on the rare row where envio has not populated the counter yet — Hasura declares the column nullable, so this is the wire's shape, not a defensive guess. --- # /docs/typescript/api/index/type-aliases/IntervalSource [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / IntervalSource # Type Alias: IntervalSource > **IntervalSource** = `object` Defined in: packages/sdk/src/interval.ts:28 The minimal market shape needed to resolve a cadence — a structural subset of [BinaryMarket](BinaryMarket.md), so these helpers stay dependency-free (no import cycle with the concept modules) and accept either the indexed row or a hand-built object. Fields accept the indexer's decimal strings OR plain numbers. ## Properties ### intervalSec? > `optional` **intervalSec?**: `string` \| `number` \| `null` Defined in: packages/sdk/src/interval.ts:31 Series cadence in seconds, as the indexer derived it (may be null on a row that predates the field, or on SPOT/PERP). *** ### tradingStart? > `optional` **tradingStart?**: `string` \| `number` \| `null` Defined in: packages/sdk/src/interval.ts:33 Unix seconds trading opened. *** ### expiry? > `optional` **expiry?**: `string` \| `number` \| `null` Defined in: packages/sdk/src/interval.ts:35 Unix seconds trading ends / the outcome is decided. --- # /docs/typescript/api/index/type-aliases/LenderConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LenderConfig # Type Alias: LenderConfig > **LenderConfig** = [`OracleHubAdminConfig`](../interfaces/OracleHubAdminConfig.md) Defined in: packages/sdk/src/lend/lender.ts:31 Signer config for the lend entry's `createLender` — same signer doctrine as every SDK write surface (a `privateKey`, a local `account`, or a browser `walletClient`). --- # /docs/typescript/api/index/type-aliases/LiquidationEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiquidationEvent # Type Alias: LiquidationEvent > **LiquidationEvent** = `object` Defined in: packages/sdk/src/perp/history.ts:146 A liquidation event (mirror of the indexer `LiquidationEvent` entity). All numeric fields are raw units; any may be null when the source event didn't carry it. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:148 Event id (`${txHash}_${logIndex}`). *** ### account > **account**: `string` Defined in: packages/sdk/src/perp/history.ts:150 Liquidated account (lowercased). *** ### pool > **pool**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:152 Perp pool (lowercased); null on account-scoped rows. *** ### kind > **kind**: `string` Defined in: packages/sdk/src/perp/history.ts:183 WHICH stage of the liquidation/deleveraging waterfall this row is. **Read this first** — the rows are stages of one mechanism, not repetitions of one event, and without it an ADL leg is indistinguishable from a liquidation: AccountLiquidated account-level summary (positionsProcessed, stageReached) PositionLiquidated per-position liquidation (size, price) PositionSkipped below min quantity, left in place (size) PositionTakenOver stage-4 backstop takeover (counterparty = bidder, price) AutoDeleveraged ADL leg (counterparty absorbed it; price = bankruptcy price) Throttled DEFERRED by the pool's per-block volume cap KeeperReward paid to the keeper that ran it (counterparty = keeper) OrderPanicked the liquidation IOC reverted with a Solidity PANIC PositionTransferred stage-4 transfer (counterparty, size) CloseOutMarginSettled stage-4 close-out margin flow (counterparty) BadDebtAbsorbed the fund was ASKED to cover (insuranceCovered, deficit, counterparty = fund). It fires on the request, not on the payment: `insuranceCovered` may be 0. Read that field before you conclude the fund paid. ResidualBadDebt uncovered, INSOLVENT hole after the waterfall (badDebt) AdlPriceCapacityExhausted terminal: hole exceeds aggregate position capacity (badDebt) ResidualBackedByOpenPnl hole fully backed by the account's OWN open PnL (deficit, equity) CoverageDeclined coverage the equity cap DEFERRED (coverageDeclined) AdlSessionDiscarded ADL session abandoned; amount is on the same-tx BadDebtAbsorbed row AdlCapacityShortfall ADL could not source enough capacity (size) A `string`, not [LiquidationKind](LiquidationKind.md): the row carries what the DEPLOYED indexer wrote, which can outrun a pinned SDK. [isLiquidationKind](../functions/isLiquidationKind.md) narrows it for an exhaustive switch or to pass back into the filter. *** ### size > **size**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:190 Signed size for the leg, where the event carries one (raw base units). Signed, not absolute: `PositionLiquidated` emits a signed `sizeDelta`, and the sign is the side being closed. *** ### price > **price**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:195 Price for the leg (raw quote per whole base) — mark price, takeover price, or ADL bankruptcy price depending on `kind`. *** ### counterparty > **counterparty**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:205 The other side of the leg: the ADL counterparty who absorbed it, the takeover bidder, the transfer/close-out peer, or — on `BadDebtAbsorbed` — the Insurance Fund the engine ASKED to cover. Null on rows with no counterparty. On `BadDebtAbsorbed` this names the fund that was asked, not one that paid. The address is recorded even when `insuranceCovered` is 0, so read that field to see whether any value moved. *** ### penalty > **penalty**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:207 Penalty charged (raw collateral; reserved — not carried by current events). *** ### badDebt > **badDebt**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:228 The LEVEL of the account's uncovered, genuinely insolvent realized hole after this `liquidate()` call — `ResidualBadDebt`, or `AdlPriceCapacityExhausted` for the terminal price-capacity case (raw collateral). **A level, not a flow — never SUM this across rows.** The underlying `residual` is a post-call state sample, so a later call on the same account re-reports the same (possibly changed) hole, and a stage-5 residual can co-fire with a terminal ADL one in a single call: two samples of one hole at two stages. Sound aggregates: the **latest row per account** is that account's currently known uncovered hole (an upper bound — a deposit can repay it with no row here, see [MarginEvent](MarginEvent.md)), and the **sum of those latest rows across accounts** is point-in-time system bad debt. Deliberately narrow: what the fund actually paid is [LiquidationEvent.insuranceCovered](#insurancecovered), a gross pre-coverage hole is [LiquidationEvent.deficit](#deficit), and a deferred coverage decision is [LiquidationEvent.coverageDeclined](#coveragedeclined). Collateral that merely MOVED between accounts is in `collateralAmount`. *** ### insuranceCovered > **insuranceCovered**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:242 Wei the Insurance Fund ACTUALLY moved — `BadDebtAbsorbed` only (raw collateral). A **flow**, and the only summable amount here: rows are disjoint payments, so a SUM over any slice is exact fund outflow. A `insuranceCovered` below the same row's `deficit` does NOT mean the fund was underfunded — part of a hole is unattributable (a pre-existing balance, or funding owed), and that remainder surfaces as a `ResidualBadDebt` row instead. `AdlSessionDiscarded` deliberately leaves this null: its absorption is the same `absorbBadDebt` call that emits `BadDebtAbsorbed` in the same transaction, so counting both would double the outflow. Join on `txHash`. *** ### deficit > **deficit**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:255 The GROSS realized hole a stage reported, before coverage (raw collateral) — `BadDebtAbsorbed` (the full negative balance) and `ResidualBackedByOpenPnl` (a hole the account's own open profit fully backs, so it is NOT bad debt; read `equity` alongside it, and note it becomes bad debt if the position reverses). **A level, and overlapping per-stage views of one hole — never SUM, and never add to `badDebt`.** When `BadDebtAbsorbed` and `ResidualBadDebt` both fire in one call the balance moved only by what the fund paid, so `badDebt == deficit - insuranceCovered` for that call: a useful cross-row audit check, and the direct proof that summing the gross figure with the residual double-counts. *** ### coverageDeclined > **coverageDeclined**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:266 Attributable coverage the stage-5 equity cap did NOT pay — `CoverageDeclined` only (raw collateral). A **flow** and summable as "total coverage deferred", but NOT a loss: the fund underwrites insolvency and the account was not insolvent by that much at that moment. If the backing later evaporates the hole returns as a pre-existing negative balance, which is unattributable by definition, so it is written off rather than re-declined (accepted policy, OQ-13). *** ### collateralAmount > **collateralAmount**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:272 Collateral that MOVED rather than was lost — `PositionTransferred` (collateral following the position) and `CloseOutMarginSettled`. Kept separate from `badDebt` so neither aggregate contaminates the other. *** ### equity > **equity**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:274 Account equity where the event reports it (`ResidualBackedByOpenPnl`; signed). *** ### positionsProcessed > **positionsProcessed**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:276 Positions processed (`AccountLiquidated` only). *** ### stageReached > **stageReached**: `number` \| `null` Defined in: packages/sdk/src/perp/history.ts:309 The deepest waterfall stage that ACTED (`AccountLiquidated` only). The protocol enum is 0-indexed and has six members. The published waterfall numbers its stages 1 to 6. The two do not line up, so map them with this table: 0 OrderCancellation before stage 3 — cancelling the account's resting orders alone restored health 1 CLOBPartial stage 3 2 BidderTakeover stage 4 3 InsuranceFund stage 5 4 ADL stage 6 5 Deferred not a stage — stage 3 hit its per-block rate limit, and stages 4 to 6 were not consulted. Ships dormant, so it does not appear yet Published stages 1 (Healthy) and 2 (Margin Call) are account states, not actions. The engine cannot reach them, so no value maps to them. Two rules the number does not state on its own: It names the deepest stage that ACTED, not the deepest stage consulted. A stage that ran and moved nothing does not promote it. So `BidderTakeover` (2) beside a `BadDebtAbsorbed` row is consistent, and means the fund was asked and paid nothing. Check `insuranceCovered` on that row to confirm. `CLOBPartial` (1) is a fall-through marker. It means stages 4 to 6 were consulted and none of them acted. It does NOT prove stage 3 filled anything. Against an empty book you get `CLOBPartial` with a `positionsProcessed` of 0, which means the account's orders were cancelled and no position was closed. Always read `positionsProcessed` with this field. *** ### marginStatusBefore > **marginStatusBefore**: `number` \| `null` Defined in: packages/sdk/src/perp/history.ts:311 Margin status before / after (`AccountLiquidated` only). *** ### marginStatusAfter > **marginStatusAfter**: `number` \| `null` Defined in: packages/sdk/src/perp/history.ts:312 *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/history.ts:314 Timestamp (unix seconds) of the row. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/history.ts:315 *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/history.ts:317 Tx hash the row landed in. Stages of one liquidation share it. --- # /docs/typescript/api/index/type-aliases/LiquidationKind [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiquidationKind # Type Alias: LiquidationKind > **LiquidationKind** = *typeof* [`LIQUIDATION_KIND`](../variables/LIQUIDATION_KIND.md)\[`number`\] Defined in: packages/sdk/src/perp/history.ts:119 One stage of the liquidation waterfall. --- # /docs/typescript/api/index/type-aliases/LiveBinaryMarketsFilter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiveBinaryMarketsFilter # Type Alias: LiveBinaryMarketsFilter > **LiveBinaryMarketsFilter** = [`BinaryMarketFilter`](BinaryMarketFilter.md) & `object` Defined in: packages/sdk/src/markets.ts:1283 Filters for `listLiveBinaryMarkets`. Every field is optional; an omitted field does NOT constrain the query. Applied server-side (Hasura `where`), so `venueId` / `intervalSec` hit their indexes. ## Type Declaration ### limit? > `optional` **limit?**: `number` Page size (default 50). Live is unbounded at scale (thousands of venues × cadences), so it is ALWAYS paginated — never fetch the whole live set. ### offset? > `optional` **offset?**: `number` Row offset for cursoring the live board (default 0). ### nowSec? > `optional` **nowSec?**: `number` Override "now" (unix seconds); defaults to `Date.now()`. Mostly for tests. --- # /docs/typescript/api/index/type-aliases/LiveMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LiveMarket # Type Alias: LiveMarket > **LiveMarket** = [`Market`](Market.md) Defined in: packages/sdk/src/store.ts:139 The live market shape IS the read-surface market union — spot and binary rows materialize into the exact shape `client.listMarkets` serves. --- # /docs/typescript/api/index/type-aliases/MarginEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarginEvent # Type Alias: MarginEvent > **MarginEvent** = `object` Defined in: packages/sdk/src/perp/history.ts:68 A margin-account movement (mirror of the indexer `MarginEvent` entity). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:70 Event id (`${txHash}_${logIndex}`). *** ### account > **account**: `string` Defined in: packages/sdk/src/perp/history.ts:72 Account (lowercased). *** ### kind > **kind**: `string` Defined in: packages/sdk/src/perp/history.ts:74 Deposit | Withdraw | Locked | Unlocked | Credited. *** ### pool > **pool**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:80 Perp pool the (un)lock targets (lowercased); null on Deposit/Withdraw/Credited, which are account-scoped. Was omitted from the query selection despite existing on the entity, so it read as always-null. *** ### amount > **amount**: `string` Defined in: packages/sdk/src/perp/history.ts:82 Collateral moved (raw units). *** ### granter > **granter**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:84 Who granted the credit (`Credited` only) — the voucher/credit rail. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/history.ts:86 Timestamp (unix seconds) of the movement. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/history.ts:88 Tx hash the movement landed in. --- # /docs/typescript/api/index/type-aliases/MarginStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarginStatus # Type Alias: MarginStatus > **MarginStatus** = `"Healthy"` \| `"MarginCall"` \| `"PartialLiquidation"` \| `"CloseOut"` Defined in: packages/sdk/src/perp/margin.ts:28 Cross-margin health status (mirror of the on-chain `MarginStatus` enum): `"Healthy"` (equity ≥ IM) · `"MarginCall"` (IM > equity ≥ MM) · `"PartialLiquidation"` (MM > equity ≥ CM) · `"CloseOut"` (equity < CM). --- # /docs/typescript/api/index/type-aliases/MarkSeries [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarkSeries # Type Alias: MarkSeries > **MarkSeries** = `ReadonlyArray`\ Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:109 A market's mark-price series: [timestampMs, price][], oldest first. --- # /docs/typescript/api/index/type-aliases/Market [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Market # Type Alias: Market > **Market** = [`SpotMarket`](SpotMarket.md) \| [`PerpMarket`](PerpMarket.md) \| [`BinaryMarket`](BinaryMarket.md) Defined in: packages/sdk/src/markets.ts:420 A market of any type, discriminated by `marketType`. --- # /docs/typescript/api/index/type-aliases/MarketActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketActivity # Type Alias: MarketActivity > **MarketActivity** = [`MarketTradeActivity`](MarketTradeActivity.md) \| [`MarketSupplyActivity`](MarketSupplyActivity.md) \| [`MarketResolutionActivity`](MarketResolutionActivity.md) \| [`MarketStatusActivity`](MarketStatusActivity.md) Defined in: packages/sdk/src/activity.ts:184 One row of a market's activity feed. Narrow on `kind`. ```ts for (const row of await client.getMarketActivity(marketId)) { if (row.kind === "TRADE") console.log(row.fillPrice, row.quantity); else if (row.kind === "RESOLUTION") console.log(row.outcome); } ``` --- # /docs/typescript/api/index/type-aliases/MarketActivityBase [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketActivityBase # Type Alias: MarketActivityBase > **MarketActivityBase** = `object` Defined in: packages/sdk/src/activity.ts:58 The fields every [MarketActivity](MarketActivity.md) row carries, whatever its kind. Sort and page on `timestamp`. Group by `txHash` to recover the rows that one transaction produced — a taker order that also minted a set writes a `TRADE` and a `MINT_SET` under the same hash. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/activity.ts:66 Feed-unique row id, `${kind}:${entityId}`. Prefixed because the source entities number their ids independently: a `Fill` and a `MarketStatusUpdate` in the same block and log position share an entity id. Stable across reads, so it is safe as a list key. *** ### kind > **kind**: [`MarketActivityKind`](MarketActivityKind.md) Defined in: packages/sdk/src/activity.ts:68 Kind discriminator — narrow on this. *** ### market > **market**: `string` Defined in: packages/sdk/src/activity.ts:70 The market's bytes32 marketId, lowercased. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/activity.ts:72 Timestamp (unix seconds) of the block the row landed in. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/activity.ts:74 Block the row landed in (decimal string). *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/activity.ts:76 Transaction the row landed in. --- # /docs/typescript/api/index/type-aliases/MarketActivityKind [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketActivityKind # Type Alias: MarketActivityKind > **MarketActivityKind** = `"TRADE"` \| `"MINT_SET"` \| `"MERGE_SET"` \| `"REDEEM"` \| `"RESOLUTION"` \| `"STATUS"` Defined in: packages/sdk/src/activity.ts:37 What a [MarketActivity](MarketActivity.md) row records. `TRADE` occurs on every market kind. The other five are binary-only, because complete sets, oracle resolution and the market lifecycle exist only there — a spot or perp market yields `TRADE` rows and nothing else. --- # /docs/typescript/api/index/type-aliases/MarketActivityOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketActivityOptions # Type Alias: MarketActivityOptions > **MarketActivityOptions** = `object` Defined in: packages/sdk/src/activity.ts:191 Options for [SomniaMarketsClient.getMarketActivity](../interfaces/SomniaMarketsClient.md#getmarketactivity). All optional. ## Properties ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/activity.ts:199 Max rows to return (default 50). Each source stream is asked for this many rows, and the merge keeps the newest `limit` of the union. So the result is the market's newest `limit` events, whichever kinds they are. *** ### kinds? > `optional` **kinds?**: readonly [`MarketActivityKind`](MarketActivityKind.md)[] Defined in: packages/sdk/src/activity.ts:206 Which kinds to read (default: every kind). A kind left out is excluded at the indexer, not dropped afterwards. An empty array therefore reads nothing and returns `[]`. *** ### since? > `optional` **since?**: `number` Defined in: packages/sdk/src/activity.ts:208 Only rows at/after this unix-seconds timestamp. *** ### until? > `optional` **until?**: `number` Defined in: packages/sdk/src/activity.ts:231 Only rows at/before this unix-seconds timestamp. This is the paging cursor. To read the page before the one you hold, pass the `timestamp` of its last row. There is no `offset`, because a row offset cannot page a merged feed: each stream would skip its own `offset` rows, so the second page would omit whatever the first page did not have room for. KNOWN LIMIT — the cursor has one-second resolution, and the bound is inclusive, so the boundary second is re-read on the next page: expect a few duplicate ids across a page edge and de-duplicate by `id` if that matters. A second holding `limit` or more rows cannot be paged past at all, because the next request returns that same second again. Tightening this needs a composite (timestamp, blockNumber, logIndex) cursor. The entity schema now carries `logIndex` on all four streams — this release adds it to the three that lacked it — so the cursor is expressible as soon as a REINDEXED deployment serves the column. It is not adopted here on purpose: ordering on a column the live Hasura does not serve is a validation error that fails the whole read, not a null, so the SDK would break against every indexer that has not caught up yet. *** ### pool? > `optional` **pool?**: `string` Defined in: packages/sdk/src/activity.ts:242 The market's pool address, when the caller already knows it. An optimization, and safe to omit. Trades are selected by market id either way; supplying the pool adds the predicate that lets the indexer read them through the `(pool, timestamp)` index instead of sorting the market's fills. It cannot widen the result — on binary a recycled pool's earlier markets are still excluded by the market-id predicate, and on spot and perp the pool address IS the market id. --- # /docs/typescript/api/index/type-aliases/MarketCreatorFilter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketCreatorFilter # Type Alias: MarketCreatorFilter > **MarketCreatorFilter** = `object` Defined in: packages/sdk/src/marketCreatorAdmin.ts:819 Server-side filter for the MarketCreator directory. Every field optional. ## Properties ### owner? > `optional` **owner?**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:821 Restrict to creators owned by this address (case-insensitive). *** ### operatorId? > `optional` **operatorId?**: `number` Defined in: packages/sdk/src/marketCreatorAdmin.ts:823 Restrict to one operator id. *** ### venueId? > `optional` **venueId?**: `string` Defined in: packages/sdk/src/marketCreatorAdmin.ts:825 Restrict to one bytes32 venue id (case-insensitive). --- # /docs/typescript/api/index/type-aliases/MarketFees [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketFees # Type Alias: MarketFees > **MarketFees** = `object` Defined in: packages/sdk/src/markets.ts:1140 The origin attribution + fee config frozen into a market at creation, mirrored from `BinaryMarketsModule.MarketCreated` / `MarketFeeConfig` into the indexer's `MarketVenue` entity. Rates are standard basis points (1 = 0.01%, 100 = 1%, 10_000 = 100%). Fee fields are null for markets indexed before the fee plumbing existed. ## Properties ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/markets.ts:1142 Origin operator id the market was created under. *** ### venueId > **venueId**: `string` Defined in: packages/sdk/src/markets.ts:1144 Origin venue id within the operator (bytes32 hex). *** ### feeRecipient > **feeRecipient**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:1146 Fee recipient frozen at creation (lowercased); null on pre-plumbing markets. *** ### makerFeeBps > **makerFeeBps**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:1148 Maker fee rate (bps, decimal string); null on pre-plumbing markets. *** ### takerFeeBps > **takerFeeBps**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:1150 Taker fee rate (bps, decimal string); null on pre-plumbing markets. *** ### maxBuilderFeeBps > **maxBuilderFeeBps**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:1152 Cap on the per-order builder fee (bps, decimal string); null pre-plumbing. *** ### routingFeeBps > **routingFeeBps**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:1154 Routing fee rate (bps, decimal string); null on pre-plumbing markets. *** ### settlementFeeBps > **settlementFeeBps**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:1156 Settlement fee skimmed from the winning payout at redeem (bps). *** ### settlementFeesCollected > **settlementFeesCollected**: `string` \| `null` Defined in: packages/sdk/src/markets.ts:1158 Realized settlement fee collected on winning redemptions so far (raw collateral). --- # /docs/typescript/api/index/type-aliases/MarketRef [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketRef # Type Alias: MarketRef > **MarketRef** = `object` Defined in: packages/sdk/src/fills.ts:362 The market a fill/order belongs to, as detail reads embed it — enough to label and scale the row (symbols + decimals) and route to the market's page, without dragging in the full per-kind [Market](Market.md) union. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/fills.ts:364 Market entity id (pool address for SPOT/PERP; marketId bytes32 for BINARY). *** ### marketType > **marketType**: `"SPOT"` \| `"PERP"` \| `"BINARY"` Defined in: packages/sdk/src/fills.ts:365 *** ### poolAddress > **poolAddress**: `string` Defined in: packages/sdk/src/fills.ts:367 Lowercased pool address serving the market. *** ### marketAddress > **marketAddress**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:369 BinaryMarket contract address; null on SPOT/PERP. *** ### baseSymbol > **baseSymbol**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:370 *** ### quoteSymbol > **quoteSymbol**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:371 *** ### baseDecimals > **baseDecimals**: `number` Defined in: packages/sdk/src/fills.ts:372 *** ### quoteDecimals > **quoteDecimals**: `number` Defined in: packages/sdk/src/fills.ts:373 *** ### asset > **asset**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:375 Underlying asset label (BINARY); null on SPOT/PERP. *** ### question > **question**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:377 The market's question text (BINARY); null on SPOT/PERP. --- # /docs/typescript/api/index/type-aliases/MarketReferenceLink [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketReferenceLink # Type Alias: MarketReferenceLink > **MarketReferenceLink** = `object` Defined in: packages/sdk/src/binary/settlement.ts:431 The oracle reference a market binds to (mirror of the indexer `MarketReferenceLink` entity). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/binary/settlement.ts:433 Entity id (== the lowercased marketId). *** ### market > **market**: `string` Defined in: packages/sdk/src/binary/settlement.ts:435 Market id (lowercased bytes32). *** ### oracleQuestionId > **oracleQuestionId**: `string` Defined in: packages/sdk/src/binary/settlement.ts:437 Reference question id the market resolves against (decimal string). *** ### pending > **pending**: `boolean` Defined in: packages/sdk/src/binary/settlement.ts:442 True once the market has its own answer but the reference question is not yet final (resolution still pending on the reference). --- # /docs/typescript/api/index/type-aliases/MarketResolutionActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketResolutionActivity # Type Alias: MarketResolutionActivity > **MarketResolutionActivity** = [`MarketActivityBase`](MarketActivityBase.md) & `object` Defined in: packages/sdk/src/activity.ts:148 The oracle acting on the market. BINARY only. `outcome` is the indexer's own word for what happened, so a caller can show a market that failed to resolve as distinct from one that resolved. ## Type Declaration ### kind > **kind**: `"RESOLUTION"` ### outcome > **outcome**: `string` `Resolved`, `Skipped` or `Failed`. ### outcomeIdx > **outcomeIdx**: `number` \| `null` The winning outcome index (0 = YES, 1 = NO), derived from a one-hot payout vector. Null on a void, a `Skipped` and a `Failed`. ### voided > **voided**: `boolean` \| `null` True when the market resolved void. Null when the event carried no verdict. --- # /docs/typescript/api/index/type-aliases/MarketResolutionEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketResolutionEvent # Type Alias: MarketResolutionEvent > **MarketResolutionEvent** = `object` Defined in: packages/sdk/src/binary/settlement.ts:392 One market-resolution lifecycle event (mirror of the indexer `MarketResolutionEvent` entity). Oracle v2: resolution is delivered as a payout VECTOR (`MarketResolved(marketId, qid, payoutDenominator, payoutNumerators, voided)`); `winningOutcome` stays as the binary-compat derivation of a one-hot vector. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/binary/settlement.ts:394 Event id (`${blockNumber}_${logIndex}`). *** ### market > **market**: `string` Defined in: packages/sdk/src/binary/settlement.ts:396 Market id (lowercased bytes32). *** ### kind > **kind**: `string` Defined in: packages/sdk/src/binary/settlement.ts:398 Resolution kind, e.g. "Resolved" | "Skipped" | "Failed" (indexer-defined). *** ### winningOutcome > **winningOutcome**: `number` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:403 Winning outcome (0 = YES, 1 = NO), derived from a one-hot payout vector; null on void / skip / non-one-hot vectors. *** ### payoutNumerators? > `optional` **payoutNumerators?**: `string`[] \| `null` Defined in: packages/sdk/src/binary/settlement.ts:409 Per-outcome payout numerators delivered with the event (decimal strings; raw Σ == payoutDenominator). Null on events indexed before the vector wire / kinds that carry none. *** ### payoutDenominator? > `optional` **payoutDenominator?**: `string` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:414 Vector denominator (`PAYOUT_VECTOR_DENOMINATOR` = 10_000_000; decimal string). Null when no vector was carried. *** ### voided? > `optional` **voided?**: `boolean` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:416 True when the market was voided (uniform vector) rather than resolved. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/binary/settlement.ts:418 Block the event landed in (decimal string). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/binary/settlement.ts:420 Timestamp (unix seconds) of the event. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/binary/settlement.ts:422 Tx hash the event landed in. --- # /docs/typescript/api/index/type-aliases/MarketStatusActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketStatusActivity # Type Alias: MarketStatusActivity > **MarketStatusActivity** = [`MarketActivityBase`](MarketActivityBase.md) & `object` Defined in: packages/sdk/src/activity.ts:166 A lifecycle transition, such as Trading to Locked. BINARY only. ## Type Declaration ### kind > **kind**: `"STATUS"` ### oldStatus > **oldStatus**: [`BinaryMarketStatus`](BinaryMarketStatus.md) Status before the transition. ### newStatus > **newStatus**: [`BinaryMarketStatus`](BinaryMarketStatus.md) Status after the transition. --- # /docs/typescript/api/index/type-aliases/MarketStatusUpdate [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketStatusUpdate # Type Alias: MarketStatusUpdate > **MarketStatusUpdate** = `object` Defined in: packages/sdk/src/markets.ts:1212 One entry in a market's lifecycle audit trail (from the indexer's MarketStatusUpdate entity). ## Properties ### oldStatus > **oldStatus**: [`BinaryMarketStatus`](BinaryMarketStatus.md) Defined in: packages/sdk/src/markets.ts:1214 Status before the transition. *** ### newStatus > **newStatus**: [`BinaryMarketStatus`](BinaryMarketStatus.md) Defined in: packages/sdk/src/markets.ts:1216 Status after the transition. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/markets.ts:1218 Block the transition landed in (decimal string). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/markets.ts:1220 Timestamp (unix seconds) of the transition. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/markets.ts:1222 Tx hash the transition landed in. --- # /docs/typescript/api/index/type-aliases/MarketSupplyActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketSupplyActivity # Type Alias: MarketSupplyActivity > **MarketSupplyActivity** = [`MarketActivityBase`](MarketActivityBase.md) & `object` Defined in: packages/sdk/src/activity.ts:123 A complete-set mint, a merge, or a redemption — collateral crossing into or out of outcome tokens. BINARY only. Amounts are raw units. ## Type Declaration ### kind > **kind**: `"MINT_SET"` \| `"MERGE_SET"` \| `"REDEEM"` ### account > **account**: `string` Acting wallet, lowercased. ### amount > **amount**: `string` `REDEEM`: outcome tokens burned. `MINT_SET` / `MERGE_SET`: the size of the complete set, meaning the amount of EACH outcome. Raw outcome-token units. ### payout > **payout**: `string` \| `null` `REDEEM` only: collateral paid out, raw units. Null on a mint or a merge. ### routedVia > **routedVia**: `string` \| `null` The periphery entry the flow used — `NativeMint`, `Permit2Mint` or `NativeRedeem`. Null on a direct call to the module. --- # /docs/typescript/api/index/type-aliases/MarketTradeActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketTradeActivity # Type Alias: MarketTradeActivity > **MarketTradeActivity** = [`MarketActivityBase`](MarketActivityBase.md) & `object` Defined in: packages/sdk/src/activity.ts:85 A trade: one fill of one resting order by one incoming order. Amounts are raw units. `fillPrice` is quote units per whole base — on binary, the YES-probability scale. ## Type Declaration ### kind > **kind**: `"TRADE"` ### pool > **pool**: `string` Pool the fill executed on, lowercased. ### fillPrice > **fillPrice**: `string` Execution price, raw quote units per whole base. ### quantity > **quantity**: `string` Base/outcome quantity filled, raw units. ### quoteQuantity > **quoteQuantity**: `string` Quote/collateral value of the fill, raw units. ### maker > **maker**: `string` \| `null` Maker (resting) wallet, lowercased; null when the indexer has not joined it. ### makerSide > **makerSide**: [`BinarySide`](BinarySide.md) \| `null` BINARY only — the maker's YES/NO side; null on spot and perp. ### taker > **taker**: `string` \| `null` Taker (aggressing) wallet, lowercased; null when the indexer has not joined it yet. Read from the taker's ORDER when the fill's own denormalized copy is absent. `Fill.taker` is populated only on spot, by a bridge that runs after the fill, so a binary trade names its taker through the order or not at all. ### takerSide > **takerSide**: [`BinarySide`](BinarySide.md) \| `null` BINARY only — the taker's YES/NO side; null on spot and perp. ### takerIsBid > **takerIsBid**: `boolean` \| `null` True when the taker bought the base (or YES) and the maker held the ask — the aggressor's direction. Null until the taker side is known. --- # /docs/typescript/api/index/type-aliases/MarketType [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MarketType # Type Alias: MarketType > **MarketType** = `"SPOT"` \| `"PERP"` \| `"BINARY"` Defined in: packages/sdk/src/markets.ts:34 The discriminator the whole market surface keys on — mirror of the indexer's `MarketType` enum. See the [Market](Market.md) union. --- # /docs/typescript/api/index/type-aliases/ObservedReadMethods [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ObservedReadMethods # Type Alias: ObservedReadMethods > **ObservedReadMethods** = `Pick`\<[`SomniaMarketsClient`](../interfaces/SomniaMarketsClient.md), [`ObservedReadOperation`](ObservedReadOperation.md)\> Defined in: packages/sdk/src/observedReads.ts:113 Domain method contracts supported by observed read requests. These retain the owner client's argument and data types. --- # /docs/typescript/api/index/type-aliases/ObservedReadOperation [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ObservedReadOperation # Type Alias: ObservedReadOperation > **ObservedReadOperation** = `"quoteBinaryStake"` \| `"quoteBinarySell"` \| `"getMarketStats24h"` \| `"getBinaryPositionPnL"` \| `"getOpenPositionsWithPnL"` \| `"getClaimable"` \| `"listMarkets"` \| `"listRegistryMarkets"` \| `"listRegistryMarketsChecked"` \| `"countMarkets"` \| `"countMarketsBounded"` \| `"getMarket"` \| `"listBinaryMarkets"` \| `"listLiveBinaryMarkets"` \| `"listBinaryVenueIds"` \| `"listBinaryAssets"` \| `"countBinaryMarkets"` \| `"countBinaryMarketsBounded"` \| `"listPastBinaryMarkets"` \| `"getBinaryMarket"` \| `"getBinaryMarketByAddress"` \| `"getMarketFees"` \| `"listSpotMarkets"` \| `"getSpotMarket"` \| `"getMarketStatusHistory"` \| `"listPerpMarkets"` \| `"getPerpMarket"` \| `"getCandles"` \| `"getMarketActivity"` \| `"getTransactionActivity"` \| `"getBlockActivity"` \| `"getLatestActiveBlock"` \| `"getAdjacentActiveBlocks"` \| `"getFills"` \| `"getTradeContext"` \| `"getUserFills"` \| `"getUserFillsPage"` \| `"getFill"` \| `"getOrderFills"` \| `"getOrder"` \| `"getOpenOrders"` \| `"getOrders"` \| `"listSweepableOrders"` \| `"getOutcomeBalances"` \| `"getPortfolio"` \| `"getSpotPortfolio"` \| `"getSpotStopOrders"` \| `"getPerpPortfolio"` \| `"listPerpStopOrders"` \| `"listPerpOrderHistory"` \| `"getMarketByPool"` \| `"listMarketsByPool"` \| `"countOrders"` \| `"countUserFills"` \| `"getRouterActions"` \| `"getMarketResolution"` \| `"getOpeningPrices"` \| `"getResolutionPrices"` \| `"getBookTops"` \| `"listProtocolFees"` \| `"listBuilderFees"` \| `"listSettlementFees"` \| `"listBuilderApprovals"` \| `"getVaultPayoutFallbacks"` \| `"getFundingPayments"` \| `"getMarginEvents"` \| `"listLiquidations"` \| `"getLiquidations"` \| `"getFundingRateHistory"` \| `"listFundingRateHistory"` \| `"listFundingRateCandles"` \| `"getOpenInterestHistory"` \| `"listPerpFees"` \| `"listPerpOrderRejections"` \| `"listPerpPositions"` \| `"listPerpInsuranceFundEvents"` \| `"listPerpWalletLinkEvents"` \| `"listPerpMarginPulls"` \| `"listPerpMainFundingEvents"` \| `"getPoolBindings"` \| `"getPool"` \| `"listOperators"` \| `"countOperators"` \| `"getOperator"` \| `"listVenues"` \| `"countVenues"` \| `"getVenue"` \| `"listMarketCreators"` \| `"getMarketCreator"` \| `"listOracleAdapters"` \| `"getOracleAdapter"` \| `"listSeries"` \| `"getSeries"` \| `"getOracleQuestion"` \| `"listOracleQuestions"` \| `"getOperatorHubAccount"` \| `"listOperatorHubAccounts"` \| `"listOracleBinds"` \| `"listOracleCallbacks"` Defined in: packages/sdk/src/observedReads.ts:11 Supported main-indexer operations. Price/oracle-service reads have no main-indexer watermark. --- # /docs/typescript/api/index/type-aliases/ObservedReadRequest [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ObservedReadRequest # Type Alias: ObservedReadRequest\ > **ObservedReadRequest**\<`K`\> = `{ [P in K]: { operation: P; args: Parameters } }`\[`K`\] Defined in: packages/sdk/src/observedReads.ts:115 Arguments retain each existing domain method's parameter contract. ## Type Parameters ### K `K` *extends* [`ObservedReadOperation`](ObservedReadOperation.md) = [`ObservedReadOperation`](ObservedReadOperation.md) --- # /docs/typescript/api/index/type-aliases/ObservedReadsBatchError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ObservedReadsBatchError # Type Alias: ObservedReadsBatchError > **ObservedReadsBatchError** = [`ObservedReadsReadError`](ObservedReadsReadError.md) Defined in: packages/sdk/src/observedReads.ts:147 A batch rejects on the first failed member; no partial success is fabricated. --- # /docs/typescript/api/index/type-aliases/ObservedReadsReadError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ObservedReadsReadError # Type Alias: ObservedReadsReadError > **ObservedReadsReadError** = [`IndexerError`](../classes/IndexerError.md) \| [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) \| [`InvariantError`](../classes/InvariantError.md) Defined in: packages/sdk/src/observedReads.ts:139 Failures of observed reads, including mixed-tier domain methods and their validation. --- # /docs/typescript/api/index/type-aliases/OpenInterestSnapshot [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OpenInterestSnapshot # Type Alias: OpenInterestSnapshot > **OpenInterestSnapshot** = `object` Defined in: packages/sdk/src/perp/history.ts:547 An open-interest snapshot (mirror of the indexer `OpenInterestSnapshot` entity). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:549 Snapshot id (`${pool}_${block}_${logIndex}`). *** ### pool > **pool**: `string` Defined in: packages/sdk/src/perp/history.ts:551 Perp pool (lowercased). *** ### openInterest > **openInterest**: `string` Defined in: packages/sdk/src/perp/history.ts:556 TOTAL open interest (raw base units) — one counter, not a long/short pair; see the `openInterest` field on [PerpMarket](PerpMarket.md) for why. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/history.ts:558 Timestamp (unix seconds) of the snapshot. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/history.ts:560 Block the snapshot came from. --- # /docs/typescript/api/index/type-aliases/OpenOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OpenOrder # Type Alias: OpenOrder > **OpenOrder** = `object` Defined in: packages/sdk/src/orders.ts:135 A currently-open resting order (subset of the indexer `Order` entity), as returned by [SomniaMarketsClient.getOpenOrders](../interfaces/SomniaMarketsClient.md#getopenorders). [OrderRow](OrderRow.md) extends it with the lifecycle/fill-progress fields for order history. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/orders.ts:137 Order id (`${pool}_${orderId}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/orders.ts:139 uint128 OrderId as a decimal string (pass to trader.cancelOrder). *** ### market > **market**: `string` Defined in: packages/sdk/src/orders.ts:150 The market's bytes32 marketId — the STABLE identity of the market this order belonged to, and the key to label a historical row by. Use this, never `pool` alone: a binary pool is recycled across successive markets, so the same `pool` names a different market depending on when the order was placed. On SPOT/PERP the pool address IS the market id, so the two agree there. Pass it straight to [client.getMarket](../interfaces/SomniaMarketsClient.md#getmarket) for the full row. *** ### marketInfo > **marketInfo**: [`OrderMarket`](OrderMarket.md) \| `null` Defined in: packages/sdk/src/orders.ts:155 The market's labelling context, so a row can be NAMED without a second query. Null only if the indexer has no market row for the order. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/orders.ts:160 Lower-cased pool address the order rests on. A TIME-VARYING binding — see `market` for the identity that does not move. *** ### side > **side**: [`BinarySide`](BinarySide.md) \| `null` Defined in: packages/sdk/src/orders.ts:165 BINARY YES/NO classification; NULL on spot orders (the indexer only sets it for binary). For a buy/sell distinction that works on BOTH kinds use `isBid`. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/orders.ts:170 True = bid (buy), false = ask (sell). The canonical buy/sell flag — set for spot AND binary, unlike `side` which is null on spot. Colour/label off this. *** ### price > **price**: `string` Defined in: packages/sdk/src/orders.ts:172 Limit price, raw quote units per whole base (binary: YES-probability scale). *** ### quantityRemaining > **quantityRemaining**: `string` Defined in: packages/sdk/src/orders.ts:174 Unfilled remainder, raw base/outcome units. --- # /docs/typescript/api/index/type-aliases/OpenPositionPnL [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OpenPositionPnL # Type Alias: OpenPositionPnL > **OpenPositionPnL** = [`BinaryPositionPnL`](../interfaces/BinaryPositionPnL.md) & `object` Defined in: packages/sdk/src/binary/portfolio.ts:139 An open binary position joined with its reliable avg-cost PnL — the batched, positions-list companion to `getBinaryPositionPnL` (which is per market). `costBasis` / `avgCost` / `markValue` / `unrealizedPnl` / `realizedPnl` are RAW collateral units; format with `market.quoteDecimals`. Those fields are BLENDED across both outcomes; the inherited `outcomes` pair carries each book on its own. ## Type Declaration ### market > **market**: [`PortfolioMarket`](PortfolioMarket.md) The market the position is in (id / addresses / quoteDecimals / status / …). --- # /docs/typescript/api/index/type-aliases/OperatorFilter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OperatorFilter # Type Alias: OperatorFilter > **OperatorFilter** = `object` Defined in: packages/sdk/src/operatorAdmin.ts:522 Server-side filter for the operator directory. Every field optional (an omitted field does not constrain). Applied as a Hasura `where`. ## Properties ### owner? > `optional` **owner?**: `string` Defined in: packages/sdk/src/operatorAdmin.ts:524 Restrict to operators owned by this address (case-insensitive). *** ### enabled? > `optional` **enabled?**: `boolean` Defined in: packages/sdk/src/operatorAdmin.ts:526 Restrict to enabled (true) / disabled (false) operators. --- # /docs/typescript/api/index/type-aliases/OperatorHubAccountRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OperatorHubAccountRecord # Type Alias: OperatorHubAccountRecord > **OperatorHubAccountRecord** = `object` Defined in: packages/sdk/src/oracleHub.ts:924 An operator's hub account (mirror of the indexer `OperatorHubAccount` entity; id = operatorId decimal string) — the earmark-at-creation surface. Running totals derived from the hub events: `earmarked` (LOCKED, never withdrawable; == `outstanding × resolveReserve`), `credit` (WITHDRAWABLE surplus), and `outstanding` (bound-but-unresolved market count). Live/authoritative figures are the chain reads `earmarkedOf`/`creditOf`/`outstandingOf`. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/oracleHub.ts:926 operatorId (decimal string == entity id). *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/oracleHub.ts:928 The operator the account belongs to (numeric form of `id`). *** ### earmarked > **earmarked**: `string` Defined in: packages/sdk/src/oracleHub.ts:930 Native LOCKED for outstanding markets (wei); Σ ReserveEarmarked − Σ released. *** ### credit > **credit**: `string` Defined in: packages/sdk/src/oracleHub.ts:932 Withdrawable surplus (wei): Σ SurplusCredited − Σ CreditWithdrawn. *** ### outstanding > **outstanding**: `string` Defined in: packages/sdk/src/oracleHub.ts:934 Bound-but-unresolved market count (binds − resolutions). *** ### createdAtBlock > **createdAtBlock**: `string` Defined in: packages/sdk/src/oracleHub.ts:936 Block the account first appeared in (decimal string). *** ### createdAtTimestamp > **createdAtTimestamp**: `string` Defined in: packages/sdk/src/oracleHub.ts:938 Timestamp (unix seconds) the account first appeared. *** ### updatedAtBlock > **updatedAtBlock**: `string` Defined in: packages/sdk/src/oracleHub.ts:940 Block of the last update to the running totals (decimal string). *** ### updatedAtTimestamp > **updatedAtTimestamp**: `string` Defined in: packages/sdk/src/oracleHub.ts:942 Timestamp (unix seconds) of the last update to the running totals. --- # /docs/typescript/api/index/type-aliases/OracleAnswer [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OracleAnswer # Type Alias: OracleAnswer > **OracleAnswer** = `object` Defined in: packages/sdk/src/binary/settlement.ts:451 The numeric answer the oracle posted for a question (mirror of the indexer `OracleAnswer` entity). ## Properties ### oracleQuestionId > **oracleQuestionId**: `string` Defined in: packages/sdk/src/binary/settlement.ts:453 oracleQuestionId (decimal string == entity id). *** ### numericValue > **numericValue**: `string` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:455 Numeric answer the oracle posted (raw; interpretation is question-specific). *** ### outcomeLabel > **outcomeLabel**: `string` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:457 Human outcome label the oracle posted, if any. *** ### voidReason > **voidReason**: `number` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:459 Void reason code (non-null only on a voided answer). *** ### resolvedAt > **resolvedAt**: `string` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:461 Timestamp (unix seconds) the answer was posted; null until posted. *** ### txHash > **txHash**: `string` \| `null` Defined in: packages/sdk/src/binary/settlement.ts:463 Tx hash the answer was posted in; null until posted. --- # /docs/typescript/api/index/type-aliases/OracleBindRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OracleBindRecord # Type Alias: OracleBindRecord > **OracleBindRecord** = `object` Defined in: packages/sdk/src/oracleHub.ts:954 One market's bind on a question (mirror of the indexer `OracleBind` entity, Oracle v2 §8e). Opens with `MarketBound` (operator attribution; the paired `ReserveEarmarked` locks the reserve), stamped at resolution with `MarketResolveCharged` (exact metered charge + subsidy; a surplus is credited via `SurplusCredited`). Per-market conservation: `charged + subsidy == cost`. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/oracleHub.ts:956 Bind id (`${oracleQuestionId}_${bindIndex}`). *** ### oracleQuestionId > **oracleQuestionId**: `string` Defined in: packages/sdk/src/oracleHub.ts:958 Question the bind belongs to (decimal string). *** ### bindIndex > **bindIndex**: `number` Defined in: packages/sdk/src/oracleHub.ts:960 1-based lifetime bind sequence on the question. *** ### operatorId > **operatorId**: `number` Defined in: packages/sdk/src/oracleHub.ts:962 Operator whose earmark funds this market's resolve. *** ### measuredGas > **measuredGas**: `string` \| `null` Defined in: packages/sdk/src/oracleHub.ts:964 gasleft()-wrapped measured gas of the resolve slice; null until resolved. *** ### overheadShare > **overheadShare**: `string` \| `null` Defined in: packages/sdk/src/oracleHub.ts:966 Pro-rata share of the callback overhead gas; null until resolved. *** ### cost > **cost**: `string` \| `null` Defined in: packages/sdk/src/oracleHub.ts:968 Exact wei the resolve cost worked out to; null until resolved. *** ### charged > **charged**: `string` \| `null` Defined in: packages/sdk/src/oracleHub.ts:973 Wei actually charged against this market's earmark; null until resolved (== min(cost, reserve)). *** ### subsidy > **subsidy**: `string` \| `null` Defined in: packages/sdk/src/oracleHub.ts:978 cost − charged: the reserve-capped shortfall the hub subsidised; null until resolved. *** ### resolvedAt > **resolvedAt**: `string` \| `null` Defined in: packages/sdk/src/oracleHub.ts:983 Timestamp the resolve cost was charged (`MarketResolveCharged`); null until resolved — the resolved flag is simply `resolvedAt != null`. *** ### boundAtBlock > **boundAtBlock**: `string` Defined in: packages/sdk/src/oracleHub.ts:985 Block the bind landed in (decimal string). *** ### boundAtTimestamp > **boundAtTimestamp**: `string` Defined in: packages/sdk/src/oracleHub.ts:987 Timestamp (unix seconds) of the bind. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/oracleHub.ts:989 Tx hash of the bind (the market-creation tx). --- # /docs/typescript/api/index/type-aliases/OracleCallbackRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OracleCallbackRecord # Type Alias: OracleCallbackRecord > **OracleCallbackRecord** = `object` Defined in: packages/sdk/src/oracleHub.ts:1003 One resolution callback's conservation record (mirror of the indexer `OracleCallback` entity ← the hub's `CallbackAccounted` event). NOT per-question (a callback drains across many qids). Invariants: `totalCost == (measuredGas + overheadGasAttributed) * gasPrice`; Σ of the callback's `OracleBindRecord.charged == totalCharged`; `totalCharged + subsidy == totalCost` (the subsidy is the hub's explicit reserve-capped shortfall). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/oracleHub.ts:1005 Callback id (`${blockNumber}_${logIndex}`). *** ### marketsResolved > **marketsResolved**: `string` Defined in: packages/sdk/src/oracleHub.ts:1007 Number of markets resolved in this callback. *** ### gasPrice > **gasPrice**: `string` Defined in: packages/sdk/src/oracleHub.ts:1009 `tx.gasprice` of the callback (wei). *** ### measuredGas > **measuredGas**: `string` Defined in: packages/sdk/src/oracleHub.ts:1011 Σ `gasleft()`-wrapped measured gas across the resolved markets. *** ### overheadGasAttributed > **overheadGasAttributed**: `string` Defined in: packages/sdk/src/oracleHub.ts:1013 The governance-calibrated `callbackBaseGas` term attributed on top. *** ### totalCost > **totalCost**: `string` Defined in: packages/sdk/src/oracleHub.ts:1015 Exact wei distributed: `(measuredGas + overhead) * gasPrice`. *** ### totalCharged > **totalCharged**: `string` Defined in: packages/sdk/src/oracleHub.ts:1017 Σ wei actually charged against market earmarks. *** ### subsidy > **subsidy**: `string` Defined in: packages/sdk/src/oracleHub.ts:1019 `totalCost − totalCharged`: the hub's explicit reserve-capped subsidy. *** ### pendingRemaining > **pendingRemaining**: `string` Defined in: packages/sdk/src/oracleHub.ts:1021 Markets still queued after this callback (0 = drain complete). *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/oracleHub.ts:1023 Block the callback landed in (decimal string). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/oracleHub.ts:1025 Timestamp (unix seconds) of the callback. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/oracleHub.ts:1027 Tx hash of the callback. --- # /docs/typescript/api/index/type-aliases/OracleQuestionRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OracleQuestionRecord # Type Alias: OracleQuestionRecord > **OracleQuestionRecord** = `object` Defined in: packages/sdk/src/oracleHub.ts:889 A hub-scheduled oracle question (mirror of the indexer `OracleQuestion` entity; id = oracleQuestionId as a decimal string). Tracks the content-addressed dedup state: the canonical key, who paid the oracle submission, and how many markets bound to it. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/oracleHub.ts:891 oracleQuestionId (decimal string == entity id). *** ### questionKey > **questionKey**: `string` \| `null` Defined in: packages/sdk/src/oracleHub.ts:896 Canonical dedup key (bytes32 hex); zero/null for non-template definitions that bypassed dedup. *** ### scheduler > **scheduler**: `string` Defined in: packages/sdk/src/oracleHub.ts:898 Caller that paid the oracle submission cost (lowercased). *** ### oracleCost > **oracleCost**: `string` Defined in: packages/sdk/src/oracleHub.ts:900 Native wei forwarded to the oracle for this submission. *** ### bindCount > **bindCount**: `number` Defined in: packages/sdk/src/oracleHub.ts:902 Lifetime bind count (from `MarketBound.bindCount`, monotonic). *** ### reuseCount > **reuseCount**: `number` Defined in: packages/sdk/src/oracleHub.ts:907 Times an identical definition deduplicated onto this question (`QuestionReused` count). *** ### createdAtBlock > **createdAtBlock**: `string` Defined in: packages/sdk/src/oracleHub.ts:909 Block the question was scheduled in (decimal string). *** ### createdAtTimestamp > **createdAtTimestamp**: `string` Defined in: packages/sdk/src/oracleHub.ts:911 Timestamp (unix seconds) the question was scheduled. --- # /docs/typescript/api/index/type-aliases/OrderDetail [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrderDetail # Type Alias: OrderDetail > **OrderDetail** = [`OrderRow`](OrderRow.md) & `object` Defined in: packages/sdk/src/orders.ts:286 [OrderRow](OrderRow.md) plus placement attribution and the market it lives on — what [SomniaMarketsClient.getOrder](../interfaces/SomniaMarketsClient.md#getorder) returns for an order detail view. ## Type Declaration ### owner > **owner**: `string` Wallet that owns the order, lowercased. ### userData > **userData**: `string` Opaque caller-supplied uint64 tag (decimal string; "0" when unset). ### placedAtBlock > **placedAtBlock**: `string` Block the order was placed in (decimal string). ### lastUpdatedAtTimestamp > **lastUpdatedAtTimestamp**: `string` Timestamp (unix seconds) of the last indexed mutation to this order. ### marketRef > **marketRef**: [`MarketRef`](MarketRef.md) The market the order's pool serves. Named `marketRef` because main's `OpenOrder.market` is the bytes32 marketId string — see the note on [Fills.FillDetail](FillDetail.md). --- # /docs/typescript/api/index/type-aliases/OrderFillRow [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrderFillRow # Type Alias: OrderFillRow > **OrderFillRow** = [`FillRow`](FillRow.md) & `object` Defined in: packages/sdk/src/fills.ts:350 A fill with its position in the chain — [FillRow](FillRow.md) plus the block and log index. What [SomniaMarketsClient.getOrderFills](../interfaces/SomniaMarketsClient.md#getorderfills) returns. ## Type Declaration ### blockNumber > **blockNumber**: `string` Block the fill landed in (decimal string). ### logIndex > **logIndex**: `number` Log index within the block (with blockNumber: the fill's id). --- # /docs/typescript/api/index/type-aliases/OrderMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrderMarket # Type Alias: OrderMarket > **OrderMarket** = `object` Defined in: packages/sdk/src/orders.ts:73 The market context carried on every order row — enough to LABEL the row (asset, question, expiry, decimals) without a second read. For the full market pass the row's `market` id to [client.getMarket](../interfaces/SomniaMarketsClient.md#getmarket). The binary-only fields are null on SPOT and PERP, which is how the indexer stores them — an order read is not scoped by market kind, so a caller sees rows of every kind mixed together. ## Properties ### marketAddress > **marketAddress**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:75 The BinaryMarket clone contract's address (lowercased); null on SPOT/PERP. *** ### asset > **asset**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:77 Underlying asset symbol (e.g. "BTC"); null on SPOT/PERP. *** ### question > **question**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:79 Display question text; null on SPOT/PERP. *** ### expiry > **expiry**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:81 Timestamp (unix seconds) trading ends; null on SPOT/PERP. *** ### tradingStart > **tradingStart**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:83 Timestamp (unix seconds) trading opened; null on SPOT/PERP. *** ### quoteDecimals > **quoteDecimals**: `number` Defined in: packages/sdk/src/orders.ts:88 Collateral decimals (per-market — e.g. 6dp TestUSDC vs 18dp USDso). Format this row's `price` and quantities with it, never a hard-coded 6. *** ### intervalSec > **intervalSec**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:90 Series cadence in seconds, as the indexer derived it; null on SPOT/PERP and on legacy rows. *** ### interval > **interval**: `string` \| `null` Defined in: packages/sdk/src/orders.ts:96 Compact cadence label ("15m" / "1h" / "4h" / "24h") — DERIVED by the SDK from [OrderMarket.intervalSec](#intervalsec), matching `PortfolioMarket.interval`. Null when unknown. --- # /docs/typescript/api/index/type-aliases/OrderRow [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrderRow # Type Alias: OrderRow > **OrderRow** = [`OpenOrder`](OpenOrder.md) & `object` Defined in: packages/sdk/src/orders.ts:237 An order row with its lifecycle status + fill progress (from [SomniaMarketsClient.getOrders](../interfaces/SomniaMarketsClient.md#getorders)). ## Type Declaration ### status > **status**: [`OrderStatus`](OrderStatus.md) Reconciled lifecycle status (Open/Filled/Cancelled/Expired/Closed). ### fullQuantity > **fullQuantity**: `string` Original order size, raw base/outcome units. ### filledQuantity > **filledQuantity**: `string` Cumulative filled quantity, raw base/outcome units. ### rested > **rested**: `boolean` Whether the order ever rested on the book (an `OrderRested` fired). ### expireTimestampNs > **expireTimestampNs**: `string` Order expiry as a uint64 nanosecond timestamp (decimal string). There is no GTC sentinel — the contract treats any future expiry as live, and this SDK writes GTC as now + 50 years (`farFutureNs`). The matcher rejects a 0/past expiry at placement, so "0" is never a live value. ### placedTxHash > **placedTxHash**: `string` Tx hash the order was placed in. ### placedAtTimestamp > **placedAtTimestamp**: `string` Timestamp (unix seconds) the order was placed. ### cancelReason > **cancelReason**: `string` \| `null` WHY the order was cancelled, when the PROTOCOL removed it rather than the owner. Null for an owner cancel and for orders that were never cancelled — so a `Cancelled` status with a null reason means the owner did it. SelfMatch same-owner match (the CancelMaker path) ExceedsPosition perps guard: the fill would push the maker past maxPositionSize NegativeEquity perps guard: the maker's equity would go negative StaleMark perps guard: the mark feed became unreadable, so an OPENING maker was pulled rather than filled against a dead reference price. A purely reducing maker is unaffected and still fills. PreFill the base pre-fill guard fired with no more specific tag PERP only today; spot pools emit the base cancel without a reason tag. ### amendedFromOrderId > **amendedFromOrderId**: `string` \| `null` Amendment linkage: the order this one REPLACED, and the one that replaced it. Lets an amend chain be followed rather than read as unrelated place/cancel pairs. Both null on an order that was never amended. ### amendedToOrderId > **amendedToOrderId**: `string` \| `null` --- # /docs/typescript/api/index/type-aliases/OrderStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrderStatus # Type Alias: OrderStatus > **OrderStatus** = `"Open"` \| `"Closed"` \| `"Filled"` \| `"Cancelled"` \| `"Expired"` Defined in: packages/sdk/src/store.ts:51 Order lifecycle — shared by spot and binary orders. Spot orders are born "Closed" and promoted to "Open" by OrderRested (mirror of the indexer). --- # /docs/typescript/api/index/type-aliases/OrdersOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OrdersOptions # Type Alias: OrdersOptions > **OrdersOptions** = `object` Defined in: packages/sdk/src/orders.ts:186 Options for [SomniaMarketsClient.getOpenOrders](../interfaces/SomniaMarketsClient.md#getopenorders) / [SomniaMarketsClient.getOrders](../interfaces/SomniaMarketsClient.md#getorders). All optional. ## Properties ### pool? > `optional` **pool?**: `string` Defined in: packages/sdk/src/orders.ts:188 Restrict to one pool. *** ### status? > `optional` **status?**: [`OrderStatus`](OrderStatus.md) Defined in: packages/sdk/src/orders.ts:190 Order status. [SomniaMarketsClient.getOrders](../interfaces/SomniaMarketsClient.md#getorders) only — [SomniaMarketsClient.getOpenOrders](../interfaces/SomniaMarketsClient.md#getopenorders) is always "Open". *** ### side? > `optional` **side?**: [`OpenOrder`](OpenOrder.md)\[`"side"`\] Defined in: packages/sdk/src/orders.ts:192 Restrict to one side. *** ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/orders.ts:194 Max rows. *** ### offset? > `optional` **offset?**: `number` Defined in: packages/sdk/src/orders.ts:196 Row offset (default 0). --- # /docs/typescript/api/index/type-aliases/OutcomeBalances [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OutcomeBalances # Type Alias: OutcomeBalances > **OutcomeBalances** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:28 A user's indexed YES/NO outcome-token balances in one binary market. Raw outcome-token units (same decimals as the market's collateral); "0" when the indexer has never seen the account touch that side. ## Properties ### yes > **yes**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:30 Raw YES balance ("0" if never held). *** ### no > **no**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:32 Raw NO balance ("0" if never held). --- # /docs/typescript/api/index/type-aliases/OutcomeIdx [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / OutcomeIdx # Type Alias: OutcomeIdx > **OutcomeIdx** = `0` \| `1` Defined in: packages/sdk/src/ids.ts:36 A binary outcome index: 0 = YES, 1 = NO. --- # /docs/typescript/api/index/type-aliases/PastBinaryMarketsOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PastBinaryMarketsOptions # Type Alias: PastBinaryMarketsOptions > **PastBinaryMarketsOptions** = [`BinaryMarketFilter`](BinaryMarketFilter.md) & `object` Defined in: packages/sdk/src/markets.ts:1326 Options for `listPastBinaryMarkets` — the [BinaryMarketFilter](BinaryMarketFilter.md) plus pagination + a `now` override. ## Type Declaration ### limit? > `optional` **limit?**: `number` Page size (default 50). ### offset? > `optional` **offset?**: `number` Row offset for cursoring the historical tail (default 0). ### nowSec? > `optional` **nowSec?**: `number` Override "now" (unix seconds); defaults to `Date.now()`. --- # /docs/typescript/api/index/type-aliases/PerpClosePreview [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpClosePreview # Type Alias: PerpClosePreview > **PerpClosePreview** = \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} \| \{ `priceable`: `true`; `asOfBlock`: `bigint`; `requestedQuantity`: `bigint`; `closedQuantity`: `bigint`; `remainingSize`: `bigint`; `fullClose`: `boolean`; `realizedPnl`: `bigint`; `fundingSettled`: `bigint`; `fee`: `bigint`; `netProceeds`: `bigint`; `placeable`: `boolean`; `fillPrice`: `bigint`; `markPrice`: `bigint`; `avgEntryPrice`: `bigint`; `lotSize`: `bigint`; `minQuantity`: `bigint`; \} Defined in: packages/sdk/src/perp/margin.ts:3313 What closing part or all of a position would realise. ## Union Members ### Type Literal \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} #### priceable > **priceable**: `false` The pool's mark feed is stale or zero, so nothing can be marked. #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. *** ### Type Literal \{ `priceable`: `true`; `asOfBlock`: `bigint`; `requestedQuantity`: `bigint`; `closedQuantity`: `bigint`; `remainingSize`: `bigint`; `fullClose`: `boolean`; `realizedPnl`: `bigint`; `fundingSettled`: `bigint`; `fee`: `bigint`; `netProceeds`: `bigint`; `placeable`: `boolean`; `fillPrice`: `bigint`; `markPrice`: `bigint`; `avgEntryPrice`: `bigint`; `lotSize`: `bigint`; `minQuantity`: `bigint`; \} #### priceable > **priceable**: `true` #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. #### requestedQuantity > **requestedQuantity**: `bigint` What the caller asked to close, raw base units — **already normalised**. An omitted `quantity` or a `0n` one means "all", and both arrive here as `|size|` rather than `0n`, so an "all" request is not distinguishable from an explicit full-size one on the way out. Compare against closedQuantity to see what the lot grid took off. #### closedQuantity > **closedQuantity**: `bigint` What would ACTUALLY close: clamped to the position, then **aligned down to the pool's lot grid**. Below requestedQuantity whenever the position is not a lot multiple, which is what leaves a remainder open on a "close all". #### remainingSize > **remainingSize**: `bigint` SIGNED size still open afterwards. `0n` on a full close. #### fullClose > **fullClose**: `boolean` Whether closedQuantity takes the position all the way to flat. #### realizedPnl > **realizedPnl**: `bigint` Realised price PnL on the closed share, signed. `floor((fill − entry) × sign(size) × closedQuantity / oneBase)` — the port of `MarginBank._realizedPnlForClose`, which FLOORS toward −∞ so a gain is credited at most true and a loss debited at least true. A partial close leaves `avgEntryPrice` untouched, so the remainder keeps its original basis. #### fundingSettled > **fundingSettled**: `bigint` Funding settled by the close, signed and **positive means the account pays**. Measured on the **whole** position, not the closed share — `settleTrade` settles funding before it touches the position. This is the term a close modal most often gets wrong. #### fee > **fee**: `bigint` The fill's fee, signed — negative is a maker rebate. #### netProceeds > **netProceeds**: `bigint` The close's total effect on collateral: `realizedPnl − fundingSettled − fee`. The number to show. Funding and fee are costs, so they subtract; showing `realizedPnl` alone reports a position as more profitable to close than it is. #### placeable > **placeable**: `boolean` Whether closedQuantity clears the pool's `minQuantity`. `false` means the close cannot be placed at all — not that it is small. A dust position below the minimum can only leave via liquidation or ADL. It is the pool minimum and **nothing else**: `true` is not a promise the placement is accepted. See the note on reducing capacity in [SomniaMarketsClient.previewPerpClosePnl](../interfaces/SomniaMarketsClient.md#previewperpclosepnl). #### fillPrice > **fillPrice**: `bigint` The price the close was quoted at. #### markPrice > **markPrice**: `bigint` Current mark. #### avgEntryPrice > **avgEntryPrice**: `bigint` The position's entry basis, untouched by a partial close. #### lotSize > **lotSize**: `bigint` The pool's quantity grid — the value closedQuantity was aligned to, floored at `1n` so a pool reporting `0n` cannot hand back a divisor that throws. #### minQuantity > **minQuantity**: `bigint` The pool's minimum order quantity. --- # /docs/typescript/api/index/type-aliases/PerpFeeRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpFeeRecord # Type Alias: PerpFeeRecord > **PerpFeeRecord** = `object` Defined in: packages/sdk/src/perp/history.ts:490 A realized perp fee, rebate, or builder credit (mirror of the indexer `PerpFeeRecord` entity). The perps fee rail, which is NOT the binary/spot one — [client.listBuilderFees](../interfaces/SomniaMarketsClient.md#listbuilderfees) and friends read `BuilderFeeRecord` / `ProtocolFeeRecord`, written by the market modules. These rows come off `MarginBank`, and `kind` says which rail within it. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:492 Record id (`${txHash}_${logIndex}`). *** ### account > **account**: `string` Defined in: packages/sdk/src/perp/history.ts:494 Account charged or credited (lowercased). *** ### pool > **pool**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:496 Perp pool (lowercased); null on account-scoped rows. *** ### amount > **amount**: `string` Defined in: packages/sdk/src/perp/history.ts:498 Amount moved (raw collateral, unsigned — read `isRebate` for the direction). *** ### isRebate > **isRebate**: `boolean` Defined in: packages/sdk/src/perp/history.ts:500 True on `Rebate` (a credit TO the account); false on `Fee` / `BuilderFee` (a debit). *** ### kind > **kind**: `string` Defined in: packages/sdk/src/perp/history.ts:515 Which rail: Fee taker/maker fee charged on a fill Rebate maker rebate paid back BuilderFee routing credit to a builder — the perps builder rail, previously unindexed while the spot and binary ones were not LiquidationFee stage-3 health-preserving liquidation fee, routed WHOLLY to an Insurance Fund tier (see `tier` / `fillNotional`) No `LiquidationFee` rows exist yet: the event is in the protocol ABI but not in the deployed implementation, and the subscription is staged ahead of the upgrade that brings it. *** ### insurancePortion > **insurancePortion**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:524 Portion of this fee routed to the Insurance Fund; null on `Rebate` / `BuilderFee`. A component OF `amount`, never an addition to it — summing both double-counts. On `Fee` it is a split of a larger fee; on `LiquidationFee` it equals `amount`, because that fee goes wholly to a tier. Written on both so `SUM(insurancePortion)` is the fund's fee inflow without special-casing the kind. *** ### tier > **tier**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:526 Insurance Fund tier credited (`LiquidationFee` only; `"0"` = general/unallocated). *** ### fillNotional > **fillNotional**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:532 The liquidation IOC's quote fill notional, which the fee's rate cap applied to (`LiquidationFee` only) — so the effective rate is reconstructible per row without tracking the penalty-bps admin parameter. *** ### builder > **builder**: `string` \| `null` Defined in: packages/sdk/src/perp/history.ts:534 Builder credited (`BuilderFee` only; lowercased). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/history.ts:536 Timestamp (unix seconds). *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/history.ts:538 Tx hash the fee landed in. --- # /docs/typescript/api/index/type-aliases/PerpFundingPayer [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpFundingPayer # Type Alias: PerpFundingPayer > **PerpFundingPayer** = \{ `funded`: `true`; `payer`: `Address`; \} \| \{ `funded`: `false`; `reason`: `"dormant"` \| `"unlinked"` \| `"isMain"`; \} Defined in: packages/sdk/src/perp/linkedWallet.ts:76 Whether a child's next position-increasing order would draw on a main's wallet, and whose. A discriminated union rather than a bare address, because zero from `quoteFundingPayer` collapses three genuinely different situations that a UI must not render identically: the rail is dormant, this wallet is unlinked, or this wallet IS a main. Narrow on `funded` first. ## Union Members ### Type Literal \{ `funded`: `true`; `payer`: `Address`; \} #### funded > **funded**: `true` A main would be debited for whatever this account's own wallet cannot cover. #### payer > **payer**: `Address` The main whose wallet would be debited. This is the live resolution, not the snapshot a past pull recorded — see [PerpMainFunding.payer](../interfaces/PerpMainFunding.md#payer) for that, and note the two can differ after an unlink and re-link. *** ### Type Literal \{ `funded`: `false`; `reason`: `"dormant"` \| `"unlinked"` \| `"isMain"`; \} #### funded > **funded**: `false` No main would be debited. `reason` says which of the three cases applies; only `unlinked` is something the user can change by linking. #### reason > **reason**: `"dormant"` \| `"unlinked"` \| `"isMain"` - `dormant` — the bank holds no registry address, so the feature is off for everyone on this deployment. Linking would not help. - `unlinked` — the rail is armed but this wallet has no main. - `isMain` — this wallet resolves to itself. Mains fund children, not the reverse; funding flows main->child only. --- # /docs/typescript/api/index/type-aliases/PerpHealthSnapshot [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpHealthSnapshot # Type Alias: PerpHealthSnapshot > **PerpHealthSnapshot** = \{ `priceable`: `true`; `oneBase`: `bigint`; `markPrice`: `bigint`; `projectedCumulativeFunding`: `bigint`; `effectiveImfBps`: `bigint`; `maintenanceMarginBps`: `bigint`; `closeOutMarginBps`: `bigint`; \} \| \{ `priceable`: `false`; \} Defined in: packages/sdk/src/perp/margin.ts:187 Every per-market input a margin or health calculation needs, sampled together. A discriminated union rather than a nullable struct because the contract's non-reverting variant returns an ALL-ZERO snapshot when the market is not priceable — and a `maintenanceMarginBps` of 0 silently reads as "no maintenance requirement", which is far more dangerous than a missing price. Narrow on `priceable` and the zeros are unreachable. ## Union Members ### Type Literal \{ `priceable`: `true`; `oneBase`: `bigint`; `markPrice`: `bigint`; `projectedCumulativeFunding`: `bigint`; `effectiveImfBps`: `bigint`; `maintenanceMarginBps`: `bigint`; `closeOutMarginBps`: `bigint`; \} #### priceable > **priceable**: `true` The pool's mark feed is fresh; every field below is real. #### oneBase > **oneBase**: `bigint` 10^decimals of the synthetic base asset — the divisor for notional math. #### markPrice > **markPrice**: `bigint` Fresh mark price, raw quote units per whole base. #### projectedCumulativeFunding > **projectedCumulativeFunding**: `bigint` Cumulative funding per unit INCLUDING unsettled intervals (1e18-scaled, signed). #### effectiveImfBps > **effectiveImfBps**: `bigint` The initial-margin factor actually in force, bps — OI-scaled when dynamic IMF is enabled, otherwise equal to [PerpRiskParams.initialMarginBps](../interfaces/PerpRiskParams.md#initialmarginbps). This, not the static base, is what the pool charges a new order. #### maintenanceMarginBps > **maintenanceMarginBps**: `bigint` Maintenance-margin threshold, bps (does not scale with OI). #### closeOutMarginBps > **closeOutMarginBps**: `bigint` Close-out / takeover threshold, bps. *** ### Type Literal \{ `priceable`: `false`; \} #### priceable > **priceable**: `false` The pool's mark feed is stale or zero, so the contract declined to produce a snapshot. Skip this market — do NOT substitute zeros or a previous reading. --- # /docs/typescript/api/index/type-aliases/PerpInsuranceFundEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpInsuranceFundEvent # Type Alias: PerpInsuranceFundEvent > **PerpInsuranceFundEvent** = `object` Defined in: packages/sdk/src/perp/system.ts:327 One movement in the InsuranceFund's tier ledger (mirror of the indexer `PerpInsuranceFundEvent` entity). Eight kinds share this row, and they are NOT interchangeable — most fields are populated for some kinds and null for the rest, so [PerpInsuranceFundEvent.kind](#kind) is the field to branch on first: | `kind` | What it records | Effect on the fund total | |---|---|---| | `BadDebtAuthorised` | coverage asked for and granted, per account | none — a summary | | `TierFunded` | a plain top-up | inflow | | `TierFundedFromSource` | a top-up drawn from the configured funding source | inflow | | `TierCredited` | the insurance share of a fee, booked by MarginBank | inflow | | `TierDebited` | the liquidation waterfall drew from a tier | outflow | | `TierWithdrawn` | an admin withdrawal | outflow | | `TierWithdrawnToTreasury` | an admin withdrawal routed to the treasury | outflow | | `TierAllocated` | a transfer from `tier` to `toTier` | **none** | **Gotchas.** - **Never sum `amount` bare.** It is populated on inflows, outflows and the internal move alike, so a plain total is gross turnover rather than a net position. Fold it BY `kind` using the table above, and remember `TierAllocated` nets to zero across the fund even though it moves wei between two tiers. - **`covered` is not an independent flow.** On a `BadDebtAuthorised` row it is the SUM of the `TierDebited` rows in the same transaction, so counting both double-counts the same wei. `requested > covered` is a PARTIAL grant, and `covered === "0"` is a REFUSAL — the only record the protocol keeps of one. - **`TierCredited` is a cross-plane duplicate.** It restates wei already recorded as `insurancePortion` on the fee plane ([client.listPerpFees](../interfaces/SomniaMarketsClient.md#listperpfees)), because `MarginBank._chargeFee` transfers the insurance share and then books the tier credit for the same amount. What this row adds is WHICH TIER received it, which the fee plane does not carry. Do not add the two together. - `kind` is a raw string, not a decoded union, for the same reason `Order.cancelReason` is: the vocabulary is the indexer's own — eight distinct events rather than a contract enum arriving as a `uint8` — so there is nothing to decode, and a kind a newer indexer emits reaches a consumer intact rather than becoming null. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/system.ts:329 Row id (`${txHash}_${logIndex}`). *** ### kind > **kind**: `string` Defined in: packages/sdk/src/perp/system.ts:331 Which of the eight movements this row is — branch on this before reading any other field. *** ### tier > **tier**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:336 The tier this row moves, or the SOURCE tier on `TierAllocated`. Null on `BadDebtAuthorised`, which is account-scoped rather than tier-scoped. *** ### toTier > **toTier**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:338 The DESTINATION tier (`TierAllocated` only). *** ### amount > **amount**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:343 Wei that actually MOVED, raw collateral units. Null on `BadDebtAuthorised`. Fold by `kind` — see the type note; a bare sum is turnover, not a balance. *** ### requested > **requested**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:345 Coverage ASKED FOR (`BadDebtAuthorised` only). *** ### covered > **covered**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:350 Coverage GRANTED (`BadDebtAuthorised` only) — the sum of the same-transaction `TierDebited` rows rather than an independent flow. `"0"` is a refusal. *** ### account > **account**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:352 The account whose bad debt was authorised (`BadDebtAuthorised` only), lowercased. *** ### counterparty > **counterparty**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:354 The funding source or the treasury, where the event names one (lowercased). *** ### caller > **caller**: `string` \| `null` Defined in: packages/sdk/src/perp/system.ts:356 Who triggered it, where the event names a caller distinct from the counterparty. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/system.ts:358 Timestamp (unix seconds) of the movement. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/system.ts:360 Block the movement landed in. *** ### logIndex > **logIndex**: `number` Defined in: packages/sdk/src/perp/system.ts:366 Position within the block. Load-bearing for ordering, not decoration: one authorisation debits SEVERAL tiers in the same block and transaction, and `id` leads with an unordered transaction hash, so nothing else can rank them. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/system.ts:368 Tx hash the movement landed in. --- # /docs/typescript/api/index/type-aliases/PerpLiquidationPreview [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpLiquidationPreview # Type Alias: PerpLiquidationPreview > **PerpLiquidationPreview** = \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} \| \{ `priceable`: `true`; `asOfBlock`: `bigint`; `markPrice`: `bigint`; `currentSize`: `bigint`; `currentLiquidationPrice`: `bigint` \| `null`; `projectedSize`: `bigint`; `projectedEntryPrice`: `bigint`; `realizedPnl`: `bigint`; `fee`: `bigint`; `projectedEquity`: `bigint`; `projectedMmReq`: `bigint`; `projectedLiquidationPrice`: `bigint` \| `null`; `projectedPositionLeverageBps`: `bigint` \| `null`; \} Defined in: packages/sdk/src/perp/margin.ts:3019 Where an order would put the liquidation price if it filled — and where it sits now, for the comparison that is the actual question. A discriminated union: an unpriceable market yields no preview, because the mark is an input to every field below. Narrow on `priceable` first. ## Union Members ### Type Literal \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} #### priceable > **priceable**: `false` The pool's mark feed is stale or zero, so there is nothing to project against — and an order with an increasing leg would revert on the contract's own freshness gate anyway. #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. *** ### Type Literal \{ `priceable`: `true`; `asOfBlock`: `bigint`; `markPrice`: `bigint`; `currentSize`: `bigint`; `currentLiquidationPrice`: `bigint` \| `null`; `projectedSize`: `bigint`; `projectedEntryPrice`: `bigint`; `realizedPnl`: `bigint`; `fee`: `bigint`; `projectedEquity`: `bigint`; `projectedMmReq`: `bigint`; `projectedLiquidationPrice`: `bigint` \| `null`; `projectedPositionLeverageBps`: `bigint` \| `null`; \} #### priceable > **priceable**: `true` #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. A projection is a statement about THIS block, not about the block the order fills in. Every field moves with the mark, so re-quote near send time for anything close to the edge. #### markPrice > **markPrice**: `bigint` Mark price the whole projection is measured against. #### currentSize > **currentSize**: `bigint` SIGNED position size before the fill, raw base units. #### currentLiquidationPrice > **currentLiquidationPrice**: `bigint` \| `null` Liquidation price of the position as it stands NOW, or `null` when flat. Identical to `client.getLiquidationPrice` at this block — same kernel, same inputs — so the two can be shown side by side without them disagreeing. #### projectedSize > **projectedSize**: `bigint` SIGNED position size after the fill; `0n` when the order closes out exactly. #### projectedEntryPrice > **projectedEntryPrice**: `bigint` Volume-weighted average entry price after the fill, raw quote per whole base. Follows `MarginBank.settleTrade`: the order's price on an OPEN or a FLIP, the floored VWAP of old and new on an INCREASE, and untouched on a reduce (a partial close does not re-price what remains). `0n` when the fill closes the position out, matching `_clearPosition`. #### realizedPnl > **realizedPnl**: `bigint` Realized PnL the fill books into the collateral balance (signed). Non-zero only for a reduce, close, or flip — an open or an increase realizes nothing. Floored toward −∞, matching `_realizedPnlForClose`. #### fee > **fee**: `bigint` Trading fee the fill would charge, raw collateral units — NEGATIVE for a maker rebate, which is a credit. Charged on fill notional at the pool's taker rate by default; pass `asMaker` for the maker rate. It reduces equity, so it moves the liquidation price, which is why it is modelled here even though [SomniaMarketsClient.previewPerpOrderMargin](../interfaces/SomniaMarketsClient.md#previewperpordermargin) (a question about the LOCK) has no reason to. #### projectedEquity > **projectedEquity**: `bigint` Account equity after the fill (signed) — the projection's numerator. `equity − uPnlBefore + uPnlAfter + realizedPnl − fee`, all at the current mark. Re-marking is what makes an adverse entry cost equity immediately: a position opens at the order's price but is marked at the mark, so the gap lands here. #### projectedMmReq > **projectedMmReq**: `bigint` Aggregate maintenance requirement after the fill — this market's contribution recomputed on the new size, with every other market's left exactly as the bank reported it. #### projectedLiquidationPrice > **projectedLiquidationPrice**: `bigint` \| `null` Liquidation price after the fill, or `null` when the order leaves the account flat in this market (nothing left to liquidate). Compare against currentLiquidationPrice: a same-side add moves it toward the mark, a reduce away from it. #### projectedPositionLeverageBps > **projectedPositionLeverageBps**: `bigint` \| `null` This position's leverage after the fill, bps of 1x — post-fill notional over post-fill equity. `null` on non-positive projected equity, as on [PerpLeverage.positionLeverageBps](../interfaces/PerpLeverage.md#positionleveragebps). --- # /docs/typescript/api/index/type-aliases/PerpMainFundingEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpMainFundingEvent # Type Alias: PerpMainFundingEvent > **PerpMainFundingEvent** = `object` Defined in: packages/sdk/src/perp/linkedWallet.ts:452 One movement of a main's claim against a child (mirror of the indexer `PerpMainFundingEvent` entity). **Bank side**, and the running principal. - `Funded` — a main's wallet was debited for the child. `amount` moved; `payer` is the main; `outstandingPrincipal` is the claim after. - `Settled` — the child's own losses discharged part of the claim at a flat moment. **NO money moved**, so `amount` is null and `previousPrincipal` → `outstandingPrincipal` is the whole content. `payer` is null: a settle has no counterparty. - `Returned` — principal went home, by either signed route (`repayFunding` by the child or `recallFromChild` by the payer). Both settle against the SNAPSHOTTED payer, which is why `payer` here can differ from the child's current main. **Gotchas.** - **`amount` is null on `Settled`, and that is not missing data** — it is the point. Treating null as zero is right for a cash total and wrong for a claim total; the claim still fell, which `outstandingPrincipal` records. - Do not add these to [PerpMarginPull](PerpMarginPull.md) rows. Same wei, two sides. See the module header. - The live claim is [client.getPerpMainFunding](../interfaces/SomniaMarketsClient.md#getperpmainfunding) — a bank read. This is how it got there, not what it is now. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:454 Row id (`${txHash}_${logIndex}`). *** ### account > **account**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:456 The child account the claim is against (lowercased). *** ### kind > **kind**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:458 `Funded` | `Settled` | `Returned`. *** ### payer > **payer**: `string` \| `null` Defined in: packages/sdk/src/perp/linkedWallet.ts:460 The main on the other side (lowercased). Null on `Settled`, which has no counterparty. *** ### amount > **amount**: `string` \| `null` Defined in: packages/sdk/src/perp/linkedWallet.ts:462 Wei that actually moved, raw collateral units. **Null on `Settled`** — see the type note. *** ### previousPrincipal > **previousPrincipal**: `string` \| `null` Defined in: packages/sdk/src/perp/linkedWallet.ts:464 The claim BEFORE this event (`Settled` only). *** ### outstandingPrincipal > **outstandingPrincipal**: `string` \| `null` Defined in: packages/sdk/src/perp/linkedWallet.ts:466 The claim after this event. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:468 Timestamp (unix seconds) of the movement. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:470 Block the movement landed in. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:472 Tx hash the movement landed in. --- # /docs/typescript/api/index/type-aliases/PerpMarginPull [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpMarginPull # Type Alias: PerpMarginPull > **PerpMarginPull** = `object` Defined in: packages/sdk/src/perp/linkedWallet.ts:403 One leg of margin pulled to fund a placement (mirror of the indexer `PerpMarginPull` entity). **Pool side.** `source` names which wallet paid, and one placement can produce BOTH legs, in this order: - `OwnWallet` — the owner's own wallet funded it, sized by `min(balance, allowance)`. - `Main` — the residual reached the owner's linked MAIN, whose address is `payer`. So a child with no approval of its own contributes zero and the whole requirement arrives as one `Main` leg, while a partly-funded child produces two rows for one order. `amount` is what THIS leg pulled, never the order's total requirement — sum the legs sharing an `orderId` for that. **Gotcha.** Do not add these to [PerpMainFundingEvent](PerpMainFundingEvent.md) rows: the same wei appears on both sides. See the module header. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:405 Row id (`${txHash}_${logIndex}`). *** ### account > **account**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:407 The account credited, and whose position the order was for (lowercased). *** ### pool > **pool**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:409 The PerpPool that pulled (lowercased). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:411 The order whose placement caused the pull — decimal string, matches `Order.orderId`. *** ### source > **source**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:413 `OwnWallet` | `Main` — which wallet paid this leg. *** ### amount > **amount**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:415 Wei pulled by THIS leg, raw collateral units — not the order's total requirement. *** ### payer > **payer**: `string` \| `null` Defined in: packages/sdk/src/perp/linkedWallet.ts:417 The main whose wallet was debited (`Main` only; null for `OwnWallet`), lowercased. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:419 Timestamp (unix seconds) of the pull. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:421 Block the pull landed in. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:423 Tx hash the pull landed in. --- # /docs/typescript/api/index/type-aliases/PerpMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpMarket # Type Alias: PerpMarket > **PerpMarket** = [`BaseMarket`](BaseMarket.md) & `object` Defined in: packages/sdk/src/markets.ts:136 A perpetual-futures order-book market. Rides the same OrderBook core as spot (base/quote book, raw quote units per whole base), with a synthetic base: positions + collateral live cross-margin in the MarginBank, and the pool tracks funding against an oracle index price. ## Type Declaration ### marketType > **marketType**: `"PERP"` Discriminator (narrowed). ### baseToken > **baseToken**: `Address` Wrapper token standing in for the synthetic base (e.g. WBTC). ### quoteToken > **quoteToken**: `Address` The MarginBank collateral token (e.g. USDso). ### baseSymbol > **baseSymbol**: `string` \| `null` Synthetic-base symbol (e.g. "WBTC"); null when the wrapper exposes none. ### quoteSymbol > **quoteSymbol**: `string` \| `null` Collateral token symbol (e.g. "USDso"); null when the token exposes none. ### baseIsNative > **baseIsNative**: `boolean` Always false — the perp base is synthetic, never native. Kept so spot-shaped base/quote code paths can treat SPOT and PERP uniformly. ### tickSize > **tickSize**: `string` Price increment, raw quote units per whole base (decimal string). ### lotSize > **lotSize**: `string` Quantity increment, raw base units (decimal string). ### minQuantity > **minQuantity**: `string` Minimum order quantity, raw base units (decimal string). ### marginBank > **marginBank**: `Address` Cross-margin MarginBank holding collateral + positions (lowercased). ### initialMarginBps > **initialMarginBps**: `number` Initial margin requirement in bps (500 = 5% = 20x max leverage). ### stopRegistry > **stopRegistry**: `Address` \| `null` Per-pool PerpStopOrderRegistry (lowercased); null on pools without one. The registry is per-pool and every stop-order write takes it as an explicit `registry` argument ([Trader.placePerpStopOrder](../interfaces/Trader.md#placeperpstoporder), [Trader.cancelPerpStopOrder](../interfaces/Trader.md#cancelperpstoporder), [Trader.cancelPerpStopOrders](../interfaces/Trader.md#cancelperpstoporders)), so this is where that address comes from — same as `stopRegistry` on a [SpotMarket](SpotMarket.md). Null means the pool has no registry deployed, and TP/SL is unavailable on it rather than merely unfound. ### markPrice > **markPrice**: `string` \| `null` Mark price sampled at FUNDING cadence (raw quote per whole base). Shares the column with the spot mark price but is a different quantity, and the difference matters: - It advances only when funding settles — hourly on every live pool — not per trade. For a live mark, read the chain (`getPerpState().markPrice`, which also reports `markPriceOk`). - It is null whenever the contract emitted its 0 sentinel for a stale/reverting mark feed. A stale feed leaves the PREVIOUS value in place rather than zeroing it, so a non-null value here is not by itself evidence of freshness — compare `markPriceUpdatedAt` against the settlement cadence. - It is NOT what drives funding, and not mark versus index either — the two routinely disagree in sign. The premium is the time-weighted IMPACT-price premium (quantity-weighted fill price at a configured notional on each side, deadbanded against the index). Read `getPerpState().emaPremium` for the quantity funding actually uses. ### markPriceUpdatedAt > **markPriceUpdatedAt**: `string` \| `null` When `markPrice` last advanced (unix seconds); null until the first settlement. ### fundingRate > **fundingRate**: `string` \| `null` Funding rate for the last settlement window (1e18-scaled fraction, signed). Null until the first FundingUpdated is indexed. ### cumulativeFundingPerUnit > **cumulativeFundingPerUnit**: `string` \| `null` Cumulative funding per base unit since inception (1e18-scaled, signed). ### indexPrice > **indexPrice**: `string` \| `null` Oracle index price at the last funding update (raw quote per whole base). ### fundingUpdatedAt > **fundingUpdatedAt**: `string` \| `null` Timestamp (unix seconds) of the last FundingUpdated; null until the first. ### fundingWindowSec > **fundingWindowSec**: `number` \| `null` The rate's DENOMINATOR in seconds (`fundingCalculationWindowSec`), 28800 on every live pool. `fundingRate` above is per THIS window — not per settlement interval and not annualized. Pass it to [normalizeFundingRate](../functions/normalizeFundingRate.md) and friends; a hardcoded denominator produces a plausible-looking wrong chart rather than an error. ### fundingIntervalSec > **fundingIntervalSec**: `number` \| `null` Settlement cadence in seconds. **3600 on every live pool**, so `fundingWindowSec / fundingIntervalSec` is 8. It has been 300 (n = 96), and the same rate value means a 12x different per-interval accrual across that boundary — which is why this is carried per row and never assumed. Indexed history still spans it. ### openInterest > **openInterest**: `string` \| `null` TOTAL open interest in base units. Replaces `longOpenInterest` / `shortOpenInterest`. The contract keeps ONE counter because the short side is provably equal in a matched CLOB, and the removed pair was null on every row anyway — the subscription feeding it was dead. ### openInterestUpdatedAt > **openInterestUpdatedAt**: `string` \| `null` Timestamp (unix seconds) of the last OpenInterestUpdated; null until the first. --- # /docs/typescript/api/index/type-aliases/PerpMarketFilter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpMarketFilter # Type Alias: PerpMarketFilter > **PerpMarketFilter** = `object` Defined in: packages/sdk/src/markets.ts:1242 Filters for [SomniaMarketsClient.listPerpMarkets](../interfaces/SomniaMarketsClient.md#listperpmarkets). All optional; applied server-side. ## Properties ### baseSymbol? > `optional` **baseSymbol?**: `string` Defined in: packages/sdk/src/markets.ts:1244 Synthetic-base token symbol, e.g. `"WBTC"`. *** ### quoteSymbol? > `optional` **quoteSymbol?**: `string` Defined in: packages/sdk/src/markets.ts:1246 Collateral (quote) token symbol, e.g. `"USDso"`. --- # /docs/typescript/api/index/type-aliases/PerpMaxOrderSize [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpMaxOrderSize # Type Alias: PerpMaxOrderSize > **PerpMaxOrderSize** = \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} \| \{ `priceable`: `true`; `asOfBlock`: `bigint`; `maxQuantity`: `bigint`; `unalignedMaxQuantity`: `bigint`; `increasingQuantity`: `bigint`; `reducingQuantity`: `bigint`; `lockAmount`: `bigint`; `topUpRequired`: `bigint`; `wallet`: \{ `balance`: `bigint`; `allowance`: `bigint`; \} \| `null`; `fundingPayer`: `Address` \| `null`; `mainWalletCapacity`: `bigint` \| `null`; `mainFundingBlocked`: `boolean`; `ownWalletPull`: `bigint`; `mainWalletPull`: `bigint`; `placeable`: `boolean`; `limitedBy`: [`PerpMaxOrderSizeLimit`](PerpMaxOrderSizeLimit.md); `lotSize`: `bigint`; `minQuantity`: `bigint`; `maxPositionSize`: `bigint`; `positionSize`: `bigint`; `markPrice`: `bigint`; `effectiveImfBps`: `bigint`; \} Defined in: packages/sdk/src/perp/margin.ts:2481 The largest order the account can actually place, or an unpriceable market. ## Union Members ### Type Literal \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} #### priceable > **priceable**: `false` The pool's mark feed is stale or zero, so no size can be quoted. #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. *** ### Type Literal \{ `priceable`: `true`; `asOfBlock`: `bigint`; `maxQuantity`: `bigint`; `unalignedMaxQuantity`: `bigint`; `increasingQuantity`: `bigint`; `reducingQuantity`: `bigint`; `lockAmount`: `bigint`; `topUpRequired`: `bigint`; `wallet`: \{ `balance`: `bigint`; `allowance`: `bigint`; \} \| `null`; `fundingPayer`: `Address` \| `null`; `mainWalletCapacity`: `bigint` \| `null`; `mainFundingBlocked`: `boolean`; `ownWalletPull`: `bigint`; `mainWalletPull`: `bigint`; `placeable`: `boolean`; `limitedBy`: [`PerpMaxOrderSizeLimit`](PerpMaxOrderSizeLimit.md); `lotSize`: `bigint`; `minQuantity`: `bigint`; `maxPositionSize`: `bigint`; `positionSize`: `bigint`; `markPrice`: `bigint`; `effectiveImfBps`: `bigint`; \} #### priceable > **priceable**: `true` #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. A max size is a statement about THIS block. The adverse-gap term moves one-for-one with the mark, so a limit bid above a falling mark can afford less than quoted a block later. Re-quote near send time. #### maxQuantity > **maxQuantity**: `bigint` The largest quantity that passes every placement gate, **aligned down to the pool's lot grid** — what a Max button should fill in. `0n` when nothing can be placed. Check placeable before offering it: a size below the pool's `minQuantity` is not a small order, it is a revert. #### unalignedMaxQuantity > **unalignedMaxQuantity**: `bigint` maxQuantity before lot alignment. Diagnostic only — placing it would revert `InvalidQuantity`. #### increasingQuantity > **increasingQuantity**: `bigint` The part of maxQuantity that increases the position, and so locks. #### reducingQuantity > **reducingQuantity**: `bigint` The part absorbed by existing exposure, which locks nothing. This is why a max on the opposite side can exceed anything the collateral would fund: a reducing order trips neither gate, so the answer starts at the reducing capacity and only then adds what the margin can carry. #### lockAmount > **lockAmount**: `bigint` The collateral the pool would lock at maxQuantity. #### topUpRequired > **topUpRequired**: `bigint` What auto-pull would REQUEST in total at maxQuantity — `0n` unless `autoPull` was passed. **Show it beside the size**: at a wallet-limited max this is essentially the whole approved balance, and a trader clicking Max deserves to see the transfer before they sign it. Split it into ownWalletPull and mainWalletPull when a main is linked, so the trader sees which wallet pays what rather than reading the total as their own debit. #### wallet > **wallet**: \{ `balance`: `bigint`; `allowance`: `bigint`; \} \| `null` The owner's collateral-token balance and MarginBank allowance, `null` unless `autoPull` was passed. Read limitedBy to see which one bound. #### fundingPayer > **fundingPayer**: `Address` \| `null` The linked MAIN eligible to fund the residual, or `null` when the account funds itself. A funded child's max is bigger than its own wallet would allow, and this names the wallet that makes up the difference. Eligibility, not a debit — see [PerpOrderMarginPreview](PerpOrderMarginPreview.md) for the full contract. #### mainWalletCapacity > **mainWalletCapacity**: `bigint` \| `null` What fundingPayer can spend, `null` whenever the payer is. #### mainFundingBlocked > **mainFundingBlocked**: `boolean` The main's leg was withheld because the account owes a prior payer, so this max is what the owner's own funding reaches. See [PerpMaxOrderSizeLimit](PerpMaxOrderSizeLimit.md) `"mainFundingBlocked"`. #### ownWalletPull > **ownWalletPull**: `bigint` The share of topUpRequired the owner's own wallet supplies at maxQuantity. #### mainWalletPull > **mainWalletPull**: `bigint` The share fundingPayer supplies at maxQuantity, `0n` with no main. #### placeable > **placeable**: `boolean` Whether maxQuantity clears the pool's `minQuantity`. #### limitedBy > **limitedBy**: [`PerpMaxOrderSizeLimit`](PerpMaxOrderSizeLimit.md) Which gate stopped it going one lot higher. #### lotSize > **lotSize**: `bigint` The pool's quantity grid — every order must be a multiple. The value maxQuantity was actually aligned to, floored at `1n`. A pool reporting `0n` has no grid to speak of, and handing that back would give a caller a divisor that throws. #### minQuantity > **minQuantity**: `bigint` The pool's minimum order quantity. #### maxPositionSize > **maxPositionSize**: `bigint` The market's per-account position cap. #### positionSize > **positionSize**: `bigint` SIGNED existing position size. #### markPrice > **markPrice**: `bigint` The mark the adverse gap was measured against. #### effectiveImfBps > **effectiveImfBps**: `bigint` The OI-scaled IMF used, bps. --- # /docs/typescript/api/index/type-aliases/PerpMaxOrderSizeLimit [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpMaxOrderSizeLimit # Type Alias: PerpMaxOrderSizeLimit > **PerpMaxOrderSizeLimit** = `"collateral"` \| `"initialMargin"` \| `"maxPositionSize"` \| `"voucherBlocked"` \| `"walletBalance"` \| `"walletAllowance"` \| `"mainWallet"` \| `"mainFundingBlocked"` \| `"restricted"` \| `"isolated"` Defined in: packages/sdk/src/perp/margin.ts:2420 Which gate stopped the size going one lot higher. --- # /docs/typescript/api/index/type-aliases/PerpOrderHistoryRow [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpOrderHistoryRow # Type Alias: PerpOrderHistoryRow > **PerpOrderHistoryRow** = [`PerpPortfolioOrder`](PerpPortfolioOrder.md) & `object` Defined in: packages/sdk/src/perp/portfolio.ts:286 A terminal (no longer working) perp order — the history counterpart to [PerpPortfolioOrder](PerpPortfolioOrder.md), which is open-orders only. Same fields plus the lifecycle ones that only matter once an order has stopped working: how it ended and when. ## Type Declaration ### status > **status**: [`OrderStatus`](OrderStatus.md) How the order ended. `Closed` is terminal, not transitional: every pool places an order as `Closed` and a following `OrderRested` promotes it to `Open`, so an IOC that partially filled without resting stays `Closed` forever. Reading it as "still working" would show a finished order as live. ### rested > **rested**: `boolean` Whether the order ever rested on the book (an `OrderRested` fired). ### expireTimestampNs > **expireTimestampNs**: `string` Expiry as a uint64 NANOsecond timestamp (decimal string) — note the unit, the rest of this row is unix seconds. GTC carries `type(uint64).max`. ### lastUpdatedAtTimestamp > **lastUpdatedAtTimestamp**: `string` Unix seconds of the last state change — effectively when the order ended. --- # /docs/typescript/api/index/type-aliases/PerpOrderMarginPreview [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpOrderMarginPreview # Type Alias: PerpOrderMarginPreview > **PerpOrderMarginPreview** = \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} \| \{ `priceable`: `true`; `asOfBlock`: `bigint`; `increasingQuantity`: `bigint`; `reducingQuantity`: `bigint`; `lockAmount`: `bigint`; `initialMarginPortion`: `bigint`; `adverseGapPortion`: `bigint`; `leverageSurcharge`: `bigint`; `effectiveImfBps`: `bigint`; `markPrice`: `bigint`; `unlockedCollateral`: `bigint`; `equity`: `bigint`; `imRequirement`: `bigint`; `feeHeadroom`: `bigint`; `topUpRequired`: `bigint`; `wallet`: \{ `balance`: `bigint`; `allowance`: `bigint`; \} \| `null`; `fundingPayer`: `Address` \| `null`; `mainWalletCapacity`: `bigint` \| `null`; `mainFundingBlocked`: `boolean`; `walletCoversTopUp`: `boolean`; `ownWalletPull`: `bigint`; `mainWalletPull`: `bigint`; `hasCollateralForLock`: `boolean`; `meetsInitialMargin`: `boolean`; `voucherBlocked`: `boolean`; `restrictedBlocked`: `boolean`; `isolationBlocked`: `boolean`; `sufficient`: `boolean`; \} Defined in: packages/sdk/src/perp/margin.ts:1515 What a perp order will cost and whether it will be accepted, computed BEFORE sending it. A discriminated union: an unpriceable market yields no preview at all, because every component below needs the mark. Narrow on `priceable` first. ## Union Members ### Type Literal \{ `priceable`: `false`; `asOfBlock`: `bigint`; \} #### priceable > **priceable**: `false` The pool's mark feed is stale or zero. Placement of any order with an increasing leg would revert on the contract's own freshness gate, so there is nothing to preview — and no field here could be trusted if there were. #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. *** ### Type Literal \{ `priceable`: `true`; `asOfBlock`: `bigint`; `increasingQuantity`: `bigint`; `reducingQuantity`: `bigint`; `lockAmount`: `bigint`; `initialMarginPortion`: `bigint`; `adverseGapPortion`: `bigint`; `leverageSurcharge`: `bigint`; `effectiveImfBps`: `bigint`; `markPrice`: `bigint`; `unlockedCollateral`: `bigint`; `equity`: `bigint`; `imRequirement`: `bigint`; `feeHeadroom`: `bigint`; `topUpRequired`: `bigint`; `wallet`: \{ `balance`: `bigint`; `allowance`: `bigint`; \} \| `null`; `fundingPayer`: `Address` \| `null`; `mainWalletCapacity`: `bigint` \| `null`; `mainFundingBlocked`: `boolean`; `walletCoversTopUp`: `boolean`; `ownWalletPull`: `bigint`; `mainWalletPull`: `bigint`; `hasCollateralForLock`: `boolean`; `meetsInitialMargin`: `boolean`; `voucherBlocked`: `boolean`; `restrictedBlocked`: `boolean`; `isolationBlocked`: `boolean`; `sufficient`: `boolean`; \} #### priceable > **priceable**: `true` #### asOfBlock > **asOfBlock**: `bigint` The block every read was pinned to. A preview is a statement about THIS block, not about the block the order lands in. The adverse-gap component moves one-for-one with the mark, so a limit bid above a falling mark locks more than quoted and either gate can flip. Re-quote near send time for anything close to the edge. #### increasingQuantity > **increasingQuantity**: `bigint` The part of the order that increases the position — the only part that locks. #### reducingQuantity > **reducingQuantity**: `bigint` The part absorbed by existing exposure. Locks nothing. #### lockAmount > **lockAmount**: `bigint` Total collateral the pool will lock (raw quote units) — the honest "margin required". #### initialMarginPortion > **initialMarginPortion**: `bigint` The initial-margin component of lockAmount, at the effective (OI-scaled) IMF. #### adverseGapPortion > **adverseGapPortion**: `bigint` The adverse mark-to-entry component of lockAmount, zero on a favourable entry. A position opens at the order's price but is marked at the current mark, so a buy above mark (or sell below) is born underwater by that gap; the pool reserves it on top of initial margin. This is the term a naive `notional × IMF` estimate misses, and the usual reason a "max" order sized that way gets rejected. #### leverageSurcharge > **leverageSurcharge**: `bigint` Extra margin demanded because the account set a per-market leverage cap STRICTER than the market's effective IMF. Zero when unset or looser. Charged on post-fill notional, and unlike the lock it comes out of free equity rather than being reserved. #### effectiveImfBps > **effectiveImfBps**: `bigint` The OI-scaled IMF actually applied, bps — not the static `initialMarginBps`. #### markPrice > **markPrice**: `bigint` Mark price the adverse gap was measured against. #### unlockedCollateral > **unlockedCollateral**: `bigint` Free collateral available to be locked. #### equity > **equity**: `bigint` Account equity (signed) before the lock. #### imRequirement > **imRequirement**: `bigint` Initial-margin requirement of EXISTING positions. #### feeHeadroom > **feeHeadroom**: `bigint` The pool's worst-case fee reserve for this order — an auto-pull addend, never part of lockAmount. See [PerpOrderMarginQuote.feeHeadroom](../interfaces/PerpOrderMarginQuote.md#feeheadroom). #### topUpRequired > **topUpRequired**: `bigint` What auto-pull would REQUEST in total, `0n` unless `autoPull` was passed. **Not the wallet spend once a main is in play** — that is ownWalletPull for the owner and mainWalletPull for the main, and an order form showing this figure as the child's debit over-states it by the main's leg. With no main the two coincide. See [PerpOrderMarginQuote.topUpRequired](../interfaces/PerpOrderMarginQuote.md#topuprequired), including the three cases where the pool declines and this reads `0n` for a reason other than "nothing needed". #### wallet > **wallet**: \{ `balance`: `bigint`; `allowance`: `bigint`; \} \| `null` The owner's collateral-token balance and MarginBank allowance, `null` unless `autoPull` was passed. Both bind on topUpRequired, and which one is short decides whether the fix is "approve more" or "fund the wallet". #### fundingPayer > **fundingPayer**: `Address` \| `null` The linked MAIN ELIGIBLE to fund what the owner's wallet cannot, or `null` when the account funds itself (unlinked, a main itself, or the rail is dormant) or `autoPull` was not passed. **Eligibility, not a debit.** This is resolved for every linked account on the `autoPull` path, including an order that needs no top-up at all and one whose own wallet covers the whole pull. Read mainWalletPull `> 0n` for the wallet that actually moves, and show THAT before the trader signs. #### mainWalletCapacity > **mainWalletCapacity**: `bigint` \| `null` What fundingPayer can spend — `MarginBank.quoteWalletCapacity(payer)`, i.e. `min(balance, allowance)`. `null` whenever fundingPayer is. #### mainFundingBlocked > **mainFundingBlocked**: `boolean` The main's leg is withheld because the account still owes a PRIOR payer, so `MarginBank.depositForFromMain` would revert `PriorFundingPayerOutstanding`. mainWalletPull is `0n` while this holds, whatever mainWalletCapacity says. Clear the old claim with `trader.repayPerpMainFunding`. #### walletCoversTopUp > **walletCoversTopUp**: `boolean` Both funding wallets together cover topUpRequired. See [PerpOrderMarginQuote.walletCoversTopUp](../interfaces/PerpOrderMarginQuote.md#walletcoverstopup). #### ownWalletPull > **ownWalletPull**: `bigint` The share of topUpRequired the owner's own wallet would supply — it pays first. See [PerpOrderMarginQuote.ownWalletPull](../interfaces/PerpOrderMarginQuote.md#ownwalletpull). #### mainWalletPull > **mainWalletPull**: `bigint` The share fundingPayer would supply, `0n` with no main. See [PerpOrderMarginQuote.mainWalletPull](../interfaces/PerpOrderMarginQuote.md#mainwalletpull). #### hasCollateralForLock > **hasCollateralForLock**: `boolean` Gate 1 — the unlocked balance covers the lock, after any auto-pull. Failing it reverts `InsufficientCollateral` before margin is even checked. Vacuously true when nothing is locked: the pool calls `lockCollateral` only `if (lockAmount > 0)`, so a purely reducing order never touches this gate even from a negative unlocked balance. Without `autoPull` it is measured against unlockedCollateral alone — see [PerpOrderMarginQuote.hasCollateralForLock](../interfaces/PerpOrderMarginQuote.md#hascollateralforlock). #### meetsInitialMargin > **meetsInitialMargin**: `boolean` Gate 2 — post-lock equity still covers the requirement: `equity + topUpRequired - lockAmount >= imRequirement + leverageSurcharge`. Vacuously true for a purely reducing order, which the pool exempts outright (`if (increasingQuantity > 0)`) on the grounds that closing can only improve account health. An account below initial margin can therefore always reduce. #### voucherBlocked > **voucherBlocked**: `boolean` The account holds a credit-voucher floor and this increasing order is barred outright — the market is not on the voucher allowlist, or the protocol's voucher leverage cap is unset. Placement reverts `VoucherMarketNotAllowed` / `VoucherLeverageCapNotSet`, whatever the margin numbers say. Distinct from the margin gates: when the market IS allowlisted, the voucher cap instead feeds the ordinary leverage path and shows up in leverageSurcharge rather than here. #### restrictedBlocked > **restrictedBlocked**: `boolean` The market is close-only and this order has an increasing leg, so placement reverts `MarketRestricted`. See [PerpOrderMarginQuote.restrictedBlocked](../interfaces/PerpOrderMarginQuote.md#restrictedblocked). #### isolationBlocked > **isolationBlocked**: `boolean` Isolated margin bars this market for this account, so placement reverts `IsolatedMarketBlocked` — the one gate here that blocks a reduce too. See [PerpOrderMarginQuote.isolationBlocked](../interfaces/PerpOrderMarginQuote.md#isolationblocked). #### sufficient > **sufficient**: `boolean` Every gate. The order should be accepted. --- # /docs/typescript/api/index/type-aliases/PerpOrderRejection [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpOrderRejection # Type Alias: PerpOrderRejection > **PerpOrderRejection** = `object` Defined in: packages/sdk/src/perp/history.ts:1003 One order refused inside a batch placement (mirror of the indexer `PerpOrderRejection` entity). **Batch placements only.** `placeOrder` / `placeOrderFor` REVERT on the same conditions, and a reverted transaction discards its logs, so a singular placement leaves no row here — its reason arrives as a decoded revert instead. A batch keeps the accepted orders and records the refused ones, which is the only reason this history exists. There is no `Order` row to join to: a rejected request never rested and never filled. `requestIndex` is its position in the submitted batch, which is how a caller maps the row back to the request it sent. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/history.ts:1005 Row id (`${txHash}_${logIndex}`). *** ### owner > **owner**: `string` Defined in: packages/sdk/src/perp/history.ts:1007 The order's owner (lowercased). *** ### pool > **pool**: `string` Defined in: packages/sdk/src/perp/history.ts:1009 The PerpPool the batch was submitted to (lowercased). *** ### reason > **reason**: [`PerpOrderRejectionReason`](PerpOrderRejectionReason.md) \| `null` Defined in: packages/sdk/src/perp/history.ts:1020 The reason as a NAME, or `null` when the pool reported a member this SDK version does not know. Null rather than a default member, deliberately, and for the same reason the `intent` field on [PerpStopOrder](PerpStopOrder.md) does it: the enum appends — `DropReason` gained `NoFill` — and naming an unrecognized index would tell a caller the order was refused for a reason it was not. [PerpOrderRejection.reasonRaw](#reasonraw) still carries the index, so a null is never a lost row. *** ### reasonRaw > **reasonRaw**: `number` Defined in: packages/sdk/src/perp/history.ts:1029 The raw enum index, always present. Kept beside the decoded name because the indexer deliberately stores this un-decoded: a member added after the reindex still lands intact, and no row is ever lost to a name the indexer did not know. A consumer that wants to handle a newer-than-SDK reason reads this. *** ### requestIndex > **requestIndex**: `string` Defined in: packages/sdk/src/perp/history.ts:1031 The order's position in the submitted batch — how to map the row back to the request. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/history.ts:1033 Timestamp (unix seconds) of the rejection. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/history.ts:1035 Block the rejection landed in. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/history.ts:1037 Tx hash the batch landed in. --- # /docs/typescript/api/index/type-aliases/PerpOrderRejectionReason [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpOrderRejectionReason # Type Alias: PerpOrderRejectionReason > **PerpOrderRejectionReason** = *typeof* [`PERP_ORDER_REJECTION_REASON`](../variables/PERP_ORDER_REJECTION_REASON.md)\[`number`\] Defined in: packages/sdk/src/perp/history.ts:985 A decoded [PerpOrderRejection.reason](PerpOrderRejection.md#reason). --- # /docs/typescript/api/index/type-aliases/PerpPoolStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPoolStatus # Type Alias: PerpPoolStatus > **PerpPoolStatus** = `object` Defined in: packages/sdk/src/perp/registry.ts:54 One factory-deployed perp market and whether it can actually be traded. **`restricted` and `registered` are independent gates that fail for unrelated reasons.** A market can be perfectly registered with the bank and still be close-only, or unrestricted and never activated. Both have to pass, which is what [tradeable](#tradeable) folds together. ## Properties ### pool > **pool**: `Address` Defined in: packages/sdk/src/perp/registry.ts:56 The PerpPool beacon proxy. *** ### baseToken > **baseToken**: `Address` Defined in: packages/sdk/src/perp/registry.ts:58 The synthetic base ERC-20 the market tracks. *** ### marginBank > **marginBank**: `Address` Defined in: packages/sdk/src/perp/registry.ts:68 The MarginBank this pool settles against, read from the pool itself. Effectively a per-network singleton, but taken per-pool because the pool is what the settlement path actually uses — so this is the bank a later `getMarginAccount` / `getPerpPosition` / `getLiquidationPrice` for this market must be addressed to. Carrying it here means a consumer never has to source it separately, and never has to hardcode it per chain. *** ### restricted > **restricted**: `boolean` Defined in: packages/sdk/src/perp/registry.ts:78 True when the market is CLOSE-ONLY: position-increasing orders revert `MarketRestricted`, while closes, reduces and cancels still work. Restricted markets stay visible on purpose — holders still have to close positions, cancel orders and withdraw collateral, and liquidation runs on them unchanged. Reversible: a restriction can be a temporary wind-down rather than a retirement. *** ### registered > **registered**: `boolean` \| `null` Defined in: packages/sdk/src/perp/registry.ts:96 Whether [marginBank](#marginbank) has this pool registered — the ACTIVATION gate. Coming from the factory only proves a pool is authentic; `addPerpPool` is the separate step that makes it usable, and `removePerpPool` revokes it. An unregistered pool rejects every settlement callback and every quote view while still reading as an ordinary market from the factory. `null` when the gate is genuinely unreadable, from either of two causes: the pool's MarginBank predates `isPerpPoolRegistered`, or that pool's bank reads failed while other pools' succeeded. Nothing substitutes for it — `getPoolTier` is itself gated on registration (so it collapses to 0 for both an uncovered-but-registered market and an unregistered one) and `getActivePerpPools` is per-account, not the registry. On the read-failure cause, [marginBank](#marginbank) is the zero address: the pool's own bank could not be established either, so do not address a settlement read to it. *** ### tradeable > **tradeable**: `boolean` \| `null` Defined in: packages/sdk/src/perp/registry.ts:104 Both gates passed — not restricted AND registered. The list to show as tradeable. `null` when [registered](#registered) is unknown: with one of the two gates unreadable, tradeability is genuinely undetermined, and reporting `false` would hide live markets while `true` would advertise dead ones. --- # /docs/typescript/api/index/type-aliases/PerpPortfolio [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPortfolio # Type Alias: PerpPortfolio > **PerpPortfolio** = `object` Defined in: packages/sdk/src/perp/portfolio.ts:126 A wallet's perp portfolio — the shape [SomniaMarketsClient.getPerpPortfolio](../interfaces/SomniaMarketsClient.md#getperpportfolio) returns. ## Properties ### account > **account**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:128 The queried account (lowercased). *** ### openOrders > **openOrders**: [`PerpPortfolioOrder`](PerpPortfolioOrder.md)[] Defined in: packages/sdk/src/perp/portfolio.ts:130 Currently-open perp orders, newest first. *** ### trades > **trades**: [`PerpPortfolioTrade`](PerpPortfolioTrade.md)[] Defined in: packages/sdk/src/perp/portfolio.ts:132 Recent perp fills the account participated in, newest first. *** ### tradesTruncated > **tradesTruncated**: `boolean` Defined in: packages/sdk/src/perp/portfolio.ts:140 The read hit its `tradesLimit`, so fills older than the last entry in `trades` exist and were NOT returned. Raise `tradesLimit` for the rest. A total folded from a truncated `trades` covers part of the history only. False when the page was short, and false for `tradesLimit: 0`, which asks for no trades at all. *** ### tradesSince > **tradesSince**: `number` Defined in: packages/sdk/src/perp/portfolio.ts:146 The lower time bound the trades leg was read with, unix seconds — `since` when passed, otherwise now minus seven days (`DEFAULT_TRADES_SINCE_SEC`). Echoed so a UI can label the list and a caller can page further back. Orders are not windowed. --- # /docs/typescript/api/index/type-aliases/PerpPortfolioMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPortfolioMarket # Type Alias: PerpPortfolioMarket > **PerpPortfolioMarket** = `object` Defined in: packages/sdk/src/perp/portfolio.ts:24 Perp market context attached to perp portfolio rows. id == poolAddress. ## Properties ### poolAddress > **poolAddress**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:26 Pool address (lowercased; == the market id for perp). *** ### baseSymbol > **baseSymbol**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:28 Synthetic-base symbol (e.g. "WBTC"); null when the wrapper exposes none. *** ### quoteSymbol > **quoteSymbol**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:30 Collateral token symbol (e.g. "USDso"); null when the token exposes none. *** ### baseDecimals > **baseDecimals**: `number` Defined in: packages/sdk/src/perp/portfolio.ts:32 Base-token decimals — format base quantities with this. *** ### quoteDecimals > **quoteDecimals**: `number` Defined in: packages/sdk/src/perp/portfolio.ts:34 Collateral decimals — format prices/collateral amounts with this. *** ### tickSize > **tickSize**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:36 Price increment, raw quote units per whole base (decimal string). *** ### lotSize > **lotSize**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:38 Quantity increment, raw base units (decimal string). *** ### minQuantity > **minQuantity**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:40 Minimum order quantity, raw base units (decimal string). *** ### lastPrice > **lastPrice**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:42 Last fill price (raw quote per whole base); null until first fill. *** ### marginBank > **marginBank**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:44 Cross-margin MarginBank holding collateral + positions (lowercased). *** ### initialMarginBps > **initialMarginBps**: `number` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:46 Initial margin requirement in bps (500 = 5% = 20x max leverage). *** ### fundingRate > **fundingRate**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:51 Funding rate for the last settlement window (1e18-scaled fraction, signed); null until the first FundingUpdated. *** ### indexPrice > **indexPrice**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:53 Oracle index price at the last funding update (raw quote per whole base). *** ### stopRegistry > **stopRegistry**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:62 Per-pool PerpStopOrderRegistry address (lowercased); null if the pool has none. Here for the same reason it is on [SpotPortfolioMarket](SpotPortfolioMarket.md): attaching a TP/SL to a row in this view needs the registry address, and every perp stop write takes it explicitly. The same column reaches a full market row as `stopRegistry` on [PerpMarket](PerpMarket.md). --- # /docs/typescript/api/index/type-aliases/PerpPortfolioOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPortfolioOrder # Type Alias: PerpPortfolioOrder > **PerpPortfolioOrder** = `object` Defined in: packages/sdk/src/perp/portfolio.ts:70 One currently-open order in a wallet's perp portfolio. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:72 Order id (`${pool}_${orderId}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:74 uint128 OrderId as a decimal string (pass to trader.cancelOrder). *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/perp/portfolio.ts:76 True = bid (long), false = ask (short). *** ### price > **price**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:78 Limit price, raw quote units per whole base. *** ### quantityRemaining > **quantityRemaining**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:80 Unfilled remainder, raw base units. *** ### filledQuantity > **filledQuantity**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:82 Cumulative filled quantity, raw base units. *** ### fullQuantity > **fullQuantity**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:84 Original order size, raw base units. *** ### placedAtTimestamp > **placedAtTimestamp**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:86 Timestamp (unix seconds) the order was placed. *** ### placedTxHash > **placedTxHash**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:88 Tx hash the order was placed in. *** ### market > **market**: [`PerpPortfolioMarket`](PerpPortfolioMarket.md) Defined in: packages/sdk/src/perp/portfolio.ts:90 The market the order rests on. --- # /docs/typescript/api/index/type-aliases/PerpPortfolioTrade [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPortfolioTrade # Type Alias: PerpPortfolioTrade > **PerpPortfolioTrade** = `object` Defined in: packages/sdk/src/perp/portfolio.ts:98 One recent fill the wallet participated in (perp portfolio view). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:100 Fill id (`${blockNumber}_${logIndex}`). *** ### fillPrice > **fillPrice**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:102 Execution price, raw quote units per whole base. *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:104 Base quantity filled, raw units. *** ### quoteQuantity > **quoteQuantity**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:106 Collateral value of the fill (raw, floored). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:108 Timestamp (unix seconds) of the fill. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/portfolio.ts:110 Tx hash the fill landed in. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/perp/portfolio.ts:112 Whether the account bought (went long) on this fill. *** ### asMaker > **asMaker**: `boolean` Defined in: packages/sdk/src/perp/portfolio.ts:114 Whether the account was the maker (resting) on this fill. *** ### counterparty > **counterparty**: `string` \| `null` Defined in: packages/sdk/src/perp/portfolio.ts:116 The other party's address, if known. *** ### market > **market**: [`PerpPortfolioMarket`](PerpPortfolioMarket.md) Defined in: packages/sdk/src/perp/portfolio.ts:118 The market the fill happened on. --- # /docs/typescript/api/index/type-aliases/PerpPositionAnalytics [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpPositionAnalytics # Type Alias: PerpPositionAnalytics > **PerpPositionAnalytics** = `object` & [`PerpPositionMetrics`](../interfaces/PerpPositionMetrics.md) \| \{ `priceable`: `false`; `asOfBlock`: `bigint`; `pool`: `Address`; \} Defined in: packages/sdk/src/perp/margin.ts:939 One position's analytics as of a block, or the market reporting itself unpriceable. ## Union Members `object` & [`PerpPositionMetrics`](../interfaces/PerpPositionMetrics.md) *** ### Type Literal \{ `priceable`: `false`; `asOfBlock`: `bigint`; `pool`: `Address`; \} #### priceable > **priceable**: `false` The pool's mark feed is stale or zero, so nothing here can be marked. Skip the row — do NOT substitute zeros, which would render a live position as flat. #### asOfBlock > **asOfBlock**: `bigint` The block the attempt was pinned to. #### pool > **pool**: `Address` The pool that could not be priced. --- # /docs/typescript/api/index/type-aliases/PerpStopDropReason [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpStopDropReason # Type Alias: PerpStopDropReason > **PerpStopDropReason** = *typeof* [`PERP_STOP_DROP_REASON`](../variables/PERP_STOP_DROP_REASON.md)\[`number`\] Defined in: packages/sdk/src/perp/stops.ts:92 A drop reason, decoded from the on-chain enum index. --- # /docs/typescript/api/index/type-aliases/PerpStopIntent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpStopIntent # Type Alias: PerpStopIntent > **PerpStopIntent** = `"reduceOnly"` \| `"opening"` Defined in: packages/sdk/src/trade.ts:1342 Whether a triggered perp stop may only REDUCE the signer's position, or may open and increase one. Omitting it means `"reduceOnly"` — a take-profit or stop-loss, which is what every perp stop was before intent existed. `"opening"` is a stop-entry or breakout: it acquires exposure rather than shedding it, so the registry gates it on initial margin at creation instead of on holding a reducible position. --- # /docs/typescript/api/index/type-aliases/PerpStopOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpStopOrder # Type Alias: PerpStopOrder > **PerpStopOrder** = `object` Defined in: packages/sdk/src/perp/stops.ts:117 One take-profit / stop-loss order on a perp market. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/stops.ts:119 Row id (`${registry}_${orderId}`). *** ### registry > **registry**: `string` Defined in: packages/sdk/src/perp/stops.ts:121 The PerpStopOrderRegistry holding it (lowercased). *** ### orderIdRaw > **orderIdRaw**: `string` Defined in: packages/sdk/src/perp/stops.ts:123 uint128 registry OrderId as a decimal string — pass to `trader.cancelStopOrder`. *** ### owner > **owner**: `string` Defined in: packages/sdk/src/perp/stops.ts:125 The order's owner (lowercased). *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/perp/stops.ts:127 True = the triggered order buys, false = sells. *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/perp/stops.ts:129 Quantity in raw base units. *** ### triggerPrice > **triggerPrice**: `string` Defined in: packages/sdk/src/perp/stops.ts:131 The MARK price at which it fires, raw quote units per whole base. *** ### triggerOperator > **triggerOperator**: `number` Defined in: packages/sdk/src/perp/stops.ts:137 Which way the mark must cross `triggerPrice` to fire: `0` = GTE (fires at or above), `1` = LTE (fires at or below). This, not the side, is what makes a stop a take-profit or a stop-loss. *** ### orderType > **orderType**: `number` Defined in: packages/sdk/src/perp/stops.ts:139 `0` = LIMIT, `1` = MARKET — the type of order placed when it fires. *** ### builder > **builder**: `string` Defined in: packages/sdk/src/perp/stops.ts:141 Builder tagged on the resulting order (lowercased); zero address for none. *** ### builderFeeBpsTimes1k > **builderFeeBpsTimes1k**: `string` Defined in: packages/sdk/src/perp/stops.ts:149 The builder fee the triggered order will charge, in bps x 1000 — so `1500` is 1.5bps, not 1500bps. `"0"` when no builder is tagged. Only knowable from the creation event: the registry deletes a pending order on every fire, so after a trigger nothing on chain can say what fee was agreed. *** ### status > **status**: [`StopOrderStatus`](StopOrderStatus.md) Defined in: packages/sdk/src/perp/stops.ts:151 Lifecycle state — see [StopOrderStatus](StopOrderStatus.md). *** ### placedOrderId > **placedOrderId**: `string` \| `null` Defined in: packages/sdk/src/perp/stops.ts:153 The PerpPool order id created on a successful trigger; null otherwise. *** ### dropReason > **dropReason**: [`PerpStopDropReason`](PerpStopDropReason.md) \| `null` Defined in: packages/sdk/src/perp/stops.ts:162 Why a trigger placed nothing, decoded — null on a pending or successful order. Read it before calling a `TRIGGER_FAILED` order a failure: a reduce-only drop means the stop was overtaken by events (position already closed, flipped, or below minimum), which is ordinary. Only `PlacementFailed` is a rejection. SOMI is consumed on every fire regardless of outcome. *** ### siblingOrderId > **siblingOrderId**: `string` \| `null` Defined in: packages/sdk/src/perp/stops.ts:180 The LIVE OCO sibling's registry id, as a decimal string — null when this stop is unlinked, and null on every terminal row. Live is the whole contract, which is why every terminal write clears it. A pair's two rows leave at different times, so a pointer surviving on a departed row names an order whose own state has moved on: a client acting on "cancel the pair" would tear down a stop the trader deliberately kept armed. A leg that fires WITHOUT filling leaves its partner live and unlinked (back to null) — that is what lets the survivor be re-paired. Provenance is deliberately not here. Which leg retired this one is [PerpStopOrder.cancelReason](#cancelreason)'s job; overloading one column with "my live partner" and "the leg that retired me" is what would make a client act on the wrong one. *** ### intent > **intent**: [`PerpStopIntent`](PerpStopIntent.md) \| `null` Defined in: packages/sdk/src/perp/stops.ts:191 Whether the triggered order may only REDUCE the owner's position (`"reduceOnly"` — a take-profit / stop-loss) or may open and increase one (`"opening"` — a stop-entry / breakout, gated on initial margin at creation). `null` means the registry reported a member this SDK version does not know, and it is deliberately not folded into `"reduceOnly"`: calling an unknown member reduce-only would promise a caller that an order cannot increase their position when a newer member might let it. Treat null as "upgrade the SDK before acting on this". *** ### cancelReason > **cancelReason**: `string` \| `null` Defined in: packages/sdk/src/perp/stops.ts:213 WHY this stop reached `CANCELLED` — `"Owner"`, `"LinkedFill"` or `"Inert"`. Null on every row that is not cancelled. All three end the same way for the trader — the order is no longer working — but they are three different stories and **two different refunds**, so a UI that renders CANCELLED as "you cancelled this, SOMI refunded to your wallet" is wrong for two of them: - `"Owner"` — the owner cancelled it, and the SOMI is pushed back to them in that same transaction. - `"LinkedFill"` — the protocol retired it because its OCO sibling FILLED. - `"Inert"` — a keeper swept it after the registry's Schedule chain wound down. The last two only CREDIT `unclaimedSomi`; the trader recovers it via `claimSomi()`. A raw string rather than a decoded union, matching `Order.cancelReason`. The vocabulary is the indexer's own — three distinct events, not a contract enum arriving as a uint8 — so there is nothing to decode, and a value this SDK version has not heard of should reach a consumer intact rather than become null. *** ### createdAt > **createdAt**: `string` Defined in: packages/sdk/src/perp/stops.ts:215 Timestamp (unix seconds) the stop was created. *** ### updatedAt > **updatedAt**: `string` Defined in: packages/sdk/src/perp/stops.ts:217 Timestamp (unix seconds) of the last state change. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/stops.ts:219 Tx hash the stop was created in. *** ### market > **market**: [`PerpStopOrderMarket`](PerpStopOrderMarket.md) Defined in: packages/sdk/src/perp/stops.ts:221 The perp market it targets. --- # /docs/typescript/api/index/type-aliases/PerpStopOrderMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpStopOrderMarket # Type Alias: PerpStopOrderMarket > **PerpStopOrderMarket** = `object` Defined in: packages/sdk/src/perp/stops.ts:99 The perp market a stop order targets. ## Properties ### poolAddress > **poolAddress**: `string` Defined in: packages/sdk/src/perp/stops.ts:101 Pool address (lowercased; == the market id for perp). *** ### baseSymbol > **baseSymbol**: `string` \| `null` Defined in: packages/sdk/src/perp/stops.ts:103 Synthetic-base symbol (e.g. "WBTC"); null when the wrapper exposes none. *** ### quoteSymbol > **quoteSymbol**: `string` \| `null` Defined in: packages/sdk/src/perp/stops.ts:105 Collateral token symbol; null when the token exposes none. *** ### baseDecimals > **baseDecimals**: `number` Defined in: packages/sdk/src/perp/stops.ts:107 Base-token decimals — format quantities with this. *** ### quoteDecimals > **quoteDecimals**: `number` Defined in: packages/sdk/src/perp/stops.ts:109 Collateral decimals — format the trigger price with this. --- # /docs/typescript/api/index/type-aliases/PerpStopOrderOnChain [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpStopOrderOnChain # Type Alias: PerpStopOrderOnChain > **PerpStopOrderOnChain** = `object` Defined in: packages/sdk/src/perp/stops.ts:391 One stored perp stop, read straight from the registry. ## Properties ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/perp/stops.ts:393 True = the triggered order buys. *** ### owner > **owner**: `Address` Defined in: packages/sdk/src/perp/stops.ts:395 Owner (checksummed as the contract stores it). *** ### quantity > **quantity**: `bigint` Defined in: packages/sdk/src/perp/stops.ts:397 Raw base units; `0n` means "the whole position at trigger". *** ### triggerPrice > **triggerPrice**: `bigint` Defined in: packages/sdk/src/perp/stops.ts:399 Mark price that arms it. *** ### triggerOperator > **triggerOperator**: `number` Defined in: packages/sdk/src/perp/stops.ts:401 0 = GTE, 1 = LTE. *** ### orderType > **orderType**: `number` Defined in: packages/sdk/src/perp/stops.ts:403 0 = LIMIT, 1 = MARKET. *** ### limitPrice > **limitPrice**: `bigint` Defined in: packages/sdk/src/perp/stops.ts:405 The LIMIT price — the one field the indexer cannot see, since no event carries it. *** ### builder > **builder**: `Address` Defined in: packages/sdk/src/perp/stops.ts:407 Builder tagged on the triggered order; zero address for none. *** ### builderFeeBpsTimes1k > **builderFeeBpsTimes1k**: `bigint` Defined in: packages/sdk/src/perp/stops.ts:409 Builder fee in bps x 1000. *** ### somiPaid > **somiPaid**: `bigint` Defined in: packages/sdk/src/perp/stops.ts:411 SOMI paid at creation. *** ### siblingOrderId > **siblingOrderId**: `bigint` Defined in: packages/sdk/src/perp/stops.ts:413 The linked sibling's id, or `0n` when unlinked. *** ### intent > **intent**: [`PerpStopIntent`](PerpStopIntent.md) \| `null` Defined in: packages/sdk/src/perp/stops.ts:423 `"reduceOnly"` or `"opening"` — `null` if the registry reported an intent this SDK version does not know. Null is deliberately not folded into `"reduceOnly"`. The registry appends to its enums, and calling an unknown member reduce-only would tell a caller an order cannot increase their position when a newer member might let it. Treat null as "upgrade the SDK before acting on this", not as a default. --- # /docs/typescript/api/index/type-aliases/PerpWalletLinkEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PerpWalletLinkEvent # Type Alias: PerpWalletLinkEvent > **PerpWalletLinkEvent** = `object` Defined in: packages/sdk/src/perp/linkedWallet.ts:364 One state change in the linked-wallet consent graph (mirror of the indexer `PerpWalletLinkEvent` entity). Four kinds, and one of them is the only record that exists: - `Proposed` — a main offered a link. **The registry has no getter for a pending proposal**, so this row is the ONLY way a child learns one was made. Without it a pending offer is invisible to everything off-chain. - `ProposalCancelled` — the main withdrew the offer before it was accepted. A client showing an inbox must apply this, or it keeps offering a link that no longer stands. - `Linked` — the child accepted; the group exists from here. - `Unlinked` — either side tore the link down. Consent for the funding rail IS the link plus the allowance, with no separate opt-out flag, so this is the revocation event. **Gotcha.** This is the CONSENT graph, not the money layer. A `Linked` row grants no authority over funds by itself — the rail is dormant until the bank's `getLinkedWalletRegistry()` is non-zero and the main has given an allowance. Ask [client.quotePerpFundingPayer](../interfaces/SomniaMarketsClient.md#quoteperpfundingpayer) whether an order would actually spend a main's wallet; do not infer it from a link. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:366 Row id (`${txHash}_${logIndex}`). *** ### kind > **kind**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:368 `Proposed` | `ProposalCancelled` | `Linked` | `Unlinked`. *** ### main > **main**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:370 The main side of the pair (lowercased) — present on every kind. *** ### child > **child**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:372 The child side of the pair (lowercased) — present on every kind. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:374 Timestamp (unix seconds) of the change. *** ### blockNumber > **blockNumber**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:376 Block the change landed in. *** ### logIndex > **logIndex**: `number` Defined in: packages/sdk/src/perp/linkedWallet.ts:378 Position within the block — needed to order two changes to the same pair in one block. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/perp/linkedWallet.ts:380 Tx hash the change landed in. --- # /docs/typescript/api/index/type-aliases/Portfolio [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / Portfolio # Type Alias: Portfolio > **Portfolio** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:316 A wallet's binary portfolio — the shape [SomniaMarketsClient.getPortfolio](../interfaces/SomniaMarketsClient.md#getportfolio) returns. ## Properties ### account > **account**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:318 The queried account (lowercased). *** ### positions > **positions**: [`PortfolioPosition`](PortfolioPosition.md)[] Defined in: packages/sdk/src/binary/portfolio.ts:320 Non-zero outcome-token positions (up to 200, largest balance first). *** ### openOrders > **openOrders**: [`PortfolioOrder`](PortfolioOrder.md)[] Defined in: packages/sdk/src/binary/portfolio.ts:322 Currently-open binary orders, newest first. *** ### trades > **trades**: [`PortfolioTrade`](PortfolioTrade.md)[] Defined in: packages/sdk/src/binary/portfolio.ts:324 Recent binary fills the account participated in, newest first. *** ### tradesTruncated > **tradesTruncated**: `boolean` Defined in: packages/sdk/src/binary/portfolio.ts:332 The read hit its `tradesLimit`, so fills older than the last entry in `trades` exist and were NOT returned. Raise `tradesLimit` for the rest. A total folded from a truncated `trades` covers part of the history only. False when the page was short, and false for `tradesLimit: 0`, which asks for no trades at all. *** ### tradesSince > **tradesSince**: `number` Defined in: packages/sdk/src/binary/portfolio.ts:338 The lower time bound the trades leg was read with, unix seconds — `since` when passed, otherwise now minus seven days (`DEFAULT_TRADES_SINCE_SEC`). Echoed so a UI can label the list and a caller can page further back. Positions and orders are not windowed. --- # /docs/typescript/api/index/type-aliases/PortfolioFlowEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioFlowEvent # Type Alias: PortfolioFlowEvent > **PortfolioFlowEvent** = [`PortfolioTradeEvent`](../interfaces/PortfolioTradeEvent.md) \| [`PortfolioFundingEvent`](../interfaces/PortfolioFundingEvent.md) Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:102 One portfolio-affecting event, human USD-quote units. --- # /docs/typescript/api/index/type-aliases/PortfolioMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioMarket # Type Alias: PortfolioMarket > **PortfolioMarket** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:57 A market context attached to portfolio rows (subset of [BinaryMarket](BinaryMarket.md)). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:62 The market's bytes32 marketId (== `BinaryMarket.id`). Key positions by this, never by `poolAddress` alone (a pool is recycled across markets). *** ### marketAddress > **marketAddress**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:64 The BinaryMarket clone contract's address (lowercased). *** ### poolAddress > **poolAddress**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:66 The pool serving the market (lowercased; a time-varying binding — see `id`). *** ### asset > **asset**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:68 Underlying asset symbol (e.g. "BTC"). *** ### question > **question**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:70 Display question text. *** ### status > **status**: [`BinaryMarketStatus`](BinaryMarketStatus.md) Defined in: packages/sdk/src/binary/portfolio.ts:72 Lifecycle status (aliased from the indexer's `clobStatus`). *** ### lastPrice > **lastPrice**: `string` \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:74 Last fill price (raw, ≈ YES probability × 10^quoteDecimals); null until first fill. *** ### strike > **strike**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:76 Strike the question resolves against (raw, oracle price scale). *** ### expiry > **expiry**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:78 Timestamp (unix seconds) trading ends. *** ### winningOutcome? > `optional` **winningOutcome?**: `number` \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:80 Winning outcome (0 = YES, 1 = NO); null until Resolved / on a void. *** ### voided > **voided**: `boolean` Defined in: packages/sdk/src/binary/portfolio.ts:87 True once the market voided. A void redeems against [PortfolioMarket.payoutNumerators](#payoutnumerators) — a half per side under the `UNIFORM` void policy, `[p, D−p]` on a `CLOB_SNAPSHOT` void that captured a two-sided close. *** ### payoutNumerators? > `optional` **payoutNumerators?**: `string`[] \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:93 Per-outcome payout numerators the market settled to (decimal strings); what a void actually pays. Null until Resolved / on markets indexed before the vector fields existed. *** ### payoutDenominator? > `optional` **payoutDenominator?**: `string` \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:95 Denominator the numerators are scaled against (decimal string); null with them. *** ### quoteDecimals > **quoteDecimals**: `number` Defined in: packages/sdk/src/binary/portfolio.ts:101 Collateral decimals (per-market — collateral is per-venue, e.g. 6dp TestUSDC vs 18dp USDso). Format prices/balances with this, never a hard-coded 6. Outcome-token amounts mirror the same decimals. *** ### intervalSec > **intervalSec**: `string` \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:103 Series cadence in seconds, as the indexer derived it; null on legacy rows. *** ### interval > **interval**: `string` \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:109 Compact series-cadence label ("15m" / "1h" / "4h" / "24h") — DERIVED by the SDK from [PortfolioMarket.intervalSec](#intervalsec), so a positions/orders row can show the contract duration without re-deriving it. `null` when unknown. --- # /docs/typescript/api/index/type-aliases/PortfolioOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioOptions # Type Alias: PortfolioOptions > **PortfolioOptions** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:354 Paging/window options shared by the portfolio queries ([SomniaMarketsClient.getPortfolio](../interfaces/SomniaMarketsClient.md#getportfolio) / [SomniaMarketsClient.getSpotPortfolio](../interfaces/SomniaMarketsClient.md#getspotportfolio) / [SomniaMarketsClient.getPerpPortfolio](../interfaces/SomniaMarketsClient.md#getperpportfolio)). All optional. ## Properties ### ordersLimit? > `optional` **ordersLimit?**: `number` Defined in: packages/sdk/src/binary/portfolio.ts:362 Max open orders to fetch (default 200). On SPOT this ALSO bounds `pendingStopOrders`: the spot query binds one limit variable to both sets, so a small value here shortens the stop-order list too, not just the open orders you asked about. *** ### tradesLimit? > `optional` **tradesLimit?**: `number` Defined in: packages/sdk/src/binary/portfolio.ts:370 Max recent trades to fetch (default 50). The reads page newest-first, so this cap drops the OLDEST fills. Check `tradesTruncated` on the returned portfolio to see whether it did: the flag is true when `trades.length` reaches this limit. *** ### since? > `optional` **since?**: `number` Defined in: packages/sdk/src/binary/portfolio.ts:376 Only trades at/after this unix-seconds timestamp. Defaults to now minus seven days (`DEFAULT_TRADES_SINCE_SEC`) — see that constant for why a bound is always applied. The bound actually used comes back as `tradesSince`. --- # /docs/typescript/api/index/type-aliases/PortfolioOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioOrder # Type Alias: PortfolioOrder > **PortfolioOrder** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:242 One currently-open order in a wallet's binary portfolio. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:244 Order id (`${pool}_${orderId}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:246 uint128 OrderId as a decimal string (pass to trader.cancelOrder). *** ### side > **side**: [`OpenOrder`](OpenOrder.md)\[`"side"`\] Defined in: packages/sdk/src/binary/portfolio.ts:248 YES/NO classification of the order. *** ### price > **price**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:250 Limit price, raw quote units (YES-probability scale). *** ### quantityRemaining > **quantityRemaining**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:252 Unfilled remainder, raw outcome units. *** ### filledQuantity > **filledQuantity**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:254 Cumulative filled quantity, raw outcome units. *** ### fullQuantity > **fullQuantity**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:256 Original order size, raw outcome units. *** ### placedAtTimestamp > **placedAtTimestamp**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:258 Timestamp (unix seconds) the order was placed. *** ### placedTxHash > **placedTxHash**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:260 Tx hash the order was placed in. *** ### market > **market**: [`PortfolioMarket`](PortfolioMarket.md) Defined in: packages/sdk/src/binary/portfolio.ts:262 The market the order rests on. --- # /docs/typescript/api/index/type-aliases/PortfolioPosition [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioPosition # Type Alias: PortfolioPosition > **PortfolioPosition** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:117 One outcome-token position in a wallet's binary portfolio. ## Properties ### market > **market**: [`PortfolioMarket`](PortfolioMarket.md) Defined in: packages/sdk/src/binary/portfolio.ts:119 The market the position is in. *** ### outcomeIndex > **outcomeIndex**: `number` Defined in: packages/sdk/src/binary/portfolio.ts:121 0 = YES, 1 = NO. *** ### tokenId > **tokenId**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:123 ERC-6909 position id on the outcome-token singleton (decimal string). *** ### balance > **balance**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:125 Raw outcome-token balance. --- # /docs/typescript/api/index/type-aliases/PortfolioTimeframe [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioTimeframe # Type Alias: PortfolioTimeframe > **PortfolioTimeframe** = `"24h"` \| `"7d"` \| `"30d"` \| `"all"` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:43 Time window for the metrics. --- # /docs/typescript/api/index/type-aliases/PortfolioTrade [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PortfolioTrade # Type Alias: PortfolioTrade > **PortfolioTrade** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:270 One recent fill the wallet participated in (binary portfolio view). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:272 Fill id (`${blockNumber}_${logIndex}`). *** ### fillPrice > **fillPrice**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:274 Execution price, raw quote units (YES-probability scale). *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:276 Outcome-token quantity filled, raw units. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:278 Timestamp (unix seconds) of the fill. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:280 Tx hash the fill landed in. *** ### side > **side**: [`OpenOrder`](OpenOrder.md)\[`"side"`\] \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:282 The queried account's side on this fill (maker or taker side), if known. *** ### asMaker > **asMaker**: `boolean` Defined in: packages/sdk/src/binary/portfolio.ts:284 Whether the account was the maker (resting) on this fill. *** ### counterparty > **counterparty**: `string` \| `null` Defined in: packages/sdk/src/binary/portfolio.ts:286 The other party's address, if known. *** ### market > **market**: `object` Defined in: packages/sdk/src/binary/portfolio.ts:288 Minimal market context for rendering the trade row. #### marketAddress > **marketAddress**: `string` The BinaryMarket clone contract's address (lowercased). #### asset > **asset**: `string` Underlying asset symbol (e.g. "BTC"). #### quoteDecimals > **quoteDecimals**: `number` Collateral decimals — format `fillPrice`/`quantity` with this. #### intervalSec > **intervalSec**: `string` \| `null` Series cadence in seconds, as the indexer derived it; null on legacy rows. #### interval > **interval**: `string` \| `null` Human timeframe label — `"15m"` / `"1h"` / `"4h"` / `"24h"` — DERIVED by the SDK from `intervalSec` (falling back to `expiry − tradingStart`) and snapped to its canonical unit. The "which timeframe was the trade for" value. Null when no cadence is determinable. #### tradingStart > **tradingStart**: `string` \| `null` Unix seconds trading opened; null on legacy rows. #### expiry > **expiry**: `string` \| `null` Unix seconds trading ends / the outcome is decided; null on legacy rows. --- # /docs/typescript/api/index/type-aliases/PositionMarkState [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PositionMarkState # Type Alias: PositionMarkState > **PositionMarkState** = `"live"` \| `"won"` \| `"lost"` \| `"voided"` \| `"settling"` Defined in: packages/sdk/src/derivedReads.ts:1258 How a position should be marked, given its market's lifecycle: - `"live"` — still trading; mark to the live book. - `"won"` / `"lost"` — resolved; this outcome pays 1 or 0. - `"voided"` — cancelled; collateral refunds, zero PnL. - `"settling"` — expired but unresolved; no reliable mark exists. --- # /docs/typescript/api/index/type-aliases/PriceCandleResolution [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PriceCandleResolution # Type Alias: PriceCandleResolution > **PriceCandleResolution** = `"M1"` \| `"H1"` \| `"D1"` Defined in: packages/sdk/src/priceFeed/types.ts:33 Candle rollup resolutions the price-feed indexer maintains (60s / 3600s / 86400s). --- # /docs/typescript/api/index/type-aliases/PriceFeedHealth [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PriceFeedHealth # Type Alias: PriceFeedHealth > **PriceFeedHealth** = `"unwatched"` \| `"hydrating"` \| `"hydrated"` \| `"streaming"` \| `"stale"` \| `"error"` Defined in: packages/sdk/src/priceFeed/types.ts:232 Per-asset watch state: `"unwatched"` (no active watch — live reads return null/empty), `"hydrating"` (snapshot/subscribe in progress), `"hydrated"` (snapshot ready), `"streaming"` (both subscriptions delivered valid data), `"stale"` (known delivery loss; last values remain), `"error"` (the server rejected or terminated this asset's subscription). Treat `"error"` as "the data has stopped and will not resume on its own". Reads keep answering with the last values they held, so a view that renders them without checking the status shows a frozen price as a live one. The server sends this for a validation failure (a schema change) or a permission denial, so it will not heal by itself: stop the watch and start a new one. Each rejection is also emitted as a `warn` event on the client's debug channel (see `ClientConfig.debug`) with the server payload. --- # /docs/typescript/api/index/type-aliases/PriceFeedStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PriceFeedStatus # Type Alias: PriceFeedStatus > **PriceFeedStatus** = `"unwatched"` \| `"hydrating"` \| `"live"` \| `"error"` Defined in: packages/sdk/src/priceFeed/types.ts:213 Per-asset watch state: `"unwatched"` (no active watch — live reads return null/empty), `"hydrating"` (snapshot/subscribe in progress), `"live"` (streaming; reads are current to the last pushed tick), `"error"` (the server rejected or terminated this asset's subscription). Treat `"error"` as "the data has stopped and will not resume on its own". Reads keep answering with the last values they held, so a view that renders them without checking the status shows a frozen price as a live one. The server sends this for a validation failure (a schema change) or a permission denial, so it will not heal by itself: stop the watch and start a new one. Each rejection is also emitted as a `warn` event on the client's debug channel (see `ClientConfig.debug`) with the server payload. --- # /docs/typescript/api/index/type-aliases/ProtocolFeeRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ProtocolFeeRecord # Type Alias: ProtocolFeeRecord > **ProtocolFeeRecord** = `object` Defined in: packages/sdk/src/fees.ts:27 A realized protocol-fee record (mirror of the indexer `ProtocolFeeRecord` entity). Amounts are raw collateral units. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/fees.ts:29 Record id (`${blockNumber}_${logIndex}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/fees.ts:31 uint128 OrderId the fee was charged on (decimal string). *** ### recipient > **recipient**: `string` Defined in: packages/sdk/src/fees.ts:33 Fee recipient (lowercased). *** ### payer > **payer**: `string` \| `null` Defined in: packages/sdk/src/fees.ts:38 Order owner who paid the fee (lowercased); null on records indexed before the payer field existed. *** ### token > **token**: `string` Defined in: packages/sdk/src/fees.ts:40 Fee token (lowercased). *** ### amount > **amount**: `string` Defined in: packages/sdk/src/fees.ts:42 Fee charged (raw collateral units). *** ### isTakerSide > **isTakerSide**: `boolean` Defined in: packages/sdk/src/fees.ts:44 true = taker rate (direct fill); false = maker rate (burn-a-pair leg). *** ### market > **market**: `string` \| `null` Defined in: packages/sdk/src/fees.ts:46 Market id the fee's pool belongs to (lowercased); null when unlinked. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/fees.ts:48 Pool the fee was charged on (lowercased). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/fees.ts:50 Timestamp (unix seconds) the fee was charged. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/fees.ts:52 Tx hash the charge landed in. --- # /docs/typescript/api/index/type-aliases/QueryKeyElement [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / QueryKeyElement # Type Alias: QueryKeyElement > **QueryKeyElement** = `string` \| `number` \| `boolean` \| `null` \| `Readonly`\<`Record`\<`string`, `string` \| `number` \| `boolean`\>\> Defined in: packages/sdk/src/queryKeys.ts:40 One element of a [ClientQueryKey](ClientQueryKey.md) — JSON-serializable by construction. --- # /docs/typescript/api/index/type-aliases/QuoteDenomination [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / QuoteDenomination # Type Alias: QuoteDenomination > **QuoteDenomination** = `"base"` \| `"quote"` Defined in: packages/sdk/src/unified/quotes.ts:26 Which unit an order size is expressed in. --- # /docs/typescript/api/index/type-aliases/RawGridDirection [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RawGridDirection # Type Alias: RawGridDirection > **RawGridDirection** = `"down"` \| `"up"` Defined in: packages/sdk/src/units.ts:617 Which way [snapRawToGrid](../functions/snapRawToGrid.md) moves a value that is off the grid. --- # /docs/typescript/api/index/type-aliases/RouterActionKind [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RouterActionKind # Type Alias: RouterActionKind > **RouterActionKind** = `"Redeem"` \| `"MintCompleteSet"` \| `"MergeCompleteSet"` Defined in: packages/sdk/src/router.ts:27 Kinds of `RouterMinter` action the indexer records (mirror of the indexer RouterActionRecord.kind enum). --- # /docs/typescript/api/index/type-aliases/RouterActionRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RouterActionRecord # Type Alias: RouterActionRecord > **RouterActionRecord** = `object` Defined in: packages/sdk/src/router.ts:35 One RouterMinter action for an account (mirror of the indexer `RouterActionRecord` entity). Amounts are raw collateral/outcome units. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/router.ts:37 Record id (`${blockNumber}_${logIndex}`). *** ### kind > **kind**: [`RouterActionKind`](RouterActionKind.md) Defined in: packages/sdk/src/router.ts:39 Redeem | MintCompleteSet | MergeCompleteSet. *** ### account > **account**: `string` Defined in: packages/sdk/src/router.ts:41 Acting wallet (lowercased). *** ### market > **market**: `string` \| `null` Defined in: packages/sdk/src/router.ts:43 Binary market id the action targeted (lowercased bytes32); null if unlinked. *** ### amount > **amount**: `string` Defined in: packages/sdk/src/router.ts:48 Redeem: winning tokens burned; Mint/Merge: amount of EACH outcome minted / merged (a complete set). Raw outcome-token units. *** ### payout > **payout**: `string` \| `null` Defined in: packages/sdk/src/router.ts:50 Collateral paid out (Redeem); null on Mint/Merge. Raw units. *** ### routedVia > **routedVia**: `string` \| `null` Defined in: packages/sdk/src/router.ts:55 Periphery entry the flow routed through (NativeMint | Permit2Mint | NativeRedeem); null on a direct module call. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/router.ts:57 Timestamp (unix seconds) of the action. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/router.ts:59 Tx hash the action landed in. --- # /docs/typescript/api/index/type-aliases/RouterActionsOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RouterActionsOptions # Type Alias: RouterActionsOptions > **RouterActionsOptions** = `object` Defined in: packages/sdk/src/router.ts:82 Options for [SomniaMarketsClient.getRouterActions](../interfaces/SomniaMarketsClient.md#getrouteractions). All optional. ## Properties ### market? > `optional` **market?**: `string` Defined in: packages/sdk/src/router.ts:84 Only actions in this market (bytes32 marketId, case-insensitive). *** ### markets? > `optional` **markets?**: readonly `string`[] Defined in: packages/sdk/src/router.ts:89 Only actions in ANY of these markets — the batched form of `market`. Supplying both narrows to the intersection. An empty array matches nothing. *** ### kind? > `optional` **kind?**: [`RouterActionKind`](RouterActionKind.md) Defined in: packages/sdk/src/router.ts:91 Only this action kind. *** ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/router.ts:93 Max rows (default 50). *** ### offset? > `optional` **offset?**: `number` Defined in: packages/sdk/src/router.ts:95 Row offset (default 0). --- # /docs/typescript/api/index/type-aliases/SettlementFeeRecord [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SettlementFeeRecord # Type Alias: SettlementFeeRecord > **SettlementFeeRecord** = `object` Defined in: packages/sdk/src/fees.ts:91 A realized settlement-fee record (mirror of the indexer `SettlementFeeRecord` entity) — the fee skimmed from a winning payout at redeem. Amounts are raw collateral units. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/fees.ts:93 Record id (`${blockNumber}_${logIndex}`). *** ### recipient > **recipient**: `string` Defined in: packages/sdk/src/fees.ts:95 Fee recipient (lowercased). *** ### amount > **amount**: `string` Defined in: packages/sdk/src/fees.ts:97 Settlement fee skimmed from the winning backing (raw). *** ### winningBacking > **winningBacking**: `string` Defined in: packages/sdk/src/fees.ts:99 Winning backing at charge time, before the fee (raw). *** ### market > **market**: `string` \| `null` Defined in: packages/sdk/src/fees.ts:101 Market id the settlement fee belongs to (lowercased); null when unlinked. *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/fees.ts:103 Timestamp (unix seconds) the fee was charged (at finalize). *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/fees.ts:105 Tx hash the charge landed in. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientCreateObservedReadsError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientCreateObservedReadsError # Type Alias: SomniaMarketsClientCreateObservedReadsError > **SomniaMarketsClientCreateObservedReadsError** = [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) Defined in: packages/sdk/src/observedReads.ts:149 Creating the capability observes the owner's head once. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetBinaryOrderBookError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetBinaryOrderBookError # Type Alias: SomniaMarketsClientGetBinaryOrderBookError > **SomniaMarketsClientGetBinaryOrderBookError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:3013 Failures from a native binary chain book read. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetClaimableError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetClaimableError # Type Alias: SomniaMarketsClientGetClaimableError > **SomniaMarketsClientGetClaimableError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`IndexerError`](../classes/IndexerError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:207 Failures from [SomniaMarketsClient.getClaimable](../interfaces/SomniaMarketsClient.md#getclaimable). --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetIndexerFreshnessError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetIndexerFreshnessError # Type Alias: SomniaMarketsClientGetIndexerFreshnessError > **SomniaMarketsClientGetIndexerFreshnessError** = [`IndexerError`](../classes/IndexerError.md) \| [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) Defined in: packages/sdk/src/observedReads.ts:151 Independent sync reads can reject validation, configuration or either service. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetLiquidationsError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetLiquidationsError # ~~Type Alias: SomniaMarketsClientGetLiquidationsError~~ > **SomniaMarketsClientGetLiquidationsError** = [`SomniaMarketsClientListLiquidationsError`](SomniaMarketsClientListLiquidationsError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:221 Failures from [SomniaMarketsClient.getLiquidations](../interfaces/SomniaMarketsClient.md#getliquidations), the deprecated alias — the same union, because it forwards verbatim. ## Deprecated Use [SomniaMarketsClientListLiquidationsError](SomniaMarketsClientListLiquidationsError.md). --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetOpenPositionsWithPnLError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetOpenPositionsWithPnLError # Type Alias: SomniaMarketsClientGetOpenPositionsWithPnLError > **SomniaMarketsClientGetOpenPositionsWithPnLError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`IndexerError`](../classes/IndexerError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:204 Failures from [SomniaMarketsClient.getOpenPositionsWithPnL](../interfaces/SomniaMarketsClient.md#getopenpositionswithpnl). --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetOrderOnchainError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetOrderOnchainError # Type Alias: SomniaMarketsClientGetOrderOnchainError > **SomniaMarketsClientGetOrderOnchainError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:3025 Failures from one on-chain order read, at head or pinned. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetPerpFeedStatusError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetPerpFeedStatusError # Type Alias: SomniaMarketsClientGetPerpFeedStatusError > **SomniaMarketsClientGetPerpFeedStatusError** = [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:242 Failures from [SomniaMarketsClient.getPerpFeedStatus](../interfaces/SomniaMarketsClient.md#getperpfeedstatus). Three chain reads under one block pin, and no input validation, so the chain is most of it: transport (the pin included — it is normalized at the read boundary like the calls below it) or a revert from the pool. The INDEX leg is the exception that never reaches a caller: its revert is swallowed on purpose, because a dead oracle is what this read reports rather than fails on. `NotConfiguredError` is reachable BEFORE any of that. `wsRpcUrl` is validly optional, and `createClient` defers the check to the first chain touch — which this read performs when it resolves the client for its block pin. A config with no WebSocket endpoint is supported right up until a chain read is attempted, so the union has to carry it. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetSpotOrderBookError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetSpotOrderBookError # Type Alias: SomniaMarketsClientGetSpotOrderBookError > **SomniaMarketsClientGetSpotOrderBookError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:3019 Failures from a native spot/perp chain book read. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetSyncStatusError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetSyncStatusError # Type Alias: SomniaMarketsClientGetSyncStatusError > **SomniaMarketsClientGetSyncStatusError** = [`IndexerError`](../classes/IndexerError.md) \| [`InvalidInputError`](../classes/InvalidInputError.md) Defined in: packages/sdk/src/observedReads.ts:157 Metadata-only reads need no chain transport. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientGetUserFillsPageError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientGetUserFillsPageError # Type Alias: SomniaMarketsClientGetUserFillsPageError > **SomniaMarketsClientGetUserFillsPageError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`IndexerError`](../classes/IndexerError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:210 Failures from bounded historical fill reads and cursor validation. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientListLiquidationsError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientListLiquidationsError # Type Alias: SomniaMarketsClientListLiquidationsError > **SomniaMarketsClientListLiquidationsError** = [`IndexerError`](../classes/IndexerError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:215 Failures from [SomniaMarketsClient.listLiquidations](../interfaces/SomniaMarketsClient.md#listliquidations). One indexed read, no chain call and no input validation, so the indexer is the only thing that can fail. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsClientListRegistryMarketsCheckedError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsClientListRegistryMarketsCheckedError # Type Alias: SomniaMarketsClientListRegistryMarketsCheckedError > **SomniaMarketsClientListRegistryMarketsCheckedError** = [`IndexerError`](../classes/IndexerError.md) Defined in: packages/sdk/src/somniaMarketsClient.ts:227 Failures from [SomniaMarketsClient.listRegistryMarketsChecked](../interfaces/SomniaMarketsClient.md#listregistrymarketschecked). One indexed read, paged, with no chain call and no input validation — so the indexer is the only thing that can fail. A row the SDK cannot parse is NOT a failure: it is counted in `dropped` and the read succeeds. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsConfig [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsConfig # Type Alias: SomniaMarketsConfig > **SomniaMarketsConfig** = [`ClientConfig`](../interfaces/ClientConfig.md) & `Pick`\<[`TraderConfig`](../interfaces/TraderConfig.md), `"privateKey"` \| `"account"` \| `"walletClient"`\> Defined in: packages/sdk/src/unified/exchange.ts:82 Config for [SomniaMarkets](../classes/SomniaMarkets.md): the native client config plus (optionally) a signer — authenticated methods throw without one. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsConstructorError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsConstructorError # Type Alias: SomniaMarketsConstructorError > **SomniaMarketsConstructorError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) Defined in: packages/sdk/src/unified/exchange.ts:95 Failures from validating owner configuration. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsFetchDataStatusError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsFetchDataStatusError # Type Alias: SomniaMarketsFetchDataStatusError > **SomniaMarketsFetchDataStatusError** = [`SomniaMarketsClientGetIndexerFreshnessError`](SomniaMarketsClientGetIndexerFreshnessError.md) Defined in: packages/sdk/src/unified/exchange.ts:22 Status observes RPC and indexer once; either service can reject. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsFetchMyTradesError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsFetchMyTradesError # Type Alias: SomniaMarketsFetchMyTradesError > **SomniaMarketsFetchMyTradesError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`IndexerError`](../classes/IndexerError.md) \| [`SignerRequiredError`](../classes/SignerRequiredError.md) Defined in: packages/sdk/src/unified/exchange.ts:100 Historical account trade read failures. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsFetchOrderBookError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsFetchOrderBookError # Type Alias: SomniaMarketsFetchOrderBookError > **SomniaMarketsFetchOrderBookError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/unified/exchange.ts:93 Failures from selecting a tradable or reading its pinned book. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsFetchTradesError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsFetchTradesError # Type Alias: SomniaMarketsFetchTradesError > **SomniaMarketsFetchTradesError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`IndexerError`](../classes/IndexerError.md) Defined in: packages/sdk/src/unified/exchange.ts:98 Historical public trade read failures. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsGetOrderHistoryPageError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsGetOrderHistoryPageError # Type Alias: SomniaMarketsGetOrderHistoryPageError > **SomniaMarketsGetOrderHistoryPageError** = [`SomniaMarketsGetOrdersPageError`](SomniaMarketsGetOrdersPageError.md) Defined in: packages/sdk/src/unified/exchange.ts:172 Failures from [SomniaMarkets.getOrderHistoryPage](../classes/SomniaMarkets.md#getorderhistorypage). --- # /docs/typescript/api/index/type-aliases/SomniaMarketsGetOrderHistoryPageOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsGetOrderHistoryPageOptions # Type Alias: SomniaMarketsGetOrderHistoryPageOptions > **SomniaMarketsGetOrderHistoryPageOptions** = [`SomniaMarketsGetOrdersPageOptions`](SomniaMarketsGetOrdersPageOptions.md) Defined in: packages/sdk/src/unified/exchange.ts:131 Filters and pagination for [SomniaMarkets.getOrderHistoryPage](../classes/SomniaMarkets.md#getorderhistorypage). --- # /docs/typescript/api/index/type-aliases/SomniaMarketsGetOrdersPageError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsGetOrdersPageError # Type Alias: SomniaMarketsGetOrdersPageError > **SomniaMarketsGetOrdersPageError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`SignerRequiredError`](../classes/SignerRequiredError.md) \| [`IndexerError`](../classes/IndexerError.md) Defined in: packages/sdk/src/unified/exchange.ts:170 Failures from [SomniaMarkets.getOrdersPage](../classes/SomniaMarkets.md#getorderspage). --- # /docs/typescript/api/index/type-aliases/SomniaMarketsGetOrdersPageOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsGetOrdersPageOptions # Type Alias: SomniaMarketsGetOrdersPageOptions > **SomniaMarketsGetOrdersPageOptions** = `object` Defined in: packages/sdk/src/unified/exchange.ts:119 Filters and pagination for [SomniaMarkets.getOrdersPage](../classes/SomniaMarkets.md#getorderspage). ## Properties ### ref? > `optional` **ref?**: `string` Defined in: packages/sdk/src/unified/exchange.ts:121 Restrict the page to one tradable. Omit it for account-wide raw orders. *** ### status? > `optional` **status?**: [`OrderStatus`](OrderStatus.md) Defined in: packages/sdk/src/unified/exchange.ts:123 Restrict the indexer read to one native order lifecycle status. *** ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/unified/exchange.ts:125 Maximum raw rows to read. The default is 100. *** ### offset? > `optional` **offset?**: `number` Defined in: packages/sdk/src/unified/exchange.ts:127 Raw indexer row offset. The default is 0. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsRedeemError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsRedeemError # Type Alias: SomniaMarketsRedeemError > **SomniaMarketsRedeemError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`SignerRequiredError`](../classes/SignerRequiredError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/unified/exchange.ts:216 Failures from [SomniaMarkets.redeem](../classes/SomniaMarkets.md#redeem). --- # /docs/typescript/api/index/type-aliases/SomniaMarketsWatchMyTradesError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsWatchMyTradesError # Type Alias: SomniaMarketsWatchMyTradesError > **SomniaMarketsWatchMyTradesError** = [`SomniaMarketsWatchTradesError`](SomniaMarketsWatchTradesError.md) \| [`SignerRequiredError`](../classes/SignerRequiredError.md) Defined in: packages/sdk/src/unified/exchange.ts:109 Account trade watch initialization and mapping failures. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsWatchOrderBookError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsWatchOrderBookError # Type Alias: SomniaMarketsWatchOrderBookError > **SomniaMarketsWatchOrderBookError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`IndexerError`](../classes/IndexerError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/unified/exchange.ts:111 Live book watch initialization failures. --- # /docs/typescript/api/index/type-aliases/SomniaMarketsWatchTradesError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SomniaMarketsWatchTradesError # Type Alias: SomniaMarketsWatchTradesError > **SomniaMarketsWatchTradesError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`NotConfiguredError`](../classes/NotConfiguredError.md) \| [`IndexerError`](../classes/IndexerError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/unified/exchange.ts:102 Live trade watch initialization and mapping failures. --- # /docs/typescript/api/index/type-aliases/SpotMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotMarket # Type Alias: SpotMarket > **SpotMarket** = [`BaseMarket`](BaseMarket.md) & `object` Defined in: packages/sdk/src/markets.ts:99 A spot (base/quote) order-book market. ## Type Declaration ### marketType > **marketType**: `"SPOT"` Discriminator (narrowed). ### baseToken > **baseToken**: `Address` Base ERC-20 address (lowercased). ### quoteToken > **quoteToken**: `Address` Quote ERC-20 address (lowercased). ### baseSymbol > **baseSymbol**: `string` \| `null` Base token symbol (e.g. "SOMI"); null when the token exposes none. ### quoteSymbol > **quoteSymbol**: `string` \| `null` Quote token symbol (e.g. "USDso"); null when the token exposes none. ### baseIsNative > **baseIsNative**: `boolean` True when the base is the chain's native token (wrapped for the book). ### tickSize > **tickSize**: `string` Price increment, raw quote units per whole base (decimal string). ### lotSize > **lotSize**: `string` Quantity increment, raw base units (decimal string). ### minQuantity > **minQuantity**: `string` Minimum order quantity, raw base units (decimal string). ### markPrice > **markPrice**: `string` \| `null` EMA-smoothed mark price (raw quote per whole base); null until first set. ### rawMidpoint > **rawMidpoint**: `string` \| `null` Unsmoothed book midpoint feeding the mark-price EMA; null until first set. ### markPriceUpdatedAt > **markPriceUpdatedAt**: `string` \| `null` Timestamp (unix seconds) the mark price last advanced; null until first set. ### stopRegistry > **stopRegistry**: `Address` \| `null` Per-pool SpotStopOrderRegistry (lowercased); null on pools without one. --- # /docs/typescript/api/index/type-aliases/SpotMarketFilter [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotMarketFilter # Type Alias: SpotMarketFilter > **SpotMarketFilter** = `object` Defined in: packages/sdk/src/markets.ts:1175 Filters for [SomniaMarketsClient.listSpotMarkets](../interfaces/SomniaMarketsClient.md#listspotmarkets). All optional; applied server-side. ## Properties ### baseSymbol? > `optional` **baseSymbol?**: `string` Defined in: packages/sdk/src/markets.ts:1177 Base token symbol, e.g. `"SOMI"` | `"WBTC"`. *** ### quoteSymbol? > `optional` **quoteSymbol?**: `string` Defined in: packages/sdk/src/markets.ts:1179 Quote token symbol, e.g. `"USDso"`. --- # /docs/typescript/api/index/type-aliases/SpotPortfolio [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotPortfolio # Type Alias: SpotPortfolio > **SpotPortfolio** = `object` Defined in: packages/sdk/src/spot/portfolio.ts:117 A wallet's spot portfolio — the shape [SomniaMarketsClient.getSpotPortfolio](../interfaces/SomniaMarketsClient.md#getspotportfolio) returns. ## Properties ### account > **account**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:119 The queried account (lowercased). *** ### openOrders > **openOrders**: [`SpotPortfolioOrder`](SpotPortfolioOrder.md)[] Defined in: packages/sdk/src/spot/portfolio.ts:121 Currently-open spot orders, newest first. *** ### stopOrders > **stopOrders**: [`SpotStopOrder`](SpotStopOrder.md)[] Defined in: packages/sdk/src/spot/portfolio.ts:123 Currently-PENDING stop orders across the wallet's spot markets. *** ### trades > **trades**: [`SpotPortfolioTrade`](SpotPortfolioTrade.md)[] Defined in: packages/sdk/src/spot/portfolio.ts:125 Recent spot fills the account participated in, newest first. *** ### tradesTruncated > **tradesTruncated**: `boolean` Defined in: packages/sdk/src/spot/portfolio.ts:133 The read hit its `tradesLimit`, so fills older than the last entry in `trades` exist and were NOT returned. Raise `tradesLimit` for the rest. A total folded from a truncated `trades` covers part of the history only. False when the page was short, and false for `tradesLimit: 0`, which asks for no trades at all. *** ### tradesSince > **tradesSince**: `number` Defined in: packages/sdk/src/spot/portfolio.ts:139 The lower time bound the trades leg was read with, unix seconds — `since` when passed, otherwise now minus seven days (`DEFAULT_TRADES_SINCE_SEC`). Echoed so a UI can label the list and a caller can page further back. Orders are not windowed. --- # /docs/typescript/api/index/type-aliases/SpotPortfolioMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotPortfolioMarket # Type Alias: SpotPortfolioMarket > **SpotPortfolioMarket** = `object` Defined in: packages/sdk/src/spot/portfolio.ts:25 Spot market context attached to spot portfolio rows. id == poolAddress. ## Properties ### poolAddress > **poolAddress**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:27 Pool address (lowercased; == the market id for spot). *** ### baseSymbol > **baseSymbol**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:29 Base token symbol; null when the token exposes none. *** ### quoteSymbol > **quoteSymbol**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:31 Quote token symbol; null when the token exposes none. *** ### baseToken > **baseToken**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:33 Base ERC-20 address (lowercased). *** ### quoteToken > **quoteToken**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:35 Quote ERC-20 address (lowercased). *** ### baseDecimals > **baseDecimals**: `number` Defined in: packages/sdk/src/spot/portfolio.ts:37 Base-token decimals — format base quantities with this. *** ### quoteDecimals > **quoteDecimals**: `number` Defined in: packages/sdk/src/spot/portfolio.ts:39 Quote-token decimals — format prices/quote amounts with this. *** ### baseIsNative > **baseIsNative**: `boolean` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:41 True when the base is the chain's native token. *** ### tickSize > **tickSize**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:43 Price increment, raw quote units per whole base (decimal string). *** ### lotSize > **lotSize**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:45 Quantity increment, raw base units (decimal string). *** ### minQuantity > **minQuantity**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:47 Minimum order quantity, raw base units (decimal string). *** ### lastPrice > **lastPrice**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:49 Last fill price (raw quote per whole base); null until first fill. *** ### markPrice > **markPrice**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:51 EMA-smoothed mark price (raw quote per whole base); null until first set. *** ### stopRegistry > **stopRegistry**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:53 Per-pool SpotStopOrderRegistry address (lowercased); null if the pool has none. --- # /docs/typescript/api/index/type-aliases/SpotPortfolioOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotPortfolioOrder # Type Alias: SpotPortfolioOrder > **SpotPortfolioOrder** = `object` Defined in: packages/sdk/src/spot/portfolio.ts:61 One currently-open order in a wallet's spot portfolio. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:63 Order id (`${pool}_${orderId}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:65 uint128 OrderId as a decimal string (pass to trader.cancelOrder). *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/spot/portfolio.ts:67 True = bid (buy base), false = ask (sell base). *** ### price > **price**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:69 Limit price, raw quote units per whole base. *** ### quantityRemaining > **quantityRemaining**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:71 Unfilled remainder, raw base units. *** ### filledQuantity > **filledQuantity**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:73 Cumulative filled quantity, raw base units. *** ### fullQuantity > **fullQuantity**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:75 Original order size, raw base units. *** ### placedAtTimestamp > **placedAtTimestamp**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:77 Timestamp (unix seconds) the order was placed. *** ### placedTxHash > **placedTxHash**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:79 Tx hash the order was placed in. *** ### market > **market**: [`SpotPortfolioMarket`](SpotPortfolioMarket.md) Defined in: packages/sdk/src/spot/portfolio.ts:81 The market the order rests on. --- # /docs/typescript/api/index/type-aliases/SpotPortfolioTrade [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotPortfolioTrade # Type Alias: SpotPortfolioTrade > **SpotPortfolioTrade** = `object` Defined in: packages/sdk/src/spot/portfolio.ts:89 One recent fill the wallet participated in (spot portfolio view). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:91 Fill id (`${blockNumber}_${logIndex}`). *** ### fillPrice > **fillPrice**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:93 Execution price, raw quote units per whole base. *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:95 Base quantity filled, raw units. *** ### quoteQuantity > **quoteQuantity**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:97 Quote value of the fill (raw, floored). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:99 Timestamp (unix seconds) of the fill. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/spot/portfolio.ts:101 Tx hash the fill landed in. *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/spot/portfolio.ts:103 Whether the account bought the base asset on this fill. *** ### asMaker > **asMaker**: `boolean` Defined in: packages/sdk/src/spot/portfolio.ts:105 Whether the account was the maker (resting) on this fill. *** ### counterparty > **counterparty**: `string` \| `null` Defined in: packages/sdk/src/spot/portfolio.ts:107 The other party's address, if known. *** ### market > **market**: [`SpotPortfolioMarket`](SpotPortfolioMarket.md) Defined in: packages/sdk/src/spot/portfolio.ts:109 The market the fill happened on. --- # /docs/typescript/api/index/type-aliases/SpotStopOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SpotStopOrder # Type Alias: SpotStopOrder > **SpotStopOrder** = `object` Defined in: packages/sdk/src/spot/stops.ts:23 A pending/historical spot stop order (mirror of the indexer StopOrder entity). ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/spot/stops.ts:25 StopOrder id (`${registry}_${orderId}`). *** ### registry > **registry**: `string` Defined in: packages/sdk/src/spot/stops.ts:27 SpotStopOrderRegistry the order lives on (lowercased). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/spot/stops.ts:29 uint128 pending-order id as a decimal string (pass to trader.cancelStopOrder). *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/spot/stops.ts:31 True = buy base (pay quote), false = sell base. *** ### quantity > **quantity**: `string` Defined in: packages/sdk/src/spot/stops.ts:33 Base quantity, raw units. *** ### triggerPrice > **triggerPrice**: `string` Defined in: packages/sdk/src/spot/stops.ts:35 Mark price that arms the trigger (raw quote per whole base). *** ### triggerOperator > **triggerOperator**: `number` Defined in: packages/sdk/src/spot/stops.ts:37 0 = GTE (trigger when mark ≥ trigger), 1 = LTE (mark ≤ trigger). *** ### orderType > **orderType**: `number` Defined in: packages/sdk/src/spot/stops.ts:39 0 = LIMIT, 1 = MARKET. *** ### status > **status**: [`StopOrderStatus`](StopOrderStatus.md) Defined in: packages/sdk/src/spot/stops.ts:41 Lifecycle status — see [StopOrderStatus](StopOrderStatus.md). *** ### placedOrderId > **placedOrderId**: `string` \| `null` Defined in: packages/sdk/src/spot/stops.ts:43 Resulting spot order id once successfully triggered, else null. *** ### createdAt > **createdAt**: `string` Defined in: packages/sdk/src/spot/stops.ts:45 Timestamp (unix seconds) the stop order was created. *** ### market > **market**: [`SpotPortfolioMarket`](SpotPortfolioMarket.md) Defined in: packages/sdk/src/spot/stops.ts:47 The spot market the stop order targets. --- # /docs/typescript/api/index/type-aliases/StopOrderStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / StopOrderStatus # Type Alias: StopOrderStatus > **StopOrderStatus** = `"PENDING"` \| `"TRIGGERED"` \| `"TRIGGER_FAILED"` \| `"CANCELLED"` Defined in: packages/sdk/src/spot/stops.ts:16 Spot stop-order lifecycle (mirror of the indexer StopOrderStatus enum). --- # /docs/typescript/api/index/type-aliases/SweepableOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SweepableOrder # Type Alias: SweepableOrder > **SweepableOrder** = `object` Defined in: packages/sdk/src/orders.ts:907 A resting order that is PAST ITS EXPIRY but has not been cleaned off the book — the target of a permissionless sweep. Carries exactly what the two sweep verbs need: `orderId` for [SomniaMarketsClient.createTrader](../interfaces/SomniaMarketsClient.md#createtrader)'s `cancelExpiredOrders`, and `isBid` + `price` for `sweepExpiredAtLevel`. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/orders.ts:909 Row id (`${pool}_${orderId}`). *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/orders.ts:911 uint128 OrderId as a decimal string — pass to `cancelExpiredOrders`. *** ### market > **market**: `string` Defined in: packages/sdk/src/orders.ts:920 The market's bytes32 marketId — the market this order rests on, stably. A sweepable order is by definition still RESTING, and a pool's book is emptied before the pool is recycled, so this read cannot be mislabelled the way order HISTORY can. It is carried anyway so all three order reads name a market the same way. *** ### marketInfo > **marketInfo**: [`OrderMarket`](OrderMarket.md) \| `null` Defined in: packages/sdk/src/orders.ts:922 The market's labelling context. Null only if the indexer has no market row. *** ### pool > **pool**: `string` Defined in: packages/sdk/src/orders.ts:924 The pool the order rests on (lowercased). A time-varying binding — see `market`. *** ### marketType > **marketType**: [`MarketType`](MarketType.md) Defined in: packages/sdk/src/orders.ts:926 Which market kind the pool is — sweeping works the same on all of them. *** ### owner > **owner**: `string` Defined in: packages/sdk/src/orders.ts:928 The order's owner (lowercased). *** ### isBid > **isBid**: `boolean` Defined in: packages/sdk/src/orders.ts:930 True = bid side, false = ask — pass to `sweepExpiredAtLevel`. *** ### price > **price**: `string` Defined in: packages/sdk/src/orders.ts:932 The exact price level, raw pool units — pass to `sweepExpiredAtLevel`. *** ### quantityRemaining > **quantityRemaining**: `string` Defined in: packages/sdk/src/orders.ts:934 Unfilled remainder that would be released, raw base/outcome units. *** ### expireTimestampNs > **expireTimestampNs**: `string` Defined in: packages/sdk/src/orders.ts:936 Expiry as a uint64 NANOsecond timestamp (decimal string). *** ### placedAtTimestamp > **placedAtTimestamp**: `string` Defined in: packages/sdk/src/orders.ts:938 Timestamp (unix seconds) the order was placed. --- # /docs/typescript/api/index/type-aliases/TailMode [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TailMode # Type Alias: TailMode > **TailMode** = `"init"` \| `"tailing"` Defined in: packages/sdk/src/store.ts:27 Data-source mode of the live tail: `"init"` until the first watch has hydrated, `"tailing"` once the store is fed by the chain event stream. --- # /docs/typescript/api/index/type-aliases/TerminalOrderStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TerminalOrderStatus # Type Alias: TerminalOrderStatus > **TerminalOrderStatus** = `Exclude`\<[`OrderStatus`](OrderStatus.md), `"Open"`\> Defined in: packages/sdk/src/perp/portfolio.ts:275 An order status that means the order has stopped working. `OrderStatus` minus `"Open"`, so a history read cannot be asked for working orders in the first place — the guard is the type, not a comment. --- # /docs/typescript/api/index/type-aliases/TradeContext [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TradeContext # Type Alias: TradeContext > **TradeContext** = `object` Defined in: packages/sdk/src/fills.ts:528 Everything the indexer knows about ONE fill: the trade itself, the market it executed in, both sides' orders, the fees it paid, and the other fills its transaction produced. The shape of a trade detail view. Each piece may be absent on its own terms — see the field docs — and absence is normal rather than an error. Distinct from [FillDetail](FillDetail.md), which is the one-query lookup behind [SomniaMarketsClient.getFill](../interfaces/SomniaMarketsClient.md#getfill): that names the fill and its market, this adds the surrounding CONTEXT — both orders resolved, the fees, the rest of the transaction — at the cost of a second round-trip. A caller that only needs to render the trade wants `getFill`. ## Properties ### fill > **fill**: [`OrderFillRow`](OrderFillRow.md) Defined in: packages/sdk/src/fills.ts:530 The fill, with its block position and post-fill remainders. *** ### market > **market**: [`Market`](Market.md) \| `null` Defined in: packages/sdk/src/fills.ts:535 The market the fill executed in; null only when the indexer has no market row for it (an unregistered pool). *** ### makerOrder > **makerOrder**: [`FillOrder`](FillOrder.md) \| `null` Defined in: packages/sdk/src/fills.ts:540 The resting order that was filled; null until the indexer has that order's row. *** ### takerOrder > **takerOrder**: [`FillOrder`](FillOrder.md) \| `null` Defined in: packages/sdk/src/fills.ts:542 The aggressing order that crossed the book; null until its row is indexed. *** ### siblings > **siblings**: [`OrderFillRow`](OrderFillRow.md)[] Defined in: packages/sdk/src/fills.ts:547 The OTHER fills of the same transaction, newest first — the rest of a taker's sweep. Empty when this fill was the whole trade. Excludes this fill. *** ### protocolFees > **protocolFees**: [`ProtocolFeeRecord`](ProtocolFeeRecord.md)[] Defined in: packages/sdk/src/fills.ts:557 Protocol fees charged in the same transaction. BINARY only, and empty when no fee was skimmed. Transaction-scoped, not fill-scoped: a fee record names the ORDER it was charged on, not the fill, so a multi-fill sweep cannot be split into per-fill fees. Match `orderId` against the fill's `makerOrder`/`takerOrder` to attribute what can be attributed. *** ### builderFees > **builderFees**: [`BuilderFeeRecord`](BuilderFeeRecord.md)[] Defined in: packages/sdk/src/fills.ts:559 Builder fees charged in the same transaction, on the same terms as [TradeContext.protocolFees](#protocolfees). --- # /docs/typescript/api/index/type-aliases/TraderBuildPlaceSpotOrderError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TraderBuildPlaceSpotOrderError # Type Alias: TraderBuildPlaceSpotOrderError > **TraderBuildPlaceSpotOrderError** = [`InvalidInputError`](../classes/InvalidInputError.md) \| [`RpcError`](../classes/RpcError.md) \| [`ContractRevertError`](../classes/ContractRevertError.md) Defined in: packages/sdk/src/trade.ts:2110 Failures from [Trader.buildPlaceSpotOrder](../interfaces/Trader.md#buildplacespotorder). --- # /docs/typescript/api/index/type-aliases/TransactionActivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TransactionActivity # Type Alias: TransactionActivity > **TransactionActivity** = `object` Defined in: packages/sdk/src/activity.ts:354 Everything the protocol did in ONE transaction. The transaction-scoped counterpart of [SomniaMarketsClient.getMarketActivity](../interfaces/SomniaMarketsClient.md#getmarketactivity): same event union, same row ids, but selected by transaction rather than by market. A transaction that touched nothing the indexer follows comes back with empty collections and a null `blockNumber` — that is "not a protocol transaction", not a failure. ## Properties ### txHash > **txHash**: `string` Defined in: packages/sdk/src/activity.ts:356 The transaction hash, LOWER-CASED — not necessarily as the caller spelled it. *** ### blockNumber > **blockNumber**: `string` \| `null` Defined in: packages/sdk/src/activity.ts:362 Block the transaction landed in; null when the indexer has nothing for this hash. Read off the events, so it is the indexer's view of the block rather than the chain's. *** ### timestamp > **timestamp**: `string` \| `null` Defined in: packages/sdk/src/activity.ts:364 Block timestamp (unix seconds); null on the same terms as `blockNumber`. *** ### events > **events**: [`MarketActivity`](MarketActivity.md)[] Defined in: packages/sdk/src/activity.ts:370 What the transaction did, in LOG ORDER — earliest first, the order the chain executed it in. The opposite of [SomniaMarketsClient.getMarketActivity](../interfaces/SomniaMarketsClient.md#getmarketactivity), which is a feed and reads newest-first. *** ### ordersPlaced > **ordersPlaced**: [`TransactionOrder`](TransactionOrder.md)[] Defined in: packages/sdk/src/activity.ts:376 Orders PLACED in this transaction. A taker order that filled immediately appears here AND as the taker of a `TRADE` event; a maker order that only rested appears here alone. *** ### protocolFees > **protocolFees**: [`ProtocolFeeRecord`](ProtocolFeeRecord.md)[] Defined in: packages/sdk/src/activity.ts:378 Protocol fees charged in this transaction. BINARY only. *** ### builderFees > **builderFees**: [`BuilderFeeRecord`](BuilderFeeRecord.md)[] Defined in: packages/sdk/src/activity.ts:380 Builder fees charged in this transaction. BINARY only. *** ### markets > **markets**: `Record`\<`string`, [`Market`](Market.md)\> Defined in: packages/sdk/src/activity.ts:385 The markets these events touched, keyed by lowercased market id — so a caller can NAME each row without a lookup per row. --- # /docs/typescript/api/index/type-aliases/TransactionActivityOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TransactionActivityOptions # Type Alias: TransactionActivityOptions > **TransactionActivityOptions** = `object` Defined in: packages/sdk/src/activity.ts:389 Options for [SomniaMarketsClient.getTransactionActivity](../interfaces/SomniaMarketsClient.md#gettransactionactivity). ## Properties ### limit? > `optional` **limit?**: `number` Defined in: packages/sdk/src/activity.ts:391 Max rows per event stream (default 100). *** ### anchor? > `optional` **anchor?**: `object` Defined in: packages/sdk/src/activity.ts:414 The transaction's block and timestamp. A PERFORMANCE FIX, not a filter. Without it, a transaction that produced no event — one that only PLACED orders, common on a live book — can be found only by probing `Order.placedTxHash`, and that column carries no index: measured, the probe runs past the gateway timeout and the read fails outright. The anchor skips the probe and goes straight to the timestamp-anchored pass, which IS index-served. WHAT IT DOES NOT FIX: a transaction that only CANCELLED orders stays unreadable by hash, and no anchor can change that. The indexer stores no cancellation record and `Order` carries only `placedTxHash`, so nothing in it is keyed by a cancel's own hash — the anchor turns that read from a timeout into a fast, honest "nothing indexed". Making those transactions readable needs an append-only order-update entity in the indexer. Normally left unset: the configured owner resolves it from its own transport. Pass it only when the block and timestamp are already in hand; both fields or neither, since the block names the transaction and the timestamp serves the query. #### blockNumber > **blockNumber**: `bigint` #### timestamp > **timestamp**: `bigint` --- # /docs/typescript/api/index/type-aliases/TransactionOrder [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TransactionOrder # Type Alias: TransactionOrder > **TransactionOrder** = [`FillOrder`](FillOrder.md) & `object` Defined in: packages/sdk/src/activity.ts:340 One order placed in a transaction — [FillOrder](FillOrder.md) plus the market it was placed in, which a transaction view needs because one transaction can touch more than one market. ## Type Declaration ### market > **market**: `string` The market's bytes32 marketId, lowercased. --- # /docs/typescript/api/index/type-aliases/UnifiedBookLevels [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedBookLevels # Type Alias: UnifiedBookLevels > **UnifiedBookLevels** = [`UnifiedOrderBook`](../interfaces/UnifiedOrderBook.md)\[`"bids"`\] Defined in: packages/sdk/src/unified/quotes.ts:19 One side of a unified book: [price, amount] pairs, best first. --- # /docs/typescript/api/index/type-aliases/UnifiedMarketType [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedMarketType # Type Alias: UnifiedMarketType > **UnifiedMarketType** = `"spot"` \| `"swap"` \| `"binary"` \| `"categorical"` Defined in: packages/sdk/src/unified/structs.ts:24 Market kind in ccxt vocabulary: "swap" is a linear perp; "binary" / "categorical" are outcome markets ("categorical" is reserved — no market carries it yet). --- # /docs/typescript/api/index/type-aliases/UnifiedOHLCV [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedOHLCV # Type Alias: UnifiedOHLCV > **UnifiedOHLCV** = \[`number`, `number`, `number`, `number`, `number`, `number`\] Defined in: packages/sdk/src/unified/structs.ts:328 An OHLCV row: [timestampMs, open, high, low, close, volume(base)]. --- # /docs/typescript/api/index/type-aliases/UnifiedOrderIdentity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedOrderIdentity # Type Alias: UnifiedOrderIdentity > **UnifiedOrderIdentity** = `object` Defined in: packages/sdk/src/unified/exchange.ts:134 Stable owner-qualified identity for one indexed order row. ## Properties ### chainId > **chainId**: `number` Defined in: packages/sdk/src/unified/exchange.ts:135 *** ### account > **account**: `Address` Defined in: packages/sdk/src/unified/exchange.ts:136 *** ### marketId > **marketId**: `string` Defined in: packages/sdk/src/unified/exchange.ts:137 *** ### pool > **pool**: `string` Defined in: packages/sdk/src/unified/exchange.ts:138 *** ### orderId > **orderId**: `string` Defined in: packages/sdk/src/unified/exchange.ts:139 --- # /docs/typescript/api/index/type-aliases/UnifiedOrderPageItem [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedOrderPageItem # Type Alias: UnifiedOrderPageItem > **UnifiedOrderPageItem** = [`UnifiedOrder`](../interfaces/UnifiedOrder.md) & `object` Defined in: packages/sdk/src/unified/exchange.ts:143 A unified display order with its immutable identity and raw indexer row. ## Type Declaration ### identity > **identity**: [`UnifiedOrderIdentity`](UnifiedOrderIdentity.md) ### info > **info**: [`OrderRow`](OrderRow.md) --- # /docs/typescript/api/index/type-aliases/UnifiedOrderStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedOrderStatus # Type Alias: UnifiedOrderStatus > **UnifiedOrderStatus** = `"open"` \| `"closed"` \| `"canceled"` \| `"expired"` Defined in: packages/sdk/src/unified/structs.ts:196 Unified order lifecycle: "closed" = fully filled; "canceled" covers both explicit cancels and an IOC/market remainder that couldn't rest. --- # /docs/typescript/api/index/type-aliases/UnifiedOrdersPage [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedOrdersPage # Type Alias: UnifiedOrdersPage > **UnifiedOrdersPage** = `object` Defined in: packages/sdk/src/unified/exchange.ts:157 One bounded indexer-offset page of an owner's orders. The page is a partial projection. The indexer does not provide a frozen revision, so concurrent changes can make later pages skip or repeat rows. An exhausted page does not prove that the result is complete account state. ## Properties ### orders > **orders**: [`UnifiedOrderPageItem`](UnifiedOrderPageItem.md)[] Defined in: packages/sdk/src/unified/exchange.ts:158 *** ### rowsRead > **rowsRead**: `number` Defined in: packages/sdk/src/unified/exchange.ts:160 Number of raw rows read before outcome filtering or identity resolution. *** ### nextOffset > **nextOffset**: `number` \| `null` Defined in: packages/sdk/src/unified/exchange.ts:162 Next raw row offset after a full page, or null after a short page. *** ### unresolved > **unresolved**: [`UnifiedOrderIdentity`](UnifiedOrderIdentity.md)[] Defined in: packages/sdk/src/unified/exchange.ts:164 Rows whose immutable market identity is absent or inconsistent in the loaded registry. *** ### coverage > **coverage**: `"partial"` Defined in: packages/sdk/src/unified/exchange.ts:165 *** ### source > **source**: `"indexer-offset"` Defined in: packages/sdk/src/unified/exchange.ts:166 --- # /docs/typescript/api/index/type-aliases/UnifiedStopOrderStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UnifiedStopOrderStatus # Type Alias: UnifiedStopOrderStatus > **UnifiedStopOrderStatus** = `"pending"` \| `"triggered"` \| `"canceled"` \| `"failed"` Defined in: packages/sdk/src/unified/structs.ts:254 A pending stop order's lifecycle, unified vocabulary. --- # /docs/typescript/api/index/type-aliases/UserFillsPage [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / UserFillsPage # Type Alias: UserFillsPage > **UserFillsPage** = `object` Defined in: packages/sdk/src/fills.ts:74 One bounded historical page. This is not a coverage or snapshot guarantee. ## Properties ### fills > **fills**: [`FillRow`](FillRow.md)[] Defined in: packages/sdk/src/fills.ts:76 Existing fill rows, newest first by numeric timestamp, block and log position. *** ### nextCursor > **nextCursor**: `string` \| `null` Defined in: packages/sdk/src/fills.ts:78 Continue with the same scope. Null means no further row was observed in this read. --- # /docs/typescript/api/index/type-aliases/VaultPayoutFallback [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / VaultPayoutFallback # Type Alias: VaultPayoutFallback > **VaultPayoutFallback** = `object` Defined in: packages/sdk/src/binary/portfolio.ts:558 A vault-credit fallback record (mirror of the indexer `VaultPayoutFallback` entity) — an append-only history of payouts that could not be delivered to the wallet and were credited to the owner's ERC20Vault balance instead. This is the HISTORY layer; for the live claimable amount read [client.getVaultBalance](../interfaces/SomniaMarketsClient.md#getvaultbalance). Amounts are raw token units. ## Properties ### id > **id**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:560 Record id (`${blockNumber}_${logIndex}`). *** ### owner > **owner**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:562 Credited owner (lowercased). *** ### token > **token**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:564 Credited token (lowercased). *** ### amount > **amount**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:566 Amount credited to the vault balance (raw token units). *** ### market > **market**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:568 Market id the fallback was emitted for (lowercased). *** ### timestamp > **timestamp**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:570 Timestamp (unix seconds) of the credit. *** ### txHash > **txHash**: `string` Defined in: packages/sdk/src/binary/portfolio.ts:572 Tx hash the credit landed in. --- # /docs/typescript/api/index/type-aliases/VenueVoidPolicy [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / VenueVoidPolicy # Type Alias: VenueVoidPolicy > **VenueVoidPolicy** = `"UNIFORM"` \| `"CLOB_SNAPSHOT"` Defined in: packages/sdk/src/operatorReads.ts:44 Void payout policy a BINARY_V1 venue's markets are created with (mirror of the contract-side `VoidPolicy` enum; the legacy `AMM_SNAPSHOT` slot (1) is rejected on-chain and never surfaces here). - `UNIFORM` (0): a voided market pays every side 1/N — the default. - `CLOB_SNAPSHOT` (2): a voided market pays `[p, D-p]` at its closing YES price (captured or read from the lock-preserved closing book); falls back to uniform when no two-sided close exists. Frozen per market at creation after resolving against the pool's actual capability. --- # /docs/typescript/api/index/type-aliases/WatchStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / WatchStatus # Type Alias: WatchStatus > **WatchStatus** = `"unwatched"` \| `"hydrating"` \| `"live"` Defined in: packages/sdk/src/liveTail.ts:81 Per-market watch state: `"unwatched"` (no active watch — `getLive*` reads return empty), `"hydrating"` (watch registered; snapshot/backfill/reconnect in progress), `"live"` (streaming with delivered-event provenance). --- # /docs/typescript/api/index/variables/ANSWER_TYPE [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ANSWER\_TYPE # Variable: ANSWER\_TYPE > `const` **ANSWER\_TYPE**: `object` Defined in: packages/sdk/src/oracleHub.ts:57 `AnswerType` enum values (OracleTypes.sol). ## Type Declaration ### Numeric > `readonly` **Numeric**: `0` = `0` Resolves to a number, bucketed by `numericIntervals`. ### Discrete > `readonly` **Discrete**: `1` = `1` Resolves to one of the `discreteOutcomes` strings. --- # /docs/typescript/api/index/variables/CADENCE_LADDER_SEC [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CADENCE\_LADDER\_SEC # Variable: CADENCE\_LADDER\_SEC > `const` **CADENCE\_LADDER\_SEC**: readonly \[`60`, `300`, `900`, `3600`, `14400`, `86400`\] Defined in: packages/sdk/src/interval.ts:107 The cadences a rolling binary series is currently rolled at, ascending: 1m, 5m, 15m, 1h, 4h, 24h. A snapshot, and NARROWING. The exact cadence is not a mystery — a series knows it, and `MarketCreator.MarketCreated` emits it as `intervalSec` for exactly this purpose ("not derivable from a single market's (tradingStart, expiry) — a series' FIRST market is a bootstrap partial — so it is surfaced here for indexers/UIs"). The indexer now DOES read that event and patches the true cadence onto the Market entity, so for anything a MarketCreator rolled the cadence is exact and joins by equality — this list, [CADENCE\_TOLERANCE\_SEC](CADENCE_TOLERANCE_SEC.md), [snapToCadence](../functions/snapToCadence.md) and the banded filter are all inert on that path. They still carry every market the patch does not reach: markets created directly through the module rather than by a creator, and history indexed before the patch shipped, both of which fall back to the lossy `intervalSec = expiry − tradingStart` derivation the contract warns about. That fallback is why the indexer's distinct values run to a hundred-odd one-off windows rather than a handful of cadences. So: still needed, but no longer the primary path. A venue rolling an off-ladder cadence outside a creator still fragments, so treat the list as a deployment's current habits, not a rule. --- # /docs/typescript/api/index/variables/CADENCE_TOLERANCE_SEC [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CADENCE\_TOLERANCE\_SEC # Variable: CADENCE\_TOLERANCE\_SEC > `const` **CADENCE\_TOLERANCE\_SEC**: `5` = `5` Defined in: packages/sdk/src/interval.ts:124 How far a market's window may sit from a ladder rung and still BE that cadence — 5 seconds either side. A rolled market's window is `expiry − tradingStart`, and trading routinely opens a second or two late, so a 15m market is indexed at 898s or 899s about as often as at 900s. Treating those as their own cadence is what split one series across three groups and made a cadence filter silently miss most of its own markets. Deliberately ABSOLUTE, not proportional: the jitter is a scheduling delay measured in seconds, so it does not grow with the cadence. A genuinely different window (a 10-minute series, a 52-minute bootstrap partial) stays outside every rung and keeps its own identity. --- # /docs/typescript/api/index/variables/CANCEL_ORDER_FOR_SELECTOR [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CANCEL\_ORDER\_FOR\_SELECTOR # Variable: CANCEL\_ORDER\_FOR\_SELECTOR > `const` **CANCEL\_ORDER\_FOR\_SELECTOR**: `"0xe37b444b"` Defined in: packages/sdk/src/spot/operatorGrants.ts:46 Selector for `cancelOrderFor` — an operator cancelling an order for its owner. Grant it alongside [PLACE\_ORDER\_FOR\_SELECTOR](PLACE_ORDER_FOR_SELECTOR.md) for a bot that manages its own orders; a place-only grant leaves the owner as the only account able to cancel. --- # /docs/typescript/api/index/variables/CANDLE_INTERVALS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / CANDLE\_INTERVALS # Variable: CANDLE\_INTERVALS > `const` **CANDLE\_INTERVALS**: readonly \[`60`, `300`, `900`, `3600`, `14400`, `86400`\] Defined in: packages/sdk/src/candles.ts:71 Candle bucket sizes (seconds): 1m, 5m, 15m, 1h, 4h, 1d — the intervals the indexer rolls up. Keep in lockstep with `indexer/src/intervals.ts` (CANDLE_INTERVALS) so [SomniaMarketsClient.getCandles](../interfaces/SomniaMarketsClient.md#getcandles) is only ever asked for a bucket the indexer actually materializes. --- # /docs/typescript/api/index/variables/DECIMALS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DECIMALS # Variable: DECIMALS > `const` **DECIMALS**: `6` = `6` Defined in: packages/sdk/src/store.ts:342 Fallback outcome-token / collateral decimals (tUSDC 6dp demo stack). Real math uses the per-market baseDecimals/quoteDecimals off the Market row. --- # /docs/typescript/api/index/variables/DEFAULT_CEX_RATE_BPS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DEFAULT\_CEX\_RATE\_BPS # Variable: DEFAULT\_CEX\_RATE\_BPS > `const` **DEFAULT\_CEX\_RATE\_BPS**: `10` = `10` Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:308 Default comparison taker rate for the fees-saved metric, bps. 10 bps ≈ the common CEX taker tier the gateway compared against. --- # /docs/typescript/api/index/variables/DEFAULT_FEES [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DEFAULT\_FEES # Variable: DEFAULT\_FEES > `const` **DEFAULT\_FEES**: [`FixedFees`](../interfaces/FixedFees.md) Defined in: packages/sdk/src/config.ts:263 SDK default for [ClientConfig.fees](../interfaces/ClientConfig.md#fees): 60 gwei ceiling (~10× the observed Somnia base fee of 6 gwei), zero tip — instant BFT inclusion needs no bribe. --- # /docs/typescript/api/index/variables/DEFAULT_SLIPPAGE_BPS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DEFAULT\_SLIPPAGE\_BPS # Variable: DEFAULT\_SLIPPAGE\_BPS > `const` **DEFAULT\_SLIPPAGE\_BPS**: `300n` = `300n` Defined in: packages/sdk/src/derivedReads.ts:773 Default market-order slippage cushion, in bps of the crossing price. --- # /docs/typescript/api/index/variables/DEFAULT_SLIPPAGE_MIN_TICKS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / DEFAULT\_SLIPPAGE\_MIN\_TICKS # Variable: DEFAULT\_SLIPPAGE\_MIN\_TICKS > `const` **DEFAULT\_SLIPPAGE\_MIN\_TICKS**: `10n` = `10n` Defined in: packages/sdk/src/derivedReads.ts:782 Default minimum slippage cushion in ticks — keeps long-shot (low-priced) outcomes, where the bps fraction rounds to almost nothing, from getting near-zero slack. --- # /docs/typescript/api/index/variables/EIGHT_HOURS_SEC [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / EIGHT\_HOURS\_SEC # Variable: EIGHT\_HOURS\_SEC > `const` **EIGHT\_HOURS\_SEC**: `28800` = `28_800` Defined in: packages/sdk/src/funding.ts:39 Seconds in the 8-hour presentation axis. --- # /docs/typescript/api/index/variables/FUNDING_PRECISION [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / FUNDING\_PRECISION # Variable: FUNDING\_PRECISION > `const` **FUNDING\_PRECISION**: `1000000000000000000n` = `1_000_000_000_000_000_000n` Defined in: packages/sdk/src/funding.ts:32 Fixed-point scale for every rate and cumulative-index value (1e18). --- # /docs/typescript/api/index/variables/HUB_MIN_FREE_BALANCE_WEI [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / HUB\_MIN\_FREE\_BALANCE\_WEI # Variable: HUB\_MIN\_FREE\_BALANCE\_WEI > `const` **HUB\_MIN\_FREE\_BALANCE\_WEI**: `bigint` Defined in: packages/sdk/src/preflight.ts:67 The minimum native balance (wei) the OracleHub should hold to fund its reactivity bond — 32 STT, mirrors the deploy-runbook's funding floor. In Oracle v2 the hub holds Σ operator earmarks + accrued credit + its own reactivity-bond float in one balance; a rough floor check is the hub's total balance clearing this floor (a precise free-float split is no longer separately tracked on-chain). --- # /docs/typescript/api/index/variables/LIQUIDATION_KIND [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / LIQUIDATION\_KIND # Variable: LIQUIDATION\_KIND > `const` **LIQUIDATION\_KIND**: readonly \[`"AccountLiquidated"`, `"PositionLiquidated"`, `"PositionSkipped"`, `"PositionTakenOver"`, `"AutoDeleveraged"`, `"Throttled"`, `"KeeperReward"`, `"OrderPanicked"`, `"PositionTransferred"`, `"CloseOutMarginSettled"`, `"BadDebtAbsorbed"`, `"ResidualBadDebt"`, `"AdlPriceCapacityExhausted"`, `"ResidualBackedByOpenPnl"`, `"CoverageDeclined"`, `"AdlSessionDiscarded"`, `"AdlCapacityShortfall"`\] Defined in: packages/sdk/src/perp/history.ts:98 Every value [LiquidationEvent.kind](../type-aliases/LiquidationEvent.md#kind) can carry, in the order the waterfall emits them. The vocabulary [ListLiquidationsOptions.kind](../interfaces/ListLiquidationsOptions.md#kind) filters on, so a filter cannot be spelled wrong. --- # /docs/typescript/api/index/variables/MARGIN_STATUS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MARGIN\_STATUS # Variable: MARGIN\_STATUS > `const` **MARGIN\_STATUS**: readonly [`MarginStatus`](../type-aliases/MarginStatus.md)[] Defined in: packages/sdk/src/perp/margin.ts:35 Ordered so index == on-chain enum value (0 Healthy … 3 CloseOut). --- # /docs/typescript/api/index/variables/MARKET_TYPE_BINARY_V1 [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MARKET\_TYPE\_BINARY\_V1 # Variable: MARKET\_TYPE\_BINARY\_V1 > `const` **MARKET\_TYPE\_BINARY\_V1**: `Hex` = `"0x06c65d9f"` Defined in: packages/sdk/src/operatorReads.ts:21 `MarketTypeIds.BINARY_V1` (`bytes4(keccak256("BINARY_V1"))`) — the only market type registered today. A venue is pinned to one type forever at `createVenue`. --- # /docs/typescript/api/index/variables/MARKET_TYPE_PLUGINS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MARKET\_TYPE\_PLUGINS # Variable: MARKET\_TYPE\_PLUGINS > `const` **MARKET\_TYPE\_PLUGINS**: `Readonly`\<`Record`\<`string`, [`MarketTypePlugin`](../interfaces/MarketTypePlugin.md)\>\> Defined in: packages/sdk/src/marketTypes/index.ts:19 Every registered market-type plugin, keyed by its bytes4 `marketType` (lowercased). Frozen — the registry is a static seam, not mutated at runtime. --- # /docs/typescript/api/index/variables/MIN_SERIES_INTERVAL_SEC [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / MIN\_SERIES\_INTERVAL\_SEC # Variable: MIN\_SERIES\_INTERVAL\_SEC > `const` **MIN\_SERIES\_INTERVAL\_SEC**: `60` = `60` Defined in: packages/sdk/src/preflight.ts:74 The minimum roll interval the module enforces (`InvalidSeriesConfig` below). --- # /docs/typescript/api/index/variables/NATIVE_TOKEN_SENTINEL [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / NATIVE\_TOKEN\_SENTINEL # Variable: NATIVE\_TOKEN\_SENTINEL > `const` **NATIVE\_TOKEN\_SENTINEL**: `Address` = `"0x28f34DeFd2b4CB48d9eE6d89f2Be4Bc601694c00"` Defined in: packages/sdk/src/vault/funding.ts:35 The vault's native-token sentinel — the pseudo-address every ERC20Vault uses to key native (SOMI) balances, since native has no ERC-20 contract. **Details** Mirrors `NATIVE_TOKEN` in the protocol's `common/Common.sol`. Pass it to [client.getVaultBalance](../interfaces/SomniaMarketsClient.md#getvaultbalance) or `withdrawVault` to address a native balance — but NOT to [Trader.depositVault](../interfaces/Trader.md#depositvault), which reverts `UseDepositNative`; native goes in through [Trader.depositVaultNative](../interfaces/Trader.md#depositvaultnative). --- # /docs/typescript/api/index/variables/ONE_HOUR_SEC [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ONE\_HOUR\_SEC # Variable: ONE\_HOUR\_SEC > `const` **ONE\_HOUR\_SEC**: `3600` = `3_600` Defined in: packages/sdk/src/funding.ts:45 Seconds in an hour. --- # /docs/typescript/api/index/variables/ONE_YEAR_SEC [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ONE\_YEAR\_SEC # Variable: ONE\_YEAR\_SEC > `const` **ONE\_YEAR\_SEC**: `31536000` = `31_536_000` Defined in: packages/sdk/src/funding.ts:51 Seconds in a 365-day year, for annualization. --- # /docs/typescript/api/index/variables/ORDER_KIND [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ORDER\_KIND # Variable: ORDER\_KIND > `const` **ORDER\_KIND**: `Record`\<[`BinarySide`](../type-aliases/BinarySide.md), `number`\> Defined in: packages/sdk/src/writer.ts:84 v2 OrderKind enum for `placeBinaryOrder` (0 BUY_YES, 1 SELL_YES, 2 BUY_NO, 3 SELL_NO) — the side is explicit, NOT encoded in userData. The pool maps kind onto the base book's (isBid, price) internally; the SDK just forwards the enum. --- # /docs/typescript/api/index/variables/ORDER_KIND_SIDE [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ORDER\_KIND\_SIDE # Variable: ORDER\_KIND\_SIDE > `const` **ORDER\_KIND\_SIDE**: readonly [`BinarySide`](../type-aliases/BinarySide.md)[] Defined in: packages/sdk/src/store.ts:366 Index → BinarySide for the on-chain `OrderKind` enum carried by the `BinaryOrderPlaced` event (settlement-extraction v2): 0 BUY_YES, 1 SELL_YES, 2 BUY_NO, 3 SELL_NO. This is the ONLY authoritative side-attribution source — v2 no longer encodes the side in `userData` (now opaque MM bookkeeping). --- # /docs/typescript/api/index/variables/ORDER_TYPE [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ORDER\_TYPE # Variable: ORDER\_TYPE > `const` **ORDER\_TYPE**: `object` Defined in: packages/sdk/src/trade.ts:399 OrderBook OrderType — shared by binary `placeOrder` and spot `placeSpotOrder` (both ride the same OrderBook core): 0 NormalOrder (limit), 1 FillOrKill, 2 ImmediateOrCancel (market), 3 PostOnly. Pass to either call's `orderType`. ## Type Declaration ### LIMIT > `readonly` **LIMIT**: `0` = `0` 0 — NormalOrder: fill what crosses, rest the remainder on the book. ### FILL\_OR\_KILL > `readonly` **FILL\_OR\_KILL**: `1` = `1` 1 — FillOrKill: fill the full quantity immediately, or place nothing. ### MARKET > `readonly` **MARKET**: `2` = `2` 2 — ImmediateOrCancel: fill what crosses now, cancel the remainder. ### POST\_ONLY > `readonly` **POST\_ONLY**: `3` = `3` 3 — PostOnly: rest only — never takes liquidity. --- # /docs/typescript/api/index/variables/PERP_ORDER_REJECTION_REASON [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PERP\_ORDER\_REJECTION\_REASON # Variable: PERP\_ORDER\_REJECTION\_REASON > `const` **PERP\_ORDER\_REJECTION\_REASON**: readonly \[`"None"`, `"AlreadyExpired"`, `"SelfMatchCancelTaker"`, `"PostOnlyWouldCross"`, `"FillOrKillUnfillable"`, `"ImmediateOrCancelNoFill"`\] Defined in: packages/sdk/src/perp/history.ts:975 The contract's `OrderRejectionReason` enum, by index — the reason a batch-placed order was refused. Index 0 is `None`, which is NOT a rejection: it means the order rested or filled. It cannot appear on a [PerpOrderRejection](../type-aliases/PerpOrderRejection.md) row, and is kept in the table only so every other member keeps its on-chain index. --- # /docs/typescript/api/index/variables/PERP_POOL_FACTORY_MARKET_STATUS_INTERFACE_ID [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PERP\_POOL\_FACTORY\_MARKET\_STATUS\_INTERFACE\_ID # Variable: PERP\_POOL\_FACTORY\_MARKET\_STATUS\_INTERFACE\_ID > `const` **PERP\_POOL\_FACTORY\_MARKET\_STATUS\_INTERFACE\_ID**: `"0xa874fb70"` Defined in: packages/sdk/src/perp/registry.ts:42 ERC-165 id of `IPerpPoolFactoryMarketStatus` — the feature-detection handle that tells an upgraded factory from one predating the market-status views. A separate interface from `IPerpPoolFactory` on purpose: two live rotation gates (`MarginBank.setPerpPoolFactory`, `OperatorPermissionsRegistry.setPerpPoolFactory`) check `type(IPerpPoolFactory).interfaceId`, so declaring these views there would have changed the advertised id and turned a one-contract upgrade into a coordinated three-contract one. --- # /docs/typescript/api/index/variables/PERP_STOP_DROP_REASON [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PERP\_STOP\_DROP\_REASON # Variable: PERP\_STOP\_DROP\_REASON > `const` **PERP\_STOP\_DROP\_REASON**: readonly \[`"None"`, `"ReduceOnlyNoPosition"`, `"ReduceOnlyWrongSide"`, `"ReduceOnlyBelowMinQty"`, `"PlacementFailed"`, `"NoFill"`\] Defined in: packages/sdk/src/perp/stops.ts:73 Why a triggered stop placed nothing. Mirrors the registry's `DropReason` enum. The distinction matters for what a UI should say. `ReduceOnly*` are ordinary outcomes of a stop that events overtook — the position was already closed, or flipped, or what remained was dust — while `PlacementFailed` is a real rejection. Collapsing them all to "failed" makes routine behaviour look broken. --- # /docs/typescript/api/index/variables/PLACE_ORDER_FOR_SELECTOR [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PLACE\_ORDER\_FOR\_SELECTOR # Variable: PLACE\_ORDER\_FOR\_SELECTOR > `const` **PLACE\_ORDER\_FOR\_SELECTOR**: `"0x80054449"` Defined in: packages/sdk/src/spot/operatorGrants.ts:36 Selector for `placeOrderFor` — an operator placing an order for its owner. Granting this is what admits a trading bot, and what `SpotRouter` requires globally. Asserted against the function signature in the test suite, so it cannot drift from the contract. --- # /docs/typescript/api/index/variables/PRICE_FEED_DECIMALS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PRICE\_FEED\_DECIMALS # Variable: PRICE\_FEED\_DECIMALS > `const` **PRICE\_FEED\_DECIMALS**: `18` = `18` Defined in: packages/sdk/src/priceFeed/types.ts:26 Price scale of the on-chain EMA oracle: prices are 1e18-scaled integers. --- # /docs/typescript/api/index/variables/PRICE_RESOLUTION_SECONDS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / PRICE\_RESOLUTION\_SECONDS # Variable: PRICE\_RESOLUTION\_SECONDS > `const` **PRICE\_RESOLUTION\_SECONDS**: `Record`\<[`PriceCandleResolution`](../type-aliases/PriceCandleResolution.md), `number`\> Defined in: packages/sdk/src/priceFeed/types.ts:40 Seconds per [PriceCandleResolution](../type-aliases/PriceCandleResolution.md). --- # /docs/typescript/api/index/variables/QUERY_KEY_SCOPE [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / QUERY\_KEY\_SCOPE # Variable: QUERY\_KEY\_SCOPE > `const` **QUERY\_KEY\_SCOPE**: `"somnia-markets"` = `"somnia-markets"` Defined in: packages/sdk/src/queryKeys.ts:33 First element of every [ClientQueryKey](../type-aliases/ClientQueryKey.md) — match on it to invalidate all SDK reads at once. --- # /docs/typescript/api/index/variables/QUESTION_SOURCE_TYPE [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / QUESTION\_SOURCE\_TYPE # Variable: QUESTION\_SOURCE\_TYPE > `const` **QUESTION\_SOURCE\_TYPE**: `object` Defined in: packages/sdk/src/oracleHub.ts:43 `QuestionSourceType` enum values (OracleTypes.sol). Only all-JSON definitions participate in the hub's content-addressed dedup. ## Type Declaration ### Website > `readonly` **Website**: `0` = `0` Answer scraped from a website URL. ### JSON > `readonly` **JSON**: `1` = `1` Answer fetched from a JSON endpoint — the only source type eligible for dedup. ### Contract > `readonly` **Contract**: `2` = `2` Answer read from an on-chain contract. --- # /docs/typescript/api/index/variables/RAY [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / RAY # Variable: RAY > `const` **RAY**: `bigint` Defined in: packages/sdk/src/lend/math.ts:11 One ray — Aave's 27-decimal fixed-point unit; rates and indexes are ray-scaled. --- # /docs/typescript/api/index/variables/SELF_MATCHING_OPTION [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SELF\_MATCHING\_OPTION # Variable: SELF\_MATCHING\_OPTION > `const` **SELF\_MATCHING\_OPTION**: `object` Defined in: packages/sdk/src/trade.ts:747 OrderBook SelfMatchingOption — what happens when your incoming taker order crosses your OWN resting order: 0 cancels the rest of the taker, 1 cancels the whole maker. Every placement and amend verb takes it, and every one of them encodes 0 when you omit it. That default is the SDK's own choice: the pool reads the value out of the order request and has no default to fall back on. ## Type Declaration ### CANCEL\_TAKER > `readonly` **CANCEL\_TAKER**: `0` = `0` 0 — cancel the remaining taker quantity, leave the maker resting. ### CANCEL\_MAKER > `readonly` **CANCEL\_MAKER**: `1` = `1` 1 — cancel the full maker order, let the taker continue. --- # /docs/typescript/api/index/variables/SOMNIA_MAINNET_ADDRESSES [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SOMNIA\_MAINNET\_ADDRESSES # Variable: SOMNIA\_MAINNET\_ADDRESSES > `const` **SOMNIA\_MAINNET\_ADDRESSES**: [`SomniaMarketsAddresses`](../interfaces/SomniaMarketsAddresses.md) Defined in: packages/sdk/src/addresses.ts:41 Somnia mainnet (chainId 5031, env `mainnet-production`) protocol addresses, baked in from the deployment manifests at release time — pass as `config.addresses` for a zero-setup start. The live view of every deployed contract is the explorer's /system page. --- # /docs/typescript/api/index/variables/SOMNIA_MAINNET_LEND [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SOMNIA\_MAINNET\_LEND # Variable: SOMNIA\_MAINNET\_LEND > `const` **SOMNIA\_MAINNET\_LEND**: [`LendAddresses`](../interfaces/LendAddresses.md) Defined in: packages/sdk/src/lend/client.ts:118 The SomniaLend mainnet deployment (chain 5031), from docs.somnialend.finance/deployed-contracts — set as `config.addresses.lend`. [SOMNIA\_TESTNET\_LEND](SOMNIA_TESTNET_LEND.md) is the testnet sibling. --- # /docs/typescript/api/index/variables/SOMNIA_MAINNET_PRICE_FEED [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SOMNIA\_MAINNET\_PRICE\_FEED # Variable: SOMNIA\_MAINNET\_PRICE\_FEED > `const` **SOMNIA\_MAINNET\_PRICE\_FEED**: [`PriceFeedConfig`](../interfaces/PriceFeedConfig.md) Defined in: packages/sdk/src/config.ts:237 The Somnia-mainnet price feed. One endpoint serves every asset. Set it as `priceFeed: SOMNIA_MAINNET_PRICE_FEED`. Reads are pinned to the USDC quote (see [PriceFeedConfig.quote](../interfaces/PriceFeedConfig.md#quote)). This feed indexes the mainnet `PriceFeedScheduler`. Use it with a mainnet client. It is a different deployment from [SOMNIA\_TESTNET\_PRICE\_FEED](SOMNIA_TESTNET_PRICE_FEED.md), not a copy of it. Each feed indexes one chain. The names do not say which chain. To identify a feed, compare a `Feed` row's block number with the block height of each chain. This feed carries fewer symbols than the testnet feed. Code written for the testnet asset list can therefore fail here. Read the feed catalog to learn which bases exist. A base the feed does not carry returns no rows. It does not raise an error. --- # /docs/typescript/api/index/variables/SOMNIA_TESTNET_ADDRESSES [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SOMNIA\_TESTNET\_ADDRESSES # Variable: SOMNIA\_TESTNET\_ADDRESSES > `const` **SOMNIA\_TESTNET\_ADDRESSES**: [`SomniaMarketsAddresses`](../interfaces/SomniaMarketsAddresses.md) Defined in: packages/sdk/src/addresses.ts:17 Somnia testnet (chainId 50312, env `testnet-development`) protocol addresses, baked in from the deployment manifests at release time — pass as `config.addresses` for a zero-setup start. The live view of every deployed contract is the explorer's /system page. --- # /docs/typescript/api/index/variables/SOMNIA_TESTNET_LEND [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SOMNIA\_TESTNET\_LEND # Variable: SOMNIA\_TESTNET\_LEND > `const` **SOMNIA\_TESTNET\_LEND**: [`LendAddresses`](../interfaces/LendAddresses.md) Defined in: packages/sdk/src/lend/client.ts:134 The SomniaLend Somnia-testnet deployment (chain 50312) — pass to `config.addresses.lend`. Undocumented on docs.somnialend.finance; extracted from the official app's testnet mode (app.somnialend.finance) and verified on-chain (`PoolAddressesProvider.getPool()` matches, the UiPoolDataProvider aggregate decodes, the gateway resolves its wrapped native). --- # /docs/typescript/api/index/variables/SOMNIA_TESTNET_PRICE_FEED [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / SOMNIA\_TESTNET\_PRICE\_FEED # Variable: SOMNIA\_TESTNET\_PRICE\_FEED > `const` **SOMNIA\_TESTNET\_PRICE\_FEED**: [`PriceFeedConfig`](../interfaces/PriceFeedConfig.md) Defined in: packages/sdk/src/config.ts:214 The known Somnia-testnet price feed (dev) — one endpoint serving every asset. Wire it up with `priceFeed: SOMNIA_TESTNET_PRICE_FEED`. Pinned to the USDC quote: the feed also holds now-stale USDT history, and matching both quotes double-counts each base (see [PriceFeedConfig.quote](../interfaces/PriceFeedConfig.md#quote)). This feed indexes the testnet `PriceFeedScheduler`. Use it with a testnet client. A mainnet client reads prices from the other chain if you use this feed. Use [SOMNIA\_MAINNET\_PRICE\_FEED](SOMNIA_MAINNET_PRICE_FEED.md) instead. --- # /docs/typescript/api/index/variables/TIMEFRAMES [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / TIMEFRAMES # Variable: TIMEFRAMES > `const` **TIMEFRAMES**: `Record`\<`string`, `number`\> Defined in: packages/sdk/src/unified/structs.ts:514 Timeframe string → seconds, matching the indexer's candle intervals. --- # /docs/typescript/api/index/variables/ZERO_ADDRESS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / ZERO\_ADDRESS # Variable: ZERO\_ADDRESS > `const` **ZERO\_ADDRESS**: `"0x0000000000000000000000000000000000000000"` = `"0x0000000000000000000000000000000000000000"` Defined in: packages/sdk/src/preflight.ts:49 The all-zero EVM address (exported as `ZERO_ADDRESS`) — the "unset" sentinel the validators test addresses against. --- # /docs/typescript/api/index/variables/binaryMarketTypePlugin [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binaryMarketTypePlugin # Variable: binaryMarketTypePlugin > `const` **binaryMarketTypePlugin**: [`MarketTypePlugin`](../interfaces/MarketTypePlugin.md)\<[`BinaryVenueParams`](../interfaces/BinaryVenueParams.md)\> Defined in: packages/sdk/src/binary/plugin.ts:51 BINARY_V1 plugin. `encodeVenueFeeParams` / `decodeVenueFeeParams` delegate to the existing operatorReads helpers (the on-chain-backed encoder + the local decoder); `decode` is pure so it needs no client. --- # /docs/typescript/api/index/variables/binaryModuleReadAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binaryModuleReadAbi # Variable: binaryModuleReadAbi > `const` **binaryModuleReadAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/moduleAbi.ts:82 Read-only BinaryMarketsModule ABI for settlement discovery, pool reuse, and market records. **When to use** Use when keeper or verification code needs the module's chain state without constructing contract signatures by hand. **Gotchas** The `markets` tuple keeps its v1 layout. Read `marketNonce` separately when you need the outcome-token identifier encoding. --- # /docs/typescript/api/index/variables/binaryModuleWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binaryModuleWriteAbi # Variable: binaryModuleWriteAbi > `const` **binaryModuleWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/moduleAbi.ts:16 BinaryMarketsModule write surface — for keepers/tooling redeeming, minting/merging complete sets, or driving `finalizeMarket`/`releasePool` directly. --- # /docs/typescript/api/index/variables/binaryPoolWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binaryPoolWriteAbi # Variable: binaryPoolWriteAbi > `const` **binaryPoolWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:24 Write ABI for binary order placement, order maintenance, and complete sets. **Gotchas** Binary placement uses `placeBinaryOrder`; the generic `placeOrder` entry reverts on a binary pool. Prices use the YES side even for NO orders. --- # /docs/typescript/api/index/variables/binarySettlementAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / binarySettlementAbi # Variable: binarySettlementAbi > `const` **binarySettlementAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/readsAbi.ts:90 The BinarySettlement redemption singleton — for keepers/tooling reading settlement records or finalizing/redeeming against it directly. --- # /docs/typescript/api/index/variables/contractErrorsAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / contractErrorsAbi # Variable: contractErrorsAbi > `const` **contractErrorsAbi**: readonly \[\{ `type`: `"error"`; `name`: `"AccessControlBadConfirmation"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AccessControlUnauthorizedAccount"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; \}, \{ `name`: `"neededRole"`; `type`: `"bytes32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"AccountNotFlat"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdapterNotApproved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AddressEmptyCode"`; `inputs`: readonly \[\{ `name`: `"target"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"AddressIsRegisteredBidder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlBadBankruptcyPrice"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlCounterpartySameSide"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlFlipNotAllowed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlGasFloorRequiresScanCap"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlRankerInvalidPrice"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlRankerNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlSelfSettle"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlSessionWindowNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AdlZeroNotional"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AllocatorAlreadyInitialised"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AllocatorNotAtZeroIndex"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AllocatorZeroFree"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AlreadyArmed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AlreadyClaimed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AlreadyFinalized"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AlreadyInitialised"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AlreadyLinked"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AlreadyRetired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AlreadySubscribed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"AmendOldOrderGone"`; `inputs`: readonly \[\{ `name`: `"oldOrderId"`; `type`: `"uint128"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"AmendReplacementRejected"`; `inputs`: readonly \[\{ `name`: `"requestIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"reason"`; `type`: `"uint8"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ArrayLengthMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BackingMismatch"`; `inputs`: readonly \[\{ `name`: `"expected"`; `type`: `"uint256"`; \}, \{ `name`: `"received"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"BackingOverflow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BaseTokenAlreadyHasPool"`; `inputs`: readonly \[\{ `name`: `"baseToken"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"BatchGasGapNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BatchLiquidationDisabled"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BatchTooLarge"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BidderAddressReserved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BidderAlreadyRegistered"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BidderCannotBeIsolated"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BidderNotAContract"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BidderNotRegistered"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BidderQuoteInProgress"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BinaryClobFactoryNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BlockInPast"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BooksNotEmpty"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BothFeedsUnavailable"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BoundaryNotAligned"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BoundaryNotFuture"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BudgetExhausted"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BuilderAddressReserved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BuilderCodesNotSupported"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BuilderFeeExceedsApproval"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BuilderFeeExceedsCap"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"BuilderNotApproved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CallerInManualVaultMode"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"CallerIsChild"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CallerIsMain"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CampaignInactive"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CannotLinkSelf"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CannotStoreZeroOrder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CaptureStepsExhausted"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CaptureTooEarly"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ChainStillTriggerable"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ChargeableExceedsDeficit"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ChargeableExceedsLosses"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CircuitBandExceedsInitialMargin"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CircuitBreakerTriggered"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CloseAlreadyCaptured"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CloseNotCaptured"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CloseOutMarginExceedsBalance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CollateralMismatch"`; `inputs`: readonly \[\{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"CollateralNotWNative"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CollateralTokenMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ContextTooLong"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"CreditRecipientInDebt"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"DeadlineExpired"`; `inputs`: readonly \[\{ `name`: `"deadline"`; `type`: `"uint64"`; \}, \{ `name`: `"currentTs"`; `type`: `"uint64"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"DryRunDifference"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"DuplicateTier"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"EMANotInitialized"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"EmptyBatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"EmptyCallData"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"EmptyFilter"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"EmptyOrderBatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"EmptySelectors"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ERC1967InvalidImplementation"`; `inputs`: readonly \[\{ `name`: `"implementation"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ERC1967NonPayable"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ERC20InsufficientAllowance"`; `inputs`: readonly \[\{ `name`: `"spender"`; `type`: `"address"`; \}, \{ `name`: `"allowance"`; `type`: `"uint256"`; \}, \{ `name`: `"needed"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ERC20InsufficientBalance"`; `inputs`: readonly \[\{ `name`: `"sender"`; `type`: `"address"`; \}, \{ `name`: `"balance"`; `type`: `"uint256"`; \}, \{ `name`: `"needed"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ERC20InvalidApprover"`; `inputs`: readonly \[\{ `name`: `"approver"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ERC20InvalidReceiver"`; `inputs`: readonly \[\{ `name`: `"receiver"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ERC20InvalidSender"`; `inputs`: readonly \[\{ `name`: `"sender"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ERC20InvalidSpender"`; `inputs`: readonly \[\{ `name`: `"spender"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"EthRefundFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ExceedsBalance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ExceedsWithdrawableBalance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ExcessiveInput"`; `inputs`: readonly \[\{ `name`: `"spent"`; `type`: `"uint256"`; \}, \{ `name`: `"maxAllowed"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ExpiredOrderMustBeCancelled"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"FailedCall"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FailedDeployment"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FaucetCapExceeded"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FeedsDiverged"`; `inputs`: readonly \[\{ `name`: `"primaryPrice"`; `type`: `"uint256"`; \}, \{ `name`: `"secondaryPrice"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"FeeParamsTooLong"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FeeRecipientNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FeeRecipientRequired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FeeTooHigh"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FillOrKillNotFillable"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FillPriceOutsideBand"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FillPriceOverflow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FinalTokenMismatch"`; `inputs`: readonly \[\{ `name`: `"expected"`; `type`: `"address"`; \}, \{ `name`: `"actual"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"FirstRollAlreadyArmed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FreshMarketRequired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FundedPrincipalOverflow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FundingCapExceedsMarginBand"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"FundingRecipientInDebt"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"GasLimitExceeded"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"GasLimitZero"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"HandlerZeroAddress"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ImmediateOrCancelNoFill"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InconsistentMinQuantityAndLotSize"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"IncorrectDryRun"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"IncorrectOrder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"IncorrectSender"`; `inputs`: readonly \[\{ `name`: `"sender"`; `type`: `"address"`; \}, \{ `name`: `"expected"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"IndexOutOfBounds"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InputEqualsOutput"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientActivationBalance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientBacking"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientBalance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientBalance"`; `inputs`: readonly \[\{ `name`: `"balance"`; `type`: `"uint256"`; \}, \{ `name`: `"needed"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientCollateral"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientCreateValue"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientCredit"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientGasForBatch"`; `inputs`: readonly \[\{ `name`: `"gasAvailable"`; `type`: `"uint256"`; \}, \{ `name`: `"gasRequired"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientGasForPayout"`; `inputs`: readonly \[\{ `name`: `"gasLeft"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientLegInput"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"available"`; `type`: `"uint256"`; \}, \{ `name`: `"required"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientMargin"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientMarginAfterWithdrawal"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientMarginAtCreation"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientMarginForOrder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientOperatorDeposit"`; `inputs`: readonly \[\{ `name`: `"operatorId"`; `type`: `"uint32"`; \}, \{ `name`: `"required"`; `type`: `"uint256"`; \}, \{ `name`: `"available"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientOutput"`; `inputs`: readonly \[\{ `name`: `"received"`; `type`: `"uint256"`; \}, \{ `name`: `"minRequired"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientPermission"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientSomiPayment"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsufficientVaultBalance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsuranceFundCandidateHasDebt"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsuranceFundCandidateHasPositions"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsuranceFundCannotTrade"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsuranceFundFeeRecipientConflict"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InsuranceFundNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidAdapter"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidAddress"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidAdlRankerContract"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidAdlRankerOrdering"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidAmount"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidAsset"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidBaseToken"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidBidderAddress"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidBuilder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidCircuitBreakerParameters"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidConfig"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidCreator"`; `inputs`: readonly \[\{ `name`: `"creator"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InvalidCreditCapBps"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidCreditGranterContract"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidDepositOrWithdrawal"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidDeviationBps"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidDynamicIMFParameters"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidFeeRecipient"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidFundingCapDivergenceMargin"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidFundingParameters"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidFundingPayer"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidGasBufferBps"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidGasParameters"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidInitialization"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidInsuranceFundContract"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidIntervalSeconds"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidLegQuantity"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InvalidLeverage"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidLimitPrice"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidLinkedWalletRegistry"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidLinkedWalletRegistryContract"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidLiquidationEngineContract"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidLotSize"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMarginBank"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMarginParameters"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMarketExpiry"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMarketIndex"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMaxChildren"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMaxFeePerGas"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMaxLegs"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMidpointEmaParameters"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMinQuantity"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMinStopDistance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidMsgValue"`; `inputs`: readonly \[\{ `name`: `"expected"`; `type`: `"uint256"`; \}, \{ `name`: `"actual"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InvalidOperator"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidOperatorPermissionsRegistry"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidOrderOwner"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidOrderPair"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidOutcomeIndex"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidOutcomeToken"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidOwner"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidParameter"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidParameters"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPaymasterData"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPayoutVector"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPerpPool"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPerpPoolFactory"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPerpPoolFactoryContract"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPolicy"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPool"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPremiumImpactNotional"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPrice"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidPrice"`; `inputs`: readonly \[\{ `name`: `"price"`; `type`: `"uint256"`; \}, \{ `name`: `"tickSize"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InvalidQuantity"`; `inputs`: readonly \[\{ `name`: `"quantity"`; `type`: `"uint256"`; \}, \{ `name`: `"constraint"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InvalidReceiver"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidRegistry"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSeriesConfig"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSettlement"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSettlementWindow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSlippage"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSlippageTolerance"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSomiPaymentPerOrder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSpotPool"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidSpotPoolRegistry"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidTakerSide"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidTickSize"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidTier"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidTokenAddress"`; `inputs`: readonly \[\{ `name`: `"token"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InvalidTradingWindow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidTriggerPrice"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidUnlinkGuard"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidVenueFeeParams"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidVenueSignature"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"InvalidVenueVoidPolicy"`; `inputs`: readonly \[\{ `name`: `"policy"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"InvalidVoidPolicy"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"IsolatedMarketBlocked"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"IsolatedSpansMultipleMarkets"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"KickoffOutOfRange"`; `inputs`: readonly \[\{ `name`: `"seriesId"`; `type`: `"uint32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"LegFillFailed"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"LegInputOverflow"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"runningInputAmount"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"LegPlacementRejected"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"reason"`; `type`: `"bytes"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"LegPlacementRevertedWithoutReason"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"LengthMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"LimitPriceIncompatibleWithTrigger"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"LinkedListCorrupted"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"LinkedListEmptyKey"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"LinkedListNodeAlreadyExists"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"LinkedWalletFundingDisabled"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"LiquidationEngineNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MainFundedAccountCannotBeCredited"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MainnetDeploymentForbidden"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarginBankMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarginBankNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarketAlreadyAdded"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarketDeployFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarketExpiryInPast"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarketNotFinalizedYet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarketNotSettled"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarketNotSettled"`; `inputs`: readonly \[\{ `name`: `"marketId"`; `type`: `"bytes32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"MarketRestricted"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarketTypeMismatch"`; `inputs`: readonly \[\{ `name`: `"expected"`; `type`: `"bytes4"`; \}, \{ `name`: `"actual"`; `type`: `"bytes4"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"MarketTypeReserved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MarkPriceUnavailable"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MaxChildrenReached"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MaxPositionSizeExceeded"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MaxTiersAboveCeiling"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MaxTiersBelowActive"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MetadataAlreadySet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"MigrationSubsNotArmed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ModuleTypeMismatch"`; `inputs`: readonly \[\{ `name`: `"expected"`; `type`: `"bytes4"`; \}, \{ `name`: `"actual"`; `type`: `"bytes4"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"MustBeSentFromZeroAddress"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NativeAmountMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NativeInputNotSupportedInAutoPullMode"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NativeIntermediateUnsupported"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"NativePayoutFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NativeRefundExceedsInput"`; `inputs`: readonly \[\{ `name`: `"refund"`; `type`: `"uint256"`; \}, \{ `name`: `"forwarded"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"NativeRefundFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NativeTokenTransferFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NativeTransferFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NativeWithdrawFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoActiveSubscription"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoBadDebt"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoCreditToReclaim"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoFundedPrincipal"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoOpenPosition"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoPositionToFlatten"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoPrecompile"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoProposalPending"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoReducingPositionAtCreation"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NoSponsorSigner"`; `inputs`: readonly \[\{ `name`: `"operatorId"`; `type`: `"uint32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"NoStateChange"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotALinkedChild"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotArmed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotASideHolder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotASpotPool"`; `inputs`: readonly \[\{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"NotAuthorizedAdapter"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotEntryPoint"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotExpired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotFinalized"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NothingOwed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NothingToAdopt"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NothingToClaim"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NothingToReturn"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotIdPool"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotInitializing"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotLinked"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotLiquidatable"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotModule"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotOperatorOwner"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotOperatorOwner"`; `inputs`: readonly \[\{ `name`: `"operatorId"`; `type`: `"uint32"`; \}, \{ `name`: `"caller"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"NotOracle"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotOwner"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotQuiesced"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotReactivity"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotReceiver"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotRegistrar"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"NotSettlement"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyAdmin"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyAgentPlatform"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyApprovedContracts"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyCreditGranter"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyFundingPayer"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyLiquidationEngine"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyMarginBank"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyPerpPool"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyPrecompile"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlyReactivityPrecompile"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OnlySelf"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OpeningOrderRequiresQuantity"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OpenInterestCapExceeded"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OperatorDisabled"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OperatorIdReserved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OperatorNotActive"`; `inputs`: readonly \[\{ `name`: `"operatorId"`; `type`: `"uint32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"OracleNotAnswered"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OracleNotInitialized"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OraclePriceStale"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OrderAlreadyExpired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OrderAlreadyLinked"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OrderDoesNotExist"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OrderExpiryBeyondMarket"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OrderIdMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OrderInfoIdMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OutcomeCountMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OutcomeTokenNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OutcomeTransferFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"OwnableInvalidOwner"`; `inputs`: readonly \[\{ `name`: `"owner"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"OwnableUnauthorizedAccount"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"OwnerMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PendingOwnerOnly"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PermitTokenMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PerpPoolAlreadyRegistered"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PerpPoolHasActivePositions"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PerpPoolNotFromFactory"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PerpPoolNotRegistered"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PerpPoolWrongMarginBank"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PerUserOrderIndexInconsistency"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PlacementRevertedWithoutReason"`; `inputs`: readonly \[\{ `name`: `"isBid"`; `type`: `"bool"`; \}, \{ `name`: `"quoteIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"PlacementRevertedWithoutReason"`; `inputs`: readonly \[\{ `name`: `"isBid"`; `type`: `"bool"`; \}, \{ `name`: `"userData"`; `type`: `"uint64"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"PokeTooSoon"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PoolAlreadyReleased"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PoolBooksNotEmpty"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PoolCreatorUnknown"`; `inputs`: readonly \[\{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"PoolIndexOutOfBounds"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PoolNotApproved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PoolNotRegistered"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"PoolStateUnchanged"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PositionBelowMinQuantity"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PostOnlyWouldCross"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PredecessorAlreadyAdopted"`; `inputs`: readonly \[\{ `name`: `"prior"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"PriceNotAlignedToTickSize"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PriceOutOfBounds"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PriceOverflow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PriceTooLarge"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PrimaryEqualsSecondary"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"PriorFundingPayerOutstanding"`; `inputs`: readonly \[\{ `name`: `"outstandingPayer"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"QuantityBelowMinimum"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"QuantityBelowMinimum"`; `inputs`: readonly \[\{ `name`: `"quantity"`; `type`: `"uint256"`; \}, \{ `name`: `"minimum"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"QuantityNotAlignedToLotSize"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"QuestionNotFinal"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"QueueEmpty"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RankerNotLinkAware"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RecoveryAmountInvalid"`; `inputs`: readonly \[\{ `name`: `"amount"`; `type`: `"uint256"`; \}, \{ `name`: `"balance"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RecoveryDestinationZero"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RecoveryRateLimited"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RecoveryTokenIsNative"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RedeemAuthExpired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RedeemNonceUsed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RedeemSignatureInvalid"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ReduceOnlyBudgetExceeded"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ReentrancyGuardReentrantCall"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RefundFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RegistryNotApprovedByOwner"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RegistryRequiredForGroupMode"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RenounceDisabled"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ReviveTooSoon"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RouteEmpty"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RouterBuilderCodesNotSupportedOnPool"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterBuilderFeeExceedsPoolCap"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"pool"`; `type`: `"address"`; \}, \{ `name`: `"builderFeeBpsTimes1k"`; `type`: `"uint96"`; \}, \{ `name`: `"maxBuilderFeeBpsTimes1k"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterBuilderFeeWithoutBuilder"`; `inputs`: readonly \[\{ `name`: `"builderFeeBpsTimes1k"`; `type`: `"uint96"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterBuilderIsPool"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterBuilderIsRouter"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RouterBuilderNotApproved"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"pool"`; `type`: `"address"`; \}, \{ `name`: `"builderFeeBpsTimes1k"`; `type`: `"uint96"`; \}, \{ `name`: `"approved"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterInvalidLegPrice"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"priceLimit"`; `type`: `"uint256"`; \}, \{ `name`: `"tickSize"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterMarketQuoteInvalidPriceLimit"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"providedPriceLimit"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterNotApprovedAsOperator"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"pool"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterQuantityBelowMinimum"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"quantity"`; `type`: `"uint256"`; \}, \{ `name`: `"minQuantity"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterQuantityNotLotAligned"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"quantity"`; `type`: `"uint256"`; \}, \{ `name`: `"lotSize"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouterQuoteInputZero"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RouterQuoteOutputZero"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"RouteTokenMismatch"`; `inputs`: readonly \[\{ `name`: `"legIndex"`; `type`: `"uint256"`; \}, \{ `name`: `"expected"`; `type`: `"address"`; \}, \{ `name`: `"actualBase"`; `type`: `"address"`; \}, \{ `name`: `"actualQuote"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"RouteTooLong"`; `inputs`: readonly \[\{ `name`: `"maxLegs"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SafeCastOverflowedIntDowncast"`; `inputs`: readonly \[\{ `name`: `"bits"`; `type`: `"uint8"`; \}, \{ `name`: `"value"`; `type`: `"int256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SafeCastOverflowedUintDowncast"`; `inputs`: readonly \[\{ `name`: `"bits"`; `type`: `"uint8"`; \}, \{ `name`: `"value"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SafeERC20FailedOperation"`; `inputs`: readonly \[\{ `name`: `"token"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SelfMatchCancelTaker"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SeriesAlreadyLive"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SeriesIdOutOfRange"`; `inputs`: readonly \[\{ `name`: `"seriesId"`; `type`: `"uint32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SeriesNotStalled"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SettlementAlreadySet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SettlementNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SettlementWindowOpen"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SideHolderIndexOutOfBounds"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SimulatedFeedRevert"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"StaleMarketId"`; `inputs`: readonly \[\{ `name`: `"marketId"`; `type`: `"bytes32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"StalePrice"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SubscriptionAlreadyActive"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SubscriptionStillActive"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"SymbolIndexOutOfRange"`; `inputs`: readonly \[\{ `name`: `"symbolIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SymbolLengthUnsupported"`; `inputs`: readonly \[\{ `name`: `"length"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SymbolMismatch"`; `inputs`: readonly \[\{ `name`: `"expected"`; `type`: `"string"`; \}, \{ `name`: `"actual"`; `type`: `"string"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SymbolNotInitialized"`; `inputs`: readonly \[\{ `name`: `"symbolIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"SymbolStalePrice"`; `inputs`: readonly \[\{ `name`: `"symbolIndex"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"TakeoverPriceOutOfRange"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TakeoverPriceOverflow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TakerFillWouldMintBadDebt"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TierBalanceInsufficient"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TimestampInPast"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TokenZero"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TooManyMarkets"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TooManyMarketsForQuestion"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TooManyRestingOrders"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TradingNotActive"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TransferRecipientReserved"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TransferSourceAndDestinationSame"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"TriggerTooCloseToEma"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"Unauthorized"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnderpaidScheduleFee"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnderpaidSchedulingCost"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnexpectedFillPair"`; `inputs`: readonly \[\{ `name`: `"takerKind"`; `type`: `"uint8"`; \}, \{ `name`: `"makerKind"`; `type`: `"uint8"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"UnexpectedNativeDeposit"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnknownFire"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnknownMarket"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnknownMarketType"`; `inputs`: readonly \[\{ `name`: `"marketType"`; `type`: `"bytes4"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"UnknownOperator"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnknownOracleQuestion"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnknownReader"`; `inputs`: readonly \[\{ `name`: `"reader"`; `type`: `"address"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"UnknownSeries"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnknownSeriesSelector"`; `inputs`: readonly \[\{ `name`: `"selector"`; `type`: `"bytes4"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"UnknownSymbol"`; `inputs`: readonly \[\{ `name`: `"symbol"`; `type`: `"string"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"UnknownVenue"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnlinkBlockedByGuard"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnsponsoredSelector"`; `inputs`: readonly \[\{ `name`: `"selector"`; `type`: `"bytes4"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"UnsubscribeFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UnsupportedFeeParamsVersion"`; `inputs`: readonly \[\{ `name`: `"version"`; `type`: `"uint8"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"UseBinaryPlacement"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UseDepositNative"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UseFundNative"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UUPSUnauthorizedCallContext"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"UUPSUnsupportedProxiableUUID"`; `inputs`: readonly \[\{ `name`: `"slot"`; `type`: `"bytes32"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"VenueAuthExpired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VenueCreationDisabled"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VenueFeeAboveHardCap"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VenueIdRequired"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VenueMismatch"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VenueNonceUsed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VenuePolicyDenied"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VenueSignerUnset"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VoucherAccountCannotBeMainFunded"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VoucherAccountLeverageLocked"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VoucherLeverageCapNotSet"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VoucherMarketNotAllowed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"VwapOverflow"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WithdrawalBelowCreditFloor"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WithdrawalBelowFundedPrincipal"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WithdrawalExceedsDeposit"`; `inputs`: readonly \[\{ `name`: `"operatorId"`; `type`: `"uint32"`; \}, \{ `name`: `"requested"`; `type`: `"uint256"`; \}, \{ `name`: `"available"`; `type`: `"uint256"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"WithdrawalFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WithdrawFailed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WrongEmitter"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WrongEvent"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WrongReserveAttached"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"WrongStatus"`; `inputs`: readonly \[\{ `name`: `"expected"`; `type`: `"uint8"`; \}, \{ `name`: `"actual"`; `type`: `"uint8"`; \}\]; \}, \{ `type`: `"error"`; `name`: `"ZeroAddress"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroAgentOracle"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroAmount"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroCollateralFillsAllowed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroDeposit"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroEntryPoint"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroImpl"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroModule"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroOrder"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroOrderIndex"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroOwner"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroPrimary"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroPriority"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroQuoteFillsAllowed"`; `inputs`: readonly \[\]; \}, \{ `type`: `"error"`; `name`: `"ZeroReader"`; `inputs`: readonly \[\]; \}\] Defined in: packages/sdk/src/contractErrorsAbi.ts:20 Custom-error ABI entries for every protocol contract — the revert-decoding table. --- # /docs/typescript/api/index/variables/erc20VaultWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / erc20VaultWriteAbi # Variable: erc20VaultWriteAbi > `const` **erc20VaultWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:230 --- # /docs/typescript/api/index/variables/erc20WriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / erc20WriteAbi # Variable: erc20WriteAbi > `const` **erc20WriteAbi**: readonly \[\{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:9 --- # /docs/typescript/api/index/variables/erc6909Abi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / erc6909Abi # Variable: erc6909Abi > `const` **erc6909Abi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/readsAbi.ts:149 The protocol-wide ERC-6909 outcome-token singleton — for keepers/tooling reading outcome balances or wiring operator approvals/transfers directly. --- # /docs/typescript/api/index/variables/lendDebtTokenAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / lendDebtTokenAbi # Variable: lendDebtTokenAbi > `const` **lendDebtTokenAbi**: readonly \[\{ \}, \{ \}\] Defined in: packages/sdk/src/lend/lendAbi.ts:71 Aave variable-debt-token credit delegation — `borrowNative` routes the borrow through the gateway, so the user must first delegate borrowing power on the WSOMI variable debt token to it (`approveDelegation`); `borrowAllowance` reads the remaining delegated headroom. --- # /docs/typescript/api/index/variables/lendGatewayAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / lendGatewayAbi # Variable: lendGatewayAbi > `const` **lendGatewayAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/lend/lendAbi.ts:55 WrappedTokenGatewayV3 — wraps/unwraps native SOMI around the WSOMI reserve so users lend/borrow the native token without touching WSOMI themselves. The v3.0 gateway takes the Pool address as its first argument on every call. --- # /docs/typescript/api/index/variables/lendPoolAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / lendPoolAbi # Variable: lendPoolAbi > `const` **lendPoolAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/lend/lendAbi.ts:17 SomniaLend Pool (Aave v3 `IPool` subset) — the user actions the SDK sends (supply / withdraw / borrow / repay and the collateral toggle) plus the account-aggregate and per-reserve reads backing the lend client's `getAccount`. --- # /docs/typescript/api/index/variables/lendUiPoolDataProviderAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / lendUiPoolDataProviderAbi # Variable: lendUiPoolDataProviderAbi > `const` **lendUiPoolDataProviderAbi**: `Abi` Defined in: packages/sdk/src/lend/lendAbi.ts:46 UiPoolDataProviderV3 — Aave's aggregated read: the whole market and a user's every position in one eth_call each (see the signature const above for the verified v3.0 tuple shape; typed as plain `Abi` deliberately). --- # /docs/typescript/api/index/variables/liquidationEngineEventsAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / liquidationEngineEventsAbi # Variable: liquidationEngineEventsAbi > `const` **liquidationEngineEventsAbi**: readonly \[\{ `type`: `"event"`; `name`: `"AccountLiquidated"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"positionsProcessed"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"stageReached"`; `type`: `"uint8"`; `indexed`: `false`; \}, \{ `name`: `"marginStatusBefore"`; `type`: `"uint8"`; `indexed`: `false`; \}, \{ `name`: `"marginStatusAfter"`; `type`: `"uint8"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"PositionLiquidated"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"sizeDelta"`; `type`: `"int128"`; `indexed`: `false`; \}, \{ `name`: `"markPrice"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"PositionSkippedBelowMinQuantity"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"size"`; `type`: `"int128"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"PositionTakenOver"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"bidder"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"size"`; `type`: `"int128"`; `indexed`: `false`; \}, \{ `name`: `"takeoverPrice"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"LiquidationFeeCharged"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"tier"`; `type`: `"uint256"`; `indexed`: `true`; \}, \{ `name`: `"fillNotional"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"LiquidationKeeperRewardPaid"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"keeper"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"LiquidationThrottled"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"blockVolume"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"volumeCap"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"ResidualBadDebt"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"residual"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"ResidualBackedByOpenPnl"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"residual"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"equity"`; `type`: `"int256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"CoverageDeclinedByEquityCap"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"declined"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"tiers"`; `type`: `"uint256[]"`; `indexed`: `false`; \}, \{ `name`: `"losses"`; `type`: `"uint256[]"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"AdlCapacityShortfall"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"residualSize"`; `type`: `"uint128"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"AdlPriceCapacityExhausted"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"residual"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"AdlSessionDiscarded"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"absorbed"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"reason"`; `type`: `"uint8"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}\] Defined in: packages/sdk/src/eventsAbi.ts:468 LiquidationEngine events — the liquidation waterfall. Also a singleton, and the waterfall is SPLIT with MarginBank: the engine emits the stages and their costs, while the settlement legs (`AutoDeleveraged`, `CloseOutMarginSettled`, `BadDebtAbsorbed`, `PositionTransferred`) land on `marginBankEventsAbi` above. A consumer that wants the whole story needs both ABIs. Account-level events carry NO pool: `AccountLiquidated` covers every position the stage walked, and the residual/ADL-shortfall events describe the account's hole. Only the per-position events are pool-scoped, which is why a per-pool liquidation filter is lossy. Owner-parameter `*Updated` events, bidder registration, and the scan-progress checkpoints (`AdlScanCheckpointed`, `AdlNoBadDebtToSocialize`) are out: they are keeper mechanics, not account outcomes. Generated from `indexer/abis/LiquidationEngine.json` and pinned by topic0 in `test/perpEventsAbi.test.ts`. --- # /docs/typescript/api/index/variables/marginBankEventsAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marginBankEventsAbi # Variable: marginBankEventsAbi > `const` **marginBankEventsAbi**: readonly \[\{ `type`: `"event"`; `name`: `"PositionUpdated"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"newSize"`; `type`: `"int128"`; `indexed`: `false`; \}, \{ `name`: `"avgEntryPrice"`; `type`: `"uint128"`; `indexed`: `false`; \}, \{ `name`: `"realizedPnl"`; `type`: `"int256"`; `indexed`: `false`; \}, \{ `name`: `"entryFundingIndex"`; `type`: `"int256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"FundingSettled"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"payment"`; `type`: `"int256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"Deposited"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"DepositedFor"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"Withdrawn"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"CollateralLocked"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"CollateralUnlocked"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"FeeCharged"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"insurancePortion"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"BuilderFeeCharged"`; `inputs`: readonly \[\{ `name`: `"payer"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"builder"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"RebatePaid"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"AutoDeleveraged"`; `inputs`: readonly \[\{ `name`: `"counterparty"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"bankrupt"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"sizeReduced"`; `type`: `"int128"`; `indexed`: `false`; \}, \{ `name`: `"bankruptcyPrice"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"CloseOutMarginSettled"`; `inputs`: readonly \[\{ `name`: `"from"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"to"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"BadDebtAbsorbed"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"badDebt"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"covered"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"absorbedBy"`; `type`: `"address"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"PositionTransferred"`; `inputs`: readonly \[\{ `name`: `"from"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"to"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"size"`; `type`: `"int128"`; `indexed`: `false`; \}, \{ `name`: `"collateralTransferred"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"LiquidationOrderPanicked"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"panicCode"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"MainFundedChild"`; `inputs`: readonly \[\{ `name`: `"child"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"payer"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"amount"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"outstandingPrincipal"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"IsolatedModeSet"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"enabled"`; `type`: `"bool"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"MaxLeverageSet"`; `inputs`: readonly \[\{ `name`: `"account"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"perpPool"`; `type`: `"address"`; `indexed`: `true`; \}, \{ `name`: `"leverageX"`; `type`: `"uint16"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}\] Defined in: packages/sdk/src/eventsAbi.ts:232 MarginBank events — the perp ACCOUNT plane. MarginBank is a singleton, so one subscription carries every account and every pool; filter on the indexed `account` / `perpPool` topics, or at read time. Three groups, in declaration order: position and funding (`PositionUpdated`, `FundingSettled`), collateral flow (`Deposited` … `CollateralUnlocked`), then money charged or moved (fees, rebates, and the settlement legs the liquidation waterfall books here rather than on `LiquidationEngine` — including the panic marker, which is a waterfall outcome despite the contract it fires from). Owner-parameter `*Updated` events are deliberately absent: they carry admin wiring, not market data. `AccountCredited` / `CreditReclaimed` and the funded-principal pair are absent for the same reason — they belong to the voucher programme, which has no client surface yet. Signatures are generated from `indexer/abis/MarginBank.json` and pinned by topic0 in `test/perpEventsAbi.test.ts`. Hand-typing is the documented failure mode here: three of these were wrong in the indexer config for exactly that reason, and the plane indexed nothing while looking healthy. --- # /docs/typescript/api/index/variables/marginBankWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / marginBankWriteAbi # Variable: marginBankWriteAbi > `const` **marginBankWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:175 --- # /docs/typescript/api/index/variables/operatorRegistryWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / operatorRegistryWriteAbi # Variable: operatorRegistryWriteAbi > `const` **operatorRegistryWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:391 --- # /docs/typescript/api/index/variables/oracleHubAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / oracleHubAbi # Variable: oracleHubAbi > `const` **oracleHubAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/machineryAbi.ts:33 OracleHub function ABI (writes + point-status views) — mirrors `smart-contracts/src/adapters/OracleHub.sol` exactly. Backs the `OracleHubAdmin` writes and the standalone oracleHub.ts reads. --- # /docs/typescript/api/index/variables/oracleHubEventsAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / oracleHubEventsAbi # Variable: oracleHubEventsAbi > `const` **oracleHubEventsAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/machineryAbi.ts:104 OracleHub event ABI — decoded from `scheduleQuestion` receipts (`QuestionScheduled` vs `QuestionReused`) and by keepers reconciling the §8e exact-metering invariants. Indexed-ness mirrors OracleHub.sol. --- # /docs/typescript/api/index/variables/orderBookBatchWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / orderBookBatchWriteAbi # Variable: orderBookBatchWriteAbi > `const` **orderBookBatchWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:136 --- # /docs/typescript/api/index/variables/orderBookEventsAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / orderBookEventsAbi # Variable: orderBookEventsAbi > `const` **orderBookEventsAbi**: readonly \[\{ `type`: `"event"`; `name`: `"OrderPlaced"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}, \{ `name`: `"placedOrder"`; `type`: `"tuple"`; `indexed`: `false`; `components`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; \}, \{ `name`: `"isBid"`; `type`: `"bool"`; \}, \{ `name`: `"owner"`; `type`: `"address"`; \}, \{ `name`: `"userData"`; `type`: `"uint64"`; \}, \{ `name`: `"price"`; `type`: `"uint256"`; \}, \{ `name`: `"fullQuantity"`; `type`: `"uint256"`; \}, \{ `name`: `"quantityRemaining"`; `type`: `"uint256"`; \}, \{ `name`: `"expireTimestampNs"`; `type`: `"uint64"`; \}\]; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OrderRested"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OrderCancelled"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OrderExpired"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OrderReduced"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}, \{ `name`: `"newQuantity"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OrderFilled"`; `inputs`: readonly \[\{ `name`: `"takerOrderId"`; `type`: `"uint128"`; `indexed`: `true`; \}, \{ `name`: `"makerOrderId"`; `type`: `"uint128"`; `indexed`: `true`; \}, \{ `name`: `"quantityFilled"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"takerRemainingQuantity"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"makerRemainingQuantity"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"fillPrice"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OrderCancelledSelfMatch"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"MakerOrderCancelledExceedsPosition"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OrderCancelledPreFill"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}\] Defined in: packages/sdk/src/eventsAbi.ts:28 Order lifecycle events shared by SpotPool + BinaryPool (the OrderBook base). --- # /docs/typescript/api/index/variables/perpPoolEventsAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / perpPoolEventsAbi # Variable: perpPoolEventsAbi > `const` **perpPoolEventsAbi**: readonly \[\{ `type`: `"event"`; `name`: `"FundingUpdated"`; `inputs`: readonly \[\{ `name`: `"fundingRate"`; `type`: `"int256"`; `indexed`: `false`; \}, \{ `name`: `"cumulativeFundingPerUnit"`; `type`: `"int256"`; `indexed`: `false`; \}, \{ `name`: `"indexPrice"`; `type`: `"uint256"`; `indexed`: `false`; \}, \{ `name`: `"intervalsSettled"`; `type`: `"uint64"`; `indexed`: `false`; \}, \{ `name`: `"markPrice"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"OpenInterestUpdated"`; `inputs`: readonly \[\{ `name`: `"openInterest"`; `type`: `"uint256"`; `indexed`: `false`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"MakerOrderCancelledNegativeEquity"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}, \{ `type`: `"event"`; `name`: `"MakerOrderCancelledStaleMark"`; `inputs`: readonly \[\{ `name`: `"orderId"`; `type`: `"uint128"`; `indexed`: `true`; \}\]; `anonymous`: `false`; \}\] Defined in: packages/sdk/src/eventsAbi.ts:163 PerpPool-only events the live tail materializes (funding + open interest). Signatures verified against the DEPLOYED implementation's runtime bytecode, not against a source tree — the claim they previously carried ("mirror IPerpPool exactly, deployed testnet implementation") was false for both events here, and being false in a comment is how it survived: a wrong arity is a different topic0, so `watchEvent` filtered on something no pool ever emitted and the live funding tail silently never fired. `mise run verify:abis` in the indexer package is what now checks this class of claim mechanically. --- # /docs/typescript/api/index/variables/perpPoolWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / perpPoolWriteAbi # Variable: perpPoolWriteAbi > `const` **perpPoolWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:158 Write ABI for perpetual order placement, cancellation, and funding updates. **Gotchas** Perpetual placement is not payable. Margin comes from MarginBank rather than per-order escrow. --- # /docs/typescript/api/index/variables/spotPoolOperatorRegistryReadAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / spotPoolOperatorRegistryReadAbi # Variable: spotPoolOperatorRegistryReadAbi > `const` **spotPoolOperatorRegistryReadAbi**: readonly \[\{ \}\] Defined in: packages/sdk/src/readsAbi.ts:168 --- # /docs/typescript/api/index/variables/spotPoolWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / spotPoolWriteAbi # Variable: spotPoolWriteAbi > `const` **spotPoolWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:89 Write ABI for single spot order placement, cancellation, and amendment. **Gotchas** `placeOrder` is payable because native-base sells can carry value. The singular amend has a different revert surface from batch amendment. --- # /docs/typescript/api/index/variables/spotStopRegistryEventsAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / spotStopRegistryEventsAbi # Variable: spotStopRegistryEventsAbi > `const` **spotStopRegistryEventsAbi**: readonly \[\{ \}, \{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:272 --- # /docs/typescript/api/index/variables/spotStopRegistryWriteAbi [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [index](../README.md) / spotStopRegistryWriteAbi # Variable: spotStopRegistryWriteAbi > `const` **spotStopRegistryWriteAbi**: readonly \[\{ \}, \{ \}, \{ \}\] Defined in: packages/sdk/src/tradeAbi.ts:248 --- # /docs/typescript/api/native [**@somnia-chain/markets-sdk**](../README.md) *** [@somnia-chain/markets-sdk](../README.md) / native # native ## native RPC - [NativeRpcRequester](interfaces/NativeRpcRequester.md) - [SomniaNative](interfaces/SomniaNative.md) - [createNative](functions/createNative.md) - [isMethodNotFound](functions/isMethodNotFound.md) - [isUnauthorized](functions/isUnauthorized.md) - [SomniaMempoolStatus](variables/SomniaMempoolStatus.md) - [SomniaMempoolStatus](type-aliases/SomniaMempoolStatus.md) - [SomniaRpcError](interfaces/SomniaRpcError.md) - [getSomniaRpcError](functions/getSomniaRpcError.md) - [sessionPrivateKey](functions/sessionPrivateKey.md) - [sessionAddress](functions/sessionAddress.md) - [SomniaBlockTag](type-aliases/SomniaBlockTag.md) - [SomniaBlockParam](type-aliases/SomniaBlockParam.md) - [SomniaBlockResources](interfaces/SomniaBlockResources.md) - [SomniaConsensusBlock](interfaces/SomniaConsensusBlock.md) - [SomniaExecutionBlock](interfaces/SomniaExecutionBlock.md) - [SomniaBlock](interfaces/SomniaBlock.md) - [SomniaChainStatistics](interfaces/SomniaChainStatistics.md) - [SomniaReactivitySubscription](interfaces/SomniaReactivitySubscription.md) - [SomniaNodePublicKeys](interfaces/SomniaNodePublicKeys.md) - [SessionTransactionRequest](interfaces/SessionTransactionRequest.md) - [RpcSomniaBlock](interfaces/RpcSomniaBlock.md) - [RpcSomniaChainStatistics](interfaces/RpcSomniaChainStatistics.md) - [RpcSomniaReactivitySubscription](interfaces/RpcSomniaReactivitySubscription.md) - [RpcSomniaNodePublicKeys](interfaces/RpcSomniaNodePublicKeys.md) --- # /docs/typescript/api/native/functions/createNative [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / createNative # Function: createNative() > **createNative**(`client`): [`SomniaNative`](../interfaces/SomniaNative.md) Defined in: packages/sdk/src/native/client.ts:230 Wrap any JSON-RPC client in the Somnia-native API. **Details** - `client`: Anything with an EIP-1193 `request` method. - Returns: The [SomniaNative](../interfaces/SomniaNative.md) surface. **Example** (Reading a native block) ```ts import { createPublicClient, http } from "viem"; import { somniaShannon } from "@somnia-chain/markets-sdk/chains"; import { createNative } from "@somnia-chain/markets-sdk/native"; const client = createPublicClient({ chain: somniaShannon, transport: http() }); const native = createNative(client); const block = await native.getBlock("latest"); console.log(block?.consensusBlock.proposerAddress, block?.executionBlock.executionGasUsed); ``` Works with the markets client too — `createNative(exchange.client.publicClient)` — and with a plain injected provider, since all it needs is `.request`. ## Parameters ### client [`NativeRpcRequester`](../interfaces/NativeRpcRequester.md) ## Returns [`SomniaNative`](../interfaces/SomniaNative.md) --- # /docs/typescript/api/native/functions/getSomniaRpcError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / getSomniaRpcError # Function: getSomniaRpcError() > **getSomniaRpcError**(`error`): [`SomniaRpcError`](../interfaces/SomniaRpcError.md) \| `null` Defined in: packages/sdk/src/native/errors.ts:144 Recover the node's own JSON-RPC error from whatever a client threw. Use it instead of `error.message` whenever the message will be logged or shown: a viem `-32000` reads "Missing or invalid parameters." while the node said "account does not exist". **Details** - `error`: Whatever was thrown. - Returns: The node's error, or `null` if this wasn't a JSON-RPC error at all. **Example** (Reading a native RPC error) ```ts import { getSomniaRpcError } from "@somnia-chain/markets-sdk/native"; try { await native.sendSessionTransaction({ seed, gas: 21_000n, to, value }); } catch (error) { const rpc = getSomniaRpcError(error); console.error(rpc?.message ?? (error as Error).message); // "account does not exist" } ``` Walks the `cause` chain and returns the **innermost** `{ code, message }` pair, which is the node's, since each wrapper layer re-describes it. Falls back to a viem `details` string when the raw object is not reachable. ## Parameters ### error `unknown` ## Returns [`SomniaRpcError`](../interfaces/SomniaRpcError.md) \| `null` --- # /docs/typescript/api/native/functions/isMethodNotFound [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / isMethodNotFound # Function: isMethodNotFound() > **isMethodNotFound**(`error`): `boolean` Defined in: packages/sdk/src/native/client.ts:370 True when an error means "this node doesn't have that method". These endpoints are node-version dependent, and a stock geth/anvil has none of them — so a UI that offers native features should degrade rather than break. Mirrors the same check the SDK's write path uses for `realtime_sendRawTransaction`. **Details** - `error`: Whatever was thrown. **Example** (Handling an unsupported method) ```ts import { createNative, isMethodNotFound } from "@somnia-chain/markets-sdk/native"; const stats = await native.getStatistics("earliest", "latest").catch((e) => { if (isMethodNotFound(e)) return null; // not a Somnia node — hide the panel throw e; }); ``` ## Parameters ### error `unknown` ## Returns `boolean` --- # /docs/typescript/api/native/functions/isUnauthorized [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / isUnauthorized # Function: isUnauthorized() > **isUnauthorized**(`error`): `boolean` Defined in: packages/sdk/src/native/client.ts:397 True when an error means "that method is operator-only on this node" — the `{ code: -1, message: "unauthorized" }` a public endpoint returns for the protected methods. Matches on the **message**, not the code, and that is deliberate: `-1` is the node's default error code, shared by at least `invalid range`, `could not load statistics` and `Block does not exist` (all confirmed live). Keying on the code would report a bad block range as an authorization failure. **Details** - `error`: Whatever was thrown. ## Parameters ### error `unknown` ## Returns `boolean` --- # /docs/typescript/api/native/functions/sessionAddress [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / sessionAddress # Function: sessionAddress() > **sessionAddress**(`seed`): `` `0x${string}` `` Defined in: packages/sdk/src/native/session.ts:115 The address a session seed controls — computed locally, no RPC. Identical to what `somnia_getSessionAddress` returns for the same seed, and cheaper: use it to display or pre-fund a session account before any network call. `client.getSessionAddress(seed)` asks the node the same question if you want the round-trip as confirmation. **Details** - `seed`: 32-byte session seed. - Returns: The checksummed address of the derived account. **Gotchas** - Throws If the seed is not 32 bytes of hex. **Example** (Deriving a session address) ```ts import { sessionAddress } from "@somnia-chain/markets-sdk/native"; const seed = "0x1111111111111111111111111111111111111111111111111111111111111111"; sessionAddress(seed); // "0xD56D8c05Aa8dA0f3Afd676Aec94014e89aF3cc51" — fund this ``` ## Parameters ### seed `` `0x${string}` `` ## Returns `` `0x${string}` `` --- # /docs/typescript/api/native/functions/sessionPrivateKey [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / sessionPrivateKey # Function: sessionPrivateKey() > **sessionPrivateKey**(`seed`): `` `0x${string}` `` Defined in: packages/sdk/src/native/session.ts:76 Derive a session's **private key** from its seed, exactly as the node does. ``` for i = 0, 1, 2, …: candidate = keccak256(seed ‖ uint64_le(i)) if 0 < candidate < secp256k1_n: return candidate ``` The loop exists only for completeness: a 256-bit keccak output falls outside `[1, n-1]` with probability under 2^-128, so `i = 0` returns in every case anyone will ever observe. (Because `i = 0` encodes to eight zero bytes, its endianness is unobservable; the node documents little-endian and that is what this implements, so a hypothetical `i > 0` would still agree.) This exists to make one thing unmissable: **whoever holds the seed holds this key**, and can move the session account's funds without touching the node. Guard a seed exactly as you would guard the key it produces. **Details** - `seed`: 32-byte session seed. - Returns: The derived secp256k1 private key. **Gotchas** - Throws If the seed is not 32 bytes of hex. **Example** (Signing with a session key) ```ts import { sessionPrivateKey } from "@somnia-chain/markets-sdk/native"; import { privateKeyToAccount } from "viem/accounts"; // Sign locally instead of letting the node sign for you. const account = privateKeyToAccount(sessionPrivateKey(seed)); ``` ## Parameters ### seed `` `0x${string}` `` ## Returns `` `0x${string}` `` --- # /docs/typescript/api/native/interfaces/NativeRpcRequester [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / NativeRpcRequester # Interface: NativeRpcRequester Defined in: packages/sdk/src/native/client.ts:86 Anything that can make a JSON-RPC request — which every viem client is, and so is an injected EIP-1193 provider (`window.ethereum`) or a wagmi connector. Typed structurally so this module never needs a viem client of its own: whatever you already have, hand it over. ## Methods ### request() > **request**(`args`, `options?`): `Promise`\<`unknown`\> Defined in: packages/sdk/src/native/client.ts:93 Make a JSON-RPC request. The second argument is viem's per-request options — only `retryCount` is used, and only to stop a value-bearing session send from being retried (see `sendSessionTransaction`). A provider that ignores it is fine; the parameter is optional. #### Parameters ##### args ###### method `string` ###### params? `unknown` ##### options? ###### retryCount? `number` #### Returns `Promise`\<`unknown`\> --- # /docs/typescript/api/native/interfaces/RpcSomniaBlock [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / RpcSomniaBlock # Interface: RpcSomniaBlock Defined in: packages/sdk/src/native/types.ts:244 Raw `somnia_getBlockByHash` / `somnia_getBlockByNumber` payload. ## Properties ### consensus\_block > **consensus\_block**: `object` Defined in: packages/sdk/src/native/types.ts:245 #### block\_number > **block\_number**: `` `0x${string}` `` #### timestamp > **timestamp**: `` `0x${string}` `` #### data\_chain\_blocks > **data\_chain\_blocks**: `` `0x${string}` ``[] #### delayed\_ledger\_block\_number > **delayed\_ledger\_block\_number**: `` `0x${string}` `` #### delayed\_ledger\_block\_hash > **delayed\_ledger\_block\_hash**: `` `0x${string}` `` #### parent\_consensus\_block\_hash > **parent\_consensus\_block\_hash**: `` `0x${string}` `` #### proposer\_address > **proposer\_address**: `` `0x${string}` `` #### block\_resources > **block\_resources**: `object` ##### block\_resources.validation\_gas > **validation\_gas**: `` `0x${string}` `` ##### block\_resources.compressed\_bytes > **compressed\_bytes**: `` `0x${string}` `` ##### block\_resources.uncompressed\_bytes > **uncompressed\_bytes**: `` `0x${string}` `` #### consensus\_block\_hash > **consensus\_block\_hash**: `` `0x${string}` `` *** ### execution\_block > **execution\_block**: `object` Defined in: packages/sdk/src/native/types.ts:256 #### transaction\_ids\_hash > **transaction\_ids\_hash**: `` `0x${string}` `` #### receipts\_hash > **receipts\_hash**: `` `0x${string}` `` #### execution\_gas\_limit > **execution\_gas\_limit**: `` `0x${string}` `` #### execution\_gas\_used > **execution\_gas\_used**: `` `0x${string}` `` #### execution\_state\_snapshot > **execution\_state\_snapshot**: `` `0x${string}` `` #### state\_snapshot\_block\_number > **state\_snapshot\_block\_number**: `` `0x${string}` `` #### operation\_sequence\_hash > **operation\_sequence\_hash**: `` `0x${string}` `` *** ### parent\_ledger\_block\_hash > **parent\_ledger\_block\_hash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:265 *** ### ledger\_block\_hash > **ledger\_block\_hash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:266 --- # /docs/typescript/api/native/interfaces/RpcSomniaChainStatistics [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / RpcSomniaChainStatistics # Interface: RpcSomniaChainStatistics Defined in: packages/sdk/src/native/types.ts:274 Raw `somnia_getStatistics` payload — camelCase on the wire, unlike the blocks. ## Properties ### numSuccessfulTransactions > **numSuccessfulTransactions**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:275 *** ### numRevertedTransactions > **numRevertedTransactions**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:276 *** ### numContractsAdded > **numContractsAdded**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:277 *** ### numAccountsAdded > **numAccountsAdded**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:278 *** ### numNewUsedEoaAccounts > **numNewUsedEoaAccounts**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:279 *** ### numNativeTransferTransactions > **numNativeTransferTransactions**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:280 *** ### numGasUnitsSpent > **numGasUnitsSpent**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:281 *** ### gasFeeSpent > **gasFeeSpent**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:282 --- # /docs/typescript/api/native/interfaces/RpcSomniaNodePublicKeys [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / RpcSomniaNodePublicKeys # Interface: RpcSomniaNodePublicKeys Defined in: packages/sdk/src/native/types.ts:309 Raw `somnia_nodePublicKeys` payload. ## Properties ### address > **address**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:310 *** ### ecdsa\_public\_key > **ecdsa\_public\_key**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:311 *** ### bls\_public\_key > **bls\_public\_key**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:312 *** ### bls\_proof\_of\_possession > **bls\_proof\_of\_possession**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:313 *** ### proof\_of\_address > **proof\_of\_address**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:314 --- # /docs/typescript/api/native/interfaces/RpcSomniaReactivitySubscription [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / RpcSomniaReactivitySubscription # Interface: RpcSomniaReactivitySubscription Defined in: packages/sdk/src/native/types.ts:290 Raw `somnia_reactivityGetSubscriptionInfo` element. ## Properties ### id > **id**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:291 *** ### topics > **topics**: `` `0x${string}` ``[] Defined in: packages/sdk/src/native/types.ts:292 *** ### origin > **origin**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:293 *** ### caller > **caller**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:294 *** ### emitter > **emitter**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:295 *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:296 *** ### handler\_contract\_address > **handler\_contract\_address**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:297 *** ### handler\_function\_selector > **handler\_function\_selector**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:298 *** ### gas\_limit > **gas\_limit**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:299 *** ### priority\_fee\_per\_gas > **priority\_fee\_per\_gas**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:300 *** ### max\_fee\_per\_gas > **max\_fee\_per\_gas**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:301 --- # /docs/typescript/api/native/interfaces/SessionTransactionRequest [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SessionTransactionRequest # Interface: SessionTransactionRequest Defined in: packages/sdk/src/native/types.ts:222 A transaction to submit through a **session** — the node derives the key from `seed`, assigns the nonce, signs, submits, retries, and returns the receipt. ⚠️ `seed` is a **secret with the authority of a private key**: anyone who knows it controls the derived account (the derivation is public — see [sessionAddress](../functions/sessionAddress.md)). Treat it exactly as you would a key. ## Properties ### seed > **seed**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:224 32-byte seed identifying the session, and therefore the sending account. *** ### gas > **gas**: `bigint` Defined in: packages/sdk/src/native/types.ts:226 Execution gas limit. Required — the node does not estimate it. *** ### to? > `optional` **to?**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:228 Recipient. **Omit to deploy a contract** (`data` is then the init code). *** ### value? > `optional` **value?**: `bigint` Defined in: packages/sdk/src/native/types.ts:230 Native value to send, in wei. Defaults to 0. *** ### data? > `optional` **data?**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:232 Calldata, or contract init code when `to` is omitted. Defaults to empty. --- # /docs/typescript/api/native/interfaces/SomniaBlock [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaBlock # Interface: SomniaBlock Defined in: packages/sdk/src/native/types.ts:112 A Somnia **ledger** block — the native block structure, which is not the same thing as the Ethereum-compatible block `eth_getBlockByNumber` returns. It pairs the consensus block (ordering, proposer, timing) with the execution block (what running the transactions produced), so it exposes detail the eth surface has no field for: the data-chain blocks committed, the state snapshot, the proposer. ## Properties ### consensusBlock > **consensusBlock**: [`SomniaConsensusBlock`](SomniaConsensusBlock.md) Defined in: packages/sdk/src/native/types.ts:114 Consensus half: ordering, timing, proposer. *** ### executionBlock > **executionBlock**: [`SomniaExecutionBlock`](SomniaExecutionBlock.md) Defined in: packages/sdk/src/native/types.ts:116 Execution half: gas, receipts hash, state snapshot. *** ### parentLedgerBlockHash > **parentLedgerBlockHash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:118 Parent ledger block hash. *** ### ledgerBlockHash > **ledgerBlockHash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:120 This block's ledger hash — what `getSomniaBlockByHash` takes. --- # /docs/typescript/api/native/interfaces/SomniaBlockResources [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaBlockResources # Interface: SomniaBlockResources Defined in: packages/sdk/src/native/types.ts:45 Resources a consensus block consumed, as the node reports them. ## Properties ### validationGas > **validationGas**: `bigint` Defined in: packages/sdk/src/native/types.ts:47 Gas spent validating the block's transactions. *** ### compressedBytes > **compressedBytes**: `bigint` Defined in: packages/sdk/src/native/types.ts:49 Compressed size of the block's data, in bytes. *** ### uncompressedBytes > **uncompressedBytes**: `bigint` Defined in: packages/sdk/src/native/types.ts:51 Uncompressed size of the block's data, in bytes. --- # /docs/typescript/api/native/interfaces/SomniaChainStatistics [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaChainStatistics # Interface: SomniaChainStatistics Defined in: packages/sdk/src/native/types.ts:130 Aggregate activity over a block range. Every field is a count except the last. ## Properties ### successfulTransactions > **successfulTransactions**: `bigint` Defined in: packages/sdk/src/native/types.ts:132 Transactions that executed successfully. *** ### revertedTransactions > **revertedTransactions**: `bigint` Defined in: packages/sdk/src/native/types.ts:134 Transactions that reverted. *** ### contractsAdded > **contractsAdded**: `bigint` Defined in: packages/sdk/src/native/types.ts:136 Contracts deployed. *** ### accountsAdded > **accountsAdded**: `bigint` Defined in: packages/sdk/src/native/types.ts:138 Accounts created. *** ### newUsedEoaAccounts > **newUsedEoaAccounts**: `bigint` Defined in: packages/sdk/src/native/types.ts:140 EOAs used for the first time. *** ### nativeTransferTransactions > **nativeTransferTransactions**: `bigint` Defined in: packages/sdk/src/native/types.ts:142 Plain native-value transfers. *** ### gasUnitsSpent > **gasUnitsSpent**: `bigint` Defined in: packages/sdk/src/native/types.ts:144 Total gas units spent. *** ### gasFeeSpent > **gasFeeSpent**: `bigint` Defined in: packages/sdk/src/native/types.ts:146 Total fees paid, in wei. --- # /docs/typescript/api/native/interfaces/SomniaConsensusBlock [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaConsensusBlock # Interface: SomniaConsensusBlock Defined in: packages/sdk/src/native/types.ts:60 The consensus half of a Somnia ledger block: ordering, timing, and which data-chain blocks it commits. ## Properties ### blockNumber > **blockNumber**: `bigint` Defined in: packages/sdk/src/native/types.ts:62 Ledger block number. *** ### timestamp > **timestamp**: `bigint` Defined in: packages/sdk/src/native/types.ts:64 Block time in unix **milliseconds** (not seconds — Somnia blocks are ~100ms). *** ### dataChainBlocks > **dataChainBlocks**: `` `0x${string}` ``[] Defined in: packages/sdk/src/native/types.ts:66 Hashes of the data-chain blocks this consensus block commits. *** ### delayedLedgerBlockNumber > **delayedLedgerBlockNumber**: `bigint` Defined in: packages/sdk/src/native/types.ts:68 The delayed ledger block this one references. *** ### delayedLedgerBlockHash > **delayedLedgerBlockHash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:70 Hash of that delayed ledger block. *** ### parentConsensusBlockHash > **parentConsensusBlockHash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:72 Parent consensus block hash. *** ### proposerAddress > **proposerAddress**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:74 Validator that proposed the block. *** ### blockResources > **blockResources**: [`SomniaBlockResources`](SomniaBlockResources.md) Defined in: packages/sdk/src/native/types.ts:76 What the block cost to validate + carry. *** ### consensusBlockHash > **consensusBlockHash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:78 This block's own consensus hash. --- # /docs/typescript/api/native/interfaces/SomniaExecutionBlock [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaExecutionBlock # Interface: SomniaExecutionBlock Defined in: packages/sdk/src/native/types.ts:86 The execution half of a ledger block: what running its transactions produced. ## Properties ### transactionIdsHash > **transactionIdsHash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:88 Hash over the executed transaction ids. *** ### receiptsHash > **receiptsHash**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:90 Hash over the produced receipts. *** ### executionGasLimit > **executionGasLimit**: `bigint` Defined in: packages/sdk/src/native/types.ts:92 Gas limit for execution. *** ### executionGasUsed > **executionGasUsed**: `bigint` Defined in: packages/sdk/src/native/types.ts:94 Gas actually used. *** ### executionStateSnapshot > **executionStateSnapshot**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:96 State snapshot this execution built on. *** ### stateSnapshotBlockNumber > **stateSnapshotBlockNumber**: `bigint` Defined in: packages/sdk/src/native/types.ts:98 Block number of that snapshot. *** ### operationSequenceHash > **operationSequenceHash**: `bigint` Defined in: packages/sdk/src/native/types.ts:100 Rolling hash of the operation sequence. --- # /docs/typescript/api/native/interfaces/SomniaNative [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaNative # Interface: SomniaNative Defined in: packages/sdk/src/native/client.ts:105 The Somnia-native RPC surface — the twelve methods in the public JSON-RPC reference. Build one with [createNative](../functions/createNative.md). Reads throw on failure and return `null` only where the node genuinely means "no such thing" — a missing block, an unknown subscription. ## Methods ### isReady() > **isReady**(`opts?`): `Promise`\<`boolean`\> Defined in: packages/sdk/src/native/client.ts:113 Is the node ready to serve? `false` while it is still syncing. **Details** - `opts`: `withErrorCode: true` calls `somnia_isReadyWithErrorCode` instead, which **throws** on a not-ready node (`Is not ready`, JSON-RPC internal error) rather than returning `false` — that variant exists so a health check can key on the error. It never returns `false`. #### Parameters ##### opts? ###### withErrorCode? `boolean` #### Returns `Promise`\<`boolean`\> *** ### getBlock() > **getBlock**(`block?`): `Promise`\<[`SomniaBlock`](SomniaBlock.md) \| `null`\> Defined in: packages/sdk/src/native/client.ts:123 A Somnia **ledger** block — richer than the Ethereum-compatible block, with the proposer, the committed data-chain blocks and the execution state snapshot. Takes a tag (`"latest"`, `"earliest"`, `"pending"`, `"safe"`, `"finalized"`), a block number, **or** a 32-byte ledger block hash — dispatching to `somnia_getBlockByHash` for the last of those. #### Parameters ##### block? `` `0x${string}` `` \| [`SomniaBlockParam`](../type-aliases/SomniaBlockParam.md) #### Returns `Promise`\<[`SomniaBlock`](SomniaBlock.md) \| `null`\> *** ### getStatistics() > **getStatistics**(`from`, `to`): `Promise`\<[`SomniaChainStatistics`](SomniaChainStatistics.md)\> Defined in: packages/sdk/src/native/client.ts:126 Aggregate activity between two blocks, inclusive. #### Parameters ##### from [`SomniaBlockParam`](../type-aliases/SomniaBlockParam.md) ##### to [`SomniaBlockParam`](../type-aliases/SomniaBlockParam.md) #### Returns `Promise`\<[`SomniaChainStatistics`](SomniaChainStatistics.md)\> *** ### listPrivilegedReceipts() > **listPrivilegedReceipts**(`block?`): `Promise`\<`TransactionReceipt`[]\> Defined in: packages/sdk/src/native/client.ts:134 Receipts for the **privileged** (protocol-issued) transactions in a block — the ones no user submitted, e.g. reactivity callbacks. Usually empty. Takes a tag, a number, or a 32-byte block hash, like [getBlock](#getblock). #### Parameters ##### block? `` `0x${string}` `` \| [`SomniaBlockParam`](../type-aliases/SomniaBlockParam.md) #### Returns `Promise`\<`TransactionReceipt`[]\> *** ### listReactivitySubscriptionIds() > **listReactivitySubscriptionIds**(`owner`): `Promise`\<`bigint`[]\> Defined in: packages/sdk/src/native/client.ts:137 Ids of every reactivity subscription owned by an address. #### Parameters ##### owner `` `0x${string}` `` #### Returns `Promise`\<`bigint`[]\> *** ### getReactivitySubscription() > **getReactivitySubscription**(`id`): `Promise`\<[`SomniaReactivitySubscription`](SomniaReactivitySubscription.md) \| `null`\> Defined in: packages/sdk/src/native/client.ts:140 One reactivity subscription, or `null` when no subscription has that id. #### Parameters ##### id `number` \| `bigint` #### Returns `Promise`\<[`SomniaReactivitySubscription`](SomniaReactivitySubscription.md) \| `null`\> *** ### listReactivitySubscriptions() > **listReactivitySubscriptions**(`ids`): `Promise`\<[`SomniaReactivitySubscription`](SomniaReactivitySubscription.md)[]\> Defined in: packages/sdk/src/native/client.ts:143 Several reactivity subscriptions in one round-trip. Unknown ids are omitted. #### Parameters ##### ids readonly (`number` \| `bigint`)[] #### Returns `Promise`\<[`SomniaReactivitySubscription`](SomniaReactivitySubscription.md)[]\> *** ### getNodePublicKeys() > **getNodePublicKeys**(): `Promise`\<[`SomniaNodePublicKeys`](SomniaNodePublicKeys.md)\> Defined in: packages/sdk/src/native/client.ts:146 The serving node's identity keys for the current epoch. #### Returns `Promise`\<[`SomniaNodePublicKeys`](SomniaNodePublicKeys.md)\> *** ### getSessionAddress() > **getSessionAddress**(`seed`): `Promise`\<`` `0x${string}` ``\> Defined in: packages/sdk/src/native/client.ts:160 The address a session seed controls, **as the node computes it**. [sessionAddress](../functions/sessionAddress.md) computes the same value locally with no round-trip; this is the way to confirm the node agrees. Note the node creates its in-memory sender for the seed as a side effect. **Gotchas** - Throws `RpcError` when the node or the transport rejects the call. The seed is never in it. `cause` is the node's own `{ code, message, data? }` when the node answered (read it with [getSomniaRpcError](../functions/getSomniaRpcError.md)), or the transport's `{ name, message, status? }` with the request text blanked when it did not. #### Parameters ##### seed `` `0x${string}` `` #### Returns `Promise`\<`` `0x${string}` ``\> *** ### sendSessionTransaction() > **sendSessionTransaction**(`tx`): `Promise`\<`TransactionReceipt`\> Defined in: packages/sdk/src/native/client.ts:186 Submit a transaction through a session and **wait for its receipt**. The node derives the key from the seed, assigns the nonce, signs, submits and retries transient failures — so this one call replaces sign + send + poll. It does not return until the transaction has executed, which can take a while under retry; give the underlying transport a generous timeout. Before using it, know four things: - **The seed is a private key.** Anyone with it controls the account. - **Pre-fund the account** ([sessionAddress](../functions/sessionAddress.md)) or the transaction cannot pay gas. - **The nonce space is shared** with `eth_sendRawTransaction` from the same address. Sending both ways at once corrupts the sequence. - The session lives in the serving node's memory, so it is not shared between nodes and is rebuilt from the seed after a restart. Sent with retries disabled: a retry would be a second transfer, not a second attempt at the same one. **Gotchas** - Throws If the node returns no receipt. - Throws `RpcError` when the node or the transport rejects the transaction (mempool errors arrive as JSON-RPC `-32000`; a node-side timeout as `timeout`). The seed is never in it. `cause` is the node's own `{ code, message, data? }` when the node answered (read it with [getSomniaRpcError](../functions/getSomniaRpcError.md)), or the transport's `{ name, message, status? }` with the request text blanked when it did not. #### Parameters ##### tx [`SessionTransactionRequest`](SessionTransactionRequest.md) #### Returns `Promise`\<`TransactionReceipt`\> *** ### request() > **request**\<`T`\>(`method`, `params?`): `Promise`\<`T`\> Defined in: packages/sdk/src/native/client.ts:200 Call any `somnia_*` method directly — the escape hatch for an endpoint this module doesn't wrap: an operator-only one, one a newer node has added, or one the public reference omits. Params go through untouched, so hex-encode quantities yourself. ⚠️ Off the documented surface you are on your own, and not every undocumented endpoint is merely unstable — `somnia_getStorageDatabaseEntries` will make a node dump unbounded data for a large enough key list, and has taken a public testnet down. Know what a method does before reaching for it here. #### Type Parameters ##### T `T` = `unknown` #### Parameters ##### method `string` ##### params? `unknown`[] #### Returns `Promise`\<`T`\> --- # /docs/typescript/api/native/interfaces/SomniaNodePublicKeys [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaNodePublicKeys # Interface: SomniaNodePublicKeys Defined in: packages/sdk/src/native/types.ts:197 The serving node's identity keys for the current epoch — the node's `EpochNodePublicKeys`, all five fields. The two proofs are what bind the keys together: without them the address and the BLS key are just three unrelated values, which is why the node publishes them alongside and why they are not dropped here. ## Properties ### address > **address**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:199 The node's address. *** ### ecdsaPublicKey > **ecdsaPublicKey**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:201 Its secp256k1 public key (compressed). *** ### blsPublicKey > **blsPublicKey**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:203 Its BLS public key. *** ### blsProofOfPossession > **blsProofOfPossession**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:205 BLS proof of possession — proves the node holds the BLS private key. *** ### proofOfAddress > **proofOfAddress**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:207 Proof binding the BLS key to [SomniaNodePublicKeys.address](#address). --- # /docs/typescript/api/native/interfaces/SomniaReactivitySubscription [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaReactivitySubscription # Interface: SomniaReactivitySubscription Defined in: packages/sdk/src/native/types.ts:160 A registered Solidity reactivity subscription, as the node stores it. The same subscriptions the reactivity precompile manages — see `@somnia-chain/markets-sdk/reactivity` for creating them. This read is the way to enumerate what already exists without decoding events. ## Properties ### id > **id**: `bigint` Defined in: packages/sdk/src/native/types.ts:162 Subscription id. *** ### topics > **topics**: \[`` `0x${string}` ``, `` `0x${string}` ``, `` `0x${string}` ``, `` `0x${string}` ``\] Defined in: packages/sdk/src/native/types.ts:164 The four topic filters; `bytes32(0)` is a wildcard / unused slot. *** ### origin > **origin**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:166 `tx.origin` filter; zero address is a wildcard. *** ### caller > **caller**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:168 Reserved by the protocol — currently always the zero address. *** ### emitter > **emitter**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:170 Emitting-contract filter; zero address is a wildcard. *** ### owner > **owner**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:172 Who owns the subscription, and whose balance funds its callbacks. *** ### handlerContractAddress > **handlerContractAddress**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:174 Handler contract the validator calls. *** ### handlerFunctionSelector > **handlerFunctionSelector**: `` `0x${string}` `` Defined in: packages/sdk/src/native/types.ts:176 Handler entrypoint (`0x53edf33d` for the default `onEvent`). *** ### gasLimit > **gasLimit**: `bigint` Defined in: packages/sdk/src/native/types.ts:178 Gas provisioned per callback. *** ### priorityFeePerGas > **priorityFeePerGas**: `bigint` Defined in: packages/sdk/src/native/types.ts:180 Tip per gas for the callback, in wei. *** ### maxFeePerGas > **maxFeePerGas**: `bigint` Defined in: packages/sdk/src/native/types.ts:182 Fee ceiling per gas for the callback, in wei. --- # /docs/typescript/api/native/interfaces/SomniaRpcError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaRpcError # Interface: SomniaRpcError Defined in: packages/sdk/src/native/errors.ts:97 The JSON-RPC error the node actually sent, recovered from a client's wrapper. ## Properties ### code > **code**: `number` Defined in: packages/sdk/src/native/errors.ts:99 JSON-RPC code — `-32000` for a mempool rejection, `-32601` unknown method, `-1` the node default. *** ### message > **message**: `string` Defined in: packages/sdk/src/native/errors.ts:101 The node's own message, e.g. `"account does not exist"` — not the client's paraphrase. *** ### data > **data**: `` `0x${string}` `` \| `null` Defined in: packages/sdk/src/native/errors.ts:103 The `data` field verbatim, or `null` when absent. *** ### mempoolStatus > **mempoolStatus**: [`SomniaMempoolStatus`](../type-aliases/SomniaMempoolStatus.md) \| `null` Defined in: packages/sdk/src/native/errors.ts:108 `data` decoded, when it is a single mempool status byte. `null` when `data` is absent, is not one byte, or is not a known code — a newer node may add one. --- # /docs/typescript/api/native/type-aliases/SomniaBlockParam [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaBlockParam # Type Alias: SomniaBlockParam > **SomniaBlockParam** = [`SomniaBlockTag`](SomniaBlockTag.md) \| `bigint` \| `number` Defined in: packages/sdk/src/native/types.ts:36 Where to read from: a tag, or an exact block number. Note the node rejects a JSON *number* (`-32602 invalid parameters`) — pass a `bigint`/`number` here and this module hex-encodes it for you. --- # /docs/typescript/api/native/type-aliases/SomniaBlockTag [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaBlockTag # Type Alias: SomniaBlockTag > **SomniaBlockTag** = `"latest"` \| `"earliest"` \| `"pending"` \| `"safe"` \| `"finalized"` Defined in: packages/sdk/src/native/types.ts:26 A block identifier the node accepts: a tag, or an exact block number. --- # /docs/typescript/api/native/type-aliases/SomniaMempoolStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaMempoolStatus # Type Alias: SomniaMempoolStatus > **SomniaMempoolStatus** = *typeof* [`SomniaMempoolStatus`](../variables/SomniaMempoolStatus.md)\[keyof *typeof* [`SomniaMempoolStatus`](../variables/SomniaMempoolStatus.md)\] Defined in: packages/sdk/src/native/errors.ts:52 One of the [SomniaMempoolStatus](../variables/SomniaMempoolStatus.md) codes. --- # /docs/typescript/api/native/variables/SomniaMempoolStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [native](../README.md) / SomniaMempoolStatus # Variable: SomniaMempoolStatus > `const` **SomniaMempoolStatus**: `object` Defined in: packages/sdk/src/native/errors.ts:52 The node's mempool verdict, as the `data` byte of a `-32000` error carries it. Worth branching on rather than matching error strings: `nonceTooSmall` is retryable with a bumped nonce, `insufficientBalance` needs funding, and `accountDoesNotExist` means the *sender* has never been seen — a different fix from either. **Example** (Branching on mempool status) ```ts import { SomniaMempoolStatus, getSomniaRpcError } from "@somnia-chain/markets-sdk/native"; const rpc = getSomniaRpcError(error); if (rpc?.mempoolStatus === SomniaMempoolStatus.nonceTooSmall) { // stale nonce count — re-read it and retry } ``` ## Type Declaration ### success > `readonly` **success**: `0` = `0` Accepted. Never seen on an error. ### hasInFlightTransactions > `readonly` **hasInFlightTransactions**: `1` = `1` The sender already has transactions in flight. ### accountDoesNotExist > `readonly` **accountDoesNotExist**: `2` = `2` The SENDER has never existed on chain — fund it before it can transact. ### insufficientBalance > `readonly` **insufficientBalance**: `3` = `3` The sender cannot cover `value` plus the gas ceiling. ### nonceTooSmall > `readonly` **nonceTooSmall**: `4` = `4` Nonce below the account's next — including when `eth_getTransactionCount` lags. ### nonceTooLarge > `readonly` **nonceTooLarge**: `5` = `5` Nonce beyond what the mempool will queue. ### nonceNotCloseEnough > `readonly` **nonceNotCloseEnough**: `6` = `6` Nonce too far ahead of the account's next to hold. ### accountAlreadyLinked > `readonly` **accountAlreadyLinked**: `7` = `7` The account is already linked. ### invalidTransaction > `readonly` **invalidTransaction**: `8` = `8` Malformed, or below the intrinsic gas cost. ### invalidSignature > `readonly` **invalidSignature**: `9` = `9` Signature did not recover to the sender. ### accountNotLinked > `readonly` **accountNotLinked**: `10` = `10` The account is not linked. ### mempoolFull > `readonly` **mempoolFull**: `11` = `11` No room; retry later. ### gasPriceBelowBaseFee > `readonly` **gasPriceBelowBaseFee**: `12` = `12` `maxFeePerGas` under the block's base fee. ### gasPriceBelowDynamicFee > `readonly` **gasPriceBelowDynamicFee**: `13` = `13` `maxFeePerGas` under the dynamic fee the node currently requires. ### tooMuchValueInFlight > `readonly` **tooMuchValueInFlight**: `14` = `14` The sender's in-flight value exceeds what the mempool allows at once. --- # /docs/typescript/api/react [**@somnia-chain/markets-sdk**](../README.md) *** [@somnia-chain/markets-sdk](../README.md) / react # react ## funding ### FundingRateSeries Re-exports [FundingRateSeries](../index/type-aliases/FundingRateSeries.md) *** ### FundingSeriesBucket Re-exports [FundingSeriesBucket](../index/type-aliases/FundingSeriesBucket.md) ## Other - [WatchAcquisitionError](type-aliases/WatchAcquisitionError.md) - [WatchAcquisitionResult](type-aliases/WatchAcquisitionResult.md) - [UseWatchMarketResultError](type-aliases/UseWatchMarketResultError.md) - [UseWatchUserResultError](type-aliases/UseWatchUserResultError.md) - [UseWatchPriceResultError](type-aliases/UseWatchPriceResultError.md) - [UseLivePriceTicksError](type-aliases/UseLivePriceTicksError.md) - [UseLivePriceFeedInfoError](type-aliases/UseLivePriceFeedInfoError.md) - [UseLivePriceError](type-aliases/UseLivePriceError.md) - [UseWatchPriceError](type-aliases/UseWatchPriceError.md) - [UseFundingRateSeriesError](type-aliases/UseFundingRateSeriesError.md) - [UseLiveFundingUpdatesError](type-aliases/UseLiveFundingUpdatesError.md) - [UseLiveSpotOrderBookError](type-aliases/UseLiveSpotOrderBookError.md) - [UseLiveBinaryOrderBookByMarketError](type-aliases/UseLiveBinaryOrderBookByMarketError.md) - [UseLiveBinaryOrderBookError](type-aliases/UseLiveBinaryOrderBookError.md) - [UseLiveUserOrdersError](type-aliases/UseLiveUserOrdersError.md) - [UseLiveMarketByPoolError](type-aliases/UseLiveMarketByPoolError.md) - [UseLiveUserFillsError](type-aliases/UseLiveUserFillsError.md) - [UseLiveFillsError](type-aliases/UseLiveFillsError.md) - [UseWatchUserError](type-aliases/UseWatchUserError.md) - [UseWatchMarketError](type-aliases/UseWatchMarketError.md) - [UseSomniaMarketsClientError](type-aliases/UseSomniaMarketsClientError.md) ## React - [SomniaMarketsProvider](functions/SomniaMarketsProvider.md) - [useSomniaMarketsClient](functions/useSomniaMarketsClient.md) - [useWatchMarketResult](functions/useWatchMarketResult.md) - [useWatchUserResult](functions/useWatchUserResult.md) - [useWatchPriceResult](functions/useWatchPriceResult.md) - [useWatchMarket](functions/useWatchMarket.md) - [useWatchUser](functions/useWatchUser.md) - [useLiveStatus](functions/useLiveStatus.md) - [useIsTailing](functions/useIsTailing.md) - [useLiveFills](functions/useLiveFills.md) - [useLiveUserFills](functions/useLiveUserFills.md) - [useLiveMarketByPool](functions/useLiveMarketByPool.md) - [useLiveMarketByAddress](functions/useLiveMarketByAddress.md) - [useLiveUserOrders](functions/useLiveUserOrders.md) - [useLiveBinaryOrderBook](functions/useLiveBinaryOrderBook.md) - [useLiveBinaryOrderBookByMarket](functions/useLiveBinaryOrderBookByMarket.md) - [useLiveSpotOrderBook](functions/useLiveSpotOrderBook.md) - [IndexerQueryState](interfaces/IndexerQueryState.md) - [useIndexerQuery](functions/useIndexerQuery.md) - [usePortfolio](functions/usePortfolio.md) - [useMarkets](functions/useMarkets.md) - [useCandles](functions/useCandles.md) - [useLiveFundingUpdates](functions/useLiveFundingUpdates.md) - [useFundingRateSeries](functions/useFundingRateSeries.md) - [useMarketFees](functions/useMarketFees.md) - [useOperators](functions/useOperators.md) - [useMarketCreators](functions/useMarketCreators.md) - [useOracleAdapters](functions/useOracleAdapters.md) - [useLiveMarkets](functions/useLiveMarkets.md) - [useWatchPrice](functions/useWatchPrice.md) - [useLivePrice](functions/useLivePrice.md) - [useLivePriceFeedInfo](functions/useLivePriceFeedInfo.md) - [useLivePriceTicks](functions/useLivePriceTicks.md) - [useLendReserves](functions/useLendReserves.md) - [useLendAccount](functions/useLendAccount.md) --- # /docs/typescript/api/react/functions/SomniaMarketsProvider [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / SomniaMarketsProvider # Function: SomniaMarketsProvider() > **SomniaMarketsProvider**(`__namedParameters`): `ReactNode` Defined in: packages/sdk/src/hooks.ts:53 Provide the SDK's engine tier to the hooks below. Build one exchange (`new SomniaMarkets(...)`) and pass its `.client` here near the root of your app. ## Parameters ### \_\_namedParameters #### client [`SomniaMarketsClient`](../../index/interfaces/SomniaMarketsClient.md) #### children `ReactNode` ## Returns `ReactNode` --- # /docs/typescript/api/react/functions/useCandles [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useCandles # Function: useCandles() > **useCandles**(`pool`, `intervalSeconds`, `opts?`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`Candle`](../../index/type-aliases/Candle.md)[]\> Defined in: packages/sdk/src/hooks.ts:544 OHLCV candles for one pool + interval (indexer read), oldest first. ## Parameters ### pool `string` \| `undefined` ### intervalSeconds `number` ### opts? #### limit? `number` #### from? `number` #### to? `number` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`Candle`](../../index/type-aliases/Candle.md)[]\> --- # /docs/typescript/api/react/functions/useFundingRateSeries [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useFundingRateSeries # Function: useFundingRateSeries() > **useFundingRateSeries**(`pool`, `intervalSeconds`, `window`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`FundingRateSeries`](../../index/type-aliases/FundingRateSeries.md)\<[`FundingRateCandle`](../../index/type-aliases/FundingRateCandle.md)\>\> Defined in: packages/sdk/src/hooks.ts:619 A pool's funding-rate rollups over `[from, to)` at one resolution (3600 | 14400 | 86400), densified onto the grid and oldest-first. The read for a funding chart. Poll plus nudge: the rollups are re-read when the live tail observes a settlement on this pool, so the tip advances at settlement time rather than on the next poll tick. Callers should not re-implement that — the whole point of this hook. THE CALLER OWNS THE CLOCK. `from`/`to` are required and must be stable across renders: a `Date.now()` read inside this hook would change the query deps on every render and refetch forever. Snap your window to the grid (`Math.floor(now / interval) * interval`) and it will be stable between buckets. Reading the result: - `avgFundingRate8h` is already per-8h. Convert with the helpers in `funding.ts` (`fundingRate1h`, `annualizedFundingRate`) — never by hand in a component. - `coverage` is a 1e18-scaled ratio in [0, 1]. A bucket at rate 0 with LOW coverage is a pause, not a measured zero — hatch it. `filled: true` marks a slot with no row at all; both cases are `coverage: "0"`, and only `filled` separates them. - Cumulative funding is exact and needs none of that reasoning: `realizedFundingPerBase(first.cumulativeFundingStart, last.cumulativeFundingEnd)` telescopes across gaps, because the index is flat over uncovered time. Watch acquisition failures use the configured debug/console warning channel. Use useWatchMarketResult for typed acquisition error UI. History query failures remain in `state.error`. ## Parameters ### pool `string` \| `undefined` ### intervalSeconds `number` ### window #### from `number` #### to `number` #### limit? `number` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`FundingRateSeries`](../../index/type-aliases/FundingRateSeries.md)\<[`FundingRateCandle`](../../index/type-aliases/FundingRateCandle.md)\>\> ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useIndexerQuery [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useIndexerQuery # Function: useIndexerQuery() > **useIndexerQuery**\<`T`\>(`fn`, `deps`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<`T`\> Defined in: packages/sdk/src/hooks.ts:469 Run an async indexer read against the context client, re-running when `deps` change. Errors are captured (not thrown) so a failed indexer read renders as `error`, not a crash. A superseded request (deps changed, `refetch`, unmount) is aborted via the `signal` handed to `fn`, and its response is discarded either way. Client reads take no per-request signal (cancellation is client-scoped, via `ClientConfig.signal`), so the signal matters when `fn` does its own fetching — pass it to anything that accepts one. **Example** (Running a custom indexer query) ```ts const { data: markets } = useIndexerQuery((c) => c.listBinaryMarkets({ limit: 20 }), []); ``` ## Type Parameters ### T `T` ## Parameters ### fn (`client`, `signal`) => `Promise`\<`T`\> ### deps readonly `unknown`[] ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<`T`\> --- # /docs/typescript/api/react/functions/useIsTailing [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useIsTailing # Function: useIsTailing() > **useIsTailing**(): `boolean` Defined in: packages/sdk/src/hooks.ts:246 True when at least one watch is live (vs idle / hydrating / reconnecting). ## Returns `boolean` --- # /docs/typescript/api/react/functions/useLendAccount [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLendAccount # Function: useLendAccount() > **useLendAccount**(`account`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`LendAccount`](../../index/interfaces/LendAccount.md) \| `undefined`\> Defined in: packages/sdk/src/hooks.ts:859 A SomniaLend account's health factor + positions (chain read). Re-runs when `account` changes; `undefined` account resolves to `undefined` data. ## Parameters ### account `` `0x${string}` `` \| `undefined` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`LendAccount`](../../index/interfaces/LendAccount.md) \| `undefined`\> --- # /docs/typescript/api/react/functions/useLendReserves [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLendReserves # Function: useLendReserves() > **useLendReserves**(): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`LendReserve`](../../index/interfaces/LendReserve.md)[]\> Defined in: packages/sdk/src/hooks.ts:849 Every SomniaLend reserve — rates, caps, prices (chain read via the UiPoolDataProvider aggregate). Errors (surfaced on `error`) when the client's `config.addresses.lend` is unset. ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`LendReserve`](../../index/interfaces/LendReserve.md)[]\> --- # /docs/typescript/api/react/functions/useLiveBinaryOrderBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveBinaryOrderBook # Function: useLiveBinaryOrderBook() > **useLiveBinaryOrderBook**(`pool`, `depth?`): [`BinaryOrderBook`](../../index/interfaces/BinaryOrderBook.md) Defined in: packages/sdk/src/hooks.ts:363 The locally-materialized resting book of a binary pool (4-sided), updating the moment an order event lands — no round-trips, no refetch interval. Watches the pool while mounted. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. The owner supplies `blockNumber` as an applied-event watermark. Heads alone do not advance it. Expiry remains a wall-clock projection. ## Parameters ### pool `string` \| `undefined` ### depth? `number` = `10` ## Returns [`BinaryOrderBook`](../../index/interfaces/BinaryOrderBook.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveBinaryOrderBookByMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveBinaryOrderBookByMarket # Function: useLiveBinaryOrderBookByMarket() > **useLiveBinaryOrderBookByMarket**(`marketId`, `depth?`): [`BinaryOrderBook`](../../index/interfaces/BinaryOrderBook.md) Defined in: packages/sdk/src/hooks.ts:390 The locally-materialized resting book of a binary MARKET, resolved by its `marketId` (4-sided) — mirrors [useLiveBinaryOrderBook](useLiveBinaryOrderBook.md) but keyed on the market rather than the pool. Because a BinaryPool is recycled across markets, this returns an EMPTY book once the given market is no longer the pool's current binding, so a stale page never shows the successor market's orders. Watches the market's pool while mounted (once the market is known to the live store). Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. The owner supplies `blockNumber` as an applied-event watermark. Heads alone do not advance it. Expiry remains a wall-clock projection. ## Parameters ### marketId `string` \| `undefined` ### depth? `number` = `10` ## Returns [`BinaryOrderBook`](../../index/interfaces/BinaryOrderBook.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveFills [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveFills # Function: useLiveFills() > **useLiveFills**(`pool`, `limit?`): [`LiveFill`](../../index/interfaces/LiveFill.md)[] Defined in: packages/sdk/src/hooks.ts:262 Live trade tape for one pool. Watches the pool while mounted. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### pool `string` \| `undefined` ### limit? `number` = `40` ## Returns [`LiveFill`](../../index/interfaces/LiveFill.md)[] ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveFundingUpdates [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveFundingUpdates # Function: useLiveFundingUpdates() > **useLiveFundingUpdates**(`pool`, `limit?`): [`LiveFundingUpdate`](../../index/interfaces/LiveFundingUpdate.md)[] Defined in: packages/sdk/src/hooks.ts:572 Funding settlements for one pool seen by the live tail, OLDEST FIRST (chart order, matching `SomniaMarketsClient.getLiveFundingUpdates`) — not newest first like [useLiveFills](useLiveFills.md). Watches the pool while mounted. These are the tail's counterpart to the indexed `FundingRateUpdate` series and carry only what `FundingUpdated` puts on the wire — no `intervalsAccrued`, no covered span. For a chart, prefer [useFundingRateSeries](useFundingRateSeries.md), which uses these purely as a nudge. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### pool `string` \| `undefined` ### limit? `number` = `50` ## Returns [`LiveFundingUpdate`](../../index/interfaces/LiveFundingUpdate.md)[] ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveMarketByAddress [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveMarketByAddress # Function: useLiveMarketByAddress() > **useLiveMarketByAddress**(`addr`): [`BinaryMarket`](../../index/type-aliases/BinaryMarket.md) \| `null` Defined in: packages/sdk/src/hooks.ts:319 One binary market by its BinaryMarket contract address. NOTE: watches are pool-keyed, so this hook does not open one — it reads whatever a pool-keyed hook (or explicit watchMarket) on the same page has hydrated. ## Parameters ### addr `string` \| `undefined` ## Returns [`BinaryMarket`](../../index/type-aliases/BinaryMarket.md) \| `null` --- # /docs/typescript/api/react/functions/useLiveMarketByPool [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveMarketByPool # Function: useLiveMarketByPool() > **useLiveMarketByPool**(`pool`): [`Market`](../../index/type-aliases/Market.md) \| `null` Defined in: packages/sdk/src/hooks.ts:302 One market by pool address (either kind). Watches the pool while mounted. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### pool `string` \| `undefined` ## Returns [`Market`](../../index/type-aliases/Market.md) \| `null` ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveMarkets [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveMarkets # Function: useLiveMarkets() > **useLiveMarkets**(): [`Market`](../../index/type-aliases/Market.md)[] Defined in: packages/sdk/src/hooks.ts:731 Every market the live store knows (spot + perp + binary), from the live tail — synchronous, memoized. Pair with [useWatchMarket](useWatchMarket.md)/`watchMarkets` to keep it populated; unlike [useMarkets](useMarkets.md) this is the zero-round-trip store view, not an indexer fetch. ## Returns [`Market`](../../index/type-aliases/Market.md)[] --- # /docs/typescript/api/react/functions/useLivePrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLivePrice # Function: useLivePrice() > **useLivePrice**(`asset`): [`LivePrice`](../../index/interfaces/LivePrice.md) \| `null` Defined in: packages/sdk/src/hooks.ts:782 The live current price of one asset, updating the moment a new tick is pushed — no round-trips, no refetch interval. Watches the feed while mounted. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### asset `string` \| `undefined` ## Returns [`LivePrice`](../../index/interfaces/LivePrice.md) \| `null` ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLivePriceFeedInfo [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLivePriceFeedInfo # Function: useLivePriceFeedInfo() > **useLivePriceFeedInfo**(`asset`): [`PriceFeedInfo`](../../index/interfaces/PriceFeedInfo.md) \| `null` Defined in: packages/sdk/src/hooks.ts:808 The live feed metadata of one asset — pair symbol, quote, decimals, and the freshness fields (`updatedAtMs` / `sourceUpdatedAtMs` / `resynced`). Watches the feed while mounted. Note this does NOT re-render as a price ages: a stalled feed pushes nothing, so the store never notifies. Callers rendering an age must drive their own timer (see [PriceFeedInfo.updatedAtMs](../../index/interfaces/PriceFeedInfo.md#updatedatms)). Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### asset `string` \| `undefined` ## Returns [`PriceFeedInfo`](../../index/interfaces/PriceFeedInfo.md) \| `null` ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLivePriceTicks [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLivePriceTicks # Function: useLivePriceTicks() > **useLivePriceTicks**(`asset`, `limit?`): [`PricePoint`](../../index/interfaces/PricePoint.md)[] Defined in: packages/sdk/src/hooks.ts:828 The live tick tape of one asset, newest first. Watches the feed while mounted. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### asset `string` \| `undefined` ### limit? `number` = `100` ## Returns [`PricePoint`](../../index/interfaces/PricePoint.md)[] ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveSpotOrderBook [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveSpotOrderBook # Function: useLiveSpotOrderBook() > **useLiveSpotOrderBook**(`pool`, `depth?`): [`SpotOrderBook`](../../index/interfaces/SpotOrderBook.md) Defined in: packages/sdk/src/hooks.ts:417 The locally-materialized resting book of a spot pool, updating the moment an order event lands — no round-trips, no refetch interval. Watches the pool while mounted. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. The owner supplies the same per-scope `blockNumber` as its native live read. It is absent until hydration supplies provenance. ## Parameters ### pool `string` \| `undefined` ### depth? `number` = `12` ## Returns [`SpotOrderBook`](../../index/interfaces/SpotOrderBook.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveStatus [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveStatus # Function: useLiveStatus() > **useLiveStatus**(): [`TailStatus`](../../index/interfaces/TailStatus.md) Defined in: packages/sdk/src/hooks.ts:236 The live tail's status snapshot (mode, blocks, event counter) — drive a connection banner off it, or use [useIsTailing](useIsTailing.md) for the common boolean. ## Returns [`TailStatus`](../../index/interfaces/TailStatus.md) --- # /docs/typescript/api/react/functions/useLiveUserFills [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveUserFills # Function: useLiveUserFills() > **useLiveUserFills**(`pool`, `user`, `limit?`): [`LiveFill`](../../index/interfaces/LiveFill.md)[] Defined in: packages/sdk/src/hooks.ts:283 Fills `user` participated in. Watches `pool` while mounted when given; with `pool === null` it reads across whatever markets other hooks are watching (pair with useWatchUser for history). Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### pool `string` \| `null` ### user `string` \| `undefined` ### limit? `number` = `50` ## Returns [`LiveFill`](../../index/interfaces/LiveFill.md)[] ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useLiveUserOrders [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useLiveUserOrders # Function: useLiveUserOrders() > **useLiveUserOrders**(`pool`, `user`, `limit?`): [`LiveOrder`](../../index/interfaces/LiveOrder.md)[] Defined in: packages/sdk/src/hooks.ts:337 `user`'s orders on one pool. Watches the pool while mounted. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### pool `string` \| `undefined` ### user `string` \| `undefined` ### limit? `number` = `100` ## Returns [`LiveOrder`](../../index/interfaces/LiveOrder.md)[] ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useMarketCreators [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useMarketCreators # Function: useMarketCreators() > **useMarketCreators**(`opts?`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`IndexedMarketCreator`](../../index/type-aliases/IndexedMarketCreator.md)[]\> Defined in: packages/sdk/src/hooks.ts:697 MarketCreator directory (indexer read) — the operator machinery list. Pass `owner`/`operatorId`/`venueId` to filter, page with `limit`/`offset`. Each row carries its nested `series`. ## Parameters ### opts? [`MarketCreatorFilter`](../../index/type-aliases/MarketCreatorFilter.md) & `object` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`IndexedMarketCreator`](../../index/type-aliases/IndexedMarketCreator.md)[]\> --- # /docs/typescript/api/react/functions/useMarketFees [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useMarketFees # Function: useMarketFees() > **useMarketFees**(`marketId`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`MarketFees`](../../index/type-aliases/MarketFees.md) \| `null` \| `undefined`\> Defined in: packages/sdk/src/hooks.ts:675 A market's frozen fee config + running total (indexer read), or null. ## Parameters ### marketId `string` \| `undefined` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`MarketFees`](../../index/type-aliases/MarketFees.md) \| `null` \| `undefined`\> --- # /docs/typescript/api/react/functions/useMarkets [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useMarkets # Function: useMarkets() > **useMarkets**(`opts?`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`Market`](../../index/type-aliases/Market.md)[]\> Defined in: packages/sdk/src/hooks.ts:531 Markets, newest first (indexer read). Pass `marketType` to narrow. ## Parameters ### opts? #### marketType? [`MarketType`](../../index/type-aliases/MarketType.md) #### limit? `number` #### offset? `number` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`Market`](../../index/type-aliases/Market.md)[]\> --- # /docs/typescript/api/react/functions/useOperators [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useOperators # Function: useOperators() > **useOperators**(`opts?`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`IndexedOperator`](../../index/type-aliases/IndexedOperator.md)[]\> Defined in: packages/sdk/src/hooks.ts:684 Operator directory (indexer read). Pass `owner`/`enabled` to filter, page with `limit`/`offset`. ## Parameters ### opts? [`OperatorFilter`](../../index/type-aliases/OperatorFilter.md) & `object` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`IndexedOperator`](../../index/type-aliases/IndexedOperator.md)[]\> --- # /docs/typescript/api/react/functions/useOracleAdapters [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useOracleAdapters # Function: useOracleAdapters() > **useOracleAdapters**(`opts?`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`IndexedOracleAdapter`](../../index/type-aliases/IndexedOracleAdapter.md)[]\> Defined in: packages/sdk/src/hooks.ts:712 Oracle-adapter directory (indexer read). Pass `owner`/`approved` to filter, page with `limit`/`offset`. ## Parameters ### opts? #### owner? `string` #### approved? `boolean` #### limit? `number` #### offset? `number` ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`IndexedOracleAdapter`](../../index/type-aliases/IndexedOracleAdapter.md)[]\> --- # /docs/typescript/api/react/functions/usePortfolio [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / usePortfolio # Function: usePortfolio() > **usePortfolio**(`account`, `opts?`): [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`Portfolio`](../../index/type-aliases/Portfolio.md) \| `undefined`\> Defined in: packages/sdk/src/hooks.ts:516 A wallet's binary portfolio (indexer read). Re-runs when `account`/`opts` change. ## Parameters ### account `string` \| `undefined` ### opts? [`PortfolioOptions`](../../index/type-aliases/PortfolioOptions.md) ## Returns [`IndexerQueryState`](../interfaces/IndexerQueryState.md)\<[`Portfolio`](../../index/type-aliases/Portfolio.md) \| `undefined`\> --- # /docs/typescript/api/react/functions/useSomniaMarketsClient [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useSomniaMarketsClient # Function: useSomniaMarketsClient() > **useSomniaMarketsClient**(): [`SomniaMarketsClient`](../../index/interfaces/SomniaMarketsClient.md) Defined in: packages/sdk/src/hooks.ts:70 The SomniaMarketsClient from the nearest provider. Throws if there isn't one. ## Returns [`SomniaMarketsClient`](../../index/interfaces/SomniaMarketsClient.md) ## Throws No SomniaMarketsProvider is present in the component tree. --- # /docs/typescript/api/react/functions/useWatchMarket [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useWatchMarket # Function: useWatchMarket() > **useWatchMarket**(`pool`): [`WatchStatus`](../../index/type-aliases/WatchStatus.md) Defined in: packages/sdk/src/hooks.ts:205 Watch one market while mounted (ref-counted; shared with the data hooks) and report its watch state — render loading UI off `"hydrating"`. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### pool `string` \| `undefined` ## Returns [`WatchStatus`](../../index/type-aliases/WatchStatus.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useWatchMarketResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useWatchMarketResult # Function: useWatchMarketResult() > **useWatchMarketResult**(`pool`): [`WatchAcquisitionResult`](../type-aliases/WatchAcquisitionResult.md) Defined in: packages/sdk/src/hooks.ts:164 Acquire a market watch and return typed acquisition failure for inline rendering. Later lifecycle remains available through the owner's getWatchStatus and useLiveStatus. Releases late handles and ignores errors after owner/key changes or unmount. ## Parameters ### pool `string` \| `undefined` ## Returns [`WatchAcquisitionResult`](../type-aliases/WatchAcquisitionResult.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useWatchPrice [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useWatchPrice # Function: useWatchPrice() > **useWatchPrice**(`asset`): [`PriceFeedStatus`](../../index/type-aliases/PriceFeedStatus.md) Defined in: packages/sdk/src/hooks.ts:761 Watch one asset's price feed (e.g. `"BTC"`, `"ETH"`) while mounted (ref-counted; shared with the price data hooks) and report its watch state. Render off the returned state. `"error"` means the server rejected this asset's subscription: the price hooks keep returning their last values, which have stopped updating. See [PriceFeedStatus](../../index/type-aliases/PriceFeedStatus.md). Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### asset `string` \| `undefined` ## Returns [`PriceFeedStatus`](../../index/type-aliases/PriceFeedStatus.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useWatchPriceResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useWatchPriceResult # Function: useWatchPriceResult() > **useWatchPriceResult**(`asset`): [`WatchAcquisitionResult`](../type-aliases/WatchAcquisitionResult.md) Defined in: packages/sdk/src/hooks.ts:183 Acquire an asset's price watch and expose typed failure without an error boundary. getPriceStatus retains legacy setup state. The concrete owner's getPriceHealth distinguishes confirmed delivery. ## Parameters ### asset `string` \| `undefined` ## Returns [`WatchAcquisitionResult`](../type-aliases/WatchAcquisitionResult.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useWatchUser [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useWatchUser # Function: useWatchUser() > **useWatchUser**(`user`): `void` Defined in: packages/sdk/src/hooks.ts:225 Hydrate + hold `user`'s order/fill history while mounted, so the user-scoped live reads have depth predating the market watches. Background acquisition failures use the configured debug/console warning channel. Use the corresponding useWatchMarketResult/useWatchUserResult/useWatchPriceResult hook for inline error UI. ## Parameters ### user `string` \| `null` \| `undefined` ## Returns `void` ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/functions/useWatchUserResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / useWatchUserResult # Function: useWatchUserResult() > **useWatchUserResult**(`user`): [`WatchAcquisitionResult`](../type-aliases/WatchAcquisitionResult.md) Defined in: packages/sdk/src/hooks.ts:173 Acquire user history and expose typed failure without an error boundary. ## Parameters ### user `string` \| `null` \| `undefined` ## Returns [`WatchAcquisitionResult`](../type-aliases/WatchAcquisitionResult.md) ## Throws No Markets provider is mounted. --- # /docs/typescript/api/react/interfaces/IndexerQueryState [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / IndexerQueryState # Interface: IndexerQueryState\ Defined in: packages/sdk/src/hooks.ts:438 The state one [useIndexerQuery](../functions/useIndexerQuery.md) exposes. ## Type Parameters ### T `T` ## Properties ### data > **data**: `T` \| `undefined` Defined in: packages/sdk/src/hooks.ts:443 Latest successful result — `undefined` until the first response lands; the previous value is kept while a refetch is in flight or after it fails. *** ### loading > **loading**: `boolean` Defined in: packages/sdk/src/hooks.ts:445 True while a request is in flight (initial load and refetches alike). *** ### error > **error**: `Error` \| `null` Defined in: packages/sdk/src/hooks.ts:447 The most recent request's failure, or null. Cleared when a new request starts. *** ### refetch > **refetch**: () => `void` Defined in: packages/sdk/src/hooks.ts:449 Re-run the query imperatively (e.g. a manual refresh button). #### Returns `void` --- # /docs/typescript/api/react/type-aliases/UseFundingRateSeriesError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseFundingRateSeriesError # Type Alias: UseFundingRateSeriesError > **UseFundingRateSeriesError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:872 Render failures for useFundingRateSeries; history query errors remain in the returned state. --- # /docs/typescript/api/react/type-aliases/UseLiveBinaryOrderBookByMarketError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveBinaryOrderBookByMarketError # Type Alias: UseLiveBinaryOrderBookByMarketError > **UseLiveBinaryOrderBookByMarketError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:878 Render failures for useLiveBinaryOrderBookByMarket. --- # /docs/typescript/api/react/type-aliases/UseLiveBinaryOrderBookError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveBinaryOrderBookError # Type Alias: UseLiveBinaryOrderBookError > **UseLiveBinaryOrderBookError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:880 Render failures for useLiveBinaryOrderBook. --- # /docs/typescript/api/react/type-aliases/UseLiveFillsError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveFillsError # Type Alias: UseLiveFillsError > **UseLiveFillsError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:888 Render failures for useLiveFills. --- # /docs/typescript/api/react/type-aliases/UseLiveFundingUpdatesError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveFundingUpdatesError # Type Alias: UseLiveFundingUpdatesError > **UseLiveFundingUpdatesError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:874 Render failures for useLiveFundingUpdates. --- # /docs/typescript/api/react/type-aliases/UseLiveMarketByPoolError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveMarketByPoolError # Type Alias: UseLiveMarketByPoolError > **UseLiveMarketByPoolError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:884 Render failures for useLiveMarketByPool. --- # /docs/typescript/api/react/type-aliases/UseLivePriceError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLivePriceError # Type Alias: UseLivePriceError > **UseLivePriceError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:868 Render failures for useLivePrice. --- # /docs/typescript/api/react/type-aliases/UseLivePriceFeedInfoError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLivePriceFeedInfoError # Type Alias: UseLivePriceFeedInfoError > **UseLivePriceFeedInfoError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:866 Render failures for useLivePriceFeedInfo. --- # /docs/typescript/api/react/type-aliases/UseLivePriceTicksError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLivePriceTicksError # Type Alias: UseLivePriceTicksError > **UseLivePriceTicksError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:864 Render failures for useLivePriceTicks. --- # /docs/typescript/api/react/type-aliases/UseLiveSpotOrderBookError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveSpotOrderBookError # Type Alias: UseLiveSpotOrderBookError > **UseLiveSpotOrderBookError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:876 Render failures for useLiveSpotOrderBook. --- # /docs/typescript/api/react/type-aliases/UseLiveUserFillsError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveUserFillsError # Type Alias: UseLiveUserFillsError > **UseLiveUserFillsError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:886 Render failures for useLiveUserFills. --- # /docs/typescript/api/react/type-aliases/UseLiveUserOrdersError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseLiveUserOrdersError # Type Alias: UseLiveUserOrdersError > **UseLiveUserOrdersError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:882 Render failures for useLiveUserOrders. --- # /docs/typescript/api/react/type-aliases/UseSomniaMarketsClientError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseSomniaMarketsClientError # Type Alias: UseSomniaMarketsClientError > **UseSomniaMarketsClientError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:894 Render failures for useSomniaMarketsClient. --- # /docs/typescript/api/react/type-aliases/UseWatchMarketError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseWatchMarketError # Type Alias: UseWatchMarketError > **UseWatchMarketError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:892 Render failures for useWatchMarket. --- # /docs/typescript/api/react/type-aliases/UseWatchMarketResultError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseWatchMarketResultError # Type Alias: UseWatchMarketResultError > **UseWatchMarketResultError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:189 Provider lookup failure for the additive market acquisition hook. --- # /docs/typescript/api/react/type-aliases/UseWatchPriceError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseWatchPriceError # Type Alias: UseWatchPriceError > **UseWatchPriceError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:870 Render failures for useWatchPrice. --- # /docs/typescript/api/react/type-aliases/UseWatchPriceResultError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseWatchPriceResultError # Type Alias: UseWatchPriceResultError > **UseWatchPriceResultError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:193 Provider lookup failure for the additive price acquisition hook. --- # /docs/typescript/api/react/type-aliases/UseWatchUserError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseWatchUserError # Type Alias: UseWatchUserError > **UseWatchUserError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:890 Render failures for useWatchUser. --- # /docs/typescript/api/react/type-aliases/UseWatchUserResultError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / UseWatchUserResultError # Type Alias: UseWatchUserResultError > **UseWatchUserResultError** = [`InvalidInputError`](../../index/classes/InvalidInputError.md) Defined in: packages/sdk/src/hooks.ts:191 Provider lookup failure for the additive user acquisition hook. --- # /docs/typescript/api/react/type-aliases/WatchAcquisitionError [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / WatchAcquisitionError # Type Alias: WatchAcquisitionError > **WatchAcquisitionError** = [`IndexerError`](../../index/classes/IndexerError.md) \| [`RpcError`](../../index/classes/RpcError.md) \| [`NotConfiguredError`](../../index/classes/NotConfiguredError.md) \| [`ContractRevertError`](../../index/classes/ContractRevertError.md) \| [`InvalidInputError`](../../index/classes/InvalidInputError.md) \| [`InvariantError`](../../index/classes/InvariantError.md) Defined in: packages/sdk/src/hooks.ts:85 A component-visible watch acquisition failure. Cancellation from a superseded effect is ignored. --- # /docs/typescript/api/react/type-aliases/WatchAcquisitionResult [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [react](../README.md) / WatchAcquisitionResult # Type Alias: WatchAcquisitionResult > **WatchAcquisitionResult** = \{ `status`: `"unwatched"` \| `"acquiring"` \| `"acquired"`; `error`: `null`; \} \| \{ `status`: `"error"`; `error`: [`WatchAcquisitionError`](WatchAcquisitionError.md); \} Defined in: packages/sdk/src/hooks.ts:93 Acquisition progress is separate from later transport health. --- # /docs/typescript/api/reactivity [**@somnia-chain/markets-sdk**](../README.md) *** [@somnia-chain/markets-sdk](../README.md) / reactivity # reactivity ## reactivity ### isLocalPrecompileUnavailable Re-exports [isLocalPrecompileUnavailable](../index/functions/isLocalPrecompileUnavailable.md) --- # /docs/typescript/api/reactivity/functions/createReactivity [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [reactivity](../README.md) / createReactivity # Function: createReactivity() > **createReactivity**(`client`, `opts?`): `SDK` Defined in: packages/sdk/src/reactivity/index.ts:196 Build a reactivity client on the markets client's own WebSocket — the socket is already open and already pointed at the right node, and `watch` needs a WebSocket transport. **Details** - `client`: The markets client (`exchange.client`) whose public client to use. - `opts`: Optional wallet client for the write methods. - Returns: An upstream `SDK` instance — the full reactivity surface. **Example** (Watching a contract event) ```ts import { SomniaMarkets } from "@somnia-chain/markets-sdk"; import { createReactivity, unwrap } from "@somnia-chain/markets-sdk/reactivity"; import { somniaShannon } from "@somnia-chain/markets-sdk/chains"; const exchange = new SomniaMarkets({ chain: somniaShannon, wsRpcUrl, indexerUrl }); const reactivity = createReactivity(exchange.client); // Every Transfer on the collateral token, with the sender's new balance read // at the very same block — one notification, no follow-up call. const watch = unwrap( await reactivity.watch({ eventContractSources: [collateral], topicOverrides: [transferTopic], ethCalls: [{ to: collateral, data: balanceOfCalldata }], onData: (n: ReactivityNotification) => console.log(n.result.simulationResults), }), ); await watch.unsubscribe(); ``` ## Parameters ### client `Pick`\<[`SomniaMarketsClient`](../../index/interfaces/SomniaMarketsClient.md), `"getViemClient"`\> ### opts? [`CreateReactivityOptions`](../interfaces/CreateReactivityOptions.md) = `{}` ## Returns `SDK` --- # /docs/typescript/api/reactivity/functions/unwrap [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [reactivity](../README.md) / unwrap # Function: unwrap() > **unwrap**\<`T`\>(`result`): `T` Defined in: packages/sdk/src/reactivity/index.ts:236 Turn an upstream result into a value or a throw. Every `@somnia-chain/reactivity` method resolves to `T | Error` rather than throwing — a shape a caller can forget to check, then treat a failure as a transaction hash. This SDK's contract is that failures throw (CONVENTIONS.md), so wrap upstream calls in `unwrap` to get that back. **Details** - `result`: Whatever an upstream reactivity method resolved to. - Returns: `result`, narrowed to exclude `Error`. **Gotchas** - Throws The `Error` upstream returned, unchanged. **Example** (Unwrapping an upstream result) ```ts import { unwrap } from "@somnia-chain/markets-sdk/reactivity"; // Throws on a rejected subscription instead of returning an Error object. const hash = unwrap( await reactivity.subscribe({ handlerContractAddress, filter: { emitter }, options }), ); ``` ## Type Parameters ### T `T` ## Parameters ### result `Error` \| `T` ## Returns `T` --- # /docs/typescript/api/reactivity/interfaces/CreateReactivityOptions [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [reactivity](../README.md) / CreateReactivityOptions # Interface: CreateReactivityOptions Defined in: packages/sdk/src/reactivity/index.ts:151 Optional extras for [createReactivity](../functions/createReactivity.md). ## Properties ### wallet? > `optional` **wallet?**: `object` Defined in: packages/sdk/src/reactivity/index.ts:157 Wallet client that signs the subscription writes; its account becomes the subscription OWNER and funds every callback. Omit for read-only / `watch`-only use. --- # /docs/typescript/api/reactivity/interfaces/ReactivityEvent [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [reactivity](../README.md) / ReactivityEvent # Interface: ReactivityEvent Defined in: packages/sdk/src/reactivity/index.ts:112 One matched log plus the results of the subscription's `ethCalls`, both read at the same block — the thing a `somnia_watch` subscription exists to deliver. Typed here because upstream types `onData` as `(data: any) => void`, so a caller gets no help at all; and because upstream's own `SubscriptionCallback` describes neither the envelope nor `address`. The shape below is what a live Shannon node actually sends (see test/reactivity.e2e.test.ts, which asserts it against the real chain). ## Properties ### address > **address**: `` `0x${string}` `` Defined in: packages/sdk/src/reactivity/index.ts:114 Contract that emitted the log. *** ### topics > **topics**: `` `0x${string}` ``[] Defined in: packages/sdk/src/reactivity/index.ts:116 Topics of the matched log, topic0 first. *** ### data > **data**: `` `0x${string}` `` Defined in: packages/sdk/src/reactivity/index.ts:118 ABI-encoded non-indexed data of the matched log. *** ### simulationResults > **simulationResults**: `` `0x${string}` ``[] Defined in: packages/sdk/src/reactivity/index.ts:120 Raw return data of each `ethCall`, in the order subscribed. --- # /docs/typescript/api/reactivity/interfaces/ReactivityNotification [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [reactivity](../README.md) / ReactivityNotification # Interface: ReactivityNotification Defined in: packages/sdk/src/reactivity/index.ts:139 What `watch`'s `onData` is actually called with. NOTE the nesting: viem's WebSocket transport unwraps the JSON-RPC envelope before handing it over, so the payload is at **`notification.result`** — not `notification.params.result`, which upstream's README and type docs still describe (verified against a live node). **Example** (Reading a notification) ```ts onData: (n: ReactivityNotification) => console.log(n.result.simulationResults) ``` ## Properties ### subscription > **subscription**: `string` Defined in: packages/sdk/src/reactivity/index.ts:141 The node's subscription id this notification belongs to. *** ### result > **result**: [`ReactivityEvent`](ReactivityEvent.md) Defined in: packages/sdk/src/reactivity/index.ts:143 The matched log + its atomic call results. --- # /docs/typescript/api/reactivity/variables/DEFAULT_SUBSCRIPTION_OPTIONS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [reactivity](../README.md) / DEFAULT\_SUBSCRIPTION\_OPTIONS # Variable: DEFAULT\_SUBSCRIPTION\_OPTIONS > `const` **DEFAULT\_SUBSCRIPTION\_OPTIONS**: `object` Defined in: packages/sdk/src/reactivity/index.ts:94 Callback gas/fee options for a subscription that doesn't care: no tip, a 20 gwei ceiling, 10M gas per callback. These are the protocol's own defaults (`SomniaExtensions.DEFAULT_*`), spelled out here because upstream's published build ships `defaultSubscriptionOptions` at runtime but leaves it out of its type declarations — a test pins these values against upstream's. The precompile's own rules on these: `gasLimit` must be in `(0, 200_000_000]`, and a non-zero `maxFeePerGas` must sit at least 6 gwei above `priorityFeePerGas` (pass `0` to skip that check). ## Type Declaration ### priorityFeePerGas > `readonly` **priorityFeePerGas**: `0n` = `0n` ### maxFeePerGas > `readonly` **maxFeePerGas**: `20000000000n` = `20_000_000_000n` ### gasLimit > `readonly` **gasLimit**: `10000000n` = `10_000_000n` --- # /docs/typescript/api/reactivity/variables/SOMNIA_REACTIVITY_PRECOMPILE_ADDRESS [**@somnia-chain/markets-sdk**](../../README.md) *** [@somnia-chain/markets-sdk](../../README.md) / [reactivity](../README.md) / SOMNIA\_REACTIVITY\_PRECOMPILE\_ADDRESS # Variable: SOMNIA\_REACTIVITY\_PRECOMPILE\_ADDRESS > `const` **SOMNIA\_REACTIVITY\_PRECOMPILE\_ADDRESS**: `Address` = `"0x0000000000000000000000000000000000000100"` Defined in: packages/sdk/src/reactivity/index.ts:79 The Somnia reactivity precompile — a privileged contract at the fixed address `0x…0100` on every Somnia network. Filter on it as the `emitter` to catch the precompile's own system ticks (`Schedule` / `BlockTick` / `EpochTick`). It has NO bytecode, so `eth_getCode` returns `0x` for it — presence cannot be probed that way. Use [isLocalPrecompileUnavailable](../../index/functions/isLocalPrecompileUnavailable.md) on the chain id instead.