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

# V0.5.5

# Monaco Protocol SDK v0.5.5

## Batch Cancel Orders & Order Status Simplification

This release introduces batch order cancellation for efficient multi-order management and simplifies order statuses by removing deprecated intermediate states.

### New Features

#### Batch Cancel Orders

Cancel multiple orders in a single API call, or cancel all active orders at once.

**Core SDK:**

* **New Method**: `sdk.trading.batchCancelOrders()` for cancelling multiple orders efficiently
* **Cancel All**: Use `{ cancelAll: true }` to cancel all active orders for the user
* **Detailed Results**: Returns individual success/failure status for each order

**Use Cases:**

* Emergency position exit (cancel all orders instantly)
* Bulk order management for market makers
* Portfolio rebalancing with clean slate
* Efficient cleanup of stale orders

***

#### Real-time Order Tracking

Track all your orders in real-time with the new `useUserOrders` React hook. Automatically syncs with WebSocket for instant order updates.

**React SDK:**

* **New Hook**: `useUserOrders()` for real-time order tracking
* **Automatic Sync**: Fetches initial orders via REST, then subscribes to WebSocket updates
* **Smart Deduplication**: Merges REST and WebSocket data without duplicates
* **Manual Refresh**: Built-in `refresh()` function for on-demand updates

**Features:**

* Real-time order status updates (placed, filled, cancelled, etc.)
* Automatic state management with configurable history limit
* Authentication-aware (requires valid JWT token)
* Built-in error handling and retry support

**Example:**

```typescript theme={null}
import { useUserOrders } from "@0xmonaco/react";

function OrdersPanel() {
  const { orders, loading, subscribed } = useUserOrders(100);

  // Filter active orders
  const activeOrders = orders.filter(
    o => o.status === "SUBMITTED" || o.status === "PARTIALLY_FILLED"
  );

  return (
    <div>
      <p>Live: {subscribed ? "Connected" : "Disconnected"}</p>
      <h3>Active Orders ({activeOrders.length})</h3>
      {activeOrders.map(order => (
        <div key={order.id}>
          {order.trading_pair}: {order.side} {order.quantity}
          {order.filled_quantity !== "0" && (
            <span>Filled: {order.filled_quantity}</span>
          )}
        </div>
      ))}
    </div>
  );
}
```

[Learn more about useUserOrders →](/sdk/react/hooks/use-user-orders)

**Example:**

```typescript theme={null}
// Cancel specific orders
const result = await sdk.trading.batchCancelOrders({
  orderIds: ['order_123', 'order_456', 'order_789']
});

console.log(`Cancelled ${result.total_cancelled} of ${result.total_requested} orders`);

// Check individual results
result.results.forEach(r => {
  if (r.success) {
    console.log(`Order ${r.order_id} cancelled at ${r.cancelled_at}`);
  } else {
    console.log(`Order ${r.order_id} failed: ${r.error?.message}`);
  }
});

// Cancel ALL active orders
const allCancelled = await sdk.trading.batchCancelOrders({ cancelAll: true });
console.log(`Emergency exit: cancelled ${allCancelled.total_cancelled} orders`);
```

[Learn more about batch cancel →](/developers/trade)

***

### Breaking Changes

#### Order Status Simplification

The `PENDING` and `ACKNOWLEDGED` order statuses have been removed from the API. Orders now transition directly to `SUBMITTED` status.

**What Changed:**

```typescript theme={null}
// Before (v0.5.4)
type OrderStatus =
  | "PENDING"          // ❌ Removed
  | "ACKNOWLEDGED"     // ❌ Removed
  | "SUBMITTED"
  | "PARTIALLY_FILLED"
  | "FILLED"
  | "CANCELLED"
  | "REJECTED"
  | "EXPIRED"
  | "SETTLED";

// After (v0.5.5)
type OrderStatus =
  | "SUBMITTED"        // Orders start here
  | "PARTIALLY_FILLED"
  | "FILLED"
  | "CANCELLED"
  | "REJECTED"
  | "EXPIRED"
  | "SETTLED";
```

**Migration Guide:**

If you were filtering or checking for `PENDING` or `ACKNOWLEDGED` statuses, update your code:

```typescript theme={null}
// Before
if (order.status === 'PENDING' || order.status === 'ACKNOWLEDGED') {
  // Wait for order to be processed
}

// After
if (order.status === 'SUBMITTED') {
  // Order is active and waiting to be filled
}
```

**Why this change:**

* Simplifies order lifecycle
* Reduces intermediate states that caused confusion
* Improves consistency across REST and WebSocket APIs
* Orders now have a cleaner state machine

***

### Breaking Change: vault.getBalance() Deprecated

The `vault.getBalance()` method has been deprecated and no longer functions. Use the Profile API for balance queries instead.

**What Changed:**

```typescript theme={null}
// Before (v0.5.4 and earlier)
const balance = await sdk.vault.getBalance(assetId);
console.log('Balance:', balance.formatted);

// After (v0.5.5+)
const balance = await sdk.profile.getUserBalanceByAssetId(assetId);
console.log('Available:', balance.available_balance);
console.log('Locked:', balance.locked_balance);
console.log('Total:', balance.total_balance);
```

**Why this change:**

* Profile API provides more detailed balance information (available, locked, total)
* Consolidates balance queries with other profile data
* Improves performance with backend optimizations
* Simplifies SDK architecture by removing duplicate functionality

**Migration Guide:**

Replace `sdk.vault.getBalance(assetId)` with `sdk.profile.getUserBalanceByAssetId(assetId)`:

```typescript theme={null}
// Old approach
const vaultBalance = await sdk.vault.getBalance(assetId);
console.log(`Balance: ${vaultBalance.formatted}`);

// New approach
const profileBalance = await sdk.profile.getUserBalanceByAssetId(assetId);
console.log(`Available: ${profileBalance.available_balance}`);
console.log(`Locked in orders: ${profileBalance.locked_balance}`);
console.log(`Total: ${profileBalance.total_balance}`);
```

For getting all balances:

```typescript theme={null}
const { balances } = await sdk.profile.getUserBalances({ limit: 100 });
balances.forEach(b => {
  console.log(`${b.symbol}: ${b.total_balance}`);
});
```

[Learn more about Profile API →](/sdk/typescript/profile)

***

### Breaking Change: TypeScript Type Updates

Several TypeScript interfaces have been updated for better consistency and to expose raw balance fields. These are breaking changes if you're using TypeScript.

#### `GetUserBalancesResponse`: Pagination Field Renamed

**What Changed:**

```typescript theme={null}
// Before (v0.5.4)
interface GetUserBalancesResponse {
  balances: AccountBalance[];
  total: number;  // Old field name
  limit: number;
  offset: number;
}

// After (v0.5.5+)
interface GetUserBalancesResponse {
  balances: AccountBalance[];
  total_count: number;  // Renamed for consistency
  limit: number;
  offset: number;
}
```

**Migration:**

```typescript theme={null}
const response = await sdk.profile.getUserBalances();
console.log(`Total: ${response.total_count}`);  // Changed from response.total
```

#### `AccountBalance`: New Required Fields

**What Changed:**

```typescript theme={null}
// After (v0.5.5+)
interface AccountBalance {
  asset_id: string;                // NEW: Asset UUID
  token: string;
  symbol: string | null;
  decimals: number;
  available_balance: string;
  locked_balance: string;
  total_balance: string;
  available_balance_raw: string;   // NEW: Raw balance (wei)
  locked_balance_raw: string;      // NEW: Raw balance (wei)
}
```

**New fields:**

* `asset_id` - Asset UUID for API operations
* `available_balance_raw` - Available balance in raw format (wei/smallest unit)
* `locked_balance_raw` - Locked balance in raw format (wei/smallest unit)

**Why this change:**

* Enables precise balance calculations without floating-point errors
* Provides asset\_id for direct use in deposit/withdraw operations
* Matches backend API response structure

#### `LedgerMovement`: Extended Metadata

**What Changed:**

The `LedgerMovement` interface has been extended with additional fields:

```typescript theme={null}
interface LedgerMovement {
  // ... existing fields ...
  amount_raw: string;              // NEW: Raw amount
  symbol: string | null;           // Now explicitly nullable
  decimals: number;
  balance_before_raw: string | null;   // NEW
  balance_after_raw: string | null;    // NEW
  locked_before: string | null;        // NEW
  locked_before_raw: string | null;    // NEW
  locked_after: string | null;         // NEW
  locked_after_raw: string | null;     // NEW
  reference_id: string | null;         // NEW
  reference_type: string | null;       // NEW
  tx_hash: string | null;              // NEW
  block_number: number | null;         // NEW
}
```

**Why this change:**

* More accurate representation of on-ledger movements
* Aligns with WebSocket event payloads
* Provides raw values for precise calculations

#### `MarketMetadata`: Nullable Fields

**What Changed:**

`MarketMetadata` fields are now nullable to reflect API behavior for markets without trade history:

```typescript theme={null}
interface MarketMetadata {
  // These fields are null if no trades have occurred yet
  last_price: string | null;
  last_price_timestamp: number | null;

  // These fields are null if less than 24 hours of data
  high_24h: string | null;
  low_24h: string | null;
  volume_24h: string | null;
  price_change_24h: string | null;
  price_change_percent_24h: string | null;

  // Null if not available
  market_initialization_timestamp: number | null;
}
```

**Migration:**

Add null checks when accessing `MarketMetadata` fields:

```typescript theme={null}
const metadata = await sdk.market.getMarketMetadata(tradingPairId);

// Before (v0.5.4) - assumed values always present
const price = metadata.last_price;

// After (v0.5.5) - handle null values
const price = metadata.last_price ?? 'N/A';
if (metadata.last_price !== null) {
  console.log(`Last price: ${metadata.last_price}`);
} else {
  console.log('No trades yet');
}
```

**Why this change:**

* Accurately represents markets that haven't had any trades yet
* Prevents displaying misleading zero or undefined values
* Matches actual API response behavior

***

### API Reference

**New Endpoint:**

* `POST /api/v1/orders/batch-cancel` - Cancel multiple orders in a single request

**New Types:**

```typescript theme={null}
interface BatchCancelOrdersResponse {
  success: boolean;              // Overall operation success
  total_requested: number;       // Total orders requested to cancel
  total_cancelled: number;       // Total orders successfully cancelled
  total_failed: number;          // Total orders that failed to cancel
  results: BatchCancelResult[];  // Individual results for each order
}

interface BatchCancelResult {
  order_id: string;              // Order identifier
  success: boolean;              // Whether cancellation was successful
  cancelled_at?: string;         // ISO 8601 timestamp when cancelled
  error?: {                      // Error details if failed
    code: string;
    message: string;
  };
}
```

**Query Parameters:**

* `cancel_all` (boolean) - Set to `true` to cancel all active orders

***

### Upgrade Instructions

1. **Update your dependencies:**

```bash theme={null}
npm install @0xmonaco/core@0.5.5 @0xmonaco/react@0.5.5
```

2. **Update balance queries:**
   * Replace `sdk.vault.getBalance(assetId)` with `sdk.profile.getUserBalanceByAssetId(assetId)`
   * Update response handling to use new balance structure (available\_balance, locked\_balance, total\_balance)
   * See [Account Vault](/developers/vault) for examples

3. **Update order status checks:**
   * Remove checks for `PENDING` status
   * Remove checks for `ACKNOWLEDGED` status
   * Use `SUBMITTED` as the initial active order state

4. **Consider using batch cancel:**
   * Replace loops calling `cancelOrder()` with `batchCancelOrders()`
   * Use `cancelAll: true` for emergency exits

5. **Handle nullable MarketMetadata fields:**
   * Add null checks when accessing `last_price`, `high_24h`, `low_24h`, etc.
   * Markets without trade history will return `null` for these fields

6. **Test your flows:**
   * Verify balance queries work correctly
   * Verify order status transitions work correctly
   * Test batch cancellation with multiple orders
   * Test handling of new markets with no trade history

***

*For complete documentation, see [Order Management](/developers/trade).*


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