@0xmonaco/core
v0.8.1
Published
⚠️ **EARLY DEVELOPMENT WARNING** ⚠️
Keywords
Readme
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/coreRequired Peer Dependencies:
npm install viem@^2.31.7Features
🔐 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
Network Support
The SDK supports the following preset networks. Configure the network by providing the network and seiRpcUrl parameters:
Preset Networks:
"development"- Development environment (https://develop.apimonaco.xyz)"staging"- Staging environment (https://staging.apimonaco.xyz)"mainnet"- Production environment (https://api.monaco.xyz)"local"- Local development (http://localhost:8080)
WebSocket URLs are automatically resolved per network.
import { MonacoSDK } from "@0xmonaco/core";
// Development configuration
const devSdk = new MonacoSDK({
walletClient,
network: "development",
seiRpcUrl: "https://evm-rpc-testnet.sei-apis.com",
});
// Staging configuration
const stagingSdk = new MonacoSDK({
walletClient,
network: "staging",
seiRpcUrl: "https://evm-rpc-testnet.sei-apis.com",
});
// Mainnet configuration
const mainnetSdk = new MonacoSDK({
walletClient,
network: "mainnet",
seiRpcUrl: "https://evm-rpc.sei-apis.com",
});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,
chain: sei, // or seiTestnet
transport: http("https://evm-rpc.sei-apis.com") // or https://evm-rpc-testnet.sei-apis.com for testnet
});
const monaco = new MonacoSDK({
walletClient,
network: "development", // or "staging", "mainnet", "local"
seiRpcUrl: "https://evm-rpc-testnet.sei-apis.com", // or https://evm-rpc.sei-apis.com for mainnet
});
// 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,
});
// 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
await monaco.auth.revokeToken();
}
// 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() {
// Get asset ID from trading pair
const pair = await monaco.market.getTradingPairBySymbol("USDC/USDT");
const assetId = pair.base_asset_id; // Asset ID (UUID)
// Check vault balance
const balance = await monaco.profile.getUserBalanceByAssetId(assetId);
console.log("Vault balance:", balance.total_balance, balance.symbol);
// Approve vault to spend tokens
const approval = await monaco.vault.approve(assetId, parseEther("1000"));
console.log("Approval transaction:", approval.hash);
// Deposit tokens
const result = await monaco.vault.deposit(assetId, parseEther("100"));
console.log("Deposit transaction:", result.hash);
// Withdraw tokens
const withdrawal = await monaco.vault.withdraw(assetId, parseEther("50"));
console.log("Withdrawal transaction:", withdrawal.hash);
}
// Trading Operations
async function tradingExample() {
// Look up the trading pair UUID first
const pair = await monaco.market.getTradingPairBySymbol("BTC/USDC");
const tradingPairId = pair.id; // UUID
// Place a limit order
const order = await monaco.trading.placeLimitOrder(
tradingPairId, // trading pair UUID
"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(
tradingPairId,
"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(
tradingPairId,
"SELL",
"0.001"
);
console.log("Market order placed:", marketOrder.order_id);
// Get paginated orders
const orders = await monaco.trading.getPaginatedOrders({
status: "SUBMITTED",
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.
Configuration
interface SDKConfig {
/** Wallet client for signing operations (optional - can be set later via setWalletClient) */
walletClient?: WalletClient;
/** Network preset: "local", "development", "staging", or "mainnet" */
network: Network;
/** RPC URL for Sei blockchain interactions */
seiRpcUrl: string;
}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
}// Revoke the current session's token
await sdk.auth.revokeToken();
// 💡 TIP: Use the built-in logout method
await sdk.logout(); // Automatically calls revokeToken internallyToken Management Methods:
login(clientId, options?)- Authenticate and get tokensclientId: Your application's client IDoptions.connectWebSocket: (optional) Auto-connect WebSocket after login (default:false)- Returns
AuthStatewith access token, refresh token, expiration, and user info
logout()- Revoke token, disconnect WebSocket, and clear state- Calls
auth.revokeToken()internally - Disconnects authenticated WebSocket channels
- Clears local auth state
- Calls
refreshAuth()- Refresh the access token using the stored refresh tokenisAuthenticated()- Check if user is authenticatedgetAuthState()- Get current auth state with tokenssetAuthState(authState)- Set auth state directly (useful for sharing across SDK instances)
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>;
}Trading API
The trading API provides comprehensive order management:
interface TradingAPI extends BaseAPI {
// Order placement
placeLimitOrder(
tradingPairId: string,
side: OrderSide,
quantity: string,
price: string,
options?: {
tradingMode?: TradingMode;
useMasterBalance?: boolean;
expirationDate?: string;
timeInForce?: TimeInForce;
}
): Promise<CreateOrderResponse>;
placeMarketOrder(
tradingPairId: string,
side: OrderSide,
quantity: string,
options?: {
tradingMode?: TradingMode;
slippageTolerance?: number;
}
): 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: trueoption 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 } 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);
}
}Error Types:
MonacoCoreError: Base error class for all SDK errorsAPIError: API request failures and communication errorsContractError: Smart contract operation errorsInvalidConfigError: Configuration validation errorsInvalidStateError: 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 configurationDevelopment Setup
Clone the repository:
git clone https://github.com/monaco-protocol/monaco-monorepo.git cd monaco-monorepoInstall dependencies:
bun run installBuild the package:
bun run build --filter @0xmonaco/core
Testing
Run the test suite:
bun run test --filter @0xmonaco/coreCode Style
The project uses ESLint and Prettier for code formatting. Run the linter:
bun run lint --filter @0xmonaco/coreSecurity 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
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.
Support
For support, please:
- Open an issue on GitHub
- Join our Discord community
- Visit our documentation site
- Check our API documentation
