Skip to main content

Monaco Protocol SDK v1.0.92

This release adds a public region status call, and new refusals for restricted regions and for wallets on the OFAC sanctions list. A stable auth refusal on a signed REST request now answers 403 with its code instead of a bare 401. The OpenAPI spec defaults to production, and the Rust REST client sends a User-Agent. Perp minimum order sizes rise to about $10 of notional. Action items: call sdk.compliance.getRegionStatus() to show a region notice before other calls fail with 451; handle ADDRESS_RESTRICTED and ACCOUNT_RESTRICTED by showing the error message as-is without retrying; if you build a Rust REST client with Client::new_with_client, set a User-Agent on your reqwest::Client; size perp orders from each pair’s current minOrderSize.

Added

Region status

sdk.compliance.getRegionStatus() (GET /api/v1/compliance/region; gRPC ComplianceService.GetRegionStatus) is public and needs no session. It returns restricted, which is true when Monaco is not available in the caller’s region, and country, the ISO 3166-1 alpha-2 code the edge geolocated (T1 for Tor, XX for unknown), empty when the request carried no location. It always answers 200, including from a restricted region. Every other request from a restricted region is refused. REST and the WebSocket upgrade answer HTTP 451 with error REGION_RESTRICTED and details.reason edge_geo_block or app_geo_block; in the SDK that is an APIError with statusCode 451 and retryable: false. gRPC answers PERMISSION_DENIED with a google.rpc.ErrorInfo reason REGION_RESTRICTED in domain compliance.0xmonaco.com. The restriction applies to production only. ComplianceAPI and GetRegionStatusResponse are exported from @0xmonaco/types, and the Rust REST client adds get_region_status. See Region Status and ComplianceService.

Sanctions refusals

Wallets on the OFAC sanctions list are refused with two stable codes, both HTTP 403 / gRPC PERMISSION_DENIED, with the code as the google.rpc.ErrorInfo reason in domain auth.0xmonaco.com:
  • ADDRESS_RESTRICTED: sign-in (POST /api/v1/auth/challenge and POST /api/v1/auth/verify; gRPC AuthService.Challenge / Verify) with a listed wallet, with the message This wallet can't be used on Monaco.; createDelegatedSession when the owner or the agent is listed; and a withdrawal (POST /api/v1/withdrawals; gRPC WithdrawalsService.InitiateWithdrawal) to a listed destination, with the message Withdrawals to this address aren't supported., before any balance is debited.
  • ACCOUNT_RESTRICTED: every signed REST and gRPC request, and WebSocket authentication and revalidation, of a session whose wallet or delegated agent is listed, with the message Your account is restricted. Contact support. It takes effect within 60 seconds of the listing.
Show the message as-is and do not retry. In the REST envelope the code is both error and code; the TypeScript SDK reads it from APIError.serverCode, and @0xmonaco/types exports SANCTIONS_ERROR_CODES and SanctionsErrorCode. The WebSocket client treats an ACCOUNT_RESTRICTED Error frame as terminal, like ACCOUNT_DEACTIVATED: it stops reconnecting, forgets the session and calls onReauthenticationRequired with that code. See Error Handling and WebSockets.

Changed

Stable auth refusals answer 403

A signed REST request refused with a stable auth code, such as ACCOUNT_DEACTIVATED, now returns HTTP 403 with the JSON error envelope and that code, instead of a bare 401. In the TypeScript SDK it surfaces as an APIError with statusCode 403 and the code in serverCode. Code that treated every 401 as “sign in again” now sees these as 403, where signing in again does not help. See Error Handling.

OpenAPI spec defaults to production

The OpenAPI spec lists https://apimonaco.xyz (Sei mainnet) as its only server, replacing the staging server. Clients generated from the spec and the docs API playground default to production. No request or response shape changed.

Perp minimum order sizes

Perp minimum order sizes rise to about $10 of notional, and the GOLD perp moves to a 0.0005 quantity step. An order already resting below its new minimum keeps resting and can still be repriced, a reduce-only order for the full position size is accepted below it, and a TP/SL leg placed under the old minimum still fires. Read each pair’s minOrderSize and quantityStepSize from getPaginatedTradingPairs or the instrument WebSocket channel rather than hard-coding them. See Markets.

Fixed

Rust REST client sends a User-Agent

Client::new and Client::new_authenticated send User-Agent: monaco-sdk-rust/<version>. Without one, Monaco’s API edge rejected requests with 403. Client::new_with_client uses the reqwest::Client you pass unchanged, so set a User-Agent on it with reqwest::Client::builder().user_agent(...). See Rust REST.

A fill funds its position from the margin drawn for orders

When the mark had moved through a resting order before it filled, the fill kept none of the margin drawn for it, so its new position could read as unfunded and the risk bucket could be auto-deleveraged at its own fill price. A fill now first keeps the risk bucket’s outstanding draw, whichever order it was made for, up to what the bucket’s positions need to reach their initial margin; a shortfall the draw cannot cover remains. It then returns what the remaining orders no longer need. See Perpetual Futures.

Repricing an order below a raised minimum

A price-only replace of an order whose remaining size is already below the pair’s minimum order size is accepted. In a batch replace it was refused after the original was cancelled, which left nothing on the book.

Upgrade