@decibeltrade/sdk 0.1.1
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/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-lint$colon$check.log +5 -0
- package/.turbo/turbo-lint.log +5 -0
- package/decibel_transactions.md +1049 -0
- package/dist/abi/abi-manager.d.ts +13 -0
- package/dist/abi/abi-manager.d.ts.map +1 -0
- package/dist/abi/abi-manager.js +21 -0
- package/dist/abi/abis.json +1322 -0
- package/dist/abi/bytecode-manager.d.ts +57 -0
- package/dist/abi/bytecode-manager.d.ts.map +1 -0
- package/dist/abi/bytecode-manager.js +62 -0
- package/dist/abi/bytecode.json +24 -0
- package/dist/abi/fetch-abis.d.ts +7 -0
- package/dist/abi/fetch-abis.d.ts.map +1 -0
- package/dist/abi/fetch-abis.js +132 -0
- package/dist/abi/fetch-bytecode.d.ts +24 -0
- package/dist/abi/fetch-bytecode.d.ts.map +1 -0
- package/dist/abi/fetch-bytecode.js +123 -0
- package/dist/abi/generate-abis.d.ts +6 -0
- package/dist/abi/generate-abis.d.ts.map +1 -0
- package/dist/abi/generate-abis.js +170 -0
- package/dist/abi/json/netna.json +1323 -0
- package/dist/abi/json/testnet.json +1315 -0
- package/dist/abi/types.d.ts +22 -0
- package/dist/abi/types.d.ts.map +1 -0
- package/dist/abi/types.js +2 -0
- package/dist/admin.d.ts +29 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +203 -0
- package/dist/base.d.ts +42 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +176 -0
- package/dist/constants.d.ts +41 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +78 -0
- package/dist/fee-pay.d.ts +11 -0
- package/dist/fee-pay.d.ts.map +1 -0
- package/dist/fee-pay.js +30 -0
- package/dist/gas/gas-price-manager.d.ts +35 -0
- package/dist/gas/gas-price-manager.d.ts.map +1 -0
- package/dist/gas/gas-price-manager.js +93 -0
- package/dist/gas-price-manager.d.ts +31 -0
- package/dist/gas-price-manager.d.ts.map +1 -0
- package/dist/gas-price-manager.js +84 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/order-event.types.d.ts +55 -0
- package/dist/order-event.types.d.ts.map +1 -0
- package/dist/order-event.types.js +3 -0
- package/dist/order-status.d.ts +43 -0
- package/dist/order-status.d.ts.map +1 -0
- package/dist/order-status.js +86 -0
- package/dist/read/account-overview/account-overview.reader.d.ts +37 -0
- package/dist/read/account-overview/account-overview.reader.d.ts.map +1 -0
- package/dist/read/account-overview/account-overview.reader.js +35 -0
- package/dist/read/account-overview/account-overview.types.d.ts +52 -0
- package/dist/read/account-overview/account-overview.types.d.ts.map +1 -0
- package/dist/read/account-overview/account-overview.types.js +36 -0
- package/dist/read/api-wallets/api-wallets.reader.d.ts +17 -0
- package/dist/read/api-wallets/api-wallets.reader.d.ts.map +1 -0
- package/dist/read/api-wallets/api-wallets.reader.js +27 -0
- package/dist/read/api-wallets/api-wallets.types.d.ts +17 -0
- package/dist/read/api-wallets/api-wallets.types.d.ts.map +1 -0
- package/dist/read/api-wallets/api-wallets.types.js +13 -0
- package/dist/read/base-reader.d.ts +22 -0
- package/dist/read/base-reader.d.ts.map +1 -0
- package/dist/read/base-reader.js +29 -0
- package/dist/read/candlesticks/candlesticks.reader.d.ts +31 -0
- package/dist/read/candlesticks/candlesticks.reader.d.ts.map +1 -0
- package/dist/read/candlesticks/candlesticks.reader.js +43 -0
- package/dist/read/candlesticks/candlesticks.types.d.ts +45 -0
- package/dist/read/candlesticks/candlesticks.types.d.ts.map +1 -0
- package/dist/read/candlesticks/candlesticks.types.js +36 -0
- package/dist/read/delegations/delegations.reader.d.ts +15 -0
- package/dist/read/delegations/delegations.reader.d.ts.map +1 -0
- package/dist/read/delegations/delegations.reader.js +23 -0
- package/dist/read/delegations/delegations.types.d.ts +17 -0
- package/dist/read/delegations/delegations.types.d.ts.map +1 -0
- package/dist/read/delegations/delegations.types.js +13 -0
- package/dist/read/index.d.ts +105 -0
- package/dist/read/index.d.ts.map +1 -0
- package/dist/read/index.js +244 -0
- package/dist/read/leaderboard/leaderboard.reader.d.ts +21 -0
- package/dist/read/leaderboard/leaderboard.reader.d.ts.map +1 -0
- package/dist/read/leaderboard/leaderboard.reader.js +22 -0
- package/dist/read/leaderboard/leaderboard.types.d.ts +27 -0
- package/dist/read/leaderboard/leaderboard.types.d.ts.map +1 -0
- package/dist/read/leaderboard/leaderboard.types.js +14 -0
- package/dist/read/market-contexts/market-contexts.reader.d.ts +22 -0
- package/dist/read/market-contexts/market-contexts.reader.d.ts.map +1 -0
- package/dist/read/market-contexts/market-contexts.reader.js +27 -0
- package/dist/read/market-contexts/market-contexts.types.d.ts +26 -0
- package/dist/read/market-contexts/market-contexts.types.d.ts.map +1 -0
- package/dist/read/market-contexts/market-contexts.types.js +19 -0
- package/dist/read/market-depth/market-depth.reader.d.ts +30 -0
- package/dist/read/market-depth/market-depth.reader.d.ts.map +1 -0
- package/dist/read/market-depth/market-depth.reader.js +46 -0
- package/dist/read/market-depth/market-depth.types.d.ts +20 -0
- package/dist/read/market-depth/market-depth.types.d.ts.map +1 -0
- package/dist/read/market-depth/market-depth.types.js +16 -0
- package/dist/read/market-prices/market-prices.reader.d.ts +44 -0
- package/dist/read/market-prices/market-prices.reader.d.ts.map +1 -0
- package/dist/read/market-prices/market-prices.reader.js +51 -0
- package/dist/read/market-prices/market-prices.types.d.ts +48 -0
- package/dist/read/market-prices/market-prices.types.d.ts.map +1 -0
- package/dist/read/market-prices/market-prices.types.js +26 -0
- package/dist/read/market-trades/market-trades.reader.d.ts +33 -0
- package/dist/read/market-trades/market-trades.reader.d.ts.map +1 -0
- package/dist/read/market-trades/market-trades.reader.js +39 -0
- package/dist/read/market-trades/market-trades.types.d.ts +52 -0
- package/dist/read/market-trades/market-trades.types.d.ts.map +1 -0
- package/dist/read/market-trades/market-trades.types.js +23 -0
- package/dist/read/markets/markets.reader.d.ts +38 -0
- package/dist/read/markets/markets.reader.d.ts.map +1 -0
- package/dist/read/markets/markets.reader.js +80 -0
- package/dist/read/markets/markets.types.d.ts +82 -0
- package/dist/read/markets/markets.types.d.ts.map +1 -0
- package/dist/read/markets/markets.types.js +46 -0
- package/dist/read/pagination.types.d.ts +14 -0
- package/dist/read/pagination.types.d.ts.map +1 -0
- package/dist/read/pagination.types.js +12 -0
- package/dist/read/portfolio-chart/portfolio-chart.reader.d.ts +14 -0
- package/dist/read/portfolio-chart/portfolio-chart.reader.d.ts.map +1 -0
- package/dist/read/portfolio-chart/portfolio-chart.reader.js +21 -0
- package/dist/read/portfolio-chart/portfolio-chart.types.d.ts +14 -0
- package/dist/read/portfolio-chart/portfolio-chart.types.d.ts.map +1 -0
- package/dist/read/portfolio-chart/portfolio-chart.types.js +12 -0
- package/dist/read/public-vaults/public-vaults.reader.d.ts +38 -0
- package/dist/read/public-vaults/public-vaults.reader.d.ts.map +1 -0
- package/dist/read/public-vaults/public-vaults.reader.js +31 -0
- package/dist/read/public-vaults/public-vaults.types.d.ts +62 -0
- package/dist/read/public-vaults/public-vaults.types.d.ts.map +1 -0
- package/dist/read/public-vaults/public-vaults.types.js +33 -0
- package/dist/read/types.d.ts +178 -0
- package/dist/read/types.d.ts.map +1 -0
- package/dist/read/types.js +87 -0
- package/dist/read/user-active-twaps/user-active-twaps.reader.d.ts +31 -0
- package/dist/read/user-active-twaps/user-active-twaps.reader.d.ts.map +1 -0
- package/dist/read/user-active-twaps/user-active-twaps.reader.js +31 -0
- package/dist/read/user-active-twaps/user-active-twaps.types.d.ts +49 -0
- package/dist/read/user-active-twaps/user-active-twaps.types.d.ts.map +1 -0
- package/dist/read/user-active-twaps/user-active-twaps.types.js +25 -0
- package/dist/read/user-bulk-orders/user-bulk-orders.reader.d.ts +31 -0
- package/dist/read/user-bulk-orders/user-bulk-orders.reader.d.ts.map +1 -0
- package/dist/read/user-bulk-orders/user-bulk-orders.reader.js +32 -0
- package/dist/read/user-bulk-orders/user-bulk-orders.types.d.ts +46 -0
- package/dist/read/user-bulk-orders/user-bulk-orders.types.d.ts.map +1 -0
- package/dist/read/user-bulk-orders/user-bulk-orders.types.js +24 -0
- package/dist/read/user-funding-history/user-funding-history.reader.d.ts +28 -0
- package/dist/read/user-funding-history/user-funding-history.reader.d.ts.map +1 -0
- package/dist/read/user-funding-history/user-funding-history.reader.js +32 -0
- package/dist/read/user-funding-history/user-funding-history.types.d.ts +37 -0
- package/dist/read/user-funding-history/user-funding-history.types.d.ts.map +1 -0
- package/dist/read/user-funding-history/user-funding-history.types.js +21 -0
- package/dist/read/user-notifications/user-notifications.reader.d.ts +13 -0
- package/dist/read/user-notifications/user-notifications.reader.d.ts.map +1 -0
- package/dist/read/user-notifications/user-notifications.reader.js +19 -0
- package/dist/read/user-notifications/user-notifications.types.d.ts +49 -0
- package/dist/read/user-notifications/user-notifications.types.d.ts.map +1 -0
- package/dist/read/user-notifications/user-notifications.types.js +18 -0
- package/dist/read/user-open-orders/user-open-orders.reader.d.ts +40 -0
- package/dist/read/user-open-orders/user-open-orders.reader.d.ts.map +1 -0
- package/dist/read/user-open-orders/user-open-orders.reader.js +31 -0
- package/dist/read/user-open-orders/user-open-orders.types.d.ts +76 -0
- package/dist/read/user-open-orders/user-open-orders.types.d.ts.map +1 -0
- package/dist/read/user-open-orders/user-open-orders.types.js +34 -0
- package/dist/read/user-order-history/user-order-history.reader.d.ts +40 -0
- package/dist/read/user-order-history/user-order-history.reader.d.ts.map +1 -0
- package/dist/read/user-order-history/user-order-history.reader.js +28 -0
- package/dist/read/user-order-history/user-order-history.types.d.ts +85 -0
- package/dist/read/user-order-history/user-order-history.types.d.ts.map +1 -0
- package/dist/read/user-order-history/user-order-history.types.js +37 -0
- package/dist/read/user-positions/user-positions.reader.d.ts +37 -0
- package/dist/read/user-positions/user-positions.reader.d.ts.map +1 -0
- package/dist/read/user-positions/user-positions.reader.js +41 -0
- package/dist/read/user-positions/user-positions.types.d.ts +2590 -0
- package/dist/read/user-positions/user-positions.types.d.ts.map +1 -0
- package/dist/read/user-positions/user-positions.types.js +31 -0
- package/dist/read/user-subaccounts/user-subaccounts.reader.d.ts +18 -0
- package/dist/read/user-subaccounts/user-subaccounts.reader.d.ts.map +1 -0
- package/dist/read/user-subaccounts/user-subaccounts.reader.js +28 -0
- package/dist/read/user-subaccounts/user-subaccounts.types.d.ts +21 -0
- package/dist/read/user-subaccounts/user-subaccounts.types.d.ts.map +1 -0
- package/dist/read/user-subaccounts/user-subaccounts.types.js +15 -0
- package/dist/read/user-trade-history/user-trade-history.reader.d.ts +33 -0
- package/dist/read/user-trade-history/user-trade-history.reader.d.ts.map +1 -0
- package/dist/read/user-trade-history/user-trade-history.reader.js +32 -0
- package/dist/read/user-trade-history/user-trade-history.types.d.ts +52 -0
- package/dist/read/user-trade-history/user-trade-history.types.d.ts.map +1 -0
- package/dist/read/user-trade-history/user-trade-history.types.js +26 -0
- package/dist/read/user-vaults/user-vaults.reader.d.ts +26 -0
- package/dist/read/user-vaults/user-vaults.reader.d.ts.map +1 -0
- package/dist/read/user-vaults/user-vaults.reader.js +32 -0
- package/dist/read/user-vaults/user-vaults.types.d.ts +39 -0
- package/dist/read/user-vaults/user-vaults.types.d.ts.map +1 -0
- package/dist/read/user-vaults/user-vaults.types.js +21 -0
- package/dist/read/vault/vault.reader.d.ts +95 -0
- package/dist/read/vault/vault.reader.d.ts.map +1 -0
- package/dist/read/vault/vault.reader.js +168 -0
- package/dist/read/vault/vault.types.d.ts +49 -0
- package/dist/read/vault/vault.types.d.ts.map +1 -0
- package/dist/read/vault/vault.types.js +45 -0
- package/dist/read/vaults/vaults.reader.d.ts +72 -0
- package/dist/read/vaults/vaults.reader.d.ts.map +1 -0
- package/dist/read/vaults/vaults.reader.js +63 -0
- package/dist/read/vaults/vaults.types.d.ts +140 -0
- package/dist/read/vaults/vaults.types.d.ts.map +1 -0
- package/dist/read/vaults/vaults.types.js +71 -0
- package/dist/read/ws-subscription.d.ts +21 -0
- package/dist/read/ws-subscription.d.ts.map +1 -0
- package/dist/read/ws-subscription.js +170 -0
- package/dist/subaccount-types.d.ts +24 -0
- package/dist/subaccount-types.d.ts.map +1 -0
- package/dist/subaccount-types.js +11 -0
- package/dist/transaction-builder.d.ts +14 -0
- package/dist/transaction-builder.d.ts.map +1 -0
- package/dist/transaction-builder.js +40 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils.d.ts +56 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +164 -0
- package/dist/vault-types.d.ts +43 -0
- package/dist/vault-types.d.ts.map +1 -0
- package/dist/vault-types.js +11 -0
- package/dist/write.d.ts +271 -0
- package/dist/write.d.ts.map +1 -0
- package/dist/write.js +485 -0
- package/eslint.config.mjs +25 -0
- package/package.json +39 -0
- package/readme.md +257 -0
- package/sdk_reference.md +876 -0
- package/src/abi/generate-abis.ts +164 -0
- package/src/abi/json/netna.json +1323 -0
- package/src/abi/json/testnet.json +1315 -0
- package/src/abi/types.ts +23 -0
- package/src/admin.ts +284 -0
- package/src/base.ts +218 -0
- package/src/constants.ts +118 -0
- package/src/fee-pay.ts +39 -0
- package/src/gas/gas-price-manager.ts +115 -0
- package/src/index.ts +10 -0
- package/src/order-event.types.ts +65 -0
- package/src/order-status.ts +89 -0
- package/src/read/account-overview/account-overview.reader.ts +43 -0
- package/src/read/account-overview/account-overview.types.ts +45 -0
- package/src/read/base-reader.ts +41 -0
- package/src/read/candlesticks/candlesticks.reader.ts +61 -0
- package/src/read/candlesticks/candlesticks.types.ts +46 -0
- package/src/read/delegations/delegations.reader.ts +22 -0
- package/src/read/delegations/delegations.types.ts +19 -0
- package/src/read/index.ts +271 -0
- package/src/read/leaderboard/leaderboard.reader.ts +21 -0
- package/src/read/leaderboard/leaderboard.types.ts +26 -0
- package/src/read/market-contexts/market-contexts.reader.ts +26 -0
- package/src/read/market-contexts/market-contexts.types.ts +18 -0
- package/src/read/market-depth/market-depth.reader.ts +60 -0
- package/src/read/market-depth/market-depth.types.ts +24 -0
- package/src/read/market-prices/market-prices.reader.ts +61 -0
- package/src/read/market-prices/market-prices.types.ts +38 -0
- package/src/read/market-trades/market-trades.reader.ts +46 -0
- package/src/read/market-trades/market-trades.types.ts +34 -0
- package/src/read/markets/markets.reader.ts +82 -0
- package/src/read/markets/markets.types.ts +54 -0
- package/src/read/pagination.types.ts +18 -0
- package/src/read/portfolio-chart/portfolio-chart.reader.ts +20 -0
- package/src/read/portfolio-chart/portfolio-chart.types.ts +21 -0
- package/src/read/types.ts +129 -0
- package/src/read/user-active-twaps/user-active-twaps.reader.ts +36 -0
- package/src/read/user-active-twaps/user-active-twaps.types.ts +33 -0
- package/src/read/user-bulk-orders/user-bulk-orders.reader.ts +37 -0
- package/src/read/user-bulk-orders/user-bulk-orders.types.ts +32 -0
- package/src/read/user-funding-history/user-funding-history.reader.ts +38 -0
- package/src/read/user-funding-history/user-funding-history.types.ts +29 -0
- package/src/read/user-notifications/user-notifications.reader.ts +17 -0
- package/src/read/user-notifications/user-notifications.types.ts +61 -0
- package/src/read/user-open-orders/user-open-orders.reader.ts +36 -0
- package/src/read/user-open-orders/user-open-orders.types.ts +42 -0
- package/src/read/user-order-history/user-order-history.reader.ts +34 -0
- package/src/read/user-order-history/user-order-history.types.ts +44 -0
- package/src/read/user-positions/user-positions.reader.ts +55 -0
- package/src/read/user-positions/user-positions.types.ts +43 -0
- package/src/read/user-subaccounts/user-subaccounts.reader.ts +30 -0
- package/src/read/user-subaccounts/user-subaccounts.types.ts +21 -0
- package/src/read/user-trade-history/user-trade-history.reader.ts +38 -0
- package/src/read/user-trade-history/user-trade-history.types.ts +33 -0
- package/src/read/vaults/vaults.reader.ts +79 -0
- package/src/read/vaults/vaults.types.ts +106 -0
- package/src/read/ws-subscription.ts +200 -0
- package/src/subaccount-types.ts +31 -0
- package/src/transaction-builder.ts +75 -0
- package/src/utils.ts +255 -0
- package/src/write.ts +965 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,1049 @@
|
|
|
1
|
+
# Decibel Smart Contract Transaction Guide
|
|
2
|
+
|
|
3
|
+
This guide shows developers exactly how to interact with Decibel's smart contracts on Aptos, with all necessary imports, configurations, and transaction patterns.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Required Dependencies](#required-dependencies)
|
|
8
|
+
2. [Configuration Setup](#configuration-setup)
|
|
9
|
+
3. [Core Transaction Infrastructure](#core-transaction-infrastructure)
|
|
10
|
+
4. [Account Management Transactions](#account-management-transactions)
|
|
11
|
+
5. [Order Management Transactions](#order-management-transactions)
|
|
12
|
+
6. [Position Management Transactions](#position-management-transactions)
|
|
13
|
+
7. [Advanced Features](#advanced-features)
|
|
14
|
+
8. [Complete Working Examples](#complete-working-examples)
|
|
15
|
+
|
|
16
|
+
## Required Dependencies
|
|
17
|
+
|
|
18
|
+
First, install the necessary packages:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @aptos-labs/ts-sdk zod
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration Setup
|
|
25
|
+
|
|
26
|
+
### 1. Network Configuration
|
|
27
|
+
|
|
28
|
+
```typescript path=null start=null
|
|
29
|
+
import {
|
|
30
|
+
Account,
|
|
31
|
+
AccountAddress,
|
|
32
|
+
AccountAuthenticator,
|
|
33
|
+
Aptos,
|
|
34
|
+
AptosConfig,
|
|
35
|
+
CommittedTransactionResponse,
|
|
36
|
+
InputGenerateTransactionPayloadData,
|
|
37
|
+
MoveString,
|
|
38
|
+
Network,
|
|
39
|
+
PendingTransactionResponse,
|
|
40
|
+
SimpleTransaction,
|
|
41
|
+
createObjectAddress,
|
|
42
|
+
} from "@aptos-labs/ts-sdk";
|
|
43
|
+
|
|
44
|
+
// Configuration interfaces
|
|
45
|
+
interface DecibelConfig {
|
|
46
|
+
network: Network;
|
|
47
|
+
fullnodeUrl: string;
|
|
48
|
+
tradingHttpUrl: string;
|
|
49
|
+
tradingWsUrl: string;
|
|
50
|
+
gasStationUrl: string;
|
|
51
|
+
deployment: Deployment;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface Deployment {
|
|
55
|
+
package: string; // Smart contract package address
|
|
56
|
+
usdc: string; // USDC token address
|
|
57
|
+
testc: string; // Test collateral address
|
|
58
|
+
perpEngineGlobal: string; // Global perpetual engine address
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Utility functions for address generation
|
|
62
|
+
function getUsdcAddress(publisherAddr: string) {
|
|
63
|
+
return createObjectAddress(
|
|
64
|
+
AccountAddress.fromString(publisherAddr),
|
|
65
|
+
new TextEncoder().encode("USDC"),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getPerpEngineGlobalAddress(publisherAddr: string) {
|
|
70
|
+
return createObjectAddress(
|
|
71
|
+
AccountAddress.fromString(publisherAddr),
|
|
72
|
+
new TextEncoder().encode("GlobalPerpEngine"),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Network configurations
|
|
77
|
+
const NETNA_PACKAGE = "0xb8a5788314451ce4d2fbbad32e1bad88d4184b73943b7fe5166eab93cf1a5a95";
|
|
78
|
+
|
|
79
|
+
const NETNA_CONFIG: DecibelConfig = {
|
|
80
|
+
network: Network.CUSTOM,
|
|
81
|
+
fullnodeUrl: "https://api.netna.staging.aptoslabs.com/v1",
|
|
82
|
+
tradingHttpUrl: "https://api.netna.aptoslabs.com/decibel",
|
|
83
|
+
tradingWsUrl: "wss://api.netna.aptoslabs.com/decibel/ws",
|
|
84
|
+
gasStationUrl: "https://fee-payer-dev-netna-us-central1-410192433417.us-central1.run.app",
|
|
85
|
+
deployment: {
|
|
86
|
+
package: NETNA_PACKAGE,
|
|
87
|
+
usdc: getUsdcAddress(NETNA_PACKAGE).toString(),
|
|
88
|
+
testc: getUsdcAddress(NETNA_PACKAGE).toString(), // Using same for test
|
|
89
|
+
perpEngineGlobal: getPerpEngineGlobalAddress(NETNA_PACKAGE).toString(),
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 2. Order Types and Constants
|
|
95
|
+
|
|
96
|
+
```typescript path=null start=null
|
|
97
|
+
// Time in Force options for orders
|
|
98
|
+
const TimeInForce = {
|
|
99
|
+
GoodTillCanceled: 0, // Order stays active until canceled
|
|
100
|
+
PostOnly: 1, // Order only adds liquidity (becomes maker)
|
|
101
|
+
ImmediateOrCancel: 2, // Execute immediately or cancel remainder
|
|
102
|
+
} as const;
|
|
103
|
+
type TimeInForce = (typeof TimeInForce)[keyof typeof TimeInForce];
|
|
104
|
+
|
|
105
|
+
// Order result interface
|
|
106
|
+
interface PlaceOrderResult {
|
|
107
|
+
success: boolean;
|
|
108
|
+
orderId?: string; // Extracted from transaction events
|
|
109
|
+
transactionHash: string | null;
|
|
110
|
+
error?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Order event structure (returned in transaction events)
|
|
114
|
+
interface OrderEvent {
|
|
115
|
+
order_id: string; // The generated order ID
|
|
116
|
+
user: string; // Subaccount address that placed the order
|
|
117
|
+
market: string; // Market address
|
|
118
|
+
price: string; // Order price
|
|
119
|
+
orig_size: string; // Original order size
|
|
120
|
+
remaining_size: string; // Remaining unfilled size
|
|
121
|
+
is_bid: boolean; // True for buy orders, false for sell
|
|
122
|
+
// ... other fields
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Core Transaction Infrastructure
|
|
127
|
+
|
|
128
|
+
### 1. Base Transaction Manager
|
|
129
|
+
|
|
130
|
+
```typescript path=null start=null
|
|
131
|
+
class DecibelTransactionManager {
|
|
132
|
+
private aptos: Aptos;
|
|
133
|
+
private config: DecibelConfig;
|
|
134
|
+
private skipSimulate: boolean;
|
|
135
|
+
private noFeePayer: boolean;
|
|
136
|
+
|
|
137
|
+
constructor(
|
|
138
|
+
config: DecibelConfig,
|
|
139
|
+
private account: Account,
|
|
140
|
+
options?: {
|
|
141
|
+
skipSimulate?: boolean;
|
|
142
|
+
noFeePayer?: boolean;
|
|
143
|
+
nodeApiKey?: string;
|
|
144
|
+
},
|
|
145
|
+
) {
|
|
146
|
+
this.config = config;
|
|
147
|
+
this.skipSimulate = options?.skipSimulate ?? false;
|
|
148
|
+
this.noFeePayer = options?.noFeePayer ?? false;
|
|
149
|
+
|
|
150
|
+
// Initialize Aptos client
|
|
151
|
+
const aptosConfig = new AptosConfig({
|
|
152
|
+
network: config.network,
|
|
153
|
+
fullnode: config.fullnodeUrl,
|
|
154
|
+
clientConfig: { API_KEY: options?.nodeApiKey },
|
|
155
|
+
});
|
|
156
|
+
this.aptos = new Aptos(aptosConfig);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Simulate transaction to get gas estimates
|
|
161
|
+
*/
|
|
162
|
+
private async getSimulatedTransaction(
|
|
163
|
+
payload: InputGenerateTransactionPayloadData,
|
|
164
|
+
sender: AccountAddress,
|
|
165
|
+
): Promise<SimpleTransaction> {
|
|
166
|
+
const transaction = await this.aptos.transaction.build.simple({
|
|
167
|
+
sender,
|
|
168
|
+
data: payload,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const [simulationResult] = await this.aptos.transaction.simulate.simple({
|
|
172
|
+
transaction,
|
|
173
|
+
options: {
|
|
174
|
+
estimateMaxGasAmount: true,
|
|
175
|
+
estimateGasUnitPrice: true,
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
if (!simulationResult?.max_gas_amount || !simulationResult?.gas_unit_price) {
|
|
180
|
+
throw new Error("Transaction simulation failed - no gas estimates returned");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Build transaction with gas estimates
|
|
184
|
+
return await this.aptos.transaction.build.simple({
|
|
185
|
+
sender,
|
|
186
|
+
data: payload,
|
|
187
|
+
options: {
|
|
188
|
+
maxGasAmount: Number(simulationResult.max_gas_amount),
|
|
189
|
+
gasUnitPrice: Number(simulationResult.gas_unit_price),
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Submit transaction with optional fee payer support
|
|
196
|
+
*/
|
|
197
|
+
private async submitTransaction(
|
|
198
|
+
transaction: SimpleTransaction,
|
|
199
|
+
senderAuthenticator: AccountAuthenticator,
|
|
200
|
+
): Promise<PendingTransactionResponse> {
|
|
201
|
+
if (this.noFeePayer) {
|
|
202
|
+
// Submit without fee payer (user pays gas)
|
|
203
|
+
return await this.aptos.transaction.submit.simple({
|
|
204
|
+
transaction,
|
|
205
|
+
senderAuthenticator,
|
|
206
|
+
});
|
|
207
|
+
} else {
|
|
208
|
+
// Submit with fee payer (Decibel pays gas)
|
|
209
|
+
return await this.submitFeePaidTransaction(transaction, senderAuthenticator);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Submit transaction using Decibel's fee payer service
|
|
215
|
+
*/
|
|
216
|
+
private async submitFeePaidTransaction(
|
|
217
|
+
transaction: SimpleTransaction,
|
|
218
|
+
senderAuthenticator: AccountAuthenticator,
|
|
219
|
+
): Promise<PendingTransactionResponse> {
|
|
220
|
+
const signatureBcs = Array.from(senderAuthenticator.bcsToBytes());
|
|
221
|
+
const transactionBcs = Array.from(transaction.rawTransaction.bcsToBytes());
|
|
222
|
+
|
|
223
|
+
const response = await fetch(this.config.gasStationUrl + "/transactions", {
|
|
224
|
+
method: "POST",
|
|
225
|
+
headers: {
|
|
226
|
+
"Content-Type": "application/json",
|
|
227
|
+
},
|
|
228
|
+
body: JSON.stringify({
|
|
229
|
+
signature: signatureBcs,
|
|
230
|
+
transaction: transactionBcs,
|
|
231
|
+
}),
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
if (!response.ok) {
|
|
235
|
+
throw new Error(`Fee payer service error: ${response.status}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return (await response.json()) as PendingTransactionResponse;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Main method to send any transaction to the blockchain
|
|
243
|
+
*/
|
|
244
|
+
async sendTransaction(
|
|
245
|
+
payload: InputGenerateTransactionPayloadData,
|
|
246
|
+
accountOverride?: Account,
|
|
247
|
+
): Promise<CommittedTransactionResponse> {
|
|
248
|
+
const signer = accountOverride ?? this.account;
|
|
249
|
+
const sender = signer.accountAddress;
|
|
250
|
+
|
|
251
|
+
let transaction: SimpleTransaction;
|
|
252
|
+
|
|
253
|
+
if (!this.skipSimulate) {
|
|
254
|
+
// Get gas estimates through simulation
|
|
255
|
+
transaction = await this.getSimulatedTransaction(payload, sender);
|
|
256
|
+
} else {
|
|
257
|
+
// Build transaction without simulation
|
|
258
|
+
const withFeePayer = !this.noFeePayer;
|
|
259
|
+
transaction = await this.aptos.transaction.build.simple({
|
|
260
|
+
sender,
|
|
261
|
+
data: payload,
|
|
262
|
+
withFeePayer,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Sign the transaction
|
|
267
|
+
const senderAuthenticator = this.aptos.transaction.sign({
|
|
268
|
+
signer,
|
|
269
|
+
transaction,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Submit and wait for confirmation
|
|
273
|
+
const pendingTransaction = await this.submitTransaction(transaction, senderAuthenticator);
|
|
274
|
+
return await this.aptos.waitForTransaction({
|
|
275
|
+
transactionHash: pendingTransaction.hash,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 2. Utility Functions
|
|
282
|
+
|
|
283
|
+
```typescript path=null start=null
|
|
284
|
+
/**
|
|
285
|
+
* Get market address from market name
|
|
286
|
+
*/
|
|
287
|
+
function getMarketAddress(marketName: string, perpEngineGlobalAddr: string): AccountAddress {
|
|
288
|
+
const marketNameBytes = new MoveString(marketName).bcsToBytes();
|
|
289
|
+
return createObjectAddress(AccountAddress.fromString(perpEngineGlobalAddr), marketNameBytes);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Get primary subaccount address for a user account
|
|
294
|
+
*/
|
|
295
|
+
function getPrimarySubaccountAddress(userAddress: AccountAddress): string {
|
|
296
|
+
const seed = new TextEncoder().encode("decibel_dex_primary");
|
|
297
|
+
return createObjectAddress(userAddress, seed).toString();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Extract order ID from transaction events
|
|
302
|
+
*/
|
|
303
|
+
function extractOrderIdFromTransaction(
|
|
304
|
+
txResponse: CommittedTransactionResponse,
|
|
305
|
+
subaccountAddr: string,
|
|
306
|
+
): string | null {
|
|
307
|
+
try {
|
|
308
|
+
if ("events" in txResponse && Array.isArray(txResponse.events)) {
|
|
309
|
+
for (const event of txResponse.events) {
|
|
310
|
+
// Look for OrderEvent from the market module
|
|
311
|
+
if (event.type.includes("::market_types::OrderEvent")) {
|
|
312
|
+
const orderEvent = event.data as OrderEvent;
|
|
313
|
+
// Verify this event is from the correct subaccount
|
|
314
|
+
if (orderEvent.user === subaccountAddr) {
|
|
315
|
+
return orderEvent.order_id;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
} catch (error) {
|
|
322
|
+
console.error("Error extracting order ID:", error);
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Account Management Transactions
|
|
329
|
+
|
|
330
|
+
### 1. Create Subaccount
|
|
331
|
+
|
|
332
|
+
```typescript path=null start=null
|
|
333
|
+
/**
|
|
334
|
+
* Create a new trading subaccount
|
|
335
|
+
* Each user can have multiple subaccounts for different trading strategies
|
|
336
|
+
*/
|
|
337
|
+
async function createSubaccount(
|
|
338
|
+
transactionManager: DecibelTransactionManager,
|
|
339
|
+
config: DecibelConfig,
|
|
340
|
+
): Promise<CommittedTransactionResponse> {
|
|
341
|
+
return await transactionManager.sendTransaction({
|
|
342
|
+
function: `${config.deployment.package}::dex_accounts::create_new_subaccount`,
|
|
343
|
+
typeArguments: [],
|
|
344
|
+
functionArguments: [],
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### 2. Deposit Collateral
|
|
350
|
+
|
|
351
|
+
```typescript path=null start=null
|
|
352
|
+
/**
|
|
353
|
+
* Deposit USDC collateral to a subaccount
|
|
354
|
+
* @param amount Amount in smallest unit (e.g., 1000000 = 1 USDC if 6 decimals)
|
|
355
|
+
* @param subaccountAddr Optional specific subaccount, uses primary if not provided
|
|
356
|
+
*/
|
|
357
|
+
async function depositCollateral(
|
|
358
|
+
transactionManager: DecibelTransactionManager,
|
|
359
|
+
config: DecibelConfig,
|
|
360
|
+
amount: number,
|
|
361
|
+
subaccountAddr: string,
|
|
362
|
+
): Promise<CommittedTransactionResponse> {
|
|
363
|
+
// Deposit to specific subaccount
|
|
364
|
+
return await transactionManager.sendTransaction({
|
|
365
|
+
function: `${config.deployment.package}::dex_accounts::deposit_to_subaccount_at`,
|
|
366
|
+
typeArguments: [],
|
|
367
|
+
functionArguments: [subaccountAddr, config.deployment.usdc, amount],
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### 3. Withdraw Collateral
|
|
373
|
+
|
|
374
|
+
```typescript path=null start=null
|
|
375
|
+
/**
|
|
376
|
+
* Withdraw collateral from a subaccount
|
|
377
|
+
* @param amount Amount in smallest unit to withdraw
|
|
378
|
+
* @param subaccountAddr Subaccount to withdraw from (uses primary if not provided)
|
|
379
|
+
*/
|
|
380
|
+
async function withdrawCollateral(
|
|
381
|
+
transactionManager: DecibelTransactionManager,
|
|
382
|
+
config: DecibelConfig,
|
|
383
|
+
amount: number,
|
|
384
|
+
subaccountAddr?: string,
|
|
385
|
+
): Promise<CommittedTransactionResponse> {
|
|
386
|
+
const subaccount =
|
|
387
|
+
subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
388
|
+
|
|
389
|
+
return await transactionManager.sendTransaction({
|
|
390
|
+
function: `${config.deployment.package}::dex_accounts::withdraw_from_subaccount`,
|
|
391
|
+
typeArguments: [],
|
|
392
|
+
functionArguments: [subaccount, config.deployment.usdc, amount],
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### 4. Configure Market Settings
|
|
398
|
+
|
|
399
|
+
```typescript path=null start=null
|
|
400
|
+
/**
|
|
401
|
+
* Configure user settings for a specific market
|
|
402
|
+
* @param marketAddr The market address to configure
|
|
403
|
+
* @param subaccountAddr The subaccount address
|
|
404
|
+
* @param isCross Whether to use cross-margin mode (vs isolated)
|
|
405
|
+
* @param userLeverage Leverage in basis points (1000 = 10x leverage)
|
|
406
|
+
*/
|
|
407
|
+
async function configureMarketSettings(
|
|
408
|
+
transactionManager: DecibelTransactionManager,
|
|
409
|
+
config: DecibelConfig,
|
|
410
|
+
marketAddr: string,
|
|
411
|
+
subaccountAddr: string,
|
|
412
|
+
isCross: boolean,
|
|
413
|
+
userLeverage: number,
|
|
414
|
+
): Promise<CommittedTransactionResponse> {
|
|
415
|
+
return await transactionManager.sendTransaction({
|
|
416
|
+
function: `${config.deployment.package}::dex_accounts::configure_user_settings_for_market`,
|
|
417
|
+
typeArguments: [],
|
|
418
|
+
functionArguments: [subaccountAddr, marketAddr, isCross, userLeverage],
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Order Management Transactions
|
|
424
|
+
|
|
425
|
+
### 1. Place Order
|
|
426
|
+
|
|
427
|
+
```typescript path=null start=null
|
|
428
|
+
/**
|
|
429
|
+
* Place a trading order on the exchange
|
|
430
|
+
*/
|
|
431
|
+
async function placeOrder(
|
|
432
|
+
transactionManager: DecibelTransactionManager,
|
|
433
|
+
config: DecibelConfig,
|
|
434
|
+
params: {
|
|
435
|
+
marketName: string; // e.g., "BTC-USD"
|
|
436
|
+
price: number; // Price in quote currency
|
|
437
|
+
size: number; // Size in base currency
|
|
438
|
+
isBuy: boolean; // true for buy, false for sell
|
|
439
|
+
timeInForce: TimeInForce; // Order execution type
|
|
440
|
+
isReduceOnly: boolean; // true to only reduce position size
|
|
441
|
+
clientOrderId?: number; // Optional client-assigned order ID
|
|
442
|
+
stopPrice?: number; // Optional stop price for stop orders
|
|
443
|
+
tpTriggerPrice?: number; // Take profit trigger price
|
|
444
|
+
tpLimitPrice?: number; // Take profit limit price
|
|
445
|
+
slTriggerPrice?: number; // Stop loss trigger price
|
|
446
|
+
slLimitPrice?: number; // Stop loss limit price
|
|
447
|
+
builderAddr?: string; // Optional builder/referrer address
|
|
448
|
+
builderFee?: number; // Builder fee in basis points
|
|
449
|
+
subaccountAddr?: string; // Optional subaccount (uses primary if not provided)
|
|
450
|
+
accountOverride?: Account; // Optional account override (for session accounts)
|
|
451
|
+
},
|
|
452
|
+
): Promise<PlaceOrderResult> {
|
|
453
|
+
try {
|
|
454
|
+
// Get market address from name
|
|
455
|
+
const marketAddr = getMarketAddress(params.marketName, config.deployment.perpEngineGlobal);
|
|
456
|
+
|
|
457
|
+
// Use primary subaccount if none provided
|
|
458
|
+
const subaccountAddr =
|
|
459
|
+
params.subaccountAddr ??
|
|
460
|
+
getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
461
|
+
|
|
462
|
+
// Send the transaction
|
|
463
|
+
const txResponse = await transactionManager.sendTransaction(
|
|
464
|
+
{
|
|
465
|
+
function: `${config.deployment.package}::dex_accounts::place_order_to_subaccount`,
|
|
466
|
+
typeArguments: [],
|
|
467
|
+
functionArguments: [
|
|
468
|
+
subaccountAddr,
|
|
469
|
+
marketAddr.toString(),
|
|
470
|
+
params.price,
|
|
471
|
+
params.size,
|
|
472
|
+
params.isBuy,
|
|
473
|
+
params.timeInForce,
|
|
474
|
+
params.isReduceOnly,
|
|
475
|
+
params.clientOrderId,
|
|
476
|
+
params.stopPrice,
|
|
477
|
+
params.tpTriggerPrice,
|
|
478
|
+
params.tpLimitPrice,
|
|
479
|
+
params.slTriggerPrice,
|
|
480
|
+
params.slLimitPrice,
|
|
481
|
+
params.builderAddr,
|
|
482
|
+
params.builderFee,
|
|
483
|
+
],
|
|
484
|
+
},
|
|
485
|
+
params.accountOverride,
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
// Extract order ID from transaction events
|
|
489
|
+
const orderId = extractOrderIdFromTransaction(txResponse, subaccountAddr);
|
|
490
|
+
|
|
491
|
+
return {
|
|
492
|
+
success: true,
|
|
493
|
+
orderId: orderId || undefined,
|
|
494
|
+
transactionHash: txResponse.hash,
|
|
495
|
+
};
|
|
496
|
+
} catch (error) {
|
|
497
|
+
console.error("Error placing order:", error);
|
|
498
|
+
return {
|
|
499
|
+
success: false,
|
|
500
|
+
transactionHash: null,
|
|
501
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 2. Cancel Order
|
|
508
|
+
|
|
509
|
+
```typescript path=null start=null
|
|
510
|
+
/**
|
|
511
|
+
* Cancel an existing order by order ID
|
|
512
|
+
*/
|
|
513
|
+
async function cancelOrder(
|
|
514
|
+
transactionManager: DecibelTransactionManager,
|
|
515
|
+
config: DecibelConfig,
|
|
516
|
+
params: {
|
|
517
|
+
orderId: number;
|
|
518
|
+
marketName?: string; // Either marketName OR marketAddr must be provided
|
|
519
|
+
marketAddr?: string;
|
|
520
|
+
subaccountAddr?: string;
|
|
521
|
+
accountOverride?: Account;
|
|
522
|
+
},
|
|
523
|
+
): Promise<CommittedTransactionResponse> {
|
|
524
|
+
// Get market address
|
|
525
|
+
const marketAddr =
|
|
526
|
+
params.marketAddr ??
|
|
527
|
+
(params.marketName
|
|
528
|
+
? getMarketAddress(params.marketName, config.deployment.perpEngineGlobal).toString()
|
|
529
|
+
: "");
|
|
530
|
+
|
|
531
|
+
if (!marketAddr) {
|
|
532
|
+
throw new Error("Either marketName or marketAddr must be provided");
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const subaccountAddr =
|
|
536
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
537
|
+
|
|
538
|
+
return await transactionManager.sendTransaction(
|
|
539
|
+
{
|
|
540
|
+
function: `${config.deployment.package}::dex_accounts::cancel_order_to_subaccount`,
|
|
541
|
+
typeArguments: [],
|
|
542
|
+
functionArguments: [subaccountAddr, params.orderId, marketAddr],
|
|
543
|
+
},
|
|
544
|
+
params.accountOverride,
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### 3. Cancel Order by Client ID
|
|
550
|
+
|
|
551
|
+
```typescript path=null start=null
|
|
552
|
+
/**
|
|
553
|
+
* Cancel an order using the client-assigned order ID
|
|
554
|
+
*/
|
|
555
|
+
async function cancelClientOrder(
|
|
556
|
+
transactionManager: DecibelTransactionManager,
|
|
557
|
+
config: DecibelConfig,
|
|
558
|
+
params: {
|
|
559
|
+
clientOrderId: number;
|
|
560
|
+
marketName: string;
|
|
561
|
+
subaccountAddr?: string;
|
|
562
|
+
accountOverride?: Account;
|
|
563
|
+
},
|
|
564
|
+
): Promise<CommittedTransactionResponse> {
|
|
565
|
+
const marketAddr = getMarketAddress(params.marketName, config.deployment.perpEngineGlobal);
|
|
566
|
+
const subaccountAddr =
|
|
567
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
568
|
+
|
|
569
|
+
return await transactionManager.sendTransaction(
|
|
570
|
+
{
|
|
571
|
+
function: `${config.deployment.package}::dex_accounts::cancel_client_order_to_subaccount`,
|
|
572
|
+
typeArguments: [],
|
|
573
|
+
functionArguments: [subaccountAddr, params.clientOrderId, marketAddr.toString()],
|
|
574
|
+
},
|
|
575
|
+
params.accountOverride,
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### 4. TWAP (Time-Weighted Average Price) Orders
|
|
581
|
+
|
|
582
|
+
```typescript path=null start=null
|
|
583
|
+
/**
|
|
584
|
+
* Place a TWAP order that executes over time
|
|
585
|
+
* @param twapFrequencySeconds How often to execute sub-orders (in seconds)
|
|
586
|
+
* @param twapDurationSeconds Total duration for the TWAP order (in seconds)
|
|
587
|
+
*/
|
|
588
|
+
async function placeTwapOrder(
|
|
589
|
+
transactionManager: DecibelTransactionManager,
|
|
590
|
+
config: DecibelConfig,
|
|
591
|
+
params: {
|
|
592
|
+
marketName: string;
|
|
593
|
+
size: number; // Total size to be executed over time
|
|
594
|
+
isBuy: boolean;
|
|
595
|
+
isReduceOnly: boolean;
|
|
596
|
+
twapFrequencySeconds: number; // e.g., 60 = execute every minute
|
|
597
|
+
twapDurationSeconds: number; // e.g., 3600 = over 1 hour
|
|
598
|
+
subaccountAddr?: string;
|
|
599
|
+
accountOverride?: Account;
|
|
600
|
+
},
|
|
601
|
+
): Promise<CommittedTransactionResponse> {
|
|
602
|
+
const marketAddr = getMarketAddress(params.marketName, config.deployment.perpEngineGlobal);
|
|
603
|
+
const subaccountAddr =
|
|
604
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
605
|
+
|
|
606
|
+
return await transactionManager.sendTransaction(
|
|
607
|
+
{
|
|
608
|
+
function: `${config.deployment.package}::dex_accounts::place_twap_order_to_subaccount`,
|
|
609
|
+
typeArguments: [],
|
|
610
|
+
functionArguments: [
|
|
611
|
+
subaccountAddr,
|
|
612
|
+
marketAddr.toString(),
|
|
613
|
+
params.size,
|
|
614
|
+
params.isBuy,
|
|
615
|
+
params.isReduceOnly,
|
|
616
|
+
params.twapFrequencySeconds,
|
|
617
|
+
params.twapDurationSeconds,
|
|
618
|
+
],
|
|
619
|
+
},
|
|
620
|
+
params.accountOverride,
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
## Position Management Transactions
|
|
626
|
+
|
|
627
|
+
### 1. Place Take-Profit/Stop-Loss Orders
|
|
628
|
+
|
|
629
|
+
```typescript path=null start=null
|
|
630
|
+
/**
|
|
631
|
+
* Place TP/SL orders for an existing position
|
|
632
|
+
*/
|
|
633
|
+
async function placeTpSlOrderForPosition(
|
|
634
|
+
transactionManager: DecibelTransactionManager,
|
|
635
|
+
config: DecibelConfig,
|
|
636
|
+
params: {
|
|
637
|
+
marketAddr: string;
|
|
638
|
+
tpTriggerPrice?: number; // Take profit trigger price
|
|
639
|
+
tpLimitPrice?: number; // Take profit limit price
|
|
640
|
+
tpSize?: number; // Take profit size (partial or full position)
|
|
641
|
+
slTriggerPrice?: number; // Stop loss trigger price
|
|
642
|
+
slLimitPrice?: number; // Stop loss limit price
|
|
643
|
+
slSize?: number; // Stop loss size
|
|
644
|
+
subaccountAddr?: string;
|
|
645
|
+
accountOverride?: Account;
|
|
646
|
+
},
|
|
647
|
+
): Promise<CommittedTransactionResponse> {
|
|
648
|
+
const subaccountAddr =
|
|
649
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
650
|
+
|
|
651
|
+
return await transactionManager.sendTransaction(
|
|
652
|
+
{
|
|
653
|
+
function: `${config.deployment.package}::dex_accounts::place_tp_sl_order_for_position`,
|
|
654
|
+
typeArguments: [],
|
|
655
|
+
functionArguments: [
|
|
656
|
+
subaccountAddr,
|
|
657
|
+
params.marketAddr,
|
|
658
|
+
params.tpTriggerPrice,
|
|
659
|
+
params.tpLimitPrice,
|
|
660
|
+
params.tpSize,
|
|
661
|
+
params.slTriggerPrice,
|
|
662
|
+
params.slLimitPrice,
|
|
663
|
+
params.slSize,
|
|
664
|
+
],
|
|
665
|
+
},
|
|
666
|
+
params.accountOverride,
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### 2. Update Take-Profit/Stop-Loss Orders
|
|
672
|
+
|
|
673
|
+
```typescript path=null start=null
|
|
674
|
+
/**
|
|
675
|
+
* Update existing TP/SL orders for a position
|
|
676
|
+
*/
|
|
677
|
+
async function updateTpSlOrderForPosition(
|
|
678
|
+
transactionManager: DecibelTransactionManager,
|
|
679
|
+
config: DecibelConfig,
|
|
680
|
+
params: {
|
|
681
|
+
marketAddr: string;
|
|
682
|
+
prevOrderId: string; // ID of the previous TP/SL order to update
|
|
683
|
+
tpTriggerPrice?: number;
|
|
684
|
+
tpLimitPrice?: number;
|
|
685
|
+
tpSize?: number;
|
|
686
|
+
slTriggerPrice?: number;
|
|
687
|
+
slLimitPrice?: number;
|
|
688
|
+
slSize?: number;
|
|
689
|
+
subaccountAddr?: string;
|
|
690
|
+
accountOverride?: Account;
|
|
691
|
+
},
|
|
692
|
+
): Promise<CommittedTransactionResponse> {
|
|
693
|
+
const subaccountAddr =
|
|
694
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
695
|
+
|
|
696
|
+
return await transactionManager.sendTransaction(
|
|
697
|
+
{
|
|
698
|
+
function: `${config.deployment.package}::dex_accounts::update_tp_sl_order_for_position`,
|
|
699
|
+
typeArguments: [],
|
|
700
|
+
functionArguments: [
|
|
701
|
+
subaccountAddr,
|
|
702
|
+
Number(params.prevOrderId),
|
|
703
|
+
params.marketAddr,
|
|
704
|
+
params.tpTriggerPrice,
|
|
705
|
+
params.tpLimitPrice,
|
|
706
|
+
params.tpSize,
|
|
707
|
+
params.slTriggerPrice,
|
|
708
|
+
params.slLimitPrice,
|
|
709
|
+
params.slSize,
|
|
710
|
+
],
|
|
711
|
+
},
|
|
712
|
+
params.accountOverride,
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### 3. Cancel Take-Profit/Stop-Loss Orders
|
|
718
|
+
|
|
719
|
+
```typescript path=null start=null
|
|
720
|
+
/**
|
|
721
|
+
* Cancel TP/SL orders for a position
|
|
722
|
+
*/
|
|
723
|
+
async function cancelTpSlOrderForPosition(
|
|
724
|
+
transactionManager: DecibelTransactionManager,
|
|
725
|
+
config: DecibelConfig,
|
|
726
|
+
params: {
|
|
727
|
+
marketName: string;
|
|
728
|
+
orderId: number;
|
|
729
|
+
subaccountAddr?: string;
|
|
730
|
+
accountOverride?: Account;
|
|
731
|
+
},
|
|
732
|
+
): Promise<CommittedTransactionResponse> {
|
|
733
|
+
const marketAddr = getMarketAddress(params.marketName, config.deployment.perpEngineGlobal);
|
|
734
|
+
const subaccountAddr =
|
|
735
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
736
|
+
|
|
737
|
+
return await transactionManager.sendTransaction(
|
|
738
|
+
{
|
|
739
|
+
function: `${config.deployment.package}::dex_accounts::cancel_tp_sl_order_for_position`,
|
|
740
|
+
typeArguments: [],
|
|
741
|
+
functionArguments: [subaccountAddr, marketAddr.toString(), params.orderId],
|
|
742
|
+
},
|
|
743
|
+
params.accountOverride,
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
## Advanced Features
|
|
749
|
+
|
|
750
|
+
### 1. Trading Delegation
|
|
751
|
+
|
|
752
|
+
```typescript path=null start=null
|
|
753
|
+
/**
|
|
754
|
+
* Delegate trading permissions to another account
|
|
755
|
+
* This allows the delegate account to trade on behalf of the subaccount
|
|
756
|
+
*/
|
|
757
|
+
async function delegateTradingTo(
|
|
758
|
+
transactionManager: DecibelTransactionManager,
|
|
759
|
+
config: DecibelConfig,
|
|
760
|
+
params: {
|
|
761
|
+
accountToDelegateTo: string; // Address to delegate trading to
|
|
762
|
+
subaccountAddr?: string;
|
|
763
|
+
},
|
|
764
|
+
): Promise<CommittedTransactionResponse> {
|
|
765
|
+
const subaccountAddr =
|
|
766
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
767
|
+
|
|
768
|
+
return await transactionManager.sendTransaction({
|
|
769
|
+
function: `${config.deployment.package}::dex_accounts::delegate_trading_to_for_subaccount`,
|
|
770
|
+
typeArguments: [],
|
|
771
|
+
functionArguments: [subaccountAddr, params.accountToDelegateTo],
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Revoke trading delegation from an account
|
|
777
|
+
*/
|
|
778
|
+
async function revokeDelegation(
|
|
779
|
+
transactionManager: DecibelTransactionManager,
|
|
780
|
+
config: DecibelConfig,
|
|
781
|
+
params: {
|
|
782
|
+
accountToRevoke: string; // Address to revoke delegation from
|
|
783
|
+
subaccountAddr?: string;
|
|
784
|
+
},
|
|
785
|
+
): Promise<CommittedTransactionResponse> {
|
|
786
|
+
const subaccountAddr =
|
|
787
|
+
params.subaccountAddr ?? getPrimarySubaccountAddress(transactionManager.account.accountAddress);
|
|
788
|
+
|
|
789
|
+
return await transactionManager.sendTransaction({
|
|
790
|
+
function: `${config.deployment.package}::dex_accounts::revoke_delegation`,
|
|
791
|
+
typeArguments: [],
|
|
792
|
+
functionArguments: [subaccountAddr, params.accountToRevoke],
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
## Complete Working Examples
|
|
798
|
+
|
|
799
|
+
### 1. Basic Trading Example
|
|
800
|
+
|
|
801
|
+
```typescript path=null start=null
|
|
802
|
+
async function basicTradingExample() {
|
|
803
|
+
// 1. Set up account and transaction manager
|
|
804
|
+
const privateKey = "your-private-key-here";
|
|
805
|
+
const account = Account.fromPrivateKey({ privateKey });
|
|
806
|
+
const transactionManager = new DecibelTransactionManager(NETNA_CONFIG, account, {
|
|
807
|
+
skipSimulate: false, // Use simulation for gas estimation
|
|
808
|
+
noFeePayer: false, // Use Decibel's fee payer service
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
try {
|
|
812
|
+
// 2. Create a subaccount
|
|
813
|
+
console.log("Creating subaccount...");
|
|
814
|
+
const createTx = await createSubaccount(transactionManager, NETNA_CONFIG);
|
|
815
|
+
console.log("Subaccount created:", createTx.hash);
|
|
816
|
+
|
|
817
|
+
// 3. Get the primary subaccount address
|
|
818
|
+
const subaccountAddr = getPrimarySubaccountAddress(account.accountAddress);
|
|
819
|
+
console.log("Primary subaccount address:", subaccountAddr);
|
|
820
|
+
|
|
821
|
+
// 4. Deposit collateral (1000 USDC = 1000000000 if 6 decimals)
|
|
822
|
+
console.log("Depositing collateral...");
|
|
823
|
+
const depositTx = await depositCollateral(
|
|
824
|
+
transactionManager,
|
|
825
|
+
NETNA_CONFIG,
|
|
826
|
+
1000000000,
|
|
827
|
+
subaccountAddr,
|
|
828
|
+
);
|
|
829
|
+
console.log("Deposit successful:", depositTx.hash);
|
|
830
|
+
|
|
831
|
+
// 5. Configure market settings for BTC-USD
|
|
832
|
+
const btcMarketAddr = getMarketAddress("BTC-USD", NETNA_CONFIG.deployment.perpEngineGlobal);
|
|
833
|
+
console.log("Configuring market settings...");
|
|
834
|
+
const configTx = await configureMarketSettings(
|
|
835
|
+
transactionManager,
|
|
836
|
+
NETNA_CONFIG,
|
|
837
|
+
btcMarketAddr.toString(),
|
|
838
|
+
subaccountAddr,
|
|
839
|
+
true, // Use cross-margin
|
|
840
|
+
1000, // 10x leverage (1000 basis points)
|
|
841
|
+
);
|
|
842
|
+
console.log("Market configured:", configTx.hash);
|
|
843
|
+
|
|
844
|
+
// 6. Place a limit buy order for 0.1 BTC at $45,000
|
|
845
|
+
console.log("Placing buy order...");
|
|
846
|
+
const orderResult = await placeOrder(transactionManager, NETNA_CONFIG, {
|
|
847
|
+
marketName: "BTC-USD",
|
|
848
|
+
price: 45000,
|
|
849
|
+
size: 0.1,
|
|
850
|
+
isBuy: true,
|
|
851
|
+
timeInForce: TimeInForce.GoodTillCanceled,
|
|
852
|
+
isReduceOnly: false,
|
|
853
|
+
subaccountAddr,
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
if (orderResult.success) {
|
|
857
|
+
console.log("Order placed successfully!");
|
|
858
|
+
console.log("Order ID:", orderResult.orderId);
|
|
859
|
+
console.log("Transaction:", orderResult.transactionHash);
|
|
860
|
+
|
|
861
|
+
// 7. Cancel the order (example)
|
|
862
|
+
if (orderResult.orderId) {
|
|
863
|
+
console.log("Canceling order...");
|
|
864
|
+
const cancelTx = await cancelOrder(transactionManager, NETNA_CONFIG, {
|
|
865
|
+
orderId: parseInt(orderResult.orderId),
|
|
866
|
+
marketName: "BTC-USD",
|
|
867
|
+
subaccountAddr,
|
|
868
|
+
});
|
|
869
|
+
console.log("Order canceled:", cancelTx.hash);
|
|
870
|
+
}
|
|
871
|
+
} else {
|
|
872
|
+
console.error("Order failed:", orderResult.error);
|
|
873
|
+
}
|
|
874
|
+
} catch (error) {
|
|
875
|
+
console.error("Error in trading example:", error);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
### 2. Advanced Position Management Example
|
|
881
|
+
|
|
882
|
+
```typescript path=null start=null
|
|
883
|
+
async function advancedPositionExample() {
|
|
884
|
+
const account = Account.fromPrivateKey({ privateKey: "your-private-key-here" });
|
|
885
|
+
const transactionManager = new DecibelTransactionManager(NETNA_CONFIG, account);
|
|
886
|
+
const subaccountAddr = getPrimarySubaccountAddress(account.accountAddress);
|
|
887
|
+
|
|
888
|
+
try {
|
|
889
|
+
// 1. Place a market buy order (using IOC with high price)
|
|
890
|
+
console.log("Opening position with market order...");
|
|
891
|
+
const marketOrderResult = await placeOrder(transactionManager, NETNA_CONFIG, {
|
|
892
|
+
marketName: "BTC-USD",
|
|
893
|
+
price: 50000, // High price to ensure execution
|
|
894
|
+
size: 1.0,
|
|
895
|
+
isBuy: true,
|
|
896
|
+
timeInForce: TimeInForce.ImmediateOrCancel,
|
|
897
|
+
isReduceOnly: false,
|
|
898
|
+
subaccountAddr,
|
|
899
|
+
});
|
|
900
|
+
|
|
901
|
+
if (!marketOrderResult.success) {
|
|
902
|
+
throw new Error("Failed to open position: " + marketOrderResult.error);
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
console.log("Position opened:", marketOrderResult.transactionHash);
|
|
906
|
+
|
|
907
|
+
// 2. Set up take-profit and stop-loss orders
|
|
908
|
+
const btcMarketAddr = getMarketAddress("BTC-USD", NETNA_CONFIG.deployment.perpEngineGlobal);
|
|
909
|
+
|
|
910
|
+
console.log("Setting up TP/SL orders...");
|
|
911
|
+
const tpSlTx = await placeTpSlOrderForPosition(transactionManager, NETNA_CONFIG, {
|
|
912
|
+
marketAddr: btcMarketAddr.toString(),
|
|
913
|
+
tpTriggerPrice: 52000, // Take profit at $52,000
|
|
914
|
+
tpLimitPrice: 51900, // Limit price for TP order
|
|
915
|
+
tpSize: 0.5, // Close half position
|
|
916
|
+
slTriggerPrice: 44000, // Stop loss at $44,000
|
|
917
|
+
slLimitPrice: 44100, // Limit price for SL order
|
|
918
|
+
slSize: 1.0, // Close entire position
|
|
919
|
+
subaccountAddr,
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
console.log("TP/SL orders placed:", tpSlTx.hash);
|
|
923
|
+
|
|
924
|
+
// 3. Place a TWAP order to scale into a larger position
|
|
925
|
+
console.log("Starting TWAP order...");
|
|
926
|
+
const twapTx = await placeTwapOrder(transactionManager, NETNA_CONFIG, {
|
|
927
|
+
marketName: "BTC-USD",
|
|
928
|
+
size: 2.0, // Buy 2 BTC total
|
|
929
|
+
isBuy: true,
|
|
930
|
+
isReduceOnly: false,
|
|
931
|
+
twapFrequencySeconds: 300, // Every 5 minutes
|
|
932
|
+
twapDurationSeconds: 3600, // Over 1 hour
|
|
933
|
+
subaccountAddr,
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
console.log("TWAP order started:", twapTx.hash);
|
|
937
|
+
} catch (error) {
|
|
938
|
+
console.error("Error in position management:", error);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
### 3. Session Account Example (for dApps)
|
|
944
|
+
|
|
945
|
+
```typescript path=null start=null
|
|
946
|
+
/**
|
|
947
|
+
* Example of using session accounts for dApp integrations
|
|
948
|
+
* The main account delegates to a session account with limited permissions
|
|
949
|
+
*/
|
|
950
|
+
async function sessionAccountExample() {
|
|
951
|
+
// Main user account
|
|
952
|
+
const mainAccount = Account.fromPrivateKey({ privateKey: "user-private-key" });
|
|
953
|
+
const transactionManager = new DecibelTransactionManager(NETNA_CONFIG, mainAccount);
|
|
954
|
+
const subaccountAddr = getPrimarySubaccountAddress(mainAccount.accountAddress);
|
|
955
|
+
|
|
956
|
+
// Generate a temporary session account
|
|
957
|
+
const sessionAccount = Account.generate();
|
|
958
|
+
console.log("Generated session account:", sessionAccount.accountAddress.toString());
|
|
959
|
+
|
|
960
|
+
try {
|
|
961
|
+
// 1. Delegate trading permissions to session account
|
|
962
|
+
console.log("Delegating trading permissions...");
|
|
963
|
+
const delegateTx = await delegateTradingTo(transactionManager, NETNA_CONFIG, {
|
|
964
|
+
accountToDelegateTo: sessionAccount.accountAddress.toString(),
|
|
965
|
+
subaccountAddr,
|
|
966
|
+
});
|
|
967
|
+
console.log("Delegation successful:", delegateTx.hash);
|
|
968
|
+
|
|
969
|
+
// 2. Use session account to place orders
|
|
970
|
+
console.log("Placing order with session account...");
|
|
971
|
+
const orderResult = await placeOrder(transactionManager, NETNA_CONFIG, {
|
|
972
|
+
marketName: "ETH-USD",
|
|
973
|
+
price: 3000,
|
|
974
|
+
size: 5.0,
|
|
975
|
+
isBuy: true,
|
|
976
|
+
timeInForce: TimeInForce.PostOnly,
|
|
977
|
+
isReduceOnly: false,
|
|
978
|
+
subaccountAddr,
|
|
979
|
+
accountOverride: sessionAccount, // Use session account to sign
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
if (orderResult.success) {
|
|
983
|
+
console.log("Session order placed:", orderResult.orderId);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// 3. Later, revoke session account permissions
|
|
987
|
+
console.log("Revoking session permissions...");
|
|
988
|
+
const revokeTx = await revokeDelegation(transactionManager, NETNA_CONFIG, {
|
|
989
|
+
accountToRevoke: sessionAccount.accountAddress.toString(),
|
|
990
|
+
subaccountAddr,
|
|
991
|
+
});
|
|
992
|
+
console.log("Permissions revoked:", revokeTx.hash);
|
|
993
|
+
} catch (error) {
|
|
994
|
+
console.error("Error in session account example:", error);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
```
|
|
998
|
+
|
|
999
|
+
## Best Practices and Notes
|
|
1000
|
+
|
|
1001
|
+
### 1. Error Handling
|
|
1002
|
+
|
|
1003
|
+
Always wrap transaction calls in try-catch blocks and handle different types of errors:
|
|
1004
|
+
|
|
1005
|
+
```typescript path=null start=null
|
|
1006
|
+
async function handleTransactionErrors() {
|
|
1007
|
+
try {
|
|
1008
|
+
const result = await placeOrder(/* parameters */);
|
|
1009
|
+
if (!result.success) {
|
|
1010
|
+
// Handle business logic errors
|
|
1011
|
+
console.error("Order placement failed:", result.error);
|
|
1012
|
+
}
|
|
1013
|
+
} catch (error) {
|
|
1014
|
+
if (error instanceof Error) {
|
|
1015
|
+
if (error.message.includes("INSUFFICIENT_BALANCE")) {
|
|
1016
|
+
console.error("Not enough collateral to place order");
|
|
1017
|
+
} else if (error.message.includes("TRANSACTION_EXPIRED")) {
|
|
1018
|
+
console.error("Transaction took too long - retry with higher gas");
|
|
1019
|
+
} else {
|
|
1020
|
+
console.error("Unexpected error:", error.message);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
### 2. Gas Management
|
|
1028
|
+
|
|
1029
|
+
- Use `skipSimulate: false` for gas estimation in production
|
|
1030
|
+
- Set appropriate gas limits for complex transactions
|
|
1031
|
+
- Monitor gas prices and adjust accordingly
|
|
1032
|
+
|
|
1033
|
+
### 3. Subaccount Management
|
|
1034
|
+
|
|
1035
|
+
- Use primary subaccount for simple use cases
|
|
1036
|
+
- Create separate subaccounts for different strategies
|
|
1037
|
+
- Always verify subaccount addresses before transactions
|
|
1038
|
+
|
|
1039
|
+
### 4. Market Address Handling
|
|
1040
|
+
|
|
1041
|
+
- Cache market addresses to avoid repeated calculations
|
|
1042
|
+
- Verify market names are correct before generating addresses
|
|
1043
|
+
- Handle market address resolution errors gracefully
|
|
1044
|
+
|
|
1045
|
+
### 5. Order Management
|
|
1046
|
+
|
|
1047
|
+
- Store order IDs for later cancellation
|
|
1048
|
+
- Use client order IDs for easier tracking
|
|
1049
|
+
- Implement proper order status monitoring
|