Monaco Protocol SDK v0.8.14
This release restructures the idless margin-collateral API into explicit parent margin account and risk bucket endpoints, adds a one-shot batch close for open positions, exposes raw total balances, and introduces thefx asset class for Pyth-backed FX perps.
Removed
Idless “auto margin account” collateral endpoints replaced
The two idless auto margin account shortcuts are removed and replaced by the explicit parent-margin-account / risk-bucket surface below:marginAccounts.transferCollateralToAutoMarginAccount({ asset, amount })—POST /api/v1/margin/collateral/transfer-inmarginAccounts.simulateAutoMarginOrderRisk(request)—POST /api/v1/margin/simulate-order-risk
transferCollateralToMarginAccount(marginAccountId, …), getMarginAccountSummary(marginAccountId, …), simulateOrderRisk(marginAccountId, …), etc.) are unchanged.
Migration:
tradingPairId (and optional strategyKey).
Added
Explicit parent-margin-account and risk-bucket collateral API
The idless margin surface is now split along the account model — one parent margin account per user/application, with isolated risk buckets nested underneath it (a bucket is created or reused pertradingPairId + optional strategyKey). No account id is required; the parent is resolved automatically from the caller.
All collateral transfers return
TransferCollateralResponse (movement_id, margin_account_id, asset, amount, status, new_equity, new_total_collateral_value, new_withdrawable_collateral). The simulate endpoints return SimulateOrderRiskResponse (accepted, reject_reason?, equity_after, initial_margin_required_after, maintenance_margin_required_after, free_collateral_after, estimated_fee?, estimated_liquidation_price?). All endpoints require user auth.
Batch close all open positions
NewPOST /api/v1/positions/batch-close-all (user auth) submits a MARKET reduce-only close for every open perp position — a one-call “panic close”. It is best-effort and partial: each position closes independently and per-position failures are reported rather than aborting the batch.
BatchCloseAllRequest, all optional): tradingPairId (limit to one pair; otherwise all open positions), slippageToleranceBps (per-close slippage tolerance).
Response (BatchCloseAllResponse): total_requested, total_closed (orders accepted — SUCCESS / PARTIAL / PENDING), total_failed, and results[] — each a BatchCloseResult with position_id, optional close_order_id, status, submitted_quantity, and an optional error ({ code, message }).
Available across @0xmonaco/core (sdk.positions.batchCloseAllPositions), @0xmonaco/react (usePositions().batchCloseAllPositions), and the batch_close_all_positions MCP tool.
Raw total balance
Balance responses gaintotal_balance_raw — the total balance (available + locked) as a raw integer string in the token’s smallest unit, alongside the existing normalized total_balance:
AccountBalance(GET /api/v1/accounts/balances) and the single-asset balance response (GET /api/v1/accounts/balances/{asset_id}).@0xmonaco/react’suseUserBalancespreservestotal_balance_rawacross WebSocket balance updates, mirroring the existing normalized-total handling.
available_balance / locked_balance / total_balance (and their _raw counterparts) are unchanged.
fx asset class
Pyth-backed FX perpetual markets add a fourth value to the trading-pair category enum: "fx" (joining "crypto", "equities", "commodities" from v0.8.11). It is accepted as a category filter on getPaginatedTradingPairs / getScreener and returned on TradingPair / ScreenerItem.
Changed
margin_bucket_* fields renamed to risk_bucket_*
Isolated-bucket fields are renamed from margin_bucket_* to risk_bucket_* across orders, positions, and margin responses. The gRPC field numbers are unchanged (binary gRPC clients are unaffected), but the JSON/REST key changes, so REST and TypeScript SDK consumers must update:
- Order placement —
placeLimitOrder/placeMarketOrderoptionsmarginBucketId→riskBucketIdandmarginBucketCollateral→riskBucketCollateral(wire:risk_bucket_id/risk_bucket_collateral).riskBucketIdroutes the order into an existing isolated bucket;riskBucketCollateralopens a new one. - Positions — the
Positionresponse fieldmargin_bucket_id→risk_bucket_id(GET /api/v1/positions,GET /api/v1/positions/{position_id}). - Margin — risk-bucket summary rows expose
risk_bucket_id.
Withdrawals migrated to merkle-proof executeWithdrawal
The withdrawal flow now submits an on-chain merkle-proof executeWithdrawal transaction, replacing the previous server-signed executeSignedWithdrawal path. Because the executable calldata needs the withdrawal’s merkle proof — which only exists once the root is confirmed on-chain — the SDK now polls GET /api/v1/withdrawals/{withdrawal_index} (which returns 404/409 until the proof is ready) before submitting. sdk.vault.withdraw(assetId, amount, autoWait?) and retryWithdrawal(...) keep their call signatures (new arguments are optional), so most call sites need only a version bump — but a v0.8.11 SDK uses the old signed-withdrawal flow (immediate executeSignedWithdrawal, no proof polling), which no longer works against the v0.8.14 backend and vault contract, so frontends must upgrade to the v0.8.14 SDK.
On a proof-poll timeout, withdraw() / retryWithdrawal() no longer throw — they resolve to { withdrawalIndex, status: "awaiting_proof" } with nothing submitted on-chain, so the caller keeps the index and can finish the withdrawal later via retryWithdrawal(withdrawalIndex). WithdrawResult.status gains "awaiting_proof" alongside "pending" / "confirmed" / "failed". The default proof-poll timeout is 5 minutes (override with retry.timeoutMs; pass Infinity to wait indefinitely).
sdk.vault.withdraw(assetId, amount, autoWait, "margin") can also source an external withdrawal directly from the parent margin account; retry options remain supported as the legacy fourth argument.
Address-shaped return types are now viem Address
Public SDK methods that return addresses now type them as viem’s Address (0x${string}) instead of string, so they flow into viem calls without a cast. SDK.getAccountAddress() returns Address and vault.getVaultAddress() returns Promise<Address>; address fields on returned response/event objects (account / profile / balances, applications config & reporting, market trading-pair contracts, delegated agents, vault balances, withdrawals, and the user balance/movement WebSocket events) are likewise typed as Address. This is a type-only change — no runtime behavior changes, and request/input address params remain string.

