> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xmonaco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# V0.8.21

# Monaco Protocol SDK v0.8.21

This release adds a new endpoint for fetching a single conditional (TP/SL) order by ID, ships a substantial update to realized-PnL accounting semantics, and fixes three correctness bugs: taker fee fields on filled orders reporting the wrong rate, cross-margin simulation failing before the first cross order, and ambiguous parent margin-account orders silently routing through the wrong path. The `conditional_orders` WebSocket channel now also gates on authentication at subscribe time.

## Added

### Get a conditional order by ID

A new endpoint fetches a single TP/SL conditional order directly by its UUID:

* **REST** — `GET /api/v1/orders/conditional/{conditionalOrderId}`
* **TypeScript SDK** — `sdk.trading.getConditionalOrder(conditionalOrderId)`
* **React SDK** — `useTrade().getConditionalOrder(conditionalOrderId)`
* **gRPC** — `OrdersService.GetConditionalOrder`

The returned `ConditionalOrder` is the same type produced by `listConditionalOrders`. The `takeProfitOrderId` and `stopLossOrderId` fields on a `createOrder` response are conditional order UUIDs queryable via this method.

```typescript theme={null}
const order = await sdk.trading.placeLimitOrder(pair.id, "BUY", "1.5", "2000", {
  tradingMode: "MARGIN",
  positionSide: "LONG",
  leverage: "10",
  takeProfit: { triggerPrice: "2200", orderType: "MARKET" },
});

// Look up the attached TP leg by ID
const tp = await sdk.trading.getConditionalOrder(order.takeProfitOrderId);
console.log(tp.state, tp.triggerPrice);
```

## Changed

### Realized PnL accounting semantics

`getPortfolioStats` (`pnl`) and `getPortfolioChart` (the `"pnl"` metric) now apply updated realized-PnL semantics as part of the unrealized-PnL rollout:

* **Spot withdrawals are fair-value disposals** — withdrawing a spot asset books `(last trade price − average cost) × quantity` as realized PnL, rather than treating the outflow as cash-neutral.
* **Deposits and withdrawals use last trade price** — cost-basis entries and disposal prices are now pinned to the last observed trade price for the pair in event order, instead of the covering 1-minute candle close.
* **Pre-first-trade transfers are PnL-neutral** — any deposit or withdrawal that occurs before the first trade on a pair does not generate realized PnL.
* **Short-entry fees reduce short profits** — fees paid on short position entry now reduce the profit of that short, rather than inflating it.

Response shape is unchanged; the `pnl` values will reflect the corrected accounting going forward.

## Fixed

### Taker order fee fields reported flat rate instead of tier rate

A filled order's fee response fields — `monacoTakerFee`, `totalTakerFees`, and `takerTotalPayment` — previously reported the trading pair's flat fee column rather than the tier-resolved rate that was actually debited at settlement. These fields now match the balance movement. Clients on a fee tier whose rate differs from the flat column will see corrected values; no request or response fields changed.

### Cross-margin simulation failed before the first cross order

`POST /api/v1/margin/risk-buckets/simulate-order-risk` (`sdk.marginAccounts.simulateRiskBucketOrderRisk`) with `marginMode: "CROSS"` previously returned an error when the user had no active cross risk bucket. The endpoint now uses the same deterministic cross risk bucket ID and first-use auto-collateral estimate as live order placement, so you can safely preflight a cross order before the bucket exists. No request or response fields changed.

### Ambiguous parent margin-account orders now fail fast

`POST /api/v1/orders` and `POST /api/v1/orders/batch-create` for a parent margin-account order that omits `marginMode` and does not provide an isolated risk-bucket selector previously silently routed through the isolated risk-bucket path. These requests now return a client error. Pass `marginMode: "CROSS"` or `marginMode: "ISOLATED"` for all parent margin-account margin orders. No request or response fields changed.

## Security

### `conditional_orders` WebSocket channel now requires authentication at subscribe time

The `conditional_orders` WebSocket channel (`sdk.ws.conditionalOrders`) now requires authentication when subscribing, matching the behavior of all other user-scoped channels (`orders`, `balances`, `positions`, `movements`, `liquidations`). Event delivery was already owner-scoped — this closes the subscribe-gate gap. No subscription API changes; unauthenticated subscribe attempts are now rejected.

## Upgrade

```bash theme={null}
npm install @0xmonaco/core@0.8.21 @0xmonaco/types@0.8.21 @0xmonaco/react@0.8.21
# or bun
bun add @0xmonaco/core@0.8.21 @0xmonaco/types@0.8.21 @0xmonaco/react@0.8.21
```

The only breaking-adjacent change in this release is the `conditional_orders` subscribe gate: unauthenticated subscribers will now receive a rejection instead of connecting successfully. Ensure your app authenticates before calling `sdk.ws.conditionalOrders(...)`. All other changes are additive or behavioral corrections with no shape changes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.