@0xmonaco/core 0.0.0-develop-20260120180031
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +693 -0
- package/dist/api/applications/api.d.ts +44 -0
- package/dist/api/applications/api.d.ts.map +1 -0
- package/dist/api/applications/api.js +54 -0
- package/dist/api/applications/api.js.map +1 -0
- package/dist/api/applications/index.d.ts +5 -0
- package/dist/api/applications/index.d.ts.map +1 -0
- package/dist/api/applications/index.js +5 -0
- package/dist/api/applications/index.js.map +1 -0
- package/dist/api/auth/api.d.ts +201 -0
- package/dist/api/auth/api.d.ts.map +1 -0
- package/dist/api/auth/api.js +293 -0
- package/dist/api/auth/api.js.map +1 -0
- package/dist/api/auth/index.d.ts +5 -0
- package/dist/api/auth/index.d.ts.map +1 -0
- package/dist/api/auth/index.js +5 -0
- package/dist/api/auth/index.js.map +1 -0
- package/dist/api/base.d.ts +124 -0
- package/dist/api/base.d.ts.map +1 -0
- package/dist/api/base.js +284 -0
- package/dist/api/base.js.map +1 -0
- package/dist/api/fees/api.d.ts +71 -0
- package/dist/api/fees/api.d.ts.map +1 -0
- package/dist/api/fees/api.js +83 -0
- package/dist/api/fees/api.js.map +1 -0
- package/dist/api/fees/index.d.ts +7 -0
- package/dist/api/fees/index.d.ts.map +1 -0
- package/dist/api/fees/index.js +7 -0
- package/dist/api/fees/index.js.map +1 -0
- package/dist/api/index.d.ts +16 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +16 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/market/api.d.ts +14 -0
- package/dist/api/market/api.d.ts.map +1 -0
- package/dist/api/market/api.js +70 -0
- package/dist/api/market/api.js.map +1 -0
- package/dist/api/market/index.d.ts +2 -0
- package/dist/api/market/index.d.ts.map +1 -0
- package/dist/api/market/index.js +2 -0
- package/dist/api/market/index.js.map +1 -0
- package/dist/api/orderbook/api.d.ts +16 -0
- package/dist/api/orderbook/api.d.ts.map +1 -0
- package/dist/api/orderbook/api.js +38 -0
- package/dist/api/orderbook/api.js.map +1 -0
- package/dist/api/orderbook/index.d.ts +2 -0
- package/dist/api/orderbook/index.d.ts.map +1 -0
- package/dist/api/orderbook/index.js +2 -0
- package/dist/api/orderbook/index.js.map +1 -0
- package/dist/api/profile/api.d.ts +119 -0
- package/dist/api/profile/api.d.ts.map +1 -0
- package/dist/api/profile/api.js +162 -0
- package/dist/api/profile/api.js.map +1 -0
- package/dist/api/profile/index.d.ts +7 -0
- package/dist/api/profile/index.d.ts.map +1 -0
- package/dist/api/profile/index.js +7 -0
- package/dist/api/profile/index.js.map +1 -0
- package/dist/api/trades/api.d.ts +45 -0
- package/dist/api/trades/api.d.ts.map +1 -0
- package/dist/api/trades/api.js +43 -0
- package/dist/api/trades/api.js.map +1 -0
- package/dist/api/trades/index.d.ts +2 -0
- package/dist/api/trades/index.d.ts.map +1 -0
- package/dist/api/trades/index.js +2 -0
- package/dist/api/trades/index.js.map +1 -0
- package/dist/api/trading/api.d.ts +213 -0
- package/dist/api/trading/api.d.ts.map +1 -0
- package/dist/api/trading/api.js +285 -0
- package/dist/api/trading/api.js.map +1 -0
- package/dist/api/trading/index.d.ts +5 -0
- package/dist/api/trading/index.d.ts.map +1 -0
- package/dist/api/trading/index.js +5 -0
- package/dist/api/trading/index.js.map +1 -0
- package/dist/api/vault/api.d.ts +257 -0
- package/dist/api/vault/api.d.ts.map +1 -0
- package/dist/api/vault/api.js +526 -0
- package/dist/api/vault/api.js.map +1 -0
- package/dist/api/vault/index.d.ts +5 -0
- package/dist/api/vault/index.d.ts.map +1 -0
- package/dist/api/vault/index.js +5 -0
- package/dist/api/vault/index.js.map +1 -0
- package/dist/api/websocket/index.d.ts +4 -0
- package/dist/api/websocket/index.d.ts.map +1 -0
- package/dist/api/websocket/index.js +4 -0
- package/dist/api/websocket/index.js.map +1 -0
- package/dist/api/websocket/types.d.ts +36 -0
- package/dist/api/websocket/types.d.ts.map +1 -0
- package/dist/api/websocket/types.js +2 -0
- package/dist/api/websocket/types.js.map +1 -0
- package/dist/api/websocket/utils.d.ts +9 -0
- package/dist/api/websocket/utils.d.ts.map +1 -0
- package/dist/api/websocket/utils.js +23 -0
- package/dist/api/websocket/utils.js.map +1 -0
- package/dist/api/websocket/websocket.d.ts +6 -0
- package/dist/api/websocket/websocket.d.ts.map +1 -0
- package/dist/api/websocket/websocket.js +345 -0
- package/dist/api/websocket/websocket.js.map +1 -0
- package/dist/errors/errors.d.ts +382 -0
- package/dist/errors/errors.d.ts.map +1 -0
- package/dist/errors/errors.js +801 -0
- package/dist/errors/errors.js.map +1 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/networks/index.d.ts +2 -0
- package/dist/networks/index.d.ts.map +1 -0
- package/dist/networks/index.js +2 -0
- package/dist/networks/index.js.map +1 -0
- package/dist/networks/networks.d.ts +15 -0
- package/dist/networks/networks.d.ts.map +1 -0
- package/dist/networks/networks.js +34 -0
- package/dist/networks/networks.js.map +1 -0
- package/dist/sdk.d.ts +128 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +272 -0
- package/dist/sdk.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/magnitude.d.ts +27 -0
- package/dist/utils/magnitude.d.ts.map +1 -0
- package/dist/utils/magnitude.js +32 -0
- package/dist/utils/magnitude.js.map +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
# Monaco Core SDK
|
|
2
|
+
|
|
3
|
+
⚠️ **EARLY DEVELOPMENT WARNING** ⚠️
|
|
4
|
+
|
|
5
|
+
This package is currently in **early development**.
|
|
6
|
+
|
|
7
|
+
**Breaking changes are expected** and may occur without notice. This version is intended for:
|
|
8
|
+
- Early adopters and testing
|
|
9
|
+
- Development and experimentation
|
|
10
|
+
- Feedback collection
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
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.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @0xmonaco/core
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Required Peer Dependencies:**
|
|
23
|
+
```bash
|
|
24
|
+
npm install viem@^2.31.7
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### TypeScript Configuration
|
|
28
|
+
|
|
29
|
+
For best results, use these TypeScript settings in your `tsconfig.json`:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"compilerOptions": {
|
|
34
|
+
"target": "ES2020",
|
|
35
|
+
"module": "nodenext",
|
|
36
|
+
"moduleResolution": "nodenext",
|
|
37
|
+
"strict": true,
|
|
38
|
+
"esModuleInterop": true,
|
|
39
|
+
"resolveJsonModule": true
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
### 🔐 **Authentication**
|
|
47
|
+
- **JWT-based Authentication**: Secure token-based authentication
|
|
48
|
+
- **Wallet Signature Verification**: EIP-712 signature-based login
|
|
49
|
+
- **Token Refresh**: Automatic token refresh and management
|
|
50
|
+
- **Session Management**: Secure session handling
|
|
51
|
+
|
|
52
|
+
### 🏦 **Vault Operations**
|
|
53
|
+
- **Token Approvals**: ERC20 token approvals for vault usage
|
|
54
|
+
- **Deposits**: Secure token deposits with signature validation
|
|
55
|
+
- **Withdrawals**: Token withdrawals with cryptographic validation
|
|
56
|
+
- **Balance Queries**: Real-time vault balance tracking
|
|
57
|
+
|
|
58
|
+
### 📈 **Trading Operations**
|
|
59
|
+
- **Order Types**: Limit and Market orders
|
|
60
|
+
- **Order Management**: Place, replace, and cancel orders
|
|
61
|
+
- **Order Queries**: Paginated orders, order history, and individual order details
|
|
62
|
+
- **Real-time Updates**: WebSocket support for live order updates
|
|
63
|
+
|
|
64
|
+
### 📊 **Market Data**
|
|
65
|
+
- **Trading Pairs**: Complete trading pair metadata
|
|
66
|
+
- **Market Information**: Fees, tick sizes, order limits
|
|
67
|
+
- **Pair Discovery**: Search and filter available markets
|
|
68
|
+
|
|
69
|
+
### 👤 **Profile Management**
|
|
70
|
+
- **User Profiles**: Account information and settings
|
|
71
|
+
- **Sub-accounts**: Multi-account management
|
|
72
|
+
- **Balance Tracking**: Cross-platform balance monitoring
|
|
73
|
+
|
|
74
|
+
### 🔐 **Security Features**
|
|
75
|
+
- **JWT Authentication**: Secure API access with token validation
|
|
76
|
+
- **EIP-712 Signatures**: Type-safe, structured data signing for authentication
|
|
77
|
+
- **API Gateway Integration**: Secure communication with Monaco backend
|
|
78
|
+
- **TLS Encryption**: Secure API communications
|
|
79
|
+
|
|
80
|
+
## Test Setup
|
|
81
|
+
|
|
82
|
+
Before running tests, ensure you have:
|
|
83
|
+
|
|
84
|
+
1. A running hardhat node with the Monaco Protocol contracts deployed:
|
|
85
|
+
```bash
|
|
86
|
+
# In the contracts package
|
|
87
|
+
cd ../contracts
|
|
88
|
+
pnpm hardhat node # Start a local hardhat node
|
|
89
|
+
pnpm hardhat deploy --network localhost # Deploy contracts
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
2. Create a `.env.test` file in the tests directory:
|
|
93
|
+
```bash
|
|
94
|
+
# Create the file
|
|
95
|
+
cd packages/core/tests
|
|
96
|
+
touch .env.test
|
|
97
|
+
|
|
98
|
+
# Add the following content to .env.test:
|
|
99
|
+
echo 'TEST_PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' > .env.test
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
3. Replace the example private key in `.env.test` with your actual test account private key:
|
|
103
|
+
- The private key must be a 0x-prefixed 64-character hex string
|
|
104
|
+
- The account must have enough ETH on the local hardhat network for transactions
|
|
105
|
+
- Never commit real private keys to version control
|
|
106
|
+
|
|
107
|
+
4. Verify your setup:
|
|
108
|
+
```bash
|
|
109
|
+
# Make sure you're in the core package directory
|
|
110
|
+
cd packages/core
|
|
111
|
+
|
|
112
|
+
# Check if .env.test exists and has the correct format
|
|
113
|
+
cat tests/.env.test
|
|
114
|
+
# Should show: TEST_PRIVATE_KEY=0x...
|
|
115
|
+
|
|
116
|
+
# Run the tests
|
|
117
|
+
pnpm test
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
If you see an error about `TEST_PRIVATE_KEY` not being set:
|
|
121
|
+
1. Double check that `.env.test` exists in `packages/core/tests` directory
|
|
122
|
+
2. Make sure the private key format is correct (0x-prefixed, 64 characters)
|
|
123
|
+
3. Try running the tests with the environment variable directly:
|
|
124
|
+
```bash
|
|
125
|
+
TEST_PRIVATE_KEY=0x1234... pnpm test
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Network Support
|
|
129
|
+
|
|
130
|
+
The SDK supports multiple preset networks and custom API URLs. Configure the network by providing the `network` and `seiRpcUrl` parameters:
|
|
131
|
+
|
|
132
|
+
**Preset Networks:**
|
|
133
|
+
- `"development"` - Development environment (https://develop.apimonaco.xyz)
|
|
134
|
+
- `"staging"` - Staging environment (https://staging.apimonaco.xyz)
|
|
135
|
+
- `"mainnet"` - Production environment (https://api.monaco.xyz)
|
|
136
|
+
- `"local"` - Local development (http://localhost:8080)
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { MonacoSDK } from "@0xmonaco/core";
|
|
140
|
+
|
|
141
|
+
// Development configuration
|
|
142
|
+
const devSdk = new MonacoSDK({
|
|
143
|
+
walletClient,
|
|
144
|
+
network: "development",
|
|
145
|
+
seiRpcUrl: "https://evm-rpc-testnet.sei-apis.com", // Atlantic-2 testnet
|
|
146
|
+
wsUrl: "wss://develop.apimonaco.xyz/ws"
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Staging configuration
|
|
150
|
+
const stagingSdk = new MonacoSDK({
|
|
151
|
+
walletClient,
|
|
152
|
+
network: "staging",
|
|
153
|
+
seiRpcUrl: "https://evm-rpc-testnet.sei-apis.com", // Atlantic-2 testnet
|
|
154
|
+
wsUrl: "wss://staging.apimonaco.xyz/ws"
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Mainnet configuration
|
|
158
|
+
const mainnetSdk = new MonacoSDK({
|
|
159
|
+
walletClient,
|
|
160
|
+
network: "mainnet",
|
|
161
|
+
seiRpcUrl: "https://evm-rpc.sei-apis.com", // Pacific-1 mainnet
|
|
162
|
+
wsUrl: "wss://api.monaco.xyz/ws"
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Custom API URL
|
|
166
|
+
const customSdk = new MonacoSDK({
|
|
167
|
+
walletClient,
|
|
168
|
+
network: "https://my-custom-api.com",
|
|
169
|
+
seiRpcUrl: "https://evm-rpc-testnet.sei-apis.com",
|
|
170
|
+
wsUrl: "wss://my-custom-api.com/ws"
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Quick Start
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { MonacoSDK } from "@0xmonaco/core";
|
|
178
|
+
import { createWalletClient, http } from "viem";
|
|
179
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
180
|
+
|
|
181
|
+
// Initialize the SDK with wallet client
|
|
182
|
+
const account = privateKeyToAccount("0x...");
|
|
183
|
+
const walletClient = createWalletClient({
|
|
184
|
+
account,
|
|
185
|
+
chain: sei, // or seiTestnet
|
|
186
|
+
transport: http("https://evm-rpc.sei-apis.com") // or https://evm-rpc-testnet.sei-apis.com for testnet
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const monaco = new MonacoSDK({
|
|
190
|
+
walletClient,
|
|
191
|
+
network: "development", // or "staging", "mainnet"
|
|
192
|
+
seiRpcUrl: "https://evm-rpc-testnet.sei-apis.com", // or https://evm-rpc.sei-apis.com for mainnet
|
|
193
|
+
wsUrl: "wss://develop.apimonaco.xyz/ws" // or wss://staging.apimonaco.xyz/ws, wss://api.monaco.xyz/ws
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Authentication
|
|
197
|
+
async function authExample() {
|
|
198
|
+
// Login with client ID and auto-connect authenticated WebSocket channels (Orders)
|
|
199
|
+
const authState = await monaco.login("your-client-id", { connectWebSocket: true });
|
|
200
|
+
console.log("Authenticated:", authState.user);
|
|
201
|
+
console.log("Tokens:", {
|
|
202
|
+
accessToken: authState.accessToken,
|
|
203
|
+
refreshToken: authState.refreshToken, // Use this for revokeToken()
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Authenticated WebSocket channels are now connected - start receiving real-time updates
|
|
207
|
+
// Currently this includes: Orders (personal order updates)
|
|
208
|
+
monaco.websocket.orders.subscribeToOrderEvents("BTC/USDC", "SPOT", (event) => {
|
|
209
|
+
console.log("Order event:", event.eventType);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Check authentication status
|
|
213
|
+
console.log("Is authenticated:", monaco.isAuthenticated());
|
|
214
|
+
|
|
215
|
+
// Logout (revokes the refresh token and disconnects authenticated WebSockets)
|
|
216
|
+
await monaco.logout();
|
|
217
|
+
|
|
218
|
+
// Or manually revoke the token
|
|
219
|
+
// ✅ CORRECT: Use authState.refreshToken
|
|
220
|
+
await monaco.auth.revokeToken(authState.refreshToken);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Market Data
|
|
224
|
+
async function marketExample() {
|
|
225
|
+
// Get all trading pairs
|
|
226
|
+
const pairs = await monaco.market.getTradingPairs();
|
|
227
|
+
console.log("Available pairs:", pairs.length);
|
|
228
|
+
|
|
229
|
+
// Get specific trading pair
|
|
230
|
+
const btcPair = await monaco.market.getTradingPairBySymbol("BTC/USDC");
|
|
231
|
+
console.log("BTC pair:", btcPair?.symbol, btcPair?.maker_fee_bps);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Vault Operations
|
|
235
|
+
async function vaultExample() {
|
|
236
|
+
// Get asset ID from trading pair
|
|
237
|
+
const pair = await monaco.market.getTradingPairBySymbol("USDC/USDT");
|
|
238
|
+
const assetId = pair.base_asset_id; // Asset ID (UUID)
|
|
239
|
+
|
|
240
|
+
// Check vault balance
|
|
241
|
+
const balance = await monaco.vault.getBalance(assetId);
|
|
242
|
+
console.log("Vault balance:", balance.formatted, balance.symbol);
|
|
243
|
+
|
|
244
|
+
// Approve vault to spend tokens
|
|
245
|
+
const approval = await monaco.vault.approve(assetId, parseEther("1000"));
|
|
246
|
+
console.log("Approval transaction:", approval.hash);
|
|
247
|
+
|
|
248
|
+
// Deposit tokens
|
|
249
|
+
const result = await monaco.vault.deposit(assetId, parseEther("100"));
|
|
250
|
+
console.log("Deposit transaction:", result.hash);
|
|
251
|
+
|
|
252
|
+
// Withdraw tokens
|
|
253
|
+
const withdrawal = await monaco.vault.withdraw(assetId, parseEther("50"));
|
|
254
|
+
console.log("Withdrawal transaction:", withdrawal.hash);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Trading Operations
|
|
258
|
+
async function tradingExample() {
|
|
259
|
+
// Place a limit order
|
|
260
|
+
const order = await monaco.trading.placeLimitOrder(
|
|
261
|
+
"BTC/USDC", // market
|
|
262
|
+
"BUY", // side
|
|
263
|
+
"0.001", // quantity
|
|
264
|
+
"50000" // price
|
|
265
|
+
);
|
|
266
|
+
console.log("Order placed:", order.order_id);
|
|
267
|
+
|
|
268
|
+
// Place a limit order with IOC (Immediate or Cancel)
|
|
269
|
+
const iocOrder = await monaco.trading.placeLimitOrder(
|
|
270
|
+
"BTC/USDC",
|
|
271
|
+
"BUY",
|
|
272
|
+
"0.001",
|
|
273
|
+
"50000",
|
|
274
|
+
{ timeInForce: "IOC" } // Execute immediately or cancel
|
|
275
|
+
);
|
|
276
|
+
console.log("IOC order placed:", iocOrder.order_id);
|
|
277
|
+
|
|
278
|
+
// Place a market order
|
|
279
|
+
const marketOrder = await monaco.trading.placeMarketOrder(
|
|
280
|
+
"BTC/USDC",
|
|
281
|
+
"SELL",
|
|
282
|
+
"0.001"
|
|
283
|
+
);
|
|
284
|
+
console.log("Market order placed:", marketOrder.order_id);
|
|
285
|
+
|
|
286
|
+
// Place a market order with FOK (Fill or Kill)
|
|
287
|
+
const fokOrder = await monaco.trading.placeMarketOrder(
|
|
288
|
+
"BTC/USDC",
|
|
289
|
+
"BUY",
|
|
290
|
+
"0.001",
|
|
291
|
+
{ timeInForce: "FOK" } // Must fill completely or cancel
|
|
292
|
+
);
|
|
293
|
+
console.log("FOK order placed:", fokOrder.order_id);
|
|
294
|
+
|
|
295
|
+
// Get paginated orders
|
|
296
|
+
const orders = await monaco.trading.getPaginatedOrders({
|
|
297
|
+
status: "PENDING",
|
|
298
|
+
trading_pair: "BTC/USDC",
|
|
299
|
+
page: 1,
|
|
300
|
+
page_size: 10
|
|
301
|
+
});
|
|
302
|
+
console.log("Orders:", orders.data.length);
|
|
303
|
+
|
|
304
|
+
// Replace an order
|
|
305
|
+
const replaceResult = await monaco.trading.replaceOrder("order-id", {
|
|
306
|
+
quantity: "0.002",
|
|
307
|
+
price: "51000"
|
|
308
|
+
});
|
|
309
|
+
console.log("Order replaced:", replaceResult.order_id);
|
|
310
|
+
|
|
311
|
+
// Cancel an order
|
|
312
|
+
const cancelResult = await monaco.trading.cancelOrder("order-id");
|
|
313
|
+
console.log("Order cancelled:", cancelResult.status);
|
|
314
|
+
|
|
315
|
+
// Get specific order
|
|
316
|
+
const orderDetails = await monaco.trading.getOrder("order-id");
|
|
317
|
+
console.log("Order details:", orderDetails.order);
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## API Reference
|
|
322
|
+
|
|
323
|
+
### MonacoSDK
|
|
324
|
+
|
|
325
|
+
The main SDK class that provides access to all protocol features.
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
class MonacoSDK {
|
|
329
|
+
readonly applications: ApplicationsAPI;
|
|
330
|
+
readonly auth: AuthAPI;
|
|
331
|
+
readonly vault: VaultAPI;
|
|
332
|
+
readonly trading: TradingAPI;
|
|
333
|
+
readonly market: MarketAPI;
|
|
334
|
+
readonly profile: ProfileAPI;
|
|
335
|
+
readonly websocket: {
|
|
336
|
+
orders: OrdersWebSocketClient;
|
|
337
|
+
ohlcv: OHLCVWebSocketClient;
|
|
338
|
+
orderbook: OrderbookWebSocketClient;
|
|
339
|
+
};
|
|
340
|
+
readonly walletClient: WalletClient;
|
|
341
|
+
readonly publicClient: PublicClient;
|
|
342
|
+
|
|
343
|
+
constructor(config: SDKConfig);
|
|
344
|
+
|
|
345
|
+
// Authentication
|
|
346
|
+
login(clientId: string, options?: { connectWebSocket?: boolean }): Promise<AuthState>;
|
|
347
|
+
logout(): Promise<void>;
|
|
348
|
+
refreshAuth(): Promise<AuthState>;
|
|
349
|
+
getAuthState(): AuthState | undefined;
|
|
350
|
+
isAuthenticated(): boolean;
|
|
351
|
+
|
|
352
|
+
// Network utilities
|
|
353
|
+
isConnected(): boolean;
|
|
354
|
+
getAccountAddress(): string;
|
|
355
|
+
getNetwork(): Network;
|
|
356
|
+
getChainId(): number;
|
|
357
|
+
waitForTransaction(hash: string, confirmations?: number, timeout?: number): Promise<TransactionReceipt>;
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Configuration
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
interface SDKConfig {
|
|
365
|
+
/** Wallet client for signing operations */
|
|
366
|
+
walletClient: WalletClient;
|
|
367
|
+
|
|
368
|
+
/** Optional network override (defaults to 'mainnet') */
|
|
369
|
+
network?: Network;
|
|
370
|
+
|
|
371
|
+
/** Optional transport for the public client */
|
|
372
|
+
transport?: Transport;
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Authentication & Token Management
|
|
377
|
+
|
|
378
|
+
The SDK uses JWT tokens for authentication. Understanding the token structure is important:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
// After login, you receive an AuthState object
|
|
382
|
+
const authState = await sdk.login(clientId);
|
|
383
|
+
|
|
384
|
+
// AuthState structure:
|
|
385
|
+
interface AuthState {
|
|
386
|
+
accessToken: string; // For making authenticated API requests
|
|
387
|
+
refreshToken: string; // For refreshing tokens AND revoking (logout)
|
|
388
|
+
expiresAt: number; // When the access token expires
|
|
389
|
+
user: User; // User information
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**⚠️ Important:** The authentication response contains `refreshToken`, NOT `revokeToken`.
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
// ✅ CORRECT: Revoke using refreshToken
|
|
397
|
+
await sdk.auth.revokeToken(authState.refreshToken);
|
|
398
|
+
|
|
399
|
+
// 💡 TIP: Use the built-in logout method
|
|
400
|
+
await sdk.logout(); // Automatically calls revokeToken internally
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Token Management Methods:**
|
|
404
|
+
- `login(clientId, options?)` - Authenticate and get tokens
|
|
405
|
+
- `clientId`: Your application's client ID
|
|
406
|
+
- `options.connectWebSocket`: (optional) Auto-connect WebSocket after login (default: `false`)
|
|
407
|
+
- Returns `AuthState` with access token, refresh token, expiration, and user info
|
|
408
|
+
- `logout()` - Revoke token, disconnect WebSocket, and clear state
|
|
409
|
+
- Calls `auth.revokeToken()` internally
|
|
410
|
+
- Disconnects authenticated WebSocket channels
|
|
411
|
+
- Clears local auth state
|
|
412
|
+
- `refreshAuth()` - Refresh the access token using the stored refresh token
|
|
413
|
+
- `isAuthenticated()` - Check if user is authenticated
|
|
414
|
+
- `getAuthState()` - Get current auth state with tokens
|
|
415
|
+
- `setAuthState(authState)` - Set auth state directly (useful for sharing across SDK instances)
|
|
416
|
+
|
|
417
|
+
### Vault API
|
|
418
|
+
|
|
419
|
+
The vault API provides secure token management operations:
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
interface VaultAPI extends BaseAPI {
|
|
423
|
+
// Vault address management
|
|
424
|
+
setVaultAddress(vaultAddress: Address): void;
|
|
425
|
+
getVaultAddress(): Address | undefined;
|
|
426
|
+
|
|
427
|
+
// Token operations
|
|
428
|
+
approve(token: string, amount: bigint, autoWait?: boolean): Promise<TransactionResult>;
|
|
429
|
+
deposit(token: string, amount: bigint, autoWait?: boolean): Promise<TransactionResult>;
|
|
430
|
+
withdraw(token: string, amount: bigint, autoWait?: boolean): Promise<TransactionResult>;
|
|
431
|
+
|
|
432
|
+
// Balance queries
|
|
433
|
+
getBalance(token: string): Promise<Balance>;
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Trading API
|
|
438
|
+
|
|
439
|
+
The trading API provides comprehensive order management:
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
interface TradingAPI extends BaseAPI {
|
|
443
|
+
// Order placement
|
|
444
|
+
placeLimitOrder(
|
|
445
|
+
market: string,
|
|
446
|
+
side: OrderSide,
|
|
447
|
+
quantity: string,
|
|
448
|
+
price: string,
|
|
449
|
+
options?: {
|
|
450
|
+
tradingMode?: string;
|
|
451
|
+
useMasterBalance?: boolean;
|
|
452
|
+
expirationDate?: string;
|
|
453
|
+
timeInForce?: string; // "GTC", "IOC", or "FOK"
|
|
454
|
+
}
|
|
455
|
+
): Promise<CreateOrderResponse>;
|
|
456
|
+
|
|
457
|
+
placeMarketOrder(
|
|
458
|
+
market: string,
|
|
459
|
+
side: OrderSide,
|
|
460
|
+
quantity: string,
|
|
461
|
+
options?: {
|
|
462
|
+
tradingMode?: string;
|
|
463
|
+
slippageTolerance?: number;
|
|
464
|
+
timeInForce?: string; // "GTC", "IOC", or "FOK"
|
|
465
|
+
}
|
|
466
|
+
): Promise<CreateOrderResponse>;
|
|
467
|
+
|
|
468
|
+
// Order management
|
|
469
|
+
cancelOrder(orderId: string): Promise<CancelOrderResponse>;
|
|
470
|
+
replaceOrder(
|
|
471
|
+
orderId: string,
|
|
472
|
+
newOrder: {
|
|
473
|
+
price?: string;
|
|
474
|
+
quantity: string;
|
|
475
|
+
useMasterBalance?: boolean;
|
|
476
|
+
}
|
|
477
|
+
): Promise<ReplaceOrderResponse>;
|
|
478
|
+
|
|
479
|
+
// Order queries
|
|
480
|
+
getPaginatedOrders(params?: GetPaginatedOrdersParams): Promise<GetPaginatedOrdersResponse>;
|
|
481
|
+
getOrder(orderId: string): Promise<GetOrderResponse>;
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Market API
|
|
486
|
+
|
|
487
|
+
The market API provides access to trading pair metadata:
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
interface MarketAPI extends BaseAPI {
|
|
491
|
+
// Market data
|
|
492
|
+
getTradingPairs(): Promise<TradingPair[]>;
|
|
493
|
+
getTradingPairBySymbol(symbol: string): Promise<TradingPair | undefined>;
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### WebSocket Authentication
|
|
498
|
+
|
|
499
|
+
The SDK provides three WebSocket clients with different authentication requirements:
|
|
500
|
+
|
|
501
|
+
#### Public WebSockets (OHLCV and Orderbook)
|
|
502
|
+
|
|
503
|
+
No authentication required. Provide public market data. You always connect manually:
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
// Step 1: Establish WebSocket connection (no authentication needed)
|
|
507
|
+
await monaco.websocket.ohlcv.connect();
|
|
508
|
+
await monaco.websocket.orderbook.connect();
|
|
509
|
+
|
|
510
|
+
// Step 2: Subscribe to public market data
|
|
511
|
+
monaco.websocket.ohlcv.subscribeToOHLCV("BTC/USDC", "SPOT", "1m", (event) => {
|
|
512
|
+
console.log("OHLCV data:", event.candlestick);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
monaco.websocket.orderbook.subscribeToOrderbookEvents("BTC/USDC", "SPOT", (event) => {
|
|
516
|
+
console.log("Orderbook update:", event.bids.length, "bids");
|
|
517
|
+
});
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
#### Authenticated WebSockets (Orders)
|
|
521
|
+
|
|
522
|
+
Requires JWT authentication for personal order updates. You can either auto-connect during login or connect manually:
|
|
523
|
+
|
|
524
|
+
**Option 1: Auto-connect (recommended for authenticated channels)**
|
|
525
|
+
```typescript
|
|
526
|
+
// Login and auto-connect all authenticated WebSocket channels
|
|
527
|
+
// Currently includes: Orders (personal order updates)
|
|
528
|
+
await monaco.login(clientId, { connectWebSocket: true });
|
|
529
|
+
|
|
530
|
+
// Subscribe to personal order events (already connected)
|
|
531
|
+
monaco.websocket.orders.subscribeToOrderEvents("BTC/USDC", "SPOT", (event) => {
|
|
532
|
+
console.log("Personal order event:", event.eventType);
|
|
533
|
+
});
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**Option 2: Manual connection (required for public channels, optional for authenticated)**
|
|
537
|
+
```typescript
|
|
538
|
+
// Public channels like OHLCV always require manual connection (no auth needed)
|
|
539
|
+
await monaco.websocket.ohlcv.connect();
|
|
540
|
+
|
|
541
|
+
monaco.websocket.ohlcv.subscribeToOHLCV("BTC/USDC", "SPOT", "1m", (event) => {
|
|
542
|
+
console.log("OHLCV data:", event.candlestick);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// For authenticated channels, you can also connect manually for more control
|
|
546
|
+
await monaco.login(clientId);
|
|
547
|
+
await monaco.websocket.orders.connect();
|
|
548
|
+
monaco.websocket.orders.subscribeToOrderEvents("BTC/USDC", "SPOT", (event) => {
|
|
549
|
+
console.log("Personal order event:", event.eventType);
|
|
550
|
+
});
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**Note:**
|
|
554
|
+
- The `connectWebSocket: true` option automatically connects all authenticated WebSocket channels (currently Orders).
|
|
555
|
+
- Public WebSocket clients (OHLCV, Orderbook) always require calling `connect()` explicitly as they don't require authentication.
|
|
556
|
+
|
|
557
|
+
### Error Handling
|
|
558
|
+
|
|
559
|
+
The SDK uses structured error classes for comprehensive error handling:
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
import { APIError, ContractError } from "@0xmonaco/core";
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
await sdk.vault.deposit(token, amount);
|
|
566
|
+
} catch (error) {
|
|
567
|
+
if (error instanceof ContractError) {
|
|
568
|
+
console.error("Contract error:", error.message);
|
|
569
|
+
console.error("Error code:", error.code);
|
|
570
|
+
} else if (error instanceof APIError) {
|
|
571
|
+
console.error("API error:", error.message);
|
|
572
|
+
console.error("Status:", error.status);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
**Error Types:**
|
|
578
|
+
- `MonacoCoreError`: Base error class for all SDK errors
|
|
579
|
+
- `APIError`: API request failures and communication errors
|
|
580
|
+
- `ContractError`: Smart contract operation errors
|
|
581
|
+
- `InvalidConfigError`: Configuration validation errors
|
|
582
|
+
- `InvalidStateError`: Invalid state or operation errors
|
|
583
|
+
|
|
584
|
+
## Development
|
|
585
|
+
|
|
586
|
+
### Project Structure
|
|
587
|
+
|
|
588
|
+
```
|
|
589
|
+
packages/core/
|
|
590
|
+
├── src/ # Source code
|
|
591
|
+
│ ├── api/ # API implementations
|
|
592
|
+
│ │ ├── applications/ # Applications API
|
|
593
|
+
│ │ ├── auth/ # Authentication API
|
|
594
|
+
│ │ ├── base.ts # Base API class
|
|
595
|
+
│ │ ├── market/ # Market data API
|
|
596
|
+
│ │ ├── profile/ # Profile management API
|
|
597
|
+
│ │ ├── trading/ # Trading operations API
|
|
598
|
+
│ │ ├── vault/ # Vault operations API
|
|
599
|
+
│ │ ├── websocket/ # WebSocket client
|
|
600
|
+
│ │ └── index.ts # API exports
|
|
601
|
+
│ ├── constants/ # Constants and configurations
|
|
602
|
+
│ ├── errors.ts # Error classes and codes
|
|
603
|
+
│ ├── networks.ts # Network endpoint configurations
|
|
604
|
+
│ ├── sdk.ts # Main SDK implementation
|
|
605
|
+
│ └── index.ts # Public API exports
|
|
606
|
+
├── tests/ # Test suite
|
|
607
|
+
├── dist/ # Compiled output
|
|
608
|
+
├── package.json # Package configuration
|
|
609
|
+
└── tsconfig.json # TypeScript configuration
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Development Setup
|
|
613
|
+
|
|
614
|
+
1. Clone the repository:
|
|
615
|
+
```bash
|
|
616
|
+
git clone https://github.com/monaco-protocol/monaco-monorepo.git
|
|
617
|
+
cd monaco-monorepo
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
2. Install dependencies:
|
|
621
|
+
```bash
|
|
622
|
+
pnpm install
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
3. Build the package:
|
|
626
|
+
```bash
|
|
627
|
+
pnpm build --filter @0xmonaco/core
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Testing
|
|
631
|
+
|
|
632
|
+
Run the test suite:
|
|
633
|
+
```bash
|
|
634
|
+
pnpm test --filter @0xmonaco/core
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Code Style
|
|
638
|
+
|
|
639
|
+
The project uses ESLint and Prettier for code formatting. Run the linter:
|
|
640
|
+
```bash
|
|
641
|
+
pnpm lint --filter @0xmonaco/core
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
## Security Features
|
|
645
|
+
|
|
646
|
+
### JWT Authentication
|
|
647
|
+
- **Token-based security**: Secure JWT tokens for API access
|
|
648
|
+
- **EIP-712 login**: Wallet signature-based authentication
|
|
649
|
+
- **Automatic refresh**: Seamless token renewal
|
|
650
|
+
- **Session management**: Secure session handling
|
|
651
|
+
|
|
652
|
+
### API Gateway Integration
|
|
653
|
+
- **Secure communication**: TLS encryption for all API calls
|
|
654
|
+
- **Token validation**: Backend validates all JWT tokens
|
|
655
|
+
- **Rate limiting**: Protection against abuse
|
|
656
|
+
- **Audit logging**: Complete transaction history
|
|
657
|
+
|
|
658
|
+
### On-chain Security
|
|
659
|
+
- **Smart contract validation**: All operations validated on-chain
|
|
660
|
+
- **Signature verification**: EIP-712 signatures for authentication
|
|
661
|
+
- **Multi-signature support**: Advanced security for institutional users
|
|
662
|
+
|
|
663
|
+
## Performance Considerations
|
|
664
|
+
|
|
665
|
+
- **Batch operations**: Efficient handling of multiple operations
|
|
666
|
+
- **Connection pooling**: Optimized API connections
|
|
667
|
+
- **Caching**: Smart caching of frequently accessed data
|
|
668
|
+
- **Async operations**: Non-blocking operations for better UX
|
|
669
|
+
|
|
670
|
+
## Contributing
|
|
671
|
+
|
|
672
|
+
We welcome contributions! Please see our [Contributing Guide](../../docs/contributing.mdx) for details.
|
|
673
|
+
|
|
674
|
+
### Development Workflow
|
|
675
|
+
1. Fork the repository
|
|
676
|
+
2. Create a feature branch
|
|
677
|
+
3. Make your changes
|
|
678
|
+
4. Add tests for new functionality
|
|
679
|
+
5. Ensure all tests pass
|
|
680
|
+
6. Submit a pull request
|
|
681
|
+
|
|
682
|
+
## License
|
|
683
|
+
|
|
684
|
+
This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details.
|
|
685
|
+
|
|
686
|
+
## Support
|
|
687
|
+
|
|
688
|
+
For support, please:
|
|
689
|
+
|
|
690
|
+
- Open an issue on GitHub
|
|
691
|
+
- Join our [Discord community](https://discord.gg/monaco)
|
|
692
|
+
- Visit our [documentation site](https://docs.monaco.xyz)
|
|
693
|
+
- Check our [API documentation](../../docs/api-reference.mdx)
|