@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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/readme.md +690 -66
  3. 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
- // ... other config options
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
- ## WebSocket Subscriptions
161
+ ## Read Operations API
162
+
163
+ ### DecibelReadDex
152
164
 
153
- The SDK supports real-time WebSocket subscriptions:
165
+ The main read client providing access to all market data and account information.
166
+
167
+ #### Constructor
154
168
 
155
169
  ```typescript
156
- import { DecibelReadDex, NETNA_CONFIG } from "@decibeltrade/sdk";
170
+ new DecibelReadDex(config: DecibelConfig, opts?: {
171
+ nodeApiKey?: string;
172
+ onWsError?: (error: ErrorEvent) => void;
173
+ })
174
+ ```
157
175
 
158
- const read = new DecibelReadDex(NETNA_CONFIG);
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
- // Subscribe to market prices
161
- const subscription = read.subscribe("all_market_prices", (data) => {
162
- console.log("Market prices:", data);
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
- // Unsubscribe when done
166
- subscription.unsubscribe();
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
- ## Examples
264
+ ### User Orders
170
265
 
171
- ### Get Market Data
266
+ Query open orders and order history.
267
+
268
+ #### Open Orders
172
269
 
173
270
  ```typescript
174
- const markets = await read.markets.getAll();
175
- const btcMarket = await read.markets.getBySymbol("BTC-PERP");
176
- const prices = await read.marketPrices.getAll();
177
- const depth = await read.marketDepth.getBySymbol("BTC-PERP", { depth: 20 });
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
- ### Get Account Information
280
+ #### Order History
181
281
 
182
282
  ```typescript
183
- const account = await read.accountOverview.getByAddr(accountAddress);
184
- const positions = await read.userPositions.getByAddr(accountAddress);
185
- const openOrders = await read.userOpenOrders.getByAddr(accountAddress);
186
- const subaccounts = await read.userSubaccounts.getByAddr(accountAddress);
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
- ### Place an Order
296
+ ### Market Data
297
+
298
+ #### Market Depth (Order Book)
190
299
 
191
300
  ```typescript
192
- const order = await write.placeOrder({
193
- subaccountAddr: subaccountAddress,
194
- marketAddr: marketAddress,
195
- price: 5670000000, // 5.67 with 9 decimals
196
- size: 1000000000, // 1.0 with 9 decimals
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: 0, // GoodTillCanceled
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
- ### Place a TWAP Order
567
+ #### TWAP Orders
204
568
 
205
569
  ```typescript
206
- const twapOrder = await write.placeTwapOrder({
207
- subaccountAddr: subaccountAddress,
208
- marketAddr: marketAddress,
209
- totalSize: 10000000000, // 10.0 with 9 decimals
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
- ## API Reference
582
+ #### Cancel Orders
217
583
 
218
- ### DecibelReadDex
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
- - `markets` - Market information and listings
221
- - `marketPrices` - Real-time and historical prices
222
- - `marketDepth` - Order book depth
223
- - `marketTrades` - Recent trades
224
- - `candlesticks` - OHLCV candlestick data
225
- - `accountOverview` - Account summary and equity
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
- ### DecibelWriteDex
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
- - `placeOrder()` - Place a limit or market order
238
- - `cancelOrder()` - Cancel an order
239
- - `placeTwapOrder()` - Place a TWAP order
240
- - `cancelTwapOrder()` - Cancel a TWAP order
241
- - `placeBulkOrder()` - Place multiple orders
242
- - `cancelBulkOrder()` - Cancel multiple orders
243
- - `placeTpSlOrder()` - Place TP/SL orders
244
- - `updateTpOrder()` - Update take profit order
245
- - `updateSlOrder()` - Update stop loss order
246
- - `createSubaccount()` - Create a new subaccount
247
- - `deposit()` - Deposit funds
248
- - `withdraw()` - Withdraw funds
249
- - `delegateTrading()` - Delegate trading permissions
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