Monaco Protocol SDK v1.0.29
This release adds a public market pulse feed, an all-markets funding-history endpoint, and cursor pagination for full order and trade history. It also widens the market-order price band, re-enables entry-attached TP/SL, and makes several portfolio and position figures more accurate. It rolls up the consumer-facing changes since v1.0.26 across every client (TypeScript, Rust REST, and Rust gRPC), so upgrading is recommended and there are a few action items worth reviewing before you deploy.Added
Market pulse feed
Newsdk.pulse.getPulse() (GET /api/v1/pulse, public — no auth) returns a cached market news and sentiment feed: generatedAt (ISO 8601 UTC, also the response ETag), watchlist, and items[] — each an asset ticker (or "MARKET" for a cross-asset story) with a sentiment of "Bullish", "Neutral", or "Bearish", a summary (≤240 chars), updatedAt, and sources[] (url, author, source, createdAt, relevance 1–5). The snapshot refreshes hourly; responses carry an ETag and support If-None-Match/304, and return 503 until the cache warms. Also on gRPC PulseService.GetPulse.
All-markets funding history
Newsdk.market.listAllFundingHistory(params?) (GET /api/v1/market/funding/history, public) returns settled funding across every perp market in one call, so you no longer fan out one listFundingHistory request per pair. Optional startTime/endTime (ms-epoch strings, inclusive on settledAt), page, pageSize (max 100), and orderBy ("ASC"/"DESC", default DESC); the response is { records, total, page, pageSize } and each FundingRecord carries its own tradingPairId. Also on gRPC MarketService.ListAllFundingHistory.
Cursor pagination for orders and trades
sdk.trading.getPaginatedOrders and sdk.profile.getUserTrades (gRPC ListOrders, GetUserTrades, ListUserTrades) accept a pageToken cursor and return a nextPageToken:
- Omit
pageTokenfor legacy page-number pagination — the recent hot window only. - Pass
pageToken: ""(empty string) to start a cursor walk over full history (hot and archived rows merged), newest first — or oldest first withorderBy: "ASC". - Pass a previous
nextPageTokento resume the walk.
nextPageToken is non-empty whenever a page returns any rows; a zero-row page with an empty token means the walk is exhausted. In cursor mode the exact total/page/totalPages counts are omitted (returned as 0).
Funding data on records and the screener
FundingRecordgains acarriedflag —truewhen the window settled at the carried last rate under the sparse-sample rule — andlistFundingHistoryacceptsorderBy("ASC"/"DESC").- Screener rows (
sdk.market.getScreener,ScreenerItem) gainlatestFundingRate(the latest capped settled rate, a decimal fraction per window) andlastFundingTime(window close, ms epoch). Both arenullfor spot pairs and for perps with no settled window yet.
Terminal position lifetime figures
Terminal position rows (CLOSED/LIQUIDATED/EXPIRED) now report lifetime totals instead of the sliver left before the final closing fill: size is the total quantity closed over the position’s life and isolatedMargin is the total initial margin allocated across its reducing executions. Two optional fields are added — netRealizedPnl (lifetime realized PnL net of trading fees and funding) and realizedRoe (that figure as a percentage of the total allocated initial margin, i.e. leverage-aware realized return). Both are absent, and the stored row values served instead, when a position’s reducing executions do not cover its whole lifetime. Open rows are unchanged.
Changed
Market-order price band widened to 1,000 bps
The mandatory server-side protective band around the reference price is now 1,000 bps (10%) — widened from 500 bps — and triggered TP/SL market legs use a wider 1,200 bps (12%) band. Market orders execute immediately-or-cancel: the quantity available inside the band fills and the remainder is cancelled; a zero-fill order still rejects as insufficient liquidity, and a market on a market with no usable reference price is still rejected as unavailable. A clientslippageToleranceBps can only tighten the band, never widen it. The fee-simulation endpoint’s default market slippage buffer follows the band to 1,000 bps, so preflight lock estimates match what placement reserves. No wire types changed.
Entry-attached TP/SL re-enabled
PassingtakeProfit/stopLoss on placeLimitOrder/placeMarketOrder is accepted again for margin entry orders under one-way semantics — the child direction follows the order side. The legs activate when the order fills and cancel if it is cancelled or expires unfilled. (This reverses the v1.0.26 rejection; spot and reduce-only orders still reject entry-attached TP/SL.)
Position-based closed-trade win rate
Closed-trade win statistics now classify each position (one flat→open→flat round-trip) once by its net realized PnL after all fees, rather than per closing fill.sdk.portfolio.getRealizedPnl().closedTrades adds a positions total (winners + losers + breakEven), and sdk.profile.getPortfolioStats().winLossRatio is position-based; count stays fill-based.
Batch orders reject time-in-force on market items
Batch order creation now rejectstimeInForce on MARKET items, matching the single-order endpoint — market orders take no time-in-force and always execute IOC-style inside the protective band. The SDK rejects this client-side before the request is sent.
Funding-state cadence
getFundingState().nextFundingTime now reflects a market’s actual settlement cadence, and estimatedNextFundingRate refreshes as new samples arrive.
Staging WebSocket ingress
Thestaging network preset now connects WebSockets to wss://ws-staging.apimonaco.xyz/ws (the development preset moved to wss://ws-develop.apimonaco.xyz/ws in v1.0.26). The previous wss://staging.apimonaco.xyz/ws path remains supported during the migration window, so custom wsUrl overrides and older SDK versions keep working unchanged.
Trade settlement status
On trade records (thesettlementStatus field on GetUserTrades/ListUserTrades in the REST and gRPC wire), the SETTLED_ON_CHAIN value is retired — the valid values are now PENDING, SETTLED (terminal), and FAILED. This is the trade-level settlement status only; the order lifecycle OrderStatus is unchanged and still includes SETTLED_ON_CHAIN.
Scoped maintenance mode
During a maintenance window the API keeps sign-in, order cancels, position closes, risk simulations, and delegated-session creation available, and rejects mutating operations (new and replace orders, TP/SL, margin changes, collateral transfers, deposits, withdrawals, faucet mint, delegated-agent config, and reward transfers). Rejected requests return REST503 with a stable OPERATIONS_BLOCKED code (gRPC UNAVAILABLE with x-maintenance-blocked metadata), so a deliberate maintenance block is distinguishable from a generic outage.
Fixed
Retryable 503 on matching-engine unavailability
POST /api/v1/positions/{positionId}/close, POST /api/v1/positions/{positionId}/tp-sl, POST /api/v1/pitpass/rewards/transfer, and GET /api/v1/orderbook/{tradingPairId} now return 503 (retryable) instead of 500 when the matching engine is momentarily unreachable or restarting. Requests and responses are unchanged; non-transient engine faults still return 500.
Upgrade
- Market band is now 1,000 bps. A market order can partially fill with the remainder cancelled;
slippageToleranceBpsonly tightens the band. Fee-simulation now defaults to a 1,000 bps market buffer. - Trade settlement status dropped
SETTLED_ON_CHAIN. If you read the trade-levelsettlementStatusover the wire, handle onlyPENDING,SETTLED, andFAILED— the orderstatusenum is unaffected. - Walk full history with a cursor. To read beyond the recent window, start with
pageToken: ""and follownextPageTokenuntil a zero-row page. - Entry-attached TP/SL works again for margin entries — attach
takeProfit/stopLossat placement instead of after the position opens if you prefer. - Treat maintenance
503s as retryable. A REST503withOPERATIONS_BLOCKED, and the matching-engine503s above, are safe to retry.

