From 0521ccda6e5250cc9b7419ae3d8be83c28fc5907 Mon Sep 17 00:00:00 2001 From: carson Date: Tue, 21 Apr 2026 15:08:45 -0400 Subject: [PATCH 1/2] Add changeset for perp v1 SDK (#295) Co-Authored-By: Claude Opus 4.7 (1M context) --- .changeset/add-perp-v1.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .changeset/add-perp-v1.md diff --git a/.changeset/add-perp-v1.md b/.changeset/add-perp-v1.md new file mode 100644 index 00000000..90eaa290 --- /dev/null +++ b/.changeset/add-perp-v1.md @@ -0,0 +1,32 @@ +--- +"@0xmonaco/types": minor +"@0xmonaco/core": minor +"@0xmonaco/react": minor +--- + +### Add perp v1 to the SDK + +- Expose perp v1 SDK clients and wire them into the SDK root +- Align perp market REST routes with backend trading-pair endpoints +- Add client-side validation for margin account and position APIs +- Harden conditional-order websocket routing, parsing, reconnect handling, and logout token cleanup + +#### `@0xmonaco/types` + +- Added `margin-accounts` types and validation schemas +- Added `positions` types and validation schemas +- Added conditional-order websocket event types +- Extended trading types, orders, and validation for perp support +- Extended market and SDK types for perp + +#### `@0xmonaco/core` + +- Added `MarginAccountsAPI` and `PositionsAPI` implementations +- Added perp routes module and wired perp clients into the SDK +- Updated `MarketAPIImpl` and `TradingAPIImpl` for perp endpoints +- Hardened websocket routing, parsing, reconnect handling, and logout token cleanup + +#### `@0xmonaco/react` + +- Added `usePositions` hook +- Extended `useMarket` and `useTrade` hooks for perp support From 36806ad410b23e59ae62ad36d9a567ebbf0b1133 Mon Sep 17 00:00:00 2001 From: carson Date: Tue, 21 Apr 2026 15:11:31 -0400 Subject: [PATCH 2/2] Expand perp v1 changeset with usage examples Add runnable snippets for sdk.marginAccounts, sdk.positions, perp market metadata, perp-aware order placement, the conditional_order_update websocket event, and the usePositions React hook so consumers can see how each new surface is used. Co-Authored-By: Claude Opus 4.7 (1M context) --- .changeset/add-perp-v1.md | 183 ++++++++++++++++++++++++++++++++++---- 1 file changed, 165 insertions(+), 18 deletions(-) diff --git a/.changeset/add-perp-v1.md b/.changeset/add-perp-v1.md index 90eaa290..000c2c5b 100644 --- a/.changeset/add-perp-v1.md +++ b/.changeset/add-perp-v1.md @@ -6,27 +6,174 @@ ### Add perp v1 to the SDK -- Expose perp v1 SDK clients and wire them into the SDK root -- Align perp market REST routes with backend trading-pair endpoints -- Add client-side validation for margin account and position APIs -- Harden conditional-order websocket routing, parsing, reconnect handling, and logout token cleanup +Adds first-class perp support across the SDK: margin accounts, isolated positions, perp market metadata, perp-aware order placement, and a `conditional_order_update` websocket event. Also adds a `usePositions` React hook and extends `useMarket` / `useTrade` with perp helpers. -#### `@0xmonaco/types` +#### `sdk.marginAccounts` — margin account management -- Added `margin-accounts` types and validation schemas -- Added `positions` types and validation schemas -- Added conditional-order websocket event types -- Extended trading types, orders, and validation for perp support -- Extended market and SDK types for perp +```ts +// Create an isolated-margin account (USDC is the default collateral) +const { margin_account_id } = await sdk.marginAccounts.createMarginAccount({ + label: "perp-main", + collateralAsset: "USDC", +}); -#### `@0xmonaco/core` +// List accounts and inspect equity / margin usage +const { accounts } = await sdk.marginAccounts.listMarginAccounts({ page: 1, page_size: 20 }); +const summary = await sdk.marginAccounts.getMarginAccountSummary(margin_account_id); +// summary.equity, summary.free_collateral, summary.maintenance_margin_required, ... -- Added `MarginAccountsAPI` and `PositionsAPI` implementations -- Added perp routes module and wired perp clients into the SDK -- Updated `MarketAPIImpl` and `TradingAPIImpl` for perp endpoints -- Hardened websocket routing, parsing, reconnect handling, and logout token cleanup +// How much of a given asset is sitting in the wallet vs. transferable to margin +const collateral = await sdk.marginAccounts.getAvailableCollateral({ asset: "USDC" }); -#### `@0xmonaco/react` +// Move collateral in / out of a margin account +await sdk.marginAccounts.transferCollateralToMarginAccount(margin_account_id, { + asset: "USDC", + amount: "1000", +}); +await sdk.marginAccounts.transferCollateralFromMarginAccount(margin_account_id, { + asset: "USDC", + amount: "250", +}); -- Added `usePositions` hook -- Extended `useMarket` and `useTrade` hooks for perp support +// Audit trail of deposits, withdrawals, PnL, funding, fees, etc. +const { movements } = await sdk.marginAccounts.getMarginAccountMovements(margin_account_id, { + page: 1, + page_size: 50, +}); + +// Pre-flight check: would this order be accepted and what does it do to the account? +const risk = await sdk.marginAccounts.simulateOrderRisk(margin_account_id, { + tradingPairId, + side: "BUY", + positionSide: "LONG", + orderType: "LIMIT", + price: "2000", + quantity: "1.5", + leverage: "10", + reduceOnly: false, +}); +// risk.accepted, risk.estimated_liquidation_price, risk.free_collateral_after, ... +``` + +#### `sdk.positions` — position management + +```ts +// List open / closed positions, optionally filtered +const { positions } = await sdk.positions.listPositions({ + margin_account_id, + status: "OPEN", +}); + +const position = await sdk.positions.getPosition(positionId); +// position.side, position.size, position.entry_price, position.mark_price, +// position.unrealized_pnl, position.liquidation_price, position.leverage, ... + +// Live risk snapshot (mark, liquidation price, margin ratio) +const risk = await sdk.positions.getPositionRisk(positionId); + +// Close: full market close, partial close, or limit close +await sdk.positions.closePosition(positionId, { closeType: "MARKET" }); +await sdk.positions.closePosition(positionId, { + closeType: "LIMIT", + limitPrice: "2050.00", + quantity: "0.5", +}); + +// Adjust isolated margin on an existing position +await sdk.positions.addPositionMargin(positionId, { amount: "200", asset: "USDC" }); +await sdk.positions.reducePositionMargin(positionId, { amount: "100" }); + +// Attach take-profit and/or stop-loss conditional orders to a position +await sdk.positions.attachPositionTpSl(positionId, { + takeProfit: { triggerPrice: "2200", orderType: "MARKET" }, + stopLoss: { triggerPrice: "1900", orderType: "LIMIT", limitPrice: "1895" }, +}); + +// Position lifecycle events (opens, fills, funding, liquidations, closes) +const { events } = await sdk.positions.listPositionHistory({ position_id: positionId }); +``` + +#### `sdk.market` — perp market metadata + +```ts +// Perp market config: tick/lot size, max leverage, margin tiers, etc. +const config = await sdk.market.getPerpMarketConfig(tradingPairId); + +// Summary stats: mark, index, funding, open interest, 24h volume +const summary = await sdk.market.getPerpMarketSummary(tradingPairId); + +// Individual metrics +const mark = await sdk.market.getMarkPrice(tradingPairId); +const index = await sdk.market.getIndexPrice(tradingPairId); +const funding = await sdk.market.getFundingState(tradingPairId); +const oi = await sdk.market.getOpenInterest(tradingPairId); + +// Historical funding payments +const { records } = await sdk.market.listFundingHistory(tradingPairId, { + page: 1, + page_size: 100, +}); +``` + +#### `sdk.trading` — perp-aware order placement + +`placeLimitOrder` and `placeMarketOrder` now accept perp options (`marginAccountId`, `positionSide`, `leverage`, `reduceOnly`): + +```ts +// Open a 10x long on a perp pair +await sdk.trading.placeLimitOrder(tradingPairId, "BUY", "1.5", "2000", { + marginAccountId, + positionSide: "LONG", + leverage: "10", +}); + +// Reduce-only market close of a short +await sdk.trading.placeMarketOrder(tradingPairId, "BUY", "0.5", { + marginAccountId, + positionSide: "SHORT", + reduceOnly: true, +}); +``` + +#### WebSocket — `conditional_order_update` event + +Conditional-order lifecycle updates (TP/SL created, triggered, cancelled, failed) now stream over the existing websocket: + +```ts +// Subscribe to all conditional-order events for the authenticated user, +// or scope to a single trading pair by passing its UUID. +const unsubscribe = sdk.ws.conditionalOrders((evt) => { + // evt.data.conditionalOrderId, evt.data.state, evt.data.reason, + // evt.data.triggeredOrderId, evt.data.triggerPrice, ... +}); + +// Later: +unsubscribe(); +``` + +#### `@0xmonaco/react` — `usePositions` hook + +```tsx +import { usePositions } from "@0xmonaco/react"; + +function PositionsPanel({ marginAccountId }: { marginAccountId: string }) { + const { + listPositions, + getPosition, + getPositionRisk, + closePosition, + addPositionMargin, + reducePositionMargin, + attachPositionTpSl, + listPositionHistory, + } = usePositions(); + + // e.g. + const load = async () => { + const { positions } = await listPositions({ margin_account_id: marginAccountId, status: "OPEN" }); + return positions; + }; +} +``` + +`useMarket` gains `getPerpMarketConfig`, `getPerpMarketSummary`, `getMarkPrice`, `getIndexPrice`, `getFundingState`, `listFundingHistory`, and `getOpenInterest`. `useTrade`'s `placeLimitOrder` / `placeMarketOrder` accept the same perp options shown above.