> ## 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.

# V1.0.57

# Monaco Protocol SDK v1.0.57

This release covers the consumer-facing changes since v1.0.56. The order listing is now unified: `GET /api/v1/orders` returns book orders, TWAP parents and conditional orders as one timestamp-sorted stream, and `orderType` gains two response-only values to name each row's kind — code that switches exhaustively on it must handle them. `@0xmonaco/contracts` ships a breaking sweeper ABI change that binds a quoted sweep to an exact amount. Batch replace now scopes every pre-sequencing validation failure to its own item instead of rejecting the whole batch, so a malformed item comes back as a failed item inside a `2xx` rather than a top-level rejection — read `results[]` per item. A TWAP parent's resting slice child can no longer be cancelled directly, closing a trap that charged taker fees for an order the caller believed cancelled. Unused execution collateral now returns to the margin account after any positive fill on a first-use isolated market order, not only a full one. And authenticated reads now draw a per-account budget, measured but not yet enforced.

## Breaking

### `SweepParams` binds a sweep to an exact amount

`SWEEPER_ABI` and `SWEEPER_FACTORY_ABI` change shape. `SweepParams` gains a leading `amount` field, so the complete tuple is now `(uint256 amount, uint256 minSwapOut, uint256 minBridgeOut, bytes lzExtraOptions)` — four fields, where it previously held the latter three. Calldata encoded against the previous shape produces arguments the new contracts reject — re-encode before upgrading.

`amount` is the exact balance the quote was computed for. The sweep moves exactly that much and leaves any excess — a deposit that landed after the quote — for the next, re-quoted sweep, so the `minSwapOut` / `minBridgeOut` minimums always cover the full swept amount and a later arrival can never dilute them. If the balance has fallen below the quoted amount by the time the sweep executes, the call reverts with the new `StaleQuote` error rather than sweeping less against minimums quoted for more; re-quote and retry.

`amount: 0n` binds nothing and sweeps the execution-time balance. It is accepted **only** on the direct CCTP route, whose burn is exact-amount and carries no minimum that could go stale. Every other route — Stargate, swap-then-bridge, and the hub unswap — rejects the zero sentinel with the new `QuoteNotBound` error. A sweep against an empty balance still reverts with `NothingToSweep`.

Both new errors are declared on `SWEEPER_ABI` only. `SWEEPER_FACTORY_ABI` gains the `amount` field on its `sweepWithParams` input but declares neither error, so a decoder built from the factory ABI alone cannot name a `StaleQuote` or `QuoteNotBound` revert bubbled up from the sweeper — give it both ABIs. `predictSweeperAddress(...)` and `encodeDepositApplicationData(...)` are unaffected — address derivation does not read `SweepParams`. See [Registered Deposit Addresses](/sdk/typescript/vault#registered-deposit-addresses).

## Changed

### One order listing for every kind of order

`GET /api/v1/orders` (gRPC `ListOrders`; `sdk.trading.getPaginatedOrders` and `iterateOrders`) returns book orders, TWAP parents and conditional orders in one stream sorted by timestamp. There is no separate open-orders endpoint: filter `status` to `SUBMITTED,PARTIALLY_FILLED` for the working set across all three kinds, in one request rather than one per kind.

```typescript theme={null}
const { orders } = await sdk.trading.getPaginatedOrders({
  status: ["SUBMITTED", "PARTIALLY_FILLED"],
});

for (const order of orders) {
  switch (order.orderType) {
    case "TWAP":
      console.log("twap", order.twap?.slicesPlaced, "of", order.twap?.plannedSlices);
      break;
    case "CONDITIONAL":
      console.log("conditional", order.conditional?.triggerPrice);
      break;
    default:
      console.log("book order", order.price, order.quantity);
  }
}
```

`orderType` names each row's kind and gains two response-only values, `TWAP` and `CONDITIONAL`. Neither can be placed: order creation still takes `LIMIT` or `MARKET`, and the two new kinds are created through their own endpoints. In `@0xmonaco/types` this is a type-level change — `Order.orderType` widens from `OrderType` to the new `ListedOrderType` (`"LIMIT" | "MARKET" | "TWAP" | "CONDITIONAL"`), while `OrderType` itself is unchanged and remains what you can place. An exhaustive `switch` or a `never` exhaustiveness check on `order.orderType` stops compiling until it handles the two new values.

A row of either kind carries its full detail under the new optional `twap` / `conditional` fields — the same shapes `GET /api/v1/orders/twap/{twapOrderId}` and the conditional-order endpoints return, so a client already handling those needs no new parsing. Exactly one is present, and only when `orderType` names that kind; a book order carries neither. The shared fields are populated from that detail, so a list renders without special-casing: a parent's `quantity` is its total and `filledQuantity` what it has executed, and `status` is its state expressed as an order status — a parent mid-execution reads `PARTIALLY_FILLED`, one that finished having executed nothing reads `EXPIRED`, and a conditional still waiting on its trigger reads `SUBMITTED`.

Existing filters (`status`, `tradingPairId`, `tradingMode`, `marginAccountId`), both pagination modes and the sort order are unchanged and apply to the merged stream. `tradingMode=SPOT` excludes conditional orders, which are margin-only. The dedicated `listTwapOrders` and `listConditionalOrders` calls are unchanged and remain the way to list one kind with its own filters.

The WebSocket `orders` channel is not affected: it still carries book orders only, and its subscribe-time snapshot has no field for either detail. See [Order queries](/sdk/typescript/trades#order-queries) and [List Orders](/developers/trade#list-orders).

### Batch replace fails per item, not per batch

`POST /api/v1/orders/batch-replace` (gRPC `BatchReplaceOrders`; `sdk.trading.batchReplace`) now scopes **every** pre-sequencing validation failure to its own item, matching batch create. A malformed `orderId`, `price`, `quantity` or `clientOrderId`, a `postOnly` violation against the persisted original, and a delegated-session item without a persisted original each fail alone — that item's result slot carries a structured `error.code` from batch create's vocabulary (`INVALID_ORDER_ID`, `INVALID_PRICE`, `INVALID_QUANTITY`, `INVALID_CLIENT_ORDER_ID`, `INVALID_POST_ONLY`, and `FORBIDDEN` for a delegated item without a persisted original) — while the batch's valid items proceed to the engine. A failed item's original order is never touched.

Previously one malformed item rejected the whole request with REST `400` / gRPC `INVALID_ARGUMENT` before anything executed. A `400` still means the batch did not execute — what changed is that a malformed item no longer produces one, so the case you have to handle now is a **`2xx` carrying per-item failures**: read `results[]` rather than inferring all-or-nothing from the top-level status. A batch whose items all fail validation returns `2xx` with every result failed and no engine round trip. Empty and oversize (more than 100 items) batches are the only input validation that still rejects the whole request; the endpoint's other top-level statuses (`401`, `429`, `500`) are unchanged.

On both batch create and batch replace, `totalSucceeded` / `totalFailed` are now derived from the merged `results[]`, so `totalRequested === totalSucceeded + totalFailed` holds on every response. An engine row that reports success without a payload is reported as an item error (`UNKNOWN_ERROR`) rather than counted as a success with no order to act on. No response shapes changed — `results[]` already carried per-item `{ code, message }` errors positionally.

Through the TypeScript SDK this is visible only for the checks the client-side schema cannot make, since its own Zod validation still rejects a malformed item before the request is sent: a `postOnly` shape violation against the persisted original, and a delegated item with no persisted original. Callers bypassing the schema see the full change. See [Batch Replace](/developers/trade#batch-replace).

### Authenticated reads draw a per-account budget

Every authenticated read now draws one request from a single per-account read budget: on REST every signed `GET` (plus the `POST` order-risk previews under `/api/v1/margin/…/simulate-order-risk`, which are reads), and on gRPC every `Get*`, `List*` and `Simulate*` RPC. The default is 30 requests per second sustained with a burst of 100. Writes are unaffected — they are metered by the existing order and movement budgets — and public, unauthenticated market data is not metered at all.

Delegated agent sessions share the owning account's read budget, because the budget is keyed to the resolved account; sub-accounts have their own. Reads return no budget headers: an over-budget read is the same contract as the other classes — REST `429` `RATE_LIMIT_EXCEEDED` with `Retry-After` and `details.retryAfter`, gRPC `RESOURCE_EXHAUSTED` with a `google.rpc.RetryInfo` detail — and the affected read operations now declare `429` in the API contract. Like the order budgets, the counters are held per API task rather than fleet-wide, so the published figure is the per-task quota.

Enforcement follows the same per-environment rollout as the order and movement budgets: until it is enabled where you trade, over-budget reads are admitted and only measured. Build the back-off handling now. Prefer the WebSocket streams for anything you would otherwise poll — order, position and balance updates arrive as events and cost no read budget. See [Rate limits](/developers/rate-limits#reads).

## Fixed

### A TWAP parent's resting slice child can no longer be cancelled directly

A `PASSIVE` TWAP parent rests one slice child on the book, and that child is a real order in the owner's book and index — so the public cancel path could reach it. Cancelling it succeeded, and that was a trap: the parent stayed live and swept the same slot as a **taker** at its deadline, so an order the trader believed cancelled came back and charged taker fees.

`POST /api/v1/orders/cancel` (the order id travels in the request body; gRPC `CancelOrder`) and the batch cancel forms now refuse a slice child with `order {orderId} is the resting slice child of TWAP parent {twapOrderId} and cannot be cancelled directly; cancel the parent instead`. Replace already refused it with the matching wording, so the parent is now the only control surface for its children on both paths.

`POST /api/v1/orders/twap/{twapOrderId}/cancel` is unchanged and remains the way to stop a TWAP — it cancels the resting child in the same atomic step. `POST /api/v1/orders/batch-cancel-all` and its by-pair form enumerate the owner's resting orders, so a slice child now appears there as one refused item naming its parent while every other order in the sweep still cancels; cancel-all does not stop TWAP parents. See [TWAP orders](/trading-mechanics/twap-orders).

### Unused execution collateral returns after a first-use isolated market order executes

Where automatic execution-collateral refunds are enabled, authenticated `MARKET` order creation through `POST /api/v1/orders` and batch order creation now release unused automatic collateral once a first-use `ISOLATED` order has executed. Any positive fill triggers it: a market order that filled only part of its quantity before the remainder was cancelled releases exactly as a fully filled one does, and the release is capped at the allocation the order originally drew. The initial execution-price and fee allowance still protects admission; settlement returns only the unused automatic allocation to the parent margin account, retaining position margin, fees, funding, losses, and the reserves of other live orders. Existing explicit collateral is untouched.

`POST /api/v1/margin/risk-buckets/simulate-order-risk` applies the same release, so projected `freeCollateralAfter` and `estimatedLiquidationPrice` reflect the final backing. Request fields are unchanged. A position's `isolatedMargin` can still sit above notional divided by leverage when the mark differs from the fill or other risk requirements consume collateral. An order that executed nothing at all releases through the ordinary cancellation-settlement rules instead.

The rollout defaults to off and is enabled per environment by an administrator through the authenticated `PUT /api/v1/feature-flags` endpoint, only once compatible verifier and proposer instances are healthy. While it is off, placement and preview retain the prior allocation behavior, and orders already recorded replay the release policy captured with them regardless of later flag changes. See [Perpetual futures](/trading-mechanics/perps).

## Upgrade

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

Three things to check before upgrading. If you encode `SweepParams` yourself, re-encode against the new leading `amount` field and add handling for `StaleQuote` and `QuoteNotBound` — the previous tuple shape is rejected. If you switch exhaustively on `order.orderType`, add the `TWAP` and `CONDITIONAL` branches; a list that assumed `GET /api/v1/orders` returned book orders only will now see parent rows. And if you call `batchReplace`, read `results[]` per item rather than inferring the outcome from the status alone — a `400` still means nothing executed, but a malformed item now comes back as a failed item inside a `2xx`.

The rest is additive or inert. `twap` and `conditional` are optional and absent on a book order. The read budget is measured rather than enforced until it is turned on per environment, so nothing that works today starts failing on upgrade — but adding `429` handling now costs nothing. The TWAP cancel change only refuses a request that previously produced a misleading success, and the execution-collateral release is off by default; when it is on it returns collateral rather than withholding it, on any positive fill.


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