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

# Build a Trading App

> A step-by-step guide for frontend teams building a trading interface on Monaco Protocol's CLOB infrastructure

Monaco Protocol gives you a production-grade Central Limit Order Book (CLOB) as infrastructure. You bring the UI — Monaco handles order matching, on-chain settlement, and real-time data feeds.

This guide walks a frontend team through everything needed to ship a fully functional DEX on top of Monaco, from initial access to a live trading interface.

***

## Before You Start

Two things are required before any code gets written:

**1. Client ID** — identifies your application with Monaco. It routes all user activity — authentication, orders, fees, and data — to your specific application instance.

**2. User Access** — Public whitelist applications are closed. Existing approvals remain valid. Confirm access with the Monaco team before integrating.

<Note>
  Email [team@0xmonaco.com](mailto:team@0xmonaco.com) to get your Client ID and confirm whitelist access before integrating.
</Note>

***

## Step 1: Install

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

`@0xmonaco/react` provides all React hooks. `@0xmonaco/types` exports TypeScript types for orders, events, and trading pairs. `viem` is required for wallet interactions and on-chain reads.

***

## Step 2: Wrap Your App with MonacoProvider

`MonacoProvider` initialises the SDK, opens the WebSocket connection, and makes every hook available throughout your component tree. It should wrap your entire app, inside your wallet provider.

```tsx theme={null}
import { MonacoProvider } from '@0xmonaco/react';

<MonacoProvider
  network="staging"
  clientId="your-client-id"
  seiRpcUrl="https://evm-rpc-testnet.sei-apis.com"
  walletClient={walletClient}
>
  {children}
</MonacoProvider>
```

The `walletClient` comes from your wallet connection library of choice — wagmi, Thirdweb, or raw viem. The WebSocket connection opens automatically when the provider mounts, so public channels (orderbook, trades, OHLCV) are live immediately.

<Note>
  For production, source `seiRpcUrl` from an environment variable rather than hardcoding it.
</Note>

→ [React SDK setup guide](/sdk/react/intro)

***

## Step 3: Connect Wallets & Authenticate

Monaco uses a challenge-response authentication flow. The user signs a short message with their wallet to authorize an ed25519 session key, which then signs every request. The `useAuth` hook handles the entire flow:

```tsx theme={null}
const { login, logout, authenticationStatus } = useAuth();

// Triggers a one-time wallet signature and starts a signed session
await login();
```

`authenticationStatus` will be `AuthenticationStatus.AUTHENTICATED`, `AuthenticationStatus.AUTHENTICATING`, or `AuthenticationStatus.UNAUTHENTICATED`. Use it to gate your trading UI and show a "Connect Wallet" button to unauthenticated users.

→ [React authentication hook](/sdk/react/hooks/use-auth)

***

## Step 4: Deposits

Users need to move tokens into Monaco's vault before they can trade. The `useVault` hook covers the full flow — ERC-20 approval, deposit, and withdrawal.

Token addresses and decimals should always be sourced from the trading pair object, not hardcoded:

```tsx theme={null}
import { parseUnits } from 'viem';

const { approve, deposit, withdraw, needsApproval } = useVault();
const { getTradingPairBySymbol } = useMarket();

const pair = await getTradingPairBySymbol('ETH/USDC');
if (!pair) throw new Error('Trading pair not found');

const assetId = pair.quoteAssetId; // Use baseAssetId for the other side

// Amounts must be bigint — use parseUnits with the pair's decimals
const amount = parseUnits('100', pair.quoteDecimals);

if (await needsApproval(assetId, amount)) {
  await approve(assetId, amount);
}
await deposit(assetId, amount);
```

Use `useUserBalances` to reflect deposit confirmation in your UI the moment it lands — it subscribes to real-time balance updates internally, no polling required.

→ [Deposit guide](/deposit/deposit-tokens) · [Account Vault](/developers/vault) · [Withdraw](/deposit/withdraw)

***

## Step 5: Orderbook & Market Data

The orderbook streams via WebSocket — every update arrives in real time with no polling.

```tsx theme={null}
const { orderbook, subscribed } = useOrderbook(
  pair.id,   // Trading pair UUID
  'SPOT',    // Trading mode
  1,         // Magnitude: controls price-level grouping
  'BASE',    // Quotation mode: 'BASE' or 'QUOTE'
  50         // Depth (number of price levels)
);
```

Use `calculateValidMagnitudes(midPrice)` from `@0xmonaco/core` to compute which magnitude steps are meaningful at the current price, and expose them as a selector so traders can zoom in or out.

For the price chart, use `useOHLCV` with intervals of `1m`, `5m`, `15m`, `1h`, `4h`, or `1d`. For a live recent-trades ticker, use `useTradeFeed(pair.id)` — it keeps the last 50 trades in state and updates in real time.

→ [WebSocket guide](/reference/websockets) · [OHLCV guide](/ohlcv)

***

## Step 6: Place & Manage Orders

```tsx theme={null}
const { placeLimitOrder, placeMarketOrder, cancelOrder } = useTrade();

// Limit order — rests on the book until filled or cancelled
await placeLimitOrder(pair.id, 'BUY', '0.5', '50000', { timeInForce: 'GTC' });

// Market order — executes immediately at the best available price
await placeMarketOrder(pair.id, 'SELL', '0.1');
```

**Time-in-Force options (limit orders only):**

| Option | Behaviour |
| - | - |
| `GTC` *(default)* | Rests on the book until filled or manually cancelled |
| `IOC` | Fills immediately, cancels any unfilled remainder |
| `FOK` | Fills completely or rejects the entire order |

Before submission, call `useFees` to show users a live fee estimate — this removes uncertainty and is one of the highest-impact UX improvements you can make.

For real-time order status, use `useUserOrders` — it fetches initial orders and subscribes to WebSocket updates automatically. You will receive lifecycle events — `OrderPlaced`, `OrderPartiallyFilled`, `OrderFilled`, `OrderCancelled`, `OrderRejected` — for every order the authenticated user places.

→ [Order Management](/developers/trade) · [useTrade](/sdk/react/hooks/use-trade)

***

## Step 7: Portfolio

The portfolio section ties together live balances, open orders, and a full activity history.

| Hook | What it provides |
| - | - |
| `useUserBalances` | Live vault balances (available, locked, total) per token — updates via WebSocket |
| `useUserOrders` | Paginated list of the user's orders with status and fill details |
| `useUserMovements` | Full ledger of deposits, withdrawals, trades, and fees |

`useUserBalances` subscribes to `ws.balances()` internally, so balances stay current across order placements, fills, deposits, and withdrawals without any extra wiring.

→ [Account Vault](/developers/vault) · [useUserOrders](/sdk/react/hooks/use-user-orders) · [useUserMovements](/sdk/react/hooks/use-user-movements)

***

## What to Build Next

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/sdk/react/hooks/use-auth">
    Deep-dive into the wallet challenge flow, session keys, and request signing
  </Card>

  <Card title="WebSocket Streams" icon="bolt" href="/reference/websockets">
    All available channels — orders, orderbook, OHLCV, trades, balances, movements
  </Card>

  <Card title="React Hooks Reference" icon="code" href="/sdk/react/intro">
    Complete reference for every hook in @0xmonaco/react
  </Card>

  <Card title="REST API" icon="book" href="/api-reference">
    REST endpoints for use cases that go beyond the SDK
  </Card>
</CardGroup>


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