Skip to main content

Monaco Protocol SDK v1.0.72

This release gives copy trading followers close and top-up controls — close a follow’s copy positions at market while keeping the follow, and add margin to a single copy position from the copy account — makes fee tiers wallet-level across applications, ties every delegated session to an active grant, and has the positions channel send a frame for every position a fill or a margin move touches. TWAP updates gain a reconciliation version. Action items: if you run bots on delegated sessions, an expired or inactive grant now ends reads, refresh and WebSocket access as well as trading, so renew grants before they lapse; and if you keep positions in sync off the positions channel, expect more frames per fill and handle the new margin_added / margin_reduced transfer frames, some of which are unranked.

Added

Close copy positions and add copy-position margin

sdk.copyTrading.closeFollowPositions(followId) (POST /api/v1/copy-trading/follows/{followId}/close-positions; gRPC CopyTradingService.CloseFollowPositions) and sdk.copyTrading.closeAllCopyPositions() (POST /api/v1/copy-trading/follows/close-positions; gRPC CopyTradingService.CloseAllCopyPositions) close copy positions at market, reduce-only and immediate-or-cancel, and cancel the resting orders and conditional orders (TP/SL) on the copy risk buckets, keeping the follows: the leader’s next trades keep mirroring, so a close is not a flatten guarantee. Closes are exits — never gated by copy trading being switched off or an operations block; only a delegated agent session is refused (403). Both share a per-account rate limit of about one close per second, burst 5 (429 with Retry-After). The response comes once each batch is durably logged; closeAllCopyPositions returns follows, stoppingFollowIds and failedFollows ({ followId, reason }, a fixed sentence to retry on). sdk.copyTrading.addFollowPositionMargin({ followId, tradingPairId, amount }) (POST /api/v1/copy-trading/follows/{followId}/position-margin; gRPC CopyTradingService.AddFollowPositionMargin) moves amount from the follow’s copy account into the margin of its isolated copy position on tradingPairId, and returns followId, tradingPairId, riskBucketId, positionId, positionMargin and copyAccountAvailable after the add. The margin account is never touched. It opens no exposure, so it works while copy trading is switched off and on a CLOSE_ONLY follow; there is no margin reduction — a follow exits by being stopped. Master account sessions only (403 for delegated agent and sub-account sessions); 404 for a follow that is not yours; 409 while the follow is stopping or once it is stopped, or with COPY_TRADING_UNAVAILABLE when copy trading is not available on the platform; 400 COPY_TRADING_REJECTED when the engine refuses; 429 over the movement budget. It is not idempotent: after a timeout, read the follow before retrying. React’s useCopyTrading() exposes all three, and the MCP server adds close_follow_positions and close_all_copy_positions (market-maker profile) and add_follow_position_margin (fund movement, full profile). See Copy Trading.

TWAP updates carry a version

twap_order_update frames and the twap_orders subscribe-time snapshot rows gain an optional version. Compare it only within one twapOrderId: accept >=, ignore lower versions, let the snapshot win an equal-version tie, and expect gaps. An absent version means unknown legacy state, not zero. See WebSockets.

Changed

Fee tiers are wallet-level

A wallet’s rolling 14-day weighted volume (14d perp + 2.5 × 14d spot) now sums its trades across every application it trades through, and that one total sets its maker/taker tier on every application. Previously each application tiered the wallet on its own share alone. GET /api/v1/fees/tier (gRPC FeesService.GetMyFeeTier) keeps its fields; weightedVolume14d, spotVolume14d, perpVolume14d, the tier, volumeToNextTier and nextTierLevel now report wallet-wide values, the same from any application. The change applies from the next daily recompute at 00:00 UTC, and a wallet signing in to a new application starts there at its wallet tier, not Tier 1. Builder fees (applicationTakerFee) are unchanged. See Fees.

Position frames cover every touched position

A fill sends a live positions frame for every open position in each risk bucket it touched, taker and makers alike — in a cross risk bucket that is every position of the bucket, in any pair, because a trade in one pair moves the others’ liquidation price. Each position is sent at most once per fill, with the fill’s version. Collateral transfers send margin_added or margin_reduced frames. A direct isolated-position margin add or reduction, and a copy-position margin add (the isolated child plus its copy cross risk bucket’s positions), are ranked at the command’s version. Cross-risk-bucket ALLOCATE / RELEASE and copy follow or stop refreshes are unranked, because those commands write no position rows. Wallet IN / OUT and plain isolated allocation send no position frame. Transfer frames are built from the command’s post-command state and released only after its durable acknowledgement. See WebSockets.

Fixed

Delegated sessions follow their grant

Signed REST and gRPC requests, WebSocket authentication and periodic revalidation, and POST /api/v1/auth/refresh all require an active owner/agent grant, including for sessions created before this release. An expired or inactive grant now ends reads and refresh as well as trading. CreateDelegatedSession (POST /api/v1/delegated-agents/sessions) and refresh return expiresAt (Unix seconds) bounded by the grant’s expiry; fields are unchanged. Renewing an expired grant requires owner reauthorization, and revocation does not cancel orders. The delegated agent docs also now state that maxOpenOrders is unsupported (requests that set it are rejected) and that a grant’s market and account scopes limit trading only: an active delegated session can read the owner’s account data whatever its scopes. See Delegated Agents.

Upgrade

Every new field and method is additive, so existing code type-checks against 1.0.72 unchanged. Two behavior changes still need attention: delegated-session automation loses read, refresh and WebSocket access once its grant expires or goes inactive, so renew grants before they lapse; and a positions consumer receives more frames per fill plus margin_added / margin_reduced transfer frames, some unranked, so match reason with a default branch and reconcile unranked frames by field comparison.