Skip to main content

Monaco Protocol SDK v1.0.36

This is an additive release — no breaking changes. It rolls up the consumer-facing changes shipped since v1.0.34. It adds registered deposit addresses with automatic sweeping — a public, keyless way to hand a user a stable deposit address that forwards every ERC20 deposit into the rollup — and exposes human-readable base/quote asset display names on every trading pair. It also hardens the MCP server: order create/replace tools are now flagged non-idempotent so an agent reconciles instead of blind-retrying after an ambiguous failure, and the MCP tool schemas were realigned with the underlying SDK methods so agent inputs are no longer silently dropped. Existing code keeps working unchanged; the new method and fields are opt-in.

Added

Registered deposit addresses with automatic sweeping

Every (application, user) pair has a deterministic on-chain deposit address. Registering the pair makes the backend monitor that address and automatically forward every ERC20 deposit into the rollup, crediting the user under the application — no per-deposit signature or transfer step.
  • sdk.sweeper.register({ clientId, userAddress }) (POST /api/v1/sweeper/register; gRPC SweeperService.Register; Rust REST register_deposit_address; Rust gRPC SweeperServiceClient::register) — register a pair. Public — no session keypair required. The reply returns immediately with the derived sweeperAddress and a status of registered (added by this call) or already_registered (known before). A one-time initial balance check — which sweeps anything already sitting on the address — runs in the background and is reported by initialSweepCheck (false right after a fresh registration, flipping once every pre-existing balance is swept). Idempotent and safe to retry: re-registering never re-triggers the initial check. The clientId is matched against existing applications by exact string, so an unknown client id — any respelling of a real one included — returns 404; requests are lightly rate-limited per client (429), reject malformed input (400), and answer 503 when the sweeper is unconfigured or its resolver is down (nothing was registered, safe to retry).
@0xmonaco/contracts gains predictSweeperAddress(...) plus the SWEEPER_ABI and SWEEPER_FACTORY_ABI exports, so you can derive the same deposit address off-chain — and show or fund it before any contract exists there — without an RPC round-trip. See Vault.

Human-readable asset display names on trading pairs

TradingPair now carries baseAssetName and quoteAssetName (wire base_asset_name / quote_asset_name) — the human-readable asset names from the asset registry (e.g. "Robinhood Markets" for HOOD, "USDC" for USDC) — alongside the existing ticker fields. They are populated on every pair returned by getPaginatedTradingPairs, getTradingPair, and getTradingPairBySymbol (REST GET /api/v1/market/pairs and GET /api/v1/market/pairs/{trading_pair_id}; gRPC MarketService.ListTradingPairs / GetTradingPair; Rust base_asset_name / quote_asset_name), all public. Add them to a market-search haystack so a query like “Robinhood” matches the HOOD market, and render them as display names next to tickers. Additive; existing fields are unchanged. See Market Data.

Fixed

MCP order tools are flagged non-idempotent

The place_limit_order, place_market_order, and replace_order MCP tool descriptions now state that order create/replace are non-idempotent and must not be blind-retried after an ambiguous outcome (a timeout, a network error, or a 5xx with no order returned). They direct the assistant to reconcile with get_orders / get_order before resubmitting, so an unattended agent no longer double-submits and opens duplicate live orders.
Correction since this release. The reconciliation surface named above was wrong. get_orders / get_order are replica-backed and can omit an order that did land, and an order rejected before acceptance is never written to them at all (one rejected after acceptance is persisted with status REJECTED), so a missing row is not evidence the order failed. Reconcile on the order WebSocket stream — which MCP has no tool for, so an ambiguous outcome cannot be resolved from inside MCP and must be reported rather than retried. See Client Order IDs.

MCP tool schemas aligned with the SDK

The MCP tool schemas and descriptions were realigned with the underlying @0xmonaco/core methods so agent inputs are no longer silently dropped and risk is stated accurately:
  • get_trading_pairs, get_balances, and get_movements now paginate with page / pageSize (the params the SDK actually reads) instead of the ignored limit / offset; get_trading_pairs also gained a category filter.
  • place_limit_order and place_market_order gained a marginMode (ISOLATED / CROSS) option for margin orders.
  • place_market_order and the batch-cancel tools now describe their real semantics: the mandatory 1,000 bps market-order price band (tightening-only slippage, possible partial fill or rejection) and the non-atomic, best-effort nature of batch cancels.
  • Every tool now carries MCP readOnlyHint / destructiveHint annotations derived from the manifest, so clients can gate the mutating and fund-movement surface.

Upgrade

The MCP server ships at 1.0.36 too; it runs via npx -y @0xmonaco/mcp-server, so restarting your assistant picks up the new version, the non-idempotent order-tool guidance, and the aligned tool schemas. Nothing in this release is breaking. Two things worth adopting:
  1. Registered deposit addresses are public and keyless. sdk.sweeper.register needs no session key — the deposit address’s destination is fixed in its own bytecode, so a caller can only ever route funds to the user they already belong to. Give a user their stable address up front and let deposits sweep in automatically.
  2. Asset display names are available for search and UI. Read baseAssetName / quoteAssetName off trading pairs to match markets by company or asset name and to render names beside tickers.