Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions .changeset/add-perp-v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
---
"@0xmonaco/types": minor
"@0xmonaco/core": minor
"@0xmonaco/react": minor
---

### Add perp v1 to the SDK

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.

#### `sdk.marginAccounts` — margin account management

```ts
// Create an isolated-margin account (USDC is the default collateral)
const { margin_account_id } = await sdk.marginAccounts.createMarginAccount({
label: "perp-main",
collateralAsset: "USDC",
});

// 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, ...

// How much of a given asset is sitting in the wallet vs. transferable to margin
const collateral = await sdk.marginAccounts.getAvailableCollateral({ asset: "USDC" });

// 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",
});

// 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.
Loading