@somnia-chain/markets-sdk / index / SomniaMarkets
Class: SomniaMarkets
Defined in: packages/sdk/src/unified/exchange.ts:154
The exchange — the SDK's single entry point. One instance per chain; wraps
the native engine (watches, local books, one-round-trip writes) behind
symbols, fetch*/watch* verbs, and human-unit structs — the idioms every
exchange bot already speaks (ccxt users will feel at home, down to the
field names).
When to use
Use as the entry point for strategy and display code — numbers are human units, which is what that code wants. Reach past it to the native engine at SomniaMarkets.client (bigint-exact reads) and SomniaMarkets.trader (raw writes) for everything the unified surface doesn't cover.
Details
Verb conventions:
fetch*— one-shot (a chain or indexer round-trip).watch*— streaming: each await resolves on the NEXT update of that channel, served from the zero-round-trip local store (the first call hydrates the ref-counted market watch).create*/cancel*— writes (fixed fees, one-round-trip confirm).
Every struct carries the raw native payload under info for exact math.
Each instance is fully isolated — its own config, live store, and lazily opened WebSocket (an indexer-only exchange never opens one) — so one process can run several: a bot per chain, per-request servers, parallel tests.
Gotchas
Call SomniaMarkets.close to release the watches when done. The native engine is not separately constructible — it is only reachable through an exchange instance.
Example
Load the market registry, stream a book, place a limit order.
import { SomniaMarkets } from "@somnia-chain/markets-sdk";
const exchange = new SomniaMarkets({
chain, // a viem Chain
wsRpcUrl, // wss:// RPC of that chain
indexerUrl, // the Envio/Hasura GraphQL endpoint
addresses, // contract addresses (e.g. from @somnia-chain/deployments)
privateKey, // optional — only createOrder & friends need a signer
});
await exchange.loadMarkets();
const book = await exchange.watchOrderBook("BTC-95000-31DEC26/USDC#YES"); // live, zero RTT
const order = await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 10, 0.62);
await exchange.close();
Constructors
Constructor
new SomniaMarkets(
config):SomniaMarkets
Defined in: packages/sdk/src/unified/exchange.ts:232
Parameters
config
Returns
SomniaMarkets
Properties
client
readonlyclient:SomniaMarketsClient
Defined in: packages/sdk/src/unified/exchange.ts:156
The native engine — bigint-exact, address-keyed. The escape hatch.
markets
markets:
Record<string,UnifiedMarket> ={}
Defined in: packages/sdk/src/unified/exchange.ts:158
Unified markets keyed by MARKET symbol (populated by loadMarkets).
symbols
symbols:
string[] =[]
Defined in: packages/sdk/src/unified/exchange.ts:160
All market symbols (populated by loadMarkets).
has
readonlyhas:object
Defined in: packages/sdk/src/unified/exchange.ts:166
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
readonlyfetchMarkets:true=true
fetchOrderBook
readonlyfetchOrderBook:true=true
fetchTrades
readonlyfetchTrades:true=true
fetchOHLCV
readonlyfetchOHLCV:true=true
fetchBalance
readonlyfetchBalance:true=true
fetchOpenOrders
readonlyfetchOpenOrders:true=true
fetchMyTrades
readonlyfetchMyTrades:true=true
fetchStatus
readonlyfetchStatus:true=true
createOrder
readonlycreateOrder:true=true
cancelOrder
readonlycancelOrder:true=true
watchOrderBook
readonlywatchOrderBook:true=true
watchTrades
readonlywatchTrades:true=true
watchOrders
readonlywatchOrders:true=true
watchMyTrades
readonlywatchMyTrades:true=true
fetchPositions
readonlyfetchPositions:true=true
fetchFundingRate
readonlyfetchFundingRate:true=true
SomniaMarkets.fetchFundingRate
fetchFundingRateHistory
readonlyfetchFundingRateHistory:true=true
SomniaMarkets.fetchFundingRateHistory — the key did not previously exist in this map, so it had to be ADDED rather than flipped.
watchPrice
readonlywatchPrice:true=true
fetchPrice
readonlyfetchPrice:true=true
fetchPriceOHLCV
readonlyfetchPriceOHLCV:true=true
Accessors
trader
Get Signature
get trader():
Trader
Defined in: packages/sdk/src/unified/exchange.ts:249
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
walletAddress
Get Signature
get walletAddress():
`0x${string}`|undefined
Defined in: packages/sdk/src/unified/exchange.ts:274
The authenticated wallet address, if a signer was configured.
Returns
`0x${string}` | undefined
Methods
setSigner()
setSigner(
signer):void
Defined in: packages/sdk/src/unified/exchange.ts:262
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, "privateKey" | "account" | "walletClient">
Returns
void
loadMarkets()
loadMarkets(
reload?):Promise<Record<string,UnifiedMarket>>
Defined in: packages/sdk/src/unified/exchange.ts:301
Load (or reload) the market registry: every market as a unified, symbol-keyed market object. Call once before anything symbol-based.
Parameters
reload?
boolean = false
Returns
Promise<Record<string, UnifiedMarket>>
market()
market(
ref):Tradable
Defined in: packages/sdk/src/unified/exchange.ts:452
Resolve any handle (symbol, tradable symbol, pool/market address, market id) to its tradable. Requires loadMarkets().
Parameters
ref
string
Returns
priceToPrecision()
priceToPrecision(
ref,price):number
Defined in: packages/sdk/src/unified/exchange.ts:472
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 — so a pool recycled mid-session keeps the
grid captured at load time until loadMarkets(true) refreshes it.
Parameters
ref
string
price
number
Returns
number
Throws
InvalidInputError 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.
amountToPrecision()
amountToPrecision(
ref,amount):number
Defined in: packages/sdk/src/unified/exchange.ts:493
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 — so a pool recycled mid-session keeps the
grid captured at load time until loadMarkets(true) refreshes it.
Parameters
ref
string
amount
number
Returns
number
Throws
InvalidInputError 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.
fetchMarkets()
fetchMarkets():
Promise<UnifiedMarket[]>
Defined in: packages/sdk/src/unified/exchange.ts:510
Every market as an array — loadMarkets (called if needed), minus the symbol keying.
When to use
Use as the ccxt-shaped sibling for list-style consumers.
Returns
Promise<UnifiedMarket[]>
fetchOrderBook()
fetchOrderBook(
ref,limit?):Promise<UnifiedOrderBook>
Defined in: packages/sdk/src/unified/exchange.ts:638
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.
Parameters
ref
string
limit?
number = 10
Returns
Promise<UnifiedOrderBook>
fetchTrades()
fetchTrades(
ref,since?,limit?):Promise<UnifiedTrade[]>
Defined in: packages/sdk/src/unified/exchange.ts:648
Recent public trades (indexer, newest first).
Parameters
ref
string
since?
number
limit?
number = 50
Returns
Promise<UnifiedTrade[]>
fetchOHLCV()
fetchOHLCV(
ref,timeframe?,since?,limit?):Promise<UnifiedOHLCV[]>
Defined in: packages/sdk/src/unified/exchange.ts:679
OHLCV candles (indexer), oldest first as [ms,o,h,l,c,vol] rows. Timeframes: 1m 5m 15m 1h 4h 1d.
Parameters
ref
string
timeframe?
string = "5m"
since?
number
limit?
number = 500
Returns
Promise<UnifiedOHLCV[]>
Example
The last 24 hourly candles, destructured per row.
const candles = await exchange.fetchOHLCV("SOMI/USDC", "1h", undefined, 24);
for (const [ts, open, high, low, close, volume] of candles) {
console.log(new Date(ts).toISOString(), open, high, low, close, volume);
}
fetchTicker()
fetchTicker(
ref):Promise<UnifiedTicker>
Defined in: packages/sdk/src/unified/exchange.ts:706
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.
Parameters
ref
string
Returns
Promise<UnifiedTicker>
Example
Drive a price strip off one call.
const tk = await exchange.fetchTicker("SOMI/USDC");
console.log(tk.last, tk.percentage, tk.baseVolume);
fetchBalance()
fetchBalance():
Promise<UnifiedBalances>
Defined in: packages/sdk/src/unified/exchange.ts:812
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.
Returns
Promise<UnifiedBalances>
Example
ERC-20s key by currency code; binary outcome holdings key by TRADABLE symbol.
const bal = await exchange.fetchBalance();
console.log(bal.USDC?.total); // collateral in the wallet
console.log(bal["BTC-95000-31DEC26/USDC#YES"]?.total); // YES shares held
Throws
SignerRequiredError - balances are per-account, so this needs
a signer (or an account) even though it only reads.
Throws
IndexerError - loadMarkets() needed the indexer and it was
unreachable. Distinct from an empty result: no balances is {}, not a throw.
Throws
RpcError - a chain balance read did not complete.
fetchOpenOrders()
fetchOpenOrders(
ref?):Promise<UnifiedOrder[]>
Defined in: packages/sdk/src/unified/exchange.ts:863
Open orders (indexer view).
When to use
Use for an occasional snapshot; a trading loop should prefer watchOrders.
Gotchas
The indexer view lags the chain slightly.
Parameters
ref?
string
Returns
Promise<UnifiedOrder[]>
fetchOrders()
fetchOrders(
ref?,since?,limit?,params?):Promise<UnifiedOrder[]>
Defined in: packages/sdk/src/unified/exchange.ts:894
The wallet's orders across every lifecycle status (indexer), newest
first — the history counterpart to fetchOpenOrders. Scope to one
tradable with ref; page with limit/params.offset.
Parameters
ref?
string
since?
number
limit?
number = 100
params?
offset?
number
Returns
Promise<UnifiedOrder[]>
Example
The last 50 orders on one book, whatever became of them.
const orders = await exchange.fetchOrders("SOMI/USDC", undefined, 50);
for (const o of orders) console.log(o.status, o.side, o.amount, o.txHash);
fetchPortfolioAnalytics()
fetchPortfolioAnalytics(
timeframe,params?):Promise<PortfolioAnalytics>
Defined in: packages/sdk/src/unified/exchange.ts:1017
The wallet's portfolio metrics plane over a timeframe: equity curve (cumulative realized + unrealized PnL), 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.
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.
Parameters
timeframe
params?
sessionSince?
number
cexRateBps?
number
Returns
Promise<PortfolioAnalytics>
Example
const p = await exchange.fetchPortfolioAnalytics("7d");
console.log(p.pnl.totalUsd, p.mwrr.return, p.equity.length);
fetchMyTrades()
fetchMyTrades(
ref?,since?,limit?):Promise<UnifiedTrade[]>
Defined in: packages/sdk/src/unified/exchange.ts:1106
My historical trades (indexer portfolios).
Parameters
ref?
string
since?
number
limit?
number = 50
Returns
Promise<UnifiedTrade[]>
fetchStatus()
fetchStatus():
Promise<{status:"error"|"ok"|"connecting";updated:number;info:TailStatus; }>
Defined in: packages/sdk/src/unified/exchange.ts:1160
Exchange health.
Details
"ok" unless a live watch is missing its socket — "connecting" while the first WS handshake is still in flight (~1s after a watch opens), "error" once a previously-live socket is lost.
Returns
Promise<{ status: "error" | "ok" | "connecting"; updated: number; info: TailStatus; }>
watchOrderBook()
watchOrderBook(
ref,limit?):Promise<UnifiedOrderBook>
Defined in: packages/sdk/src/unified/exchange.ts:1263
Streaming book off the local store: zero round-trips, current to the last block; each await resolves on the next book change.
Parameters
ref
string
limit?
number = 10
Returns
Promise<UnifiedOrderBook>
Example
A quoting loop: wake on every book change, read the touch.
while (true) {
const book = await exchange.watchOrderBook("SOMI/USDC", 5);
const [bestBid] = book.bids[0] ?? [];
const [bestAsk] = book.asks[0] ?? [];
console.log(`bid ${bestBid} / ask ${bestAsk}`);
}
watchTrades()
watchTrades(
ref,limit?):Promise<UnifiedTrade[]>
Defined in: packages/sdk/src/unified/exchange.ts:1288
Streaming public trades (the live tape), newest first.
Parameters
ref
string
limit?
number = 50
Returns
Promise<UnifiedTrade[]>
Example
Print each fill as it lands ([0] is always the latest).
while (true) {
const [latest] = await exchange.watchTrades("SOMI/USDC", 1);
if (latest) console.log(`${latest.side ?? "?"} ${latest.amount} @ ${latest.price}`);
}
watchOrders()
watchOrders(
ref,limit?):Promise<UnifiedOrder[]>
Defined in: packages/sdk/src/unified/exchange.ts:1333
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".
Parameters
ref
string
limit?
number = 100
Returns
Promise<UnifiedOrder[]>
Example
Place a limit order, then block until it fully fills (or dies).
const placed = await exchange.createOrder(symbol, "limit", "buy", 10, 0.62);
while (placed.status === "open") {
const orders = await exchange.watchOrders(symbol); // resolves on the next change
const mine = orders.find((o) => o.id === placed.id);
if (!mine || mine.status !== "open") break; // filled, canceled, or expired
}
watchMyTrades()
watchMyTrades(
ref,limit?):Promise<UnifiedTrade[]>
Defined in: packages/sdk/src/unified/exchange.ts:1370
Streaming view of MY fills on this tradable (authenticated).
Parameters
ref
string
limit?
number = 50
Returns
Promise<UnifiedTrade[]>
watchPrice()
watchPrice(
asset):Promise<UnifiedPrice>
Defined in: packages/sdk/src/unified/exchange.ts:1416
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>
fetchPrice()
fetchPrice(
asset):Promise<UnifiedPrice|null>
Defined in: packages/sdk/src/unified/exchange.ts:1430
One-shot current price (indexer HTTP read; no watch needed), or null if the feed has no observations yet.
Parameters
asset
string
Returns
Promise<UnifiedPrice | null>
fetchPriceOHLCV()
fetchPriceOHLCV(
asset,timeframe?,since?,limit?):Promise<UnifiedOHLCV[]>
Defined in: packages/sdk/src/unified/exchange.ts:1446
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[]>
createOrder()
createOrder(
ref,type,side,amount,price?,params?):Promise<UnifiedOrder>
Defined in: packages/sdk/src/unified/exchange.ts:1512
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 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 / amountToPrecision makes
this a no-op, since aligning an aligned value changes nothing.
Note 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 rather than silently placing a zero-quantity order.
Parameters
ref
string
type
"market" | "limit"
side
"buy" | "sell"
amount
number
price?
number
params?
CreateOrderParams = {}
Returns
Promise<UnifiedOrder>
Example
Rest a bid at 62% on YES, then take the NO book at market.
const rested = await exchange.createOrder("BTC-95000-31DEC26/USDC#YES", "limit", "buy", 25, 0.62);
console.log(rested.status, rested.filled); // "open" 0 — or "closed" if it crossed
const taken = await exchange.createOrder("BTC-95000-31DEC26/USDC#NO", "market", "sell", 10, undefined, {
slippage: 0.02, // accept up to 2% past the best bid
});
Throws
SignerRequiredError - the exchange was built without a
privateKey / account / walletClient.
Throws
InvalidInputError - 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 - the chain rejected the order. Branch on
errorName for the protocol's own reason (e.g. InsufficientBalance,
ExpiredOrderMustBeCancelled).
Throws
RpcError - the send never got an answer from the node.
Throws
IndexerError - a symbol lookup needed the indexer and it was unreachable.
cancelOrder()
cancelOrder(
id,ref):Promise<{id:string;symbol:string;status:"canceled";info:unknown; }>
Defined in: packages/sdk/src/unified/exchange.ts:1687
Cancel a resting order by id (from createOrder / watchOrders).
Parameters
id
string
ref
string
Returns
Promise<{ id: string; symbol: string; status: "canceled"; info: unknown; }>
Example
const placed = await exchange.createOrder("SOMI/USDC", "limit", "buy", 10, 0.55);
if (placed.status === "open") await exchange.cancelOrder(placed.id, "SOMI/USDC");
Throws
SignerRequiredError - no signer on this exchange.
Throws
InvalidInputError - unknown symbol.
Throws
ContractRevertError - the cancel did not land; errorName says
why (an already-filled or already-canceled order reverts).
Throws
RpcError - the send never got an answer from the node.
createStopOrder()
createStopOrder(
ref,type,side,amount,triggerPrice,price?,params?):Promise<UnifiedStopOrder>
Defined in: packages/sdk/src/unified/exchange.ts:1747
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.
Parameters
ref
string
type
"market" | "limit"
side
"buy" | "sell"
amount
number
triggerPrice
number
price?
number
params?
triggerDirection?
"above" | "below"
Returns
Promise<UnifiedStopOrder>
Example
A stop-loss: sell 5 if the mark drops to 1.10.
const stop = await exchange.createStopOrder("SOMI/USDC", "market", "sell", 5, 1.10);
// …later: await exchange.cancelStopOrder(stop.id, "SOMI/USDC");
fetchOpenStopOrders()
fetchOpenStopOrders(
ref?):Promise<UnifiedStopOrder[]>
Defined in: packages/sdk/src/unified/exchange.ts:1863
The wallet's pending (armed, untriggered) stop orders, newest first.
Scope to one tradable with ref.
Parameters
ref?
string
Returns
Promise<UnifiedStopOrder[]>
cancelStopOrder()
cancelStopOrder(
id,ref):Promise<{id:string;symbol:string;status:"canceled";info:unknown; }>
Defined in: packages/sdk/src/unified/exchange.ts:1899
Cancel a pending stop order on its registry (refunds the keeper
payment). id comes from fetchOpenStopOrders.
Parameters
id
string
ref
string
Returns
Promise<{ id: string; symbol: string; status: "canceled"; info: unknown; }>
fetchFundingRate()
fetchFundingRate(
ref):Promise<UnifiedFundingRate>
Defined in: packages/sdk/src/unified/exchange.ts:1917
Live funding-rate + mark/index snapshot for a perp market (chain read).
Parameters
ref
string
Returns
Promise<UnifiedFundingRate>
fetchFundingRateHistory()
fetchFundingRateHistory(
ref,since?,limit?):Promise<UnifiedFundingRate[]>
Defined in: packages/sdk/src/unified/exchange.ts:1983
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.
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
market symbol or pool address
since?
number
unix MILLISECONDS (ccxt convention), inclusive; acts as a forward cursor
limit?
number
max rows (default 100)
Returns
Promise<UnifiedFundingRate[]>
fetchPositions()
fetchPositions(
refs?):Promise<UnifiedPosition[]>
Defined in: packages/sdk/src/unified/exchange.ts:2019
Open perp positions (authenticated; on-chain MarginBank reads). Pass symbols to scope; defaults to every loaded perp market.
Parameters
refs?
string[]
Returns
Promise<UnifiedPosition[]>
depositMargin()
depositMargin(
ref,amount):Promise<{hash:string;info:unknown; }>
Defined in: packages/sdk/src/unified/exchange.ts:2084
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:2100
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:2135
Mint complete sets: amount collateral → amount of EVERY outcome.
Parameters
ref
string
amount
number
Returns
Promise<{ hash: string; info: unknown; }>
Example
Mint 100 sets (100 USDC → 100 YES + 100 NO), then sell the side you don't want.
await exchange.mintSet("BTC-95000-31DEC26/USDC", 100);
await exchange.createOrder("BTC-95000-31DEC26/USDC#NO", "limit", "sell", 100, 0.38);
burnSet()
burnSet(
ref,amount):Promise<{hash:string;info:unknown; }>
Defined in: packages/sdk/src/unified/exchange.ts:2147
Burn complete sets back to collateral.
Parameters
ref
string
amount
number
Returns
Promise<{ hash: string; info: unknown; }>
redeem()
redeem(
ref,amount):Promise<{hash:string;info:unknown; }>
Defined in: packages/sdk/src/unified/exchange.ts:2171
Redeem winning outcome tokens for collateral (post-resolution). Settlement-
extraction v2: module-routed by marketId (the winning outcome is read off
the BinaryMarket contract when not resolved yet in the indexed row).
Parameters
ref
string
amount
number
Returns
Promise<{ hash: string; info: unknown; }>
Example
After resolution, redeem the winning side found in the balance map.
const bal = await exchange.fetchBalance();
const winning = bal["BTC-95000-31DEC26/USDC#YES"]?.total ?? 0;
if (winning > 0) await exchange.redeem("BTC-95000-31DEC26/USDC", winning);
close()
close():
Promise<void>
Defined in: packages/sdk/src/unified/exchange.ts:2207
Release every watch + channel this exchange holds and stop the client's live machinery.
Details
The instance stays usable for one-shot fetch calls.
Returns
Promise<void>