Skip to main content

Monaco Protocol SDK v1.0.65

This release bounds the page-number item counts on seven more listing reads and fills two WebSocket gaps. sdk.profile.getUserTrades, sdk.positions.listPositions / listPositionHistory, the margin-account movement reads, and sdk.trading.listConditionalOrders / listTwapOrders now cap the legacy page-number total (and getUserTrades’s totalPages) at each listing’s pagination reach — exact up to pageSize × 10,000 rows and saturating there — so a caller with more history than page-number mode can page through reads the cap instead of driving an unbounded count, and page above 10,000 is now rejected. This is the saturating shape (no new field, unlike v1.0.64’s totalCapped on order history): the response schema is unchanged, only the count values move, and only for callers above the reach. Of the seven, only getUserTrades also offers cursor (pageToken) pagination — its SDK default, unchanged and still reporting no totals; the other six are page-number-only (page / pageSize). On the socket, sdk.ws.twapOrders now delivers a subscribe-time snapshot the way the other stateful channels do, and sdk.ws.instruments now carries each market’s baseIconUrl / quoteIconUrl. The instrument icons ride the existing frame handler; the TWAP snapshot — like every subscribe-time baseline — arrives through the optional onSnapshot callback, so a subscription already passing one receives it with no code change and one that omits it should add an onSnapshot handler to opt in.

Changed

Page-number listing counts are bounded by their pagination reach

Seven more listing reads now bound the legacy page-number count instead of counting a caller’s whole matching history on every page render:
  • sdk.profile.getUserTrades (GET /api/v1/accounts/trades; gRPC AccountsService.GetUserTrades and TradesService.ListUserTrades)
  • sdk.positions.listPositions (GET /api/v1/positions) and sdk.positions.listPositionHistory (GET /api/v1/positions/history)
  • sdk.marginAccounts.getMarginAccountMovements (GET /api/v1/margin/accounts/{marginAccountId}/movements) and sdk.marginAccounts.getParentMarginAccountMovements (GET /api/v1/margin/parent-margin-account/movements)
  • sdk.trading.listConditionalOrders (GET /api/v1/orders/conditional) and sdk.trading.listTwapOrders (GET /api/v1/orders/twap)
In legacy page-number mode the response total is now exact up to pageSize × 10,000 matching rows and saturates there; getUserTrades bounds totalPages the same way (exact up to 10,000, the last page page-number mode can reach). A caller with more matching rows than page-number mode can page through reads the capped figure rather than its lifetime total. page is capped at 10,000: a larger page is rejected as invalid input (page must be <= 10000) instead of fetching rows past the reported last page. getUserTrades is the only one of the seven with a cursor (pageToken) mode — its SDK default, unchanged: it still walks full history (hot and archived merged) and reports no totals (total / totalPages / page are 0), and its page-number totals stay deprecated in favour of that cursor; build “load more” UIs on its nextPageToken. The other six are page-number-only — page / pageSize, no pageToken — and total is simply the count they report (it is not deprecated). The response schema does not change on any of them — every field keeps its type — so there is nothing to adopt. The count values change only for a page-number caller above the reach: it now reads the saturated cap where it previously read an exact lifetime count. A page-number loop that stops at page >= totalPages keeps terminating; only code that reads total as an exact lifetime figure should treat a saturated value as “at least this many”. See Trade history, Positions, Margin accounts, and the API reference.

Fixed

The twapOrders channel delivers a subscribe-time snapshot

sdk.ws.twapOrders(handler, tradingPairId?, onSnapshot) now receives a subscribe-time snapshot ahead of the live frames, the way the other stateful channels do: one TwapOrderEventData row per owned non-terminal (PENDING / ACTIVE) TWAP parent, optionally scoped to the subscription’s trading pair, each row the same shape as a live twap_order_update with reason: "snapshot". Previously the server sent no TWAP snapshot, so the onSnapshot callback was inert and a baseline needed a REST read. The SDK plumbing was already in place, so the baseline reaches only subscriptions that pass an onSnapshot handler: a caller already passing one receives it with no code change, and a caller subscribing as sdk.ws.twapOrders(handler) should add an onSnapshot handler to opt in. An empty baseline arrives as onSnapshot([]); if the read is unavailable the subscription surfaces SNAPSHOT_UNAVAILABLE and stays active while live diffs keep flowing.

The instruments channel carries base and quote asset icon URLs

sdk.ws.instruments(handler, tradingPairId?, onSnapshot) now surfaces baseIconUrl and quoteIconUrl (string | null) on each parsed InstrumentEventData, on both the subscribe-time snapshot and the live frames. The server sends each key present on every market (spot and perp) — an explicit null when that asset has no configured icon, never a synthesized URL — and the parser reads it tolerantly, mapping a missing key to null so a frame is never dropped for want of it. InstrumentEventData gains the two fields as optional (baseIconUrl? / quoteIconUrl?), so the addition is non-breaking for code that constructs or mocks the shape. A client can now join a position’s tradingPairId to the instrument row and render both icons without a REST read.

Upgrade

The response schemas are additive-safe — no signature changes to adopt. Two behaviours differ: a page-number caller with more than pageSize × 10,000 matching rows on the seven bounded listings now reads a saturated total (treat it as “at least this many”), and the twapOrders and instruments WebSocket channels now deliver data — a TWAP snapshot and asset icon URLs — that clients previously fetched over REST.