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

# Complete Integration Example

> End-to-end example showing authentication, deposits, withdrawals, and trading with Monaco Protocol SDK

This example demonstrates a complete integration workflow using Monaco Protocol SDK's core features: authentication, deposits, withdrawals, and trading.

## Installation

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

## Complete Example

```typescript theme={null}
import { MonacoSDK } from '@0xmonaco/core';
import { createWalletClient, custom, parseUnits } from 'viem';
import { seiTestnet } from 'viem/chains';

async function completeMonacoIntegration() {
  try {
    // 1. Request account access
    const [account] = await window.ethereum.request({ 
      method: 'eth_requestAccounts' 
    });

    // 2. Initialize SDK with wallet
    const walletClient = createWalletClient({
      account,
      chain: seiTestnet,
      transport: custom(window.ethereum)
    });

    const sdk = new MonacoSDK({
      walletClient,
      network: 'staging',
      seiRpcUrl: 'https://evm-rpc-testnet.sei-apis.com', // public testnet RPC — use a private provider in production
    });

    // 3. Authenticate (registers a session key; every authenticated request is signed).
    //    Pass connectWebSocket: true to also open the realtime stream (off by default).
    console.log('Authenticating...');
    const authState = await sdk.login('your-client-id', { connectWebSocket: true });
    console.log('Authenticated as:', authState.user.address);

    // 4. Get trading pair to access asset IDs
    // Asset IDs come from trading pairs, not balances
    const usdcPair = await sdk.market.getTradingPairBySymbol('ETH/USDC');
    if (!usdcPair) {
      throw new Error('Trading pair not found');
    }

    // For USDC (the quote token in ETH/USDC):
    const assetId = usdcPair.quoteAssetId;  // All vault operations use assetId
    const decimals = 6; // USDC decimals

    // 5. Check token balance
    const balance = await sdk.profile.getUserBalanceByAssetId(assetId);
    console.log('Available balance:', balance.availableBalance, balance.symbol);
    console.log('Locked balance:', balance.lockedBalance, balance.symbol);

    // 6. Deposit tokens (if you have them)
    const depositAmount = parseUnits('10', decimals);
    
    // Check if approval is needed
    const needsApproval = await sdk.vault.needsApproval(assetId, depositAmount);
    if (needsApproval) {
      console.log('Approving tokens...');
      const approvalResult = await sdk.vault.approve(assetId, depositAmount);
      console.log('Approval transaction:', approvalResult.hash);
    }

    // Deposit tokens
    console.log('Depositing tokens...');
    const depositResult = await sdk.vault.deposit(assetId, depositAmount);
    console.log('Deposit transaction:', depositResult.hash);

    // 7. Check updated balance
    const newBalance = await sdk.profile.getUserBalanceByAssetId(assetId);
    console.log('Available balance:', newBalance.availableBalance, newBalance.symbol);
    console.log('Total balance:', newBalance.totalBalance, newBalance.symbol);

    // 8. Withdraw tokens (optional)
    const withdrawAmount = parseUnits('5', decimals);
    console.log('Withdrawing tokens...');
    const withdrawResult = await sdk.vault.withdraw(assetId, withdrawAmount);
    console.log('Withdrawal transaction:', withdrawResult.hash);

    // Check balance after withdrawal
    const balanceAfterWithdraw = await sdk.profile.getUserBalanceByAssetId(assetId);
    console.log('Available balance:', balanceAfterWithdraw.availableBalance, balanceAfterWithdraw.symbol);
    console.log('Total balance:', balanceAfterWithdraw.totalBalance, balanceAfterWithdraw.symbol);

    // 9. Get trading pair (reuse the same one for trading)
    const tradingPair = usdcPair;  // ETH/USDC from step 4

    // 10. Place a trading order
    console.log('Placing limit order...');
    const limitOrder = await sdk.trading.placeLimitOrder(
      tradingPair.id,  // Trading pair UUID
      'BUY',           // Side  
      '0.1',           // Quantity (0.1 ETH)
      '2000'           // Price ($2000)
    );
    console.log('Order placed:', limitOrder.orderId);

    // 11. Check order status (optional)
    console.log('Order details:', limitOrder);

  } catch (error) {
    console.error('Error:', error.message);
    
    // Handle specific error types
    if (error.statusCode === 401) {
      console.log('Authentication failed - check client ID');
    } else if (error.statusCode === 403) {
      console.log('Session expired or unauthorized - need to re-authenticate');
    } else {
      console.log('Other error:', error);
    }
  }
}

// Run the complete integration
completeMonacoIntegration();
```

## React Hook Example

For React applications, here's a reusable hook:

```typescript theme={null}
import { useState, useEffect } from 'react';
import { MonacoSDK } from '@0xmonaco/core';
import { createWalletClient, custom } from 'viem';
import { seiTestnet } from 'viem/chains';

function useMonacoSDK(clientId: string) {
  const [sdk, setSdk] = useState<MonacoSDK | null>(null);
  const [authState, setAuthState] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Initialize SDK
  useEffect(() => {
    const initSDK = async () => {
      if (!window.ethereum) {
        setError('No wallet detected');
        return;
      }

      try {
        // Request account access
        const [account] = await window.ethereum.request({ 
          method: 'eth_requestAccounts' 
        });

        const walletClient = createWalletClient({
          account,
          chain: seiTestnet,
          transport: custom(window.ethereum)
        });

        const monacoSDK = new MonacoSDK({
          walletClient,
          network: 'staging',
          seiRpcUrl: 'https://evm-rpc-testnet.sei-apis.com',
        });

        setSdk(monacoSDK);
      } catch (err) {
        setError(err.message);
      }
    };

    initSDK();
  }, []);

  // Authentication function
  const login = async () => {
    if (!sdk) return;

    setLoading(true);
    setError(null);

    try {
      const result = await sdk.login(clientId);
      setAuthState(result);
      return result;
    } catch (err) {
      setError(err.message);
      throw err;
    } finally {
      setLoading(false);
    }
  };

  return {
    sdk,
    authState,
    loading,
    error,
    login,
    isAuthenticated: !!authState
  };
}

// Usage in component
function TradingApp() {
  const { sdk, authState, loading, error, login, isAuthenticated } = useMonacoSDK('your-client-id');

  return (
    <div>
      {!isAuthenticated ? (
        <button onClick={login} disabled={loading}>
          {loading ? 'Connecting...' : 'Connect Wallet'}
        </button>
      ) : (
        <div>
          <p>Connected: {authState.user.address}</p>
          {/* Your trading interface here */}
        </div>
      )}
      {error && <p>Error: {error}</p>}
    </div>
  );
}
```

## Key Points

### **Authentication**

* Use `sdk.login(clientId)` - it registers a local session key and signs every authenticated request (public market reads are unsigned); there are no tokens to copy or refresh
* The WebSocket is NOT auto-connected by default — pass `sdk.login(clientId, { connectWebSocket: true })` (or connect explicitly) before using `sdk.ws.orders()` to subscribe
* Handle 401/403 status codes for authentication errors

### **Deposits & Withdrawals**

* **Get `assetId` from trading pairs** via `sdk.market.getTradingPairBySymbol()` - use `quoteAssetId` or `baseAssetId`
* **`assetId`** (UUID) is used for vault operations: `approve()`, `deposit()`, `withdraw()`, `getAllowance()`, and `needsApproval()`
* **Check balances** using `sdk.profile.getUserBalanceByAssetId(assetId)` for detailed balance info (available, locked, total)
* Always check `needsApproval()` before depositing
* Use `parseUnits()` with correct decimals for token amounts
* Vault operations require authentication

### **Trading**

* All amounts are strings (e.g., `'1.5'`, `'2000.50'`)
* Trading operations require authentication
* Orders return an `orderId` for tracking
* Time-In-Force (TIF) options: `'GTC'` (default), `'IOC'`, or `'FOK'`
  * **GTC**: Order stays active until filled or canceled
  * **IOC**: Fill immediately, cancel unfilled portion
  * **FOK**: Fill completely or reject entirely

### **Error Handling**

* Check `error.statusCode` for HTTP errors (401, 403)
* All operations can throw `APIError`, `ContractError`, etc.

## Next Steps

This example covers the core SDK functionality. For detailed guides on each feature:

* [Authentication Guide](/sdk/typescript/auth) - Wallet-based authentication
* [Deposit Guide](/deposit/deposit-tokens) - Token deposits and withdrawals
* [Order Management](/developers/trade) - Order placement and management
* [REST API](/api-reference) - Direct REST API usage

<Note>
  Comprehensive example repositories with Vite and Next.js are in development for more complete project setups.
</Note>


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