@decibeltrade/sdk 0.1.2 → 0.1.3
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/package.json +1 -1
- package/readme.md +690 -66
- package/sdk_reference.md +0 -876
package/readme.md
CHANGED
|
@@ -40,6 +40,7 @@ import { DecibelReadDex, NETNA_CONFIG } from "@decibeltrade/sdk";
|
|
|
40
40
|
|
|
41
41
|
const read = new DecibelReadDex(NETNA_CONFIG, {
|
|
42
42
|
nodeApiKey: process.env.APTOS_NODE_API_KEY, // required
|
|
43
|
+
onWsError: (error) => console.error("WebSocket error:", error), // optional
|
|
43
44
|
});
|
|
44
45
|
|
|
45
46
|
// Get all markets
|
|
@@ -116,7 +117,7 @@ const order = await write.placeOrder({
|
|
|
116
117
|
The SDK supports multiple network configurations:
|
|
117
118
|
|
|
118
119
|
```typescript
|
|
119
|
-
import { NETNA_CONFIG, TESTNET_CONFIG, LOCAL_CONFIG } from "@decibeltrade/sdk";
|
|
120
|
+
import { NETNA_CONFIG, TESTNET_CONFIG, LOCAL_CONFIG, DOCKER_CONFIG } from "@decibeltrade/sdk";
|
|
120
121
|
|
|
121
122
|
// Netna (devnet)
|
|
122
123
|
const read = new DecibelReadDex(NETNA_CONFIG);
|
|
@@ -126,6 +127,9 @@ const read = new DecibelReadDex(TESTNET_CONFIG);
|
|
|
126
127
|
|
|
127
128
|
// Local development
|
|
128
129
|
const read = new DecibelReadDex(LOCAL_CONFIG);
|
|
130
|
+
|
|
131
|
+
// Docker environment
|
|
132
|
+
const read = new DecibelReadDex(DOCKER_CONFIG);
|
|
129
133
|
```
|
|
130
134
|
|
|
131
135
|
### Custom Configuration
|
|
@@ -139,7 +143,13 @@ const customConfig: DecibelConfig = {
|
|
|
139
143
|
fullnodeUrl: "https://api.testnet.aptoslabs.com/v1",
|
|
140
144
|
tradingHttpUrl: "https://api.testnet.aptoslabs.com/decibel",
|
|
141
145
|
tradingWsUrl: "wss://api.testnet.aptoslabs.com/decibel/ws",
|
|
142
|
-
|
|
146
|
+
gasStationUrl: "https://your-fee-payer.com",
|
|
147
|
+
deployment: {
|
|
148
|
+
package: "0x...",
|
|
149
|
+
usdc: "0x...",
|
|
150
|
+
testc: "0x...",
|
|
151
|
+
perpEngineGlobal: "0x...",
|
|
152
|
+
},
|
|
143
153
|
};
|
|
144
154
|
```
|
|
145
155
|
|
|
@@ -148,105 +158,719 @@ const customConfig: DecibelConfig = {
|
|
|
148
158
|
- **Use `DecibelReadDex`** when you need market data, order/position history, or account state. No private keys required.
|
|
149
159
|
- **Use `DecibelWriteDex`** for on-chain actions and trading. In browsers, avoid embedding private keys — prefer session keys or a wallet and pass `accountOverride` for specific calls.
|
|
150
160
|
|
|
151
|
-
##
|
|
161
|
+
## Read Operations API
|
|
162
|
+
|
|
163
|
+
### DecibelReadDex
|
|
152
164
|
|
|
153
|
-
The
|
|
165
|
+
The main read client providing access to all market data and account information.
|
|
166
|
+
|
|
167
|
+
#### Constructor
|
|
154
168
|
|
|
155
169
|
```typescript
|
|
156
|
-
|
|
170
|
+
new DecibelReadDex(config: DecibelConfig, opts?: {
|
|
171
|
+
nodeApiKey?: string;
|
|
172
|
+
onWsError?: (error: ErrorEvent) => void;
|
|
173
|
+
})
|
|
174
|
+
```
|
|
157
175
|
|
|
158
|
-
|
|
176
|
+
#### Global Methods
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// Get global perpetual engine state
|
|
180
|
+
await readDex.globalPerpEngineState();
|
|
181
|
+
|
|
182
|
+
// Get collateral balance decimals
|
|
183
|
+
await readDex.collateralBalanceDecimals();
|
|
184
|
+
|
|
185
|
+
// Get USDC decimals (cached)
|
|
186
|
+
await readDex.usdcDecimals();
|
|
187
|
+
|
|
188
|
+
// Get USDC balance for an address
|
|
189
|
+
await readDex.usdcBalance("0x123...");
|
|
190
|
+
|
|
191
|
+
// Get account balance
|
|
192
|
+
await readDex.accountBalance("0x123...");
|
|
193
|
+
|
|
194
|
+
// Get position size
|
|
195
|
+
await readDex.positionSize("0x123...", "metadata_address");
|
|
196
|
+
|
|
197
|
+
// Get crossed position
|
|
198
|
+
await readDex.getCrossedPosition("0x123...");
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Markets
|
|
202
|
+
|
|
203
|
+
Access market information and configuration.
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// Get all available markets
|
|
207
|
+
const markets = await readDex.markets.getAll();
|
|
208
|
+
|
|
209
|
+
// Get specific market by name
|
|
210
|
+
const market = await readDex.markets.getByName("BTC-USD");
|
|
211
|
+
|
|
212
|
+
// Get market by symbol
|
|
213
|
+
const market = await readDex.markets.getBySymbol("BTC-PERP");
|
|
214
|
+
|
|
215
|
+
// List all market addresses
|
|
216
|
+
const addresses = await readDex.markets.listMarketAddresses();
|
|
217
|
+
|
|
218
|
+
// Get market name by address
|
|
219
|
+
const name = await readDex.markets.marketNameByAddress("0x123...");
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Account Overview
|
|
223
|
+
|
|
224
|
+
Get comprehensive account information including balances and positions.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// Get account overview
|
|
228
|
+
const overview = await readDex.accountOverview.getByAddr("subaccount_address", "30d"); // volume_window = "30d"
|
|
229
|
+
|
|
230
|
+
// Subscribe to real-time account updates
|
|
231
|
+
const unsubscribe = readDex.accountOverview.subscribeByAddr("subaccount_address", (data) =>
|
|
232
|
+
console.log("Account update:", data),
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
// Later, unsubscribe
|
|
236
|
+
unsubscribe();
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### User Positions
|
|
159
240
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
241
|
+
Query user positions across markets.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// Get all positions for a user
|
|
245
|
+
const positions = await readDex.userPositions.getByAddr({
|
|
246
|
+
subAddr: "subaccount_address",
|
|
247
|
+
includeDeleted: false,
|
|
248
|
+
limit: 10,
|
|
163
249
|
});
|
|
164
250
|
|
|
165
|
-
//
|
|
166
|
-
|
|
251
|
+
// Get positions for specific market
|
|
252
|
+
const marketPositions = await readDex.userPositions.getByAddr({
|
|
253
|
+
subAddr: "subaccount_address",
|
|
254
|
+
marketAddr: "market_address",
|
|
255
|
+
limit: 10,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Subscribe to position updates
|
|
259
|
+
const unsubscribe = readDex.userPositions.subscribeByAddr("subaccount_address", (data) =>
|
|
260
|
+
console.log("Position update:", data),
|
|
261
|
+
);
|
|
167
262
|
```
|
|
168
263
|
|
|
169
|
-
|
|
264
|
+
### User Orders
|
|
170
265
|
|
|
171
|
-
|
|
266
|
+
Query open orders and order history.
|
|
267
|
+
|
|
268
|
+
#### Open Orders
|
|
172
269
|
|
|
173
270
|
```typescript
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
271
|
+
// Get open orders
|
|
272
|
+
const openOrders = await readDex.userOpenOrders.getByAddr("subaccount_address");
|
|
273
|
+
|
|
274
|
+
// Subscribe to open orders updates
|
|
275
|
+
const unsubscribe = readDex.userOpenOrders.subscribeByAddr("subaccount_address", (data) =>
|
|
276
|
+
console.log("Orders update:", data),
|
|
277
|
+
);
|
|
178
278
|
```
|
|
179
279
|
|
|
180
|
-
|
|
280
|
+
#### Order History
|
|
181
281
|
|
|
182
282
|
```typescript
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
283
|
+
// Get order history
|
|
284
|
+
const orderHistory = await readDex.userOrderHistory.getByAddr({
|
|
285
|
+
subAddr: "subaccount_address",
|
|
286
|
+
marketAddr: "market_address", // optional
|
|
287
|
+
limit: 50,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// Subscribe to order history updates
|
|
291
|
+
const unsubscribe = readDex.userOrderHistory.subscribeByAddr("subaccount_address", (data) =>
|
|
292
|
+
console.log("Order history update:", data),
|
|
293
|
+
);
|
|
187
294
|
```
|
|
188
295
|
|
|
189
|
-
###
|
|
296
|
+
### Market Data
|
|
297
|
+
|
|
298
|
+
#### Market Depth (Order Book)
|
|
190
299
|
|
|
191
300
|
```typescript
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
301
|
+
// Get market depth
|
|
302
|
+
const depth = await readDex.marketDepth.getByName("BTC-USD", 100); // limit = 100
|
|
303
|
+
const depth = await readDex.marketDepth.getBySymbol("BTC-PERP", { depth: 100 });
|
|
304
|
+
|
|
305
|
+
// Subscribe to depth updates
|
|
306
|
+
const unsubscribe = readDex.marketDepth.subscribeByName("BTC-USD", (data) =>
|
|
307
|
+
console.log("Depth update:", data),
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
// Reset subscription (clear cached data)
|
|
311
|
+
readDex.marketDepth.resetSubscriptionByName("BTC-USD");
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
#### Market Prices
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// Get current prices
|
|
318
|
+
const prices = await readDex.marketPrices.getByName("BTC-USD");
|
|
319
|
+
const prices = await readDex.marketPrices.getAll();
|
|
320
|
+
|
|
321
|
+
// Subscribe to price updates
|
|
322
|
+
const unsubscribe = readDex.marketPrices.subscribeByName("BTC-USD", (data) =>
|
|
323
|
+
console.log("Price update:", data),
|
|
324
|
+
);
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### Market Trades
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
// Get recent trades
|
|
331
|
+
const trades = await readDex.marketTrades.getByName("BTC-USD", 50); // limit = 50
|
|
332
|
+
|
|
333
|
+
// Subscribe to trade updates
|
|
334
|
+
const unsubscribe = readDex.marketTrades.subscribeByName("BTC-USD", (data) =>
|
|
335
|
+
console.log("Trade update:", data),
|
|
336
|
+
);
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
#### Candlesticks
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
import { CandlestickInterval } from "@decibeltrade/sdk";
|
|
343
|
+
|
|
344
|
+
// Get historical candlestick data
|
|
345
|
+
const candlesticks = await readDex.candlesticks.getByName(
|
|
346
|
+
"BTC-USD",
|
|
347
|
+
CandlestickInterval.MINUTE_1,
|
|
348
|
+
startTimestamp,
|
|
349
|
+
endTimestamp,
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
// Subscribe to candlestick updates
|
|
353
|
+
const unsubscribe = readDex.candlesticks.subscribeByName(
|
|
354
|
+
"BTC-USD",
|
|
355
|
+
CandlestickInterval.MINUTE_1,
|
|
356
|
+
(data) => console.log("Candlestick update:", data),
|
|
357
|
+
);
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Market Contexts
|
|
361
|
+
|
|
362
|
+
Get additional market metadata and context.
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
// Get market contexts
|
|
366
|
+
const contexts = await readDex.marketContexts.getAll();
|
|
367
|
+
|
|
368
|
+
// Subscribe to market context updates
|
|
369
|
+
const unsubscribe = readDex.marketContexts.subscribeAll((data) =>
|
|
370
|
+
console.log("Market contexts update:", data),
|
|
371
|
+
);
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### User Trade History
|
|
375
|
+
|
|
376
|
+
Query historical trade data for a user.
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
// Get trade history
|
|
380
|
+
const trades = await readDex.userTradeHistory.getByAddr({
|
|
381
|
+
subAddr: "subaccount_address",
|
|
382
|
+
marketAddr: "market_address", // optional
|
|
383
|
+
limit: 100,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Subscribe to trade history updates
|
|
387
|
+
const unsubscribe = readDex.userTradeHistory.subscribeByAddr("subaccount_address", (data) =>
|
|
388
|
+
console.log("Trade history update:", data),
|
|
389
|
+
);
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### User Funding History
|
|
393
|
+
|
|
394
|
+
Query funding payment history.
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
// Get funding history
|
|
398
|
+
const funding = await readDex.userFundingHistory.getByAddr({
|
|
399
|
+
subAddr: "subaccount_address",
|
|
400
|
+
marketAddr: "market_address", // optional
|
|
401
|
+
limit: 50,
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// Subscribe to funding history updates
|
|
405
|
+
const unsubscribe = readDex.userFundingHistory.subscribeByAddr("subaccount_address", (data) =>
|
|
406
|
+
console.log("Funding history update:", data),
|
|
407
|
+
);
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### User Subaccounts
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// Get all subaccounts for a user
|
|
414
|
+
const subaccounts = await readDex.userSubaccounts.getByAddr("account_address");
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Vaults
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
// Get user vault positions
|
|
421
|
+
const userVaults = await readDex.userVaults.getByAddr("account_address");
|
|
422
|
+
|
|
423
|
+
// Get public vault information
|
|
424
|
+
const vaults = await readDex.vaults.getAll();
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Write Operations API
|
|
428
|
+
|
|
429
|
+
### DecibelWriteDex
|
|
430
|
+
|
|
431
|
+
The main write client for executing trades and managing account operations.
|
|
432
|
+
|
|
433
|
+
#### Constructor
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
import { Ed25519Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk";
|
|
437
|
+
|
|
438
|
+
const account = new Ed25519Account({
|
|
439
|
+
privateKey: new Ed25519PrivateKey("your-private-key"),
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
const writeDex = new DecibelWriteDex(config, account, opts?: {
|
|
443
|
+
nodeApiKey?: string;
|
|
444
|
+
sponsorAccount?: Ed25519Account;
|
|
445
|
+
maxGasAmount?: number;
|
|
446
|
+
gasUnitPrice?: number;
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Account Management
|
|
451
|
+
|
|
452
|
+
#### Subaccount Operations
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
// Create a new subaccount
|
|
456
|
+
await writeDex.createSubaccount();
|
|
457
|
+
|
|
458
|
+
// Deposit collateral to primary subaccount
|
|
459
|
+
await writeDex.deposit(1000000); // amount in smallest unit
|
|
460
|
+
|
|
461
|
+
// Deposit to specific subaccount
|
|
462
|
+
await writeDex.deposit(1000000, "subaccount_address");
|
|
463
|
+
|
|
464
|
+
// Withdraw from subaccount
|
|
465
|
+
await writeDex.withdraw(500000, "subaccount_address");
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
#### Trading Delegation
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
// Delegate trading permissions
|
|
472
|
+
await writeDex.delegateTradingTo({
|
|
473
|
+
subaccountAddr: "your_subaccount",
|
|
474
|
+
accountToDelegateTo: "delegate_account_address",
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// Revoke delegation
|
|
478
|
+
await writeDex.revokeDelegation({
|
|
479
|
+
subaccountAddr: "your_subaccount",
|
|
480
|
+
accountToRevoke: "delegate_account_address",
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### Market Configuration
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
// Configure user settings for a market
|
|
488
|
+
await writeDex.configureUserSettingsForMarket({
|
|
489
|
+
marketAddr: "market_address",
|
|
490
|
+
subaccountAddr: "subaccount_address",
|
|
491
|
+
isCross: true, // cross-margin mode
|
|
492
|
+
userLeverage: 1000, // 10x leverage (basis points)
|
|
493
|
+
});
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Order Management
|
|
497
|
+
|
|
498
|
+
#### Place Orders
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
import { TimeInForce } from "@decibeltrade/sdk";
|
|
502
|
+
|
|
503
|
+
// Place a limit order
|
|
504
|
+
const result = await writeDex.placeOrder({
|
|
505
|
+
marketName: "BTC-USD",
|
|
506
|
+
price: 45000,
|
|
507
|
+
size: 1.5,
|
|
197
508
|
isBuy: true,
|
|
198
|
-
timeInForce:
|
|
509
|
+
timeInForce: TimeInForce.GoodTillCanceled,
|
|
510
|
+
isReduceOnly: false,
|
|
511
|
+
clientOrderId: "12345", // optional
|
|
512
|
+
subaccountAddr: "subaccount_address", // optional
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// Place a post-only order
|
|
516
|
+
await writeDex.placeOrder({
|
|
517
|
+
marketName: "ETH-USD",
|
|
518
|
+
price: 3000,
|
|
519
|
+
size: 2.0,
|
|
520
|
+
isBuy: false,
|
|
521
|
+
timeInForce: TimeInForce.PostOnly,
|
|
522
|
+
isReduceOnly: false,
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// Place an IOC (Immediate or Cancel) order
|
|
526
|
+
await writeDex.placeOrder({
|
|
527
|
+
marketName: "SOL-USD",
|
|
528
|
+
price: 100,
|
|
529
|
+
size: 10,
|
|
530
|
+
isBuy: true,
|
|
531
|
+
timeInForce: TimeInForce.ImmediateOrCancel,
|
|
532
|
+
isReduceOnly: true,
|
|
533
|
+
});
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
#### Advanced Order Types
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
// Place order with stop-loss and take-profit
|
|
540
|
+
await writeDex.placeOrder({
|
|
541
|
+
marketName: "BTC-USD",
|
|
542
|
+
price: 45000,
|
|
543
|
+
size: 1.0,
|
|
544
|
+
isBuy: true,
|
|
545
|
+
timeInForce: TimeInForce.GoodTillCanceled,
|
|
546
|
+
isReduceOnly: false,
|
|
547
|
+
stopPrice: 44000, // stop-loss trigger
|
|
548
|
+
tpTriggerPrice: 46000, // take-profit trigger
|
|
549
|
+
tpLimitPrice: 45900, // take-profit limit price
|
|
550
|
+
slTriggerPrice: 44000, // stop-loss trigger
|
|
551
|
+
slLimitPrice: 44100, // stop-loss limit price
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// Place order with builder fee
|
|
555
|
+
await writeDex.placeOrder({
|
|
556
|
+
marketName: "BTC-USD",
|
|
557
|
+
price: 45000,
|
|
558
|
+
size: 1.0,
|
|
559
|
+
isBuy: true,
|
|
560
|
+
timeInForce: TimeInForce.GoodTillCanceled,
|
|
199
561
|
isReduceOnly: false,
|
|
562
|
+
builderAddr: "builder_account_address",
|
|
563
|
+
builderFee: 100, // fee in basis points
|
|
200
564
|
});
|
|
201
565
|
```
|
|
202
566
|
|
|
203
|
-
|
|
567
|
+
#### TWAP Orders
|
|
204
568
|
|
|
205
569
|
```typescript
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
duration: 3600, // 1 hour in seconds
|
|
211
|
-
interval: 60, // 1 minute intervals
|
|
570
|
+
// Place a Time-Weighted Average Price order
|
|
571
|
+
await writeDex.placeTwapOrder({
|
|
572
|
+
marketName: "BTC-USD",
|
|
573
|
+
size: 10.0,
|
|
212
574
|
isBuy: true,
|
|
575
|
+
isReduceOnly: false,
|
|
576
|
+
twapFrequencySeconds: 60, // execute every 60 seconds
|
|
577
|
+
twapDurationSeconds: 3600, // over 1 hour period
|
|
578
|
+
subaccountAddr: "subaccount_address", // optional
|
|
213
579
|
});
|
|
214
580
|
```
|
|
215
581
|
|
|
216
|
-
|
|
582
|
+
#### Cancel Orders
|
|
217
583
|
|
|
218
|
-
|
|
584
|
+
```typescript
|
|
585
|
+
// Cancel order by ID and market name
|
|
586
|
+
await writeDex.cancelOrder({
|
|
587
|
+
orderId: 12345,
|
|
588
|
+
marketName: "BTC-USD",
|
|
589
|
+
subaccountAddr: "subaccount_address", // optional
|
|
590
|
+
});
|
|
219
591
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
- `userPositions` - User positions
|
|
227
|
-
- `userOpenOrders` - Open orders
|
|
228
|
-
- `userOrderHistory` - Order history
|
|
229
|
-
- `userTradeHistory` - Trade history
|
|
230
|
-
- `userSubaccounts` - Subaccount management
|
|
231
|
-
- `userVaults` - Vault positions
|
|
232
|
-
- `vaults` - Public vault information
|
|
233
|
-
- `subscribe()` - WebSocket subscriptions
|
|
592
|
+
// Cancel order by ID and market address
|
|
593
|
+
await writeDex.cancelOrder({
|
|
594
|
+
orderId: 12345,
|
|
595
|
+
marketAddr: "market_address",
|
|
596
|
+
subaccountAddr: "subaccount_address", // optional
|
|
597
|
+
});
|
|
234
598
|
|
|
235
|
-
|
|
599
|
+
// Cancel order by client order ID
|
|
600
|
+
await writeDex.cancelClientOrder({
|
|
601
|
+
clientOrderId: "54321",
|
|
602
|
+
marketName: "BTC-USD",
|
|
603
|
+
subaccountAddr: "subaccount_address", // optional
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
// Cancel TWAP order
|
|
607
|
+
await writeDex.cancelTwapOrder({
|
|
608
|
+
orderId: "twap_order_id",
|
|
609
|
+
subaccountAddr: "subaccount_address", // optional
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
// Cancel bulk orders
|
|
613
|
+
await writeDex.cancelBulkOrder({
|
|
614
|
+
orderIds: [12345, 12346, 12347],
|
|
615
|
+
marketName: "BTC-USD",
|
|
616
|
+
subaccountAddr: "subaccount_address", // optional
|
|
617
|
+
});
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Position Management
|
|
621
|
+
|
|
622
|
+
#### Take-Profit / Stop-Loss Orders
|
|
623
|
+
|
|
624
|
+
```typescript
|
|
625
|
+
// Place TP/SL order for existing position
|
|
626
|
+
await writeDex.placeTpSlOrderForPosition({
|
|
627
|
+
marketAddr: "market_address",
|
|
628
|
+
tpTriggerPrice: 46000,
|
|
629
|
+
tpLimitPrice: 45900,
|
|
630
|
+
tpSize: 0.5, // partial position size
|
|
631
|
+
slTriggerPrice: 44000,
|
|
632
|
+
slLimitPrice: 44100,
|
|
633
|
+
slSize: 1.0, // full position size
|
|
634
|
+
subaccountAddr: "subaccount_address", // optional
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
// Update existing TP/SL order
|
|
638
|
+
await writeDex.updateTpSlOrderForPosition({
|
|
639
|
+
marketAddr: "market_address",
|
|
640
|
+
prevOrderId: "previous_order_id",
|
|
641
|
+
tpTriggerPrice: 47000, // new TP trigger
|
|
642
|
+
tpLimitPrice: 46900,
|
|
643
|
+
tpSize: 0.75,
|
|
644
|
+
// ... other parameters
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
// Cancel TP/SL order
|
|
648
|
+
await writeDex.cancelTpSlOrderForPosition({
|
|
649
|
+
marketName: "BTC-USD",
|
|
650
|
+
orderId: 12345,
|
|
651
|
+
subaccountAddr: "subaccount_address", // optional
|
|
652
|
+
});
|
|
653
|
+
```
|
|
236
654
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
655
|
+
### Session Accounts
|
|
656
|
+
|
|
657
|
+
You can override the default account for specific transactions using session accounts:
|
|
658
|
+
|
|
659
|
+
```typescript
|
|
660
|
+
import { Ed25519Account } from "@aptos-labs/ts-sdk";
|
|
661
|
+
|
|
662
|
+
const sessionAccount = Ed25519Account.generate();
|
|
663
|
+
|
|
664
|
+
// Use session account for this transaction
|
|
665
|
+
await writeDex.placeOrder({
|
|
666
|
+
marketName: "BTC-USD",
|
|
667
|
+
price: 45000,
|
|
668
|
+
size: 1.0,
|
|
669
|
+
isBuy: true,
|
|
670
|
+
timeInForce: TimeInForce.GoodTillCanceled,
|
|
671
|
+
isReduceOnly: false,
|
|
672
|
+
accountOverride: sessionAccount,
|
|
673
|
+
});
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### Error Handling
|
|
677
|
+
|
|
678
|
+
All write operations return transaction results. For order placement, you get a structured result:
|
|
679
|
+
|
|
680
|
+
```typescript
|
|
681
|
+
interface PlaceOrderResult {
|
|
682
|
+
success: boolean;
|
|
683
|
+
orderId?: string;
|
|
684
|
+
transactionHash: string;
|
|
685
|
+
error?: string;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
const result = await writeDex.placeOrder({
|
|
689
|
+
// ... order parameters
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
if (result.success) {
|
|
693
|
+
console.log("Order placed successfully:", result.orderId);
|
|
694
|
+
console.log("Transaction:", result.transactionHash);
|
|
695
|
+
} else {
|
|
696
|
+
console.error("Order failed:", result.error);
|
|
697
|
+
}
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
## Constants and Enums
|
|
701
|
+
|
|
702
|
+
### Time in Force
|
|
703
|
+
|
|
704
|
+
```typescript
|
|
705
|
+
export const TimeInForce = {
|
|
706
|
+
GoodTillCanceled: 0,
|
|
707
|
+
PostOnly: 1,
|
|
708
|
+
ImmediateOrCancel: 2,
|
|
709
|
+
} as const;
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Candlestick Intervals
|
|
713
|
+
|
|
714
|
+
```typescript
|
|
715
|
+
export enum CandlestickInterval {
|
|
716
|
+
MINUTE_1 = "1m",
|
|
717
|
+
MINUTE_5 = "5m",
|
|
718
|
+
MINUTE_15 = "15m",
|
|
719
|
+
HOUR_1 = "1h",
|
|
720
|
+
HOUR_4 = "4h",
|
|
721
|
+
DAY_1 = "1d",
|
|
722
|
+
}
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
## Utilities
|
|
726
|
+
|
|
727
|
+
### Address Utilities
|
|
728
|
+
|
|
729
|
+
```typescript
|
|
730
|
+
import { getPrimarySubaccountAddr, getMarketAddr } from "@decibeltrade/sdk";
|
|
731
|
+
|
|
732
|
+
// Get primary subaccount address for an account
|
|
733
|
+
const subaccountAddr = getPrimarySubaccountAddr("account_address");
|
|
734
|
+
|
|
735
|
+
// Get market address from name
|
|
736
|
+
const marketAddr = getMarketAddr("BTC-USD", "perp_engine_global_address");
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
## WebSocket Subscriptions
|
|
740
|
+
|
|
741
|
+
All read operations that support real-time updates return an unsubscribe function:
|
|
742
|
+
|
|
743
|
+
```typescript
|
|
744
|
+
// Subscribe to multiple streams
|
|
745
|
+
const unsubscribeDepth = readDex.marketDepth.subscribeByName("BTC-USD", handleDepth);
|
|
746
|
+
const unsubscribePrices = readDex.marketPrices.subscribeByName("BTC-USD", handlePrices);
|
|
747
|
+
const unsubscribeOrders = readDex.userOpenOrders.subscribeByAddr("subaccount", handleOrders);
|
|
748
|
+
|
|
749
|
+
// Clean up subscriptions
|
|
750
|
+
function cleanup() {
|
|
751
|
+
unsubscribeDepth();
|
|
752
|
+
unsubscribePrices();
|
|
753
|
+
unsubscribeOrders();
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// Handle errors
|
|
757
|
+
const readDex = new DecibelReadDex(NETNA_CONFIG, {
|
|
758
|
+
onWsError: (error) => {
|
|
759
|
+
console.error("WebSocket error:", error);
|
|
760
|
+
// Implement reconnection logic
|
|
761
|
+
},
|
|
762
|
+
});
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
## TypeScript Types
|
|
766
|
+
|
|
767
|
+
The SDK is fully typed with Zod schemas for runtime validation. Import types for better development experience:
|
|
768
|
+
|
|
769
|
+
```typescript
|
|
770
|
+
import type {
|
|
771
|
+
DecibelConfig,
|
|
772
|
+
PerpMarket,
|
|
773
|
+
UserPosition,
|
|
774
|
+
MarketDepth,
|
|
775
|
+
CandlestickData,
|
|
776
|
+
AccountOverview,
|
|
777
|
+
PlaceOrderResult,
|
|
778
|
+
} from "@decibeltrade/sdk";
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
## Best Practices
|
|
782
|
+
|
|
783
|
+
1. **Connection Management**: Reuse SDK instances where possible to maintain WebSocket connections.
|
|
784
|
+
|
|
785
|
+
2. **Error Handling**: Always wrap SDK calls in try-catch blocks and handle errors appropriately.
|
|
786
|
+
|
|
787
|
+
3. **Subscription Cleanup**: Always call unsubscribe functions to prevent memory leaks.
|
|
788
|
+
|
|
789
|
+
4. **Rate Limiting**: Be mindful of API rate limits when making frequent requests.
|
|
790
|
+
|
|
791
|
+
5. **Account Security**: Never expose private keys in client-side code. Use environment variables or secure key management.
|
|
792
|
+
|
|
793
|
+
6. **Precision**: Be careful with number precision for prices and sizes. The SDK handles decimal precision internally.
|
|
794
|
+
|
|
795
|
+
## Complete Trading Bot Example
|
|
796
|
+
|
|
797
|
+
```typescript
|
|
798
|
+
import { DecibelReadDex, DecibelWriteDex, NETNA_CONFIG, TimeInForce } from "@decibeltrade/sdk";
|
|
799
|
+
import { Ed25519Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk";
|
|
800
|
+
|
|
801
|
+
class TradingBot {
|
|
802
|
+
private readDex: DecibelReadDex;
|
|
803
|
+
private writeDex: DecibelWriteDex;
|
|
804
|
+
private subaccountAddr: string;
|
|
805
|
+
|
|
806
|
+
constructor(privateKey: string, subaccountAddr: string) {
|
|
807
|
+
this.readDex = new DecibelReadDex(NETNA_CONFIG, {
|
|
808
|
+
nodeApiKey: process.env.APTOS_NODE_API_KEY,
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
const account = new Ed25519Account({
|
|
812
|
+
privateKey: new Ed25519PrivateKey(privateKey),
|
|
813
|
+
});
|
|
814
|
+
this.writeDex = new DecibelWriteDex(NETNA_CONFIG, account, {
|
|
815
|
+
nodeApiKey: process.env.APTOS_NODE_API_KEY,
|
|
816
|
+
});
|
|
817
|
+
this.subaccountAddr = subaccountAddr;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
async start() {
|
|
821
|
+
// Subscribe to market data
|
|
822
|
+
this.readDex.marketPrices.subscribeByName("BTC-USD", this.handlePriceUpdate.bind(this));
|
|
823
|
+
this.readDex.marketDepth.subscribeByName("BTC-USD", this.handleDepthUpdate.bind(this));
|
|
824
|
+
|
|
825
|
+
// Subscribe to account updates
|
|
826
|
+
this.readDex.userPositions.subscribeByAddr(
|
|
827
|
+
this.subaccountAddr,
|
|
828
|
+
this.handlePositionUpdate.bind(this),
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
private async handlePriceUpdate(priceData: any) {
|
|
833
|
+
// Implement your trading logic here
|
|
834
|
+
console.log("Price update:", priceData);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
private async handleDepthUpdate(depthData: any) {
|
|
838
|
+
// Analyze order book for trading opportunities
|
|
839
|
+
console.log("Depth update:", depthData);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
private async handlePositionUpdate(positionData: any) {
|
|
843
|
+
// Monitor positions and manage risk
|
|
844
|
+
console.log("Position update:", positionData);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
async placeMarketBuyOrder(size: number) {
|
|
848
|
+
try {
|
|
849
|
+
const result = await this.writeDex.placeOrder({
|
|
850
|
+
marketName: "BTC-USD",
|
|
851
|
+
price: 0, // Market order (implementation may vary)
|
|
852
|
+
size,
|
|
853
|
+
isBuy: true,
|
|
854
|
+
timeInForce: TimeInForce.ImmediateOrCancel,
|
|
855
|
+
isReduceOnly: false,
|
|
856
|
+
subaccountAddr: this.subaccountAddr,
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
if (result.success) {
|
|
860
|
+
console.log(`Market buy order placed: ${result.orderId}`);
|
|
861
|
+
} else {
|
|
862
|
+
console.error(`Order failed: ${result.error}`);
|
|
863
|
+
}
|
|
864
|
+
} catch (error) {
|
|
865
|
+
console.error("Error placing order:", error);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// Usage
|
|
871
|
+
const bot = new TradingBot("your-private-key", "your-subaccount-address");
|
|
872
|
+
bot.start();
|
|
873
|
+
```
|
|
250
874
|
|
|
251
875
|
## Resources
|
|
252
876
|
|