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

# Monaco Protocol SDK v1.0.91

This release rolls up the consumer-facing changes shipped since v1.0.88. Fee simulation drops its deprecated whole-bps rate fields, and a TWAP `clientTwapId` is reserved for 30 days after its parent ends instead of forever. User trades gain margin account and order filters and a corrected `UserTrade` type, and `TradesService.ListUserTrades` is deprecated in favor of `AccountsService.GetUserTrades`. New public market reads cover trader positioning, taker trade flow and liquidation history, with a live `market_liquidations` channel and a React `useLiquidationFeed` hook. Sweeper deposits can be tracked by transaction hash, collateral transfers take an idempotency key, and `placeLimitOrder` / `placeMarketOrder` resend a lost response under the same key. **Action items:** read `monacoTakerFeeBpsExact` and `monacoMakerRebateBpsExact` instead of the removed integer rates; handle an absent `quoteVolume`, `fee` or `executedAt` on `UserTrade`; in Rust gRPC code, rename `trades::UserTrade` to `ListedUserTrade` and move to `AccountsServiceClient::get_user_trades`.

## Breaking

### Integer fee rates removed from fee simulation

`simulateFees` (`GET /api/v1/fees/simulate`; gRPC `FeesService.SimulateFees`) no longer returns `monacoTakerFeeBps` or `monacoMakerRebateBps`. They echoed the trading pair's flat rate, not the tier rate you are charged. Read `monacoTakerFeeBpsExact` and `monacoMakerRebateBpsExact` instead: decimal basis-point strings such as `"6.5"` that match the fee charged. The fields also leave the `SimulateFeeResponse` type, the Rust REST and gRPC clients and the OpenAPI spec. See [Trades](/sdk/typescript/trades).

### TWAP client keys are reserved for 30 days

A TWAP `clientTwapId` (`POST /api/v1/orders/twap`; gRPC `OrdersService.CreateTwapOrder`) is reserved while its parent is live and for 30 days after it ends, instead of forever. Inside that window a duplicate is still refused with `409`; after it, the same key creates a new parent. A keyed create is also refused with the retryable `503` `ORDER_SUBMISSION_CAPACITY_EXCEEDED`, applying nothing, once your user and application hold 10,000 reserved keys or the exchange-wide reservation ceiling is reached. See [TWAP Orders](/trading-mechanics/twap-orders).

### `UserTrade` matches what `getUserTrades` returns

`UserTrade` from `sdk.profile.getUserTrades` (`GET /api/v1/accounts/trades`; gRPC `AccountsService.GetUserTrades`) adds `tradingMode`, `makerOrderId`, `takerOrderId`, `quantityRaw`, `quoteVolumeRaw`, `feeRaw`, `feeToken`, `monacoFeeRaw`, `builderFeeRaw`, `settlementStatus`, `settlementTxHash` and `liquidityRole` (`MAKER` or `TAKER`; a self-trade reads as `MAKER`). `quoteVolume`, `fee` and `executedAt` are now optional, because the API omits them when a trade has none recorded, and `monacoFee` can be `null` when `fee` is absent. Code that read those three fields as always present must handle `undefined`.

The generated Rust REST `UserTrade` was built from a different message with the same name; it now drops `orderId`, `positionId`, `realizedPnl` and `timestamp`, which the endpoint never sent, and gains the fields above. In `monaco-grpc-sdk`, `monaco::api::trades::UserTrade` is renamed `ListedUserTrade`; the wire format is unchanged. See [Profile](/sdk/typescript/profile#trade-history).

## Deprecated

### `TradesService.ListUserTrades`

`TradesService.ListUserTrades` and `TradesServiceClient::list_user_trades` are deprecated and will be removed. Call `AccountsService.GetUserTrades`, which now takes the same `margin_account_id` and `order_id` filters. The `trades.UserTrade` message is renamed `ListedUserTrade`; field numbers are unchanged. See [TradesService](/grpc/protos/trades).

## Added

### Trader metrics and trade flow

`sdk.market.getTraderMetrics(tradingPairId)` (`GET /api/v1/market/pairs/{tradingPairId}/trader-metrics`; gRPC `MarketService.GetTraderMetrics`) returns the market's current long/short account counts, shares and ratio, plus distinct-trader counts for 1h, 24h and 7d. No account ids are returned: a position split is `null` when either side has fewer than five accounts, and an activity count is `null` below five users.

`sdk.market.getTradeFlow(tradingPairId, { interval, startTime, endTime })` (`GET /api/v1/market/pairs/{tradingPairId}/trade-flow`; gRPC `MarketService.GetTradeFlow`) returns UTC buckets of taker buy and sell notional, ratio, net notional, cumulative volume delta and trade count. `interval` is `1m`, `5m` or `1h`; `[startTime, endTime)` is in Unix milliseconds and limited to seven days and 2,048 buckets. Empty buckets are omitted, and notionals stay in the quote asset. The React `useMarket` hook and the MCP server (`get_trader_metrics`, `get_trade_flow`) expose both. See [Market](/sdk/typescript/market).

### Public liquidation history and live feed

`sdk.market.listLiquidationEvents` (`GET /api/v1/market/pairs/{tradingPairId}/liquidation-events`; gRPC `MarketService.ListLiquidationEvents`) lists a market's liquidation events newest first, with inclusive `startTime`, exclusive `endTime`, `pageSize` (default 50, at most 1000) and `pageToken`. Each event carries `wallet`, `side`, `positionSize`, the event-time `markPrice` and `markNotional`, which is `positionSize` × that same mark in the quote asset. `sdk.market.getLiquidationMetrics` (`GET /api/v1/market/pairs/{tradingPairId}/liquidation-metrics`; gRPC `MarketService.GetLiquidationMetrics`) returns long and short totals per `1m`, `5m` or `1h` bucket; `eventCount` counts stored events, not wallets.

The public `market_liquidations:{tradingPairId}` WebSocket channel (`sdk.ws.marketLiquidations`) streams the same events live. The React `useLiquidationFeed` hook subscribes, backfills history after each subscription acknowledgement and reconnect, deduplicates by `eventId` and keeps the newest 500 events. The MCP server adds `list_liquidation_events` and `get_liquidation_metrics`. See [Market](/sdk/typescript/market) and [useLiquidationFeed](/sdk/react/hooks/use-liquidation-feed).

### Sweeper deposit status

`sdk.sweeper.getDepositStatus(txHash)` (`GET /api/v1/sweeper/deposits/{txHash}`; gRPC `SweeperService.GetDepositStatus`) returns where your deposits made by one transaction are, on any supported chain. Poll it until each deposit reads `DEPOSITED`, or `FAILED` with `failureReason` `REFUNDED`; the list is empty until the sweeper has indexed the transaction. `sdk.sweeper.listDeposits({ pageSize?, pageToken? })` (`GET /api/v1/sweeper/deposits`; gRPC `SweeperService.ListDeposits`) lists your deposits newest first. Both require a session and return only the session's own deposits. The SDK throws `InvalidConfigError` before sending a malformed `txHash` or a `pageSize` outside 1 to 100. See [Vault](/sdk/typescript/vault#registered-deposit-addresses).

### Idempotent collateral transfers

Every margin collateral transfer takes an optional `idempotencyKey`, in the same namespace as order create: the margin account, parent margin account, risk bucket and sub-account `transfer-in` / `transfer-out` routes, and `POST /api/v1/margin/collateral/transfer`. A retry with the same key and request within 15 minutes returns the first transfer's result, `movementId` included, without moving money again. A different request under the same key returns `IDEMPOTENCY_KEY_CONFLICT` (HTTP `409` / gRPC `ALREADY_EXISTS`). See [Retrying a transfer safely](/sdk/typescript/margin-accounts#retrying-a-transfer-safely).

### Per-market funding impact notional

`sdk.market.getPerpMarketConfig` (`GET /api/v1/market/pairs/{tradingPairId}/perp/config`; gRPC `MarketService.GetPerpMarketConfig`) returns `fundingImpactNotional`: the quote notional each funding premium sample walks through each side of the book. It is set per market, and every market starts at `"2000"`. See [Funding Rates](/trading-mechanics/funding-rates).

### User trade filters

`getUserTrades` and `iterateUserTrades` accept `marginAccountId` and `orderId`, matching your side of each fill. Like `tradingPairId`, a filtered response carries no `total`, and a page token resumes only the filters it was issued with. See [Profile](/sdk/typescript/profile#trade-history).

## Changed

### BuilderCodes balance follows the payout address

Shortly after Monaco moves a frontend's payout address to a new wallet, the unclaimed balance accrued to the old wallet moves to the new one, in the same step that starts crediting it. Amounts the old wallet already claimed or withdrew do not move. `sdk.buildercodes.claimBuildercodeRewards` and `getRewardsBalance` (`POST /api/v1/buildercodes/rewards/claim`, `GET /api/v1/buildercodes/rewards/balance`) still resolve the bucket from the signed-in wallet without requiring current enrollment, so a former payout wallet can still read and claim whatever remains in its bucket. Request and response fields are unchanged. See [BuilderCodes](/sdk/typescript/buildercodes).

### Faster transaction receipts

The SDK's internal viem client now polls for transaction receipts every 200 ms by default, about half a Sei block, down from 750 ms. `sdk.vault.deposit`, `sdk.vault.approve` and `sdk.waitForTransaction` see a mined transaction within about half a block. Set `pollingInterval: 750` on `SDKConfig` to keep the previous cadence. See [Configuration](/sdk/typescript/intro).

### Finer SEI and FARTCOIN perp ticks

The SEI/USDC and FARTCOIN/USDC perps trade on a `0.00001` price tick, down from `0.0001`. Resting orders were kept. Read the tick from the trading pair rather than hard-coding it.

### A diverged book no longer pauses a market

A perp whose book drifts away from the oracle keeps trading, liquidating, paying funding and updating its mark like any other market. It still reads `DIVERGED` in `last_regime` for monitoring. Previously such a market refused takers and liquidations, and skipped funding, until its book re-centred. See [Markets](/developers/markets).

### Auto-deleveraging starts at the bankruptcy price

With auto-deleveraging enabled, a liquidating risk bucket that is below three quarters of its maintenance margin, or has been at any point in this liquidation, goes to auto-deleveraging once its marks cross the bankruptcy prices pinned when liquidation began, whatever the order book holds, or once the ADL backstop (five minutes by default) has passed. A bucket that never falls that far stays in ordinary liquidation. This replaces the earlier rule that waited on repeated empty-book passes. See [Auto-Deleveraging](/trading-mechanics/auto-deleveraging).

## Fixed

### Order creates resend a lost response

When `placeLimitOrder` or `placeMarketOrder` generated the idempotency key and the outcome is unknown (a network error, an unreadable success response, or HTTP 5xx including `ORDER_SUBMISSION_UNAVAILABLE`), the SDK re-sends the same request and key up to 3 more times after 1, 2 and 4 seconds. The server replays the original result instead of placing a second order. A maintenance `OPERATIONS_BLOCKED` refusal, any 4xx and a `Retry-After` above 5 seconds return at once; retries stop 60 seconds after the first send, or when the session changes. If every attempt is ambiguous the call throws an `APIError` naming the key to reuse. A key you supply, and `batchCreate`, still send once. See [Safe Retries](/developers/trade#safe-retries-with-idempotency-keys).

### Deactivated applications

Once an application is deactivated, order creates, batch creates, replacements and TWAP creates placed through it are refused with HTTP `403` / gRPC `PERMISSION_DENIED` and code `APPLICATION_INACTIVE` (per-item `error.code` in a batch). Reduce-only orders that close a margin position are still accepted, and spot balances can still be withdrawn. The application's resting orders and running TWAP orders are cancelled and its copy trading follows stopped. `upsertLeadTrader` and `upsertFollow` from a deactivated application return `403` with `Application is inactive`.

### Fee simulation matches the engine's charge

`simulateFees` returns every amount truncated toward zero to the quote token's decimals, as the engine charges it: `notional`, each fee and rebate, and the totals `totalTakerFees`, `takerTotalPayment` and `makerTotalReceipt`, now sums of the truncated parts. Totals could previously exceed the charge by one atomic unit, and a rebate under one atomic unit now reads `0`.

### Portfolio figures

`getSummary`'s `current.availableValue` (`GET /api/v1/accounts/me/portfolio/summary`) is now what you can spend or withdraw: USDC available on spot plus the parent margin account's `withdrawableCollateral`. It previously valued every spot asset and counted unrealized margin gains, and it is now served even when `valuationStatus` is `partial`. `getPerformance` (`GET /api/v1/accounts/me/portfolio/performance`) reports `deposits`, `withdrawals` and `netExternalFlows` from the period start, so an account funded inside the period no longer reports `0`. See [Portfolio](/sdk/typescript/portfolio).

### Position fees and risk

A closed position reports each reducing fee once in `cumFees`, `netRealizedPnl` and `realizedRoe` (`GET /api/v1/positions`, `GET /api/v1/positions/{positionId}`); positions closed earlier keep the extra fees until their PnL is recomputed. `getPositionRisk` (`GET /api/v1/positions/{positionId}/risk`) prices `marginRatio` from the maintenance margin at the current mark, the same mark as `maintenanceMarginRequired`, instead of the requirement stored at the last fill. Liquidation and auto-deleveraging orders now carry the closed position's leverage instead of `1`.

### Maker rebates in movements

Ledger history and movements list the BUY-side maker rebate for each fill as a `TRADE` credit described as `Trade <id> - maker rebate <amount> <symbol>`. The row was missing, so BUY makers appeared to pay the full notional; balances were always correct. See [Account Balances](/developers/account-balances#movements).

### Clearer and fewer order refusals

A margin reduce-only order with no risk bucket behind it is refused with `reduce_only margin orders require an existing position`, instead of advice to transfer collateral that could not help. Match the new text if you matched the old one. A delegated agent's cancel is no longer held to its `maxLeverage` cap, which applies only to orders it creates or replaces.

### Sign-in

A wallet whose first contact with Monaco was a deposit can now sign in; it was refused as deactivated. A redeemed Mainnet invite code can no longer be revoked, so the redeeming wallet keeps signing in without a code. See [Mainnet Invite Codes](/sdk/typescript/auth#mainnet-invite-codes).

## Upgrade

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


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