Socket
Book a DemoInstallSign in
Socket

@0xmonaco/core

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@0xmonaco/core

⚠️ **EARLY DEVELOPMENT WARNING** ⚠️

latest
npmnpm
Version
0.3.0
Version published
Maintainers
2
Created
Source

Monaco Core SDK

⚠️ EARLY DEVELOPMENT WARNING ⚠️

This package is currently in early development.

Breaking changes are expected and may occur without notice. This version is intended for:

  • Early adopters and testing
  • Development and experimentation
  • Feedback collection

Core SDK implementation for interacting with Monaco Protocol. This SDK provides a comprehensive implementation with Authentication, Vault, Trading, Market, and Profile APIs, featuring JWT authentication and secure API Gateway integration.

Installation

npm install @0xmonaco/core

Features

🔐 Authentication

  • JWT-based Authentication: Secure token-based authentication
  • Wallet Signature Verification: EIP-712 signature-based login
  • Token Refresh: Automatic token refresh and management
  • Session Management: Secure session handling

🏦 Vault Operations

  • Token Approvals: ERC20 token approvals for vault usage
  • Deposits: Secure token deposits with signature validation
  • Withdrawals: Token withdrawals with cryptographic validation
  • Balance Queries: Real-time vault balance tracking

📈 Trading Operations

  • Order Types: Limit and Market orders
  • Order Management: Place, replace, and cancel orders
  • Order Queries: Paginated orders, order history, and individual order details
  • Real-time Updates: WebSocket support for live order updates

📊 Market Data

  • Trading Pairs: Complete trading pair metadata
  • Market Information: Fees, tick sizes, order limits
  • Pair Discovery: Search and filter available markets

👤 Profile Management

  • User Profiles: Account information and settings
  • Sub-accounts: Multi-account management
  • Balance Tracking: Cross-platform balance monitoring

🔐 Security Features

  • JWT Authentication: Secure API access with token validation
  • EIP-712 Signatures: Type-safe, structured data signing for authentication
  • API Gateway Integration: Secure communication with Monaco backend
  • TLS Encryption: Secure API communications

Test Setup

Before running tests, ensure you have:

  • A running hardhat node with the Monaco Protocol contracts deployed:

    # In the contracts package
    cd ../contracts
    pnpm hardhat node  # Start a local hardhat node
    pnpm hardhat deploy --network localhost  # Deploy contracts
    
  • Create a .env.test file in the tests directory:

    # Create the file
    cd packages/core/src/tests
    touch .env.test
    
    # Add the following content to .env.test:
    echo 'TEST_PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' > .env.test
    
  • Replace the example private key in .env.test with your actual test account private key:

    • The private key must be a 0x-prefixed 64-character hex string
    • The account must have enough ETH on the local hardhat network for transactions
    • Never commit real private keys to version control
  • Verify your setup:

    # Make sure you're in the core package directory
    cd packages/core
    
    # Check if .env.test exists and has the correct format
    cat src/tests/.env.test
    # Should show: TEST_PRIVATE_KEY=0x...
    
    # Run the tests
    pnpm test
    

If you see an error about TEST_PRIVATE_KEY not being set:

  • Double check that .env.test exists in packages/core/src/tests directory
  • Make sure the private key format is correct (0x-prefixed, 64 characters)
  • Try running the tests with the environment variable directly:
    TEST_PRIVATE_KEY=0x1234... pnpm test
    

Network Support

The SDK supports both Sei mainnet (pacific-1) and testnet (atlantic-2) networks. Network configurations are automatically handled through the NETWORK_ENDPOINTS constant:

import { NETWORK_ENDPOINTS } from "@0xmonaco/core";

// Access network configurations by network name
const mainnetConfig = NETWORK_ENDPOINTS.mainnet; // Pacific-1 mainnet
const testnetConfig = NETWORK_ENDPOINTS.testnet; // Atlantic-2 testnet

// Each network config includes:
// - rpcUrl: RPC endpoint for the network
// - apiUrl: API gateway endpoint for the network

Quick Start

import { MonacoSDK } from "@0xmonaco/core";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";

// Initialize the SDK with wallet client
const account = privateKeyToAccount("0x...");
const walletClient = createWalletClient({
  account,
  transport: http()
});

const monaco = new MonacoSDK({
  walletClient,
  network: "mainnet", // or "testnet"
});

// Authentication
async function authExample() {
  // Login with client ID and auto-connect authenticated WebSocket channels (Orders)
  const authState = await monaco.login("your-client-id", { connectWebSocket: true });
  console.log("Authenticated:", authState.user);
  console.log("Tokens:", {
    accessToken: authState.accessToken,
    refreshToken: authState.refreshToken, // Use this for revokeToken()
  });
  
  // Authenticated WebSocket channels are now connected - start receiving real-time updates
  // Currently this includes: Orders (personal order updates)
  monaco.websocket.orders.subscribeToOrderEvents("BTC/USDC", "SPOT", (event) => {
    console.log("Order event:", event.eventType);
  });
  
  // Check authentication status
  console.log("Is authenticated:", monaco.isAuthenticated());
  
  // Logout (revokes the refresh token and disconnects authenticated WebSockets)
  await monaco.logout();
  
  // Or manually revoke the token
  // ✅ CORRECT: Use authState.refreshToken
  await monaco.auth.revokeToken(authState.refreshToken);
}

// Market Data
async function marketExample() {
  // Get all trading pairs
  const pairs = await monaco.market.getTradingPairs();
  console.log("Available pairs:", pairs.length);
  
  // Get specific trading pair
  const btcPair = await monaco.market.getTradingPairBySymbol("BTC/USDC");
  console.log("BTC pair:", btcPair?.symbol, btcPair?.maker_fee_bps);
}

// Vault Operations
async function vaultExample() {
  // Check vault balance
  const balance = await monaco.vault.getBalance("0x..."); // token address
  console.log("Vault balance:", balance.formatted, balance.symbol);

  // Approve vault to spend tokens
  const approval = await monaco.vault.approve("0x...", parseEther("1000"));
  console.log("Approval transaction:", approval.hash);

  // Deposit tokens
  const result = await monaco.vault.deposit("0x...", parseEther("100"));
  console.log("Deposit transaction:", result.hash);
  
  // Withdraw tokens
  const withdrawal = await monaco.vault.withdraw("0x...", parseEther("50"));
  console.log("Withdrawal transaction:", withdrawal.hash);
}

// Trading Operations
async function tradingExample() {
  // Place a limit order
  const order = await monaco.trading.placeLimitOrder(
    "BTC/USDC", // market
    "BUY", // side
    "0.001", // quantity
    "50000" // price
  );
  console.log("Order placed:", order.order_id);

  // Place a limit order with IOC (Immediate or Cancel)
  const iocOrder = await monaco.trading.placeLimitOrder(
    "BTC/USDC",
    "BUY",
    "0.001",
    "50000",
    { timeInForce: "IOC" } // Execute immediately or cancel
  );
  console.log("IOC order placed:", iocOrder.order_id);

  // Place a market order
  const marketOrder = await monaco.trading.placeMarketOrder(
    "BTC/USDC",
    "SELL",
    "0.001"
  );
  console.log("Market order placed:", marketOrder.order_id);

  // Place a market order with FOK (Fill or Kill)
  const fokOrder = await monaco.trading.placeMarketOrder(
    "BTC/USDC",
    "BUY",
    "0.001",
    { timeInForce: "FOK" } // Must fill completely or cancel
  );
  console.log("FOK order placed:", fokOrder.order_id);

  // Get paginated orders
  const orders = await monaco.trading.getPaginatedOrders({
    status: "PENDING",
    trading_pair: "BTC/USDC",
    page: 1,
    page_size: 10
  });
  console.log("Orders:", orders.data.length);

  // Replace an order
  const replaceResult = await monaco.trading.replaceOrder("order-id", {
    quantity: "0.002",
    price: "51000"
  });
  console.log("Order replaced:", replaceResult.order_id);

  // Cancel an order
  const cancelResult = await monaco.trading.cancelOrder("order-id");
  console.log("Order cancelled:", cancelResult.status);
  
  // Get specific order
  const orderDetails = await monaco.trading.getOrder("order-id");
  console.log("Order details:", orderDetails.order);
}

API Reference

MonacoSDK

The main SDK class that provides access to all protocol features.

class MonacoSDK {
  readonly applications: ApplicationsAPI;
  readonly auth: AuthAPI;
  readonly vault: VaultAPI;
  readonly trading: TradingAPI;
  readonly market: MarketAPI;
  readonly profile: ProfileAPI;
  readonly websocket: {
    orders: OrdersWebSocketClient;
    ohlcv: OHLCVWebSocketClient;
    orderbook: OrderbookWebSocketClient;
  };
  readonly walletClient: WalletClient;
  readonly publicClient: PublicClient;

  constructor(config: SDKConfig);
  
  // Authentication
  login(clientId: string, options?: { connectWebSocket?: boolean }): Promise<AuthState>;
  logout(): Promise<void>;
  refreshAuth(): Promise<AuthState>;
  getAuthState(): AuthState | undefined;
  isAuthenticated(): boolean;
  
  // Network utilities
  isConnected(): boolean;
  getAccountAddress(): string;
  getNetwork(): Network;
  getChainId(): number;
  waitForTransaction(hash: string, confirmations?: number, timeout?: number): Promise<TransactionReceipt>;
}

Configuration

interface SDKConfig {
  /** Wallet client for signing operations */
  walletClient: WalletClient;
  
  /** Optional network override (defaults to 'mainnet') */
  network?: Network;
  
  /** Optional transport for the public client */
  transport?: Transport;
}

Authentication & Token Management

The SDK uses JWT tokens for authentication. Understanding the token structure is important:

// After login, you receive an AuthState object
const authState = await sdk.login(clientId);

// AuthState structure:
interface AuthState {
  accessToken: string;    // For making authenticated API requests
  refreshToken: string;   // For refreshing tokens AND revoking (logout)
  expiresAt: number;      // When the access token expires
  user: User;             // User information
}

⚠️ Important: The authentication response contains refreshToken, NOT revokeToken.

// ✅ CORRECT: Revoke using refreshToken
await sdk.auth.revokeToken(authState.refreshToken);

// 💡 TIP: Use the built-in logout method
await sdk.logout(); // Automatically calls revokeToken internally

Token Management Methods:

  • login(clientId, options?) - Authenticate and get tokens
    • clientId: Your application's client ID
    • options.connectWebSocket: (optional) Auto-connect all authenticated WebSocket channels after login (default: false)
  • logout() - Revoke token and clear state
  • refreshAuth() - Refresh the access token using the stored refresh token
  • isAuthenticated() - Check if user is authenticated
  • getAuthState() - Get current auth state with tokens

Vault API

The vault API provides secure token management operations:

interface VaultAPI extends BaseAPI {
  // Vault address management
  setVaultAddress(vaultAddress: Address): void;
  getVaultAddress(): Address | undefined;
  
  // Token operations
  approve(token: string, amount: bigint, autoWait?: boolean): Promise<TransactionResult>;
  deposit(token: string, amount: bigint, autoWait?: boolean): Promise<TransactionResult>;
  withdraw(token: string, amount: bigint, autoWait?: boolean): Promise<TransactionResult>;
  
  // Balance queries
  getBalance(token: string): Promise<Balance>;
}

Trading API

The trading API provides comprehensive order management:

interface TradingAPI extends BaseAPI {
  // Order placement
  placeLimitOrder(
    market: string, 
    side: OrderSide, 
    quantity: string, 
    price: string, 
    options?: {
      tradingMode?: string;
      useMasterBalance?: boolean;
      expirationDate?: string;
      timeInForce?: string; // "GTC", "IOC", or "FOK"
    }
  ): Promise<CreateOrderResponse>;
  
  placeMarketOrder(
    market: string, 
    side: OrderSide, 
    quantity: string, 
    options?: { 
      tradingMode?: string;
      slippageTolerance?: number;
      timeInForce?: string; // "GTC", "IOC", or "FOK"
    }
  ): Promise<CreateOrderResponse>;
  
  // Order management
  cancelOrder(orderId: string): Promise<CancelOrderResponse>;
  replaceOrder(
    orderId: string, 
    newOrder: {
      price?: string;
      quantity: string;
      useMasterBalance?: boolean;
    }
  ): Promise<ReplaceOrderResponse>;
  
  // Order queries
  getPaginatedOrders(params?: GetPaginatedOrdersParams): Promise<GetPaginatedOrdersResponse>;
  getOrder(orderId: string): Promise<GetOrderResponse>;
}

Market API

The market API provides access to trading pair metadata:

interface MarketAPI extends BaseAPI {
  // Market data
  getTradingPairs(): Promise<TradingPair[]>;
  getTradingPairBySymbol(symbol: string): Promise<TradingPair | undefined>;
}

WebSocket Authentication

The SDK provides three WebSocket clients with different authentication requirements:

Public WebSockets (OHLCV and Orderbook)

No authentication required. Provide public market data. You always connect manually:

// Step 1: Establish WebSocket connection (no authentication needed)
await monaco.websocket.ohlcv.connect();
await monaco.websocket.orderbook.connect();

// Step 2: Subscribe to public market data
monaco.websocket.ohlcv.subscribeToOHLCV("BTC/USDC", "SPOT", "1m", (event) => {
  console.log("OHLCV data:", event.candlestick);
});

monaco.websocket.orderbook.subscribeToOrderbookEvents("BTC/USDC", "SPOT", (event) => {
  console.log("Orderbook update:", event.bids.length, "bids");
});

Authenticated WebSockets (Orders)

Requires JWT authentication for personal order updates. You can either auto-connect during login or connect manually:

Option 1: Auto-connect (recommended for authenticated channels)

// Login and auto-connect all authenticated WebSocket channels
// Currently includes: Orders (personal order updates)
await monaco.login(clientId, { connectWebSocket: true });

// Subscribe to personal order events (already connected)
monaco.websocket.orders.subscribeToOrderEvents("BTC/USDC", "SPOT", (event) => {
  console.log("Personal order event:", event.eventType);
});

Option 2: Manual connection (required for public channels, optional for authenticated)

// Public channels like OHLCV always require manual connection (no auth needed)
await monaco.websocket.ohlcv.connect();

monaco.websocket.ohlcv.subscribeToOHLCV("BTC/USDC", "SPOT", "1m", (event) => {
  console.log("OHLCV data:", event.candlestick);
});

// For authenticated channels, you can also connect manually for more control
await monaco.login(clientId);
await monaco.websocket.orders.connect();
monaco.websocket.orders.subscribeToOrderEvents("BTC/USDC", "SPOT", (event) => {
  console.log("Personal order event:", event.eventType);
});

Note:

  • The connectWebSocket: true option automatically connects all authenticated WebSocket channels (currently Orders).
  • Public WebSocket clients (OHLCV, Orderbook) always require calling connect() explicitly as they don't require authentication.

Error Handling

The SDK uses structured error classes for comprehensive error handling:

import { APIError, ContractError, TransactionError, OrderError } from "@0xmonaco/core";

try {
  await sdk.vault.deposit(token, amount);
} catch (error) {
  if (error instanceof ContractError) {
    console.error("Contract error:", error.message);
    console.error("Error code:", error.code);
  } else if (error instanceof APIError) {
    console.error("API error:", error.message);
    console.error("Status:", error.status);
  } else if (error instanceof TransactionError) {
    console.error("Transaction error:", error.message);
  } else if (error instanceof OrderError) {
    console.error("Order error:", error.message);
    console.error("Market:", error.market);
  }
}

Error Types:

  • MonacoCoreError: Base error class for all SDK errors
  • APIError: API request failures and communication errors
  • ContractError: Smart contract operation errors
  • TransactionError: Blockchain transaction errors
  • OrderError: Trading order specific errors
  • InvalidConfigError: Configuration validation errors
  • InvalidStateError: Invalid state or operation errors

Development

Project Structure

packages/core/
├── src/                   # Source code
│   ├── api/               # API implementations
│   │   ├── applications/  # Applications API
│   │   ├── auth/          # Authentication API
│   │   ├── base.ts        # Base API class
│   │   ├── market/        # Market data API
│   │   ├── profile/       # Profile management API
│   │   ├── trading/       # Trading operations API
│   │   ├── vault/         # Vault operations API
│   │   ├── websocket/     # WebSocket client
│   │   └── index.ts       # API exports
│   ├── constants/         # Constants and configurations
│   ├── errors.ts          # Error classes and codes
│   ├── networks.ts        # Network endpoint configurations
│   ├── sdk.ts             # Main SDK implementation
│   └── index.ts           # Public API exports
├── tests/                 # Test suite
├── dist/                  # Compiled output
├── package.json           # Package configuration
└── tsconfig.json          # TypeScript configuration

Development Setup

  • Clone the repository:
git clone https://github.com/monaco-protocol/monaco-monorepo.git
cd monaco-monorepo
  • Install dependencies:
pnpm install
  • Build the package:
pnpm build --filter @0xmonaco/core

Testing

Run the test suite:

pnpm test --filter @0xmonaco/core

Code Style

The project uses ESLint and Prettier for code formatting. Run the linter:

pnpm lint --filter @0xmonaco/core

Security Features

JWT Authentication

  • Token-based security: Secure JWT tokens for API access
  • EIP-712 login: Wallet signature-based authentication
  • Automatic refresh: Seamless token renewal
  • Session management: Secure session handling

API Gateway Integration

  • Secure communication: TLS encryption for all API calls
  • Token validation: Backend validates all JWT tokens
  • Rate limiting: Protection against abuse
  • Audit logging: Complete transaction history

On-chain Security

  • Smart contract validation: All operations validated on-chain
  • Signature verification: EIP-712 signatures for authentication
  • Multi-signature support: Advanced security for institutional users

Performance Considerations

  • Batch operations: Efficient handling of multiple operations
  • Connection pooling: Optimized API connections
  • Caching: Smart caching of frequently accessed data
  • Async operations: Non-blocking operations for better UX

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Workflow

  • Fork the repository
  • Create a feature branch
  • Make your changes
  • Add tests for new functionality
  • Ensure all tests pass
  • Submit a pull request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For support, please:

FAQs

Package last updated on 07 Nov 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts