@mysten/deepbook-v3 1.1.4 → 1.2.0

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 (116) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/client.d.mts +58 -763
  3. package/dist/client.d.mts.map +1 -1
  4. package/dist/client.mjs +253 -2127
  5. package/dist/client.mjs.map +1 -1
  6. package/dist/contracts/utils/index.mjs +1 -1
  7. package/dist/index.d.mts +4 -4
  8. package/dist/index.mjs +4 -4
  9. package/dist/pyth/pyth.mjs +1 -1
  10. package/dist/queries/accountQueries.mjs +104 -0
  11. package/dist/queries/accountQueries.mjs.map +1 -0
  12. package/dist/queries/balanceManagerQueries.mjs +113 -0
  13. package/dist/queries/balanceManagerQueries.mjs.map +1 -0
  14. package/dist/queries/context.mjs +15 -0
  15. package/dist/queries/context.mjs.map +1 -0
  16. package/dist/queries/marginManagerQueries.mjs +365 -0
  17. package/dist/queries/marginManagerQueries.mjs.map +1 -0
  18. package/dist/queries/marginPoolQueries.mjs +184 -0
  19. package/dist/queries/marginPoolQueries.mjs.map +1 -0
  20. package/dist/queries/orderQueries.mjs +165 -0
  21. package/dist/queries/orderQueries.mjs.map +1 -0
  22. package/dist/queries/poolQueries.mjs +234 -0
  23. package/dist/queries/poolQueries.mjs.map +1 -0
  24. package/dist/queries/priceFeedQueries.mjs +83 -0
  25. package/dist/queries/priceFeedQueries.mjs.map +1 -0
  26. package/dist/queries/quantityQueries.mjs +216 -0
  27. package/dist/queries/quantityQueries.mjs.map +1 -0
  28. package/dist/queries/referralQueries.mjs +96 -0
  29. package/dist/queries/referralQueries.mjs.map +1 -0
  30. package/dist/queries/registryQueries.mjs +162 -0
  31. package/dist/queries/registryQueries.mjs.map +1 -0
  32. package/dist/queries/tpslQueries.mjs +62 -0
  33. package/dist/queries/tpslQueries.mjs.map +1 -0
  34. package/dist/transactions/balanceManager.d.mts.map +1 -1
  35. package/dist/transactions/balanceManager.mjs +5 -4
  36. package/dist/transactions/balanceManager.mjs.map +1 -1
  37. package/dist/transactions/deepbook.d.mts +24 -24
  38. package/dist/transactions/deepbook.d.mts.map +1 -1
  39. package/dist/transactions/deepbook.mjs +48 -47
  40. package/dist/transactions/deepbook.mjs.map +1 -1
  41. package/dist/transactions/deepbookAdmin.d.mts +2 -2
  42. package/dist/transactions/deepbookAdmin.d.mts.map +1 -1
  43. package/dist/transactions/deepbookAdmin.mjs +10 -9
  44. package/dist/transactions/deepbookAdmin.mjs.map +1 -1
  45. package/dist/transactions/flashLoans.d.mts.map +1 -1
  46. package/dist/transactions/flashLoans.mjs +6 -4
  47. package/dist/transactions/flashLoans.mjs.map +1 -1
  48. package/dist/transactions/governance.d.mts.map +1 -1
  49. package/dist/transactions/governance.mjs +5 -4
  50. package/dist/transactions/governance.mjs.map +1 -1
  51. package/dist/transactions/marginAdmin.d.mts +7 -7
  52. package/dist/transactions/marginAdmin.d.mts.map +1 -1
  53. package/dist/transactions/marginAdmin.mjs +8 -7
  54. package/dist/transactions/marginAdmin.mjs.map +1 -1
  55. package/dist/transactions/marginLiquidations.d.mts +3 -3
  56. package/dist/transactions/marginLiquidations.d.mts.map +1 -1
  57. package/dist/transactions/marginLiquidations.mjs +5 -4
  58. package/dist/transactions/marginLiquidations.mjs.map +1 -1
  59. package/dist/transactions/marginMaintainer.d.mts +5 -5
  60. package/dist/transactions/marginMaintainer.d.mts.map +1 -1
  61. package/dist/transactions/marginMaintainer.mjs +15 -14
  62. package/dist/transactions/marginMaintainer.mjs.map +1 -1
  63. package/dist/transactions/marginManager.d.mts +23 -23
  64. package/dist/transactions/marginManager.d.mts.map +1 -1
  65. package/dist/transactions/marginManager.mjs +12 -11
  66. package/dist/transactions/marginManager.mjs.map +1 -1
  67. package/dist/transactions/marginPool.d.mts.map +1 -1
  68. package/dist/transactions/marginPool.mjs +3 -2
  69. package/dist/transactions/marginPool.mjs.map +1 -1
  70. package/dist/transactions/marginRegistry.d.mts +15 -15
  71. package/dist/transactions/marginTPSL.d.mts +1 -1
  72. package/dist/transactions/marginTPSL.d.mts.map +1 -1
  73. package/dist/transactions/marginTPSL.mjs +6 -8
  74. package/dist/transactions/marginTPSL.mjs.map +1 -1
  75. package/dist/transactions/poolProxy.d.mts.map +1 -1
  76. package/dist/transactions/poolProxy.mjs +13 -13
  77. package/dist/transactions/poolProxy.mjs.map +1 -1
  78. package/dist/types/index.d.mts +189 -52
  79. package/dist/types/index.d.mts.map +1 -1
  80. package/dist/types/index.mjs.map +1 -1
  81. package/dist/utils/constants.d.mts.map +1 -1
  82. package/dist/utils/constants.mjs +10 -0
  83. package/dist/utils/constants.mjs.map +1 -1
  84. package/dist/utils/conversion.mjs +26 -0
  85. package/dist/utils/conversion.mjs.map +1 -0
  86. package/package.json +5 -4
  87. package/src/client.ts +421 -2662
  88. package/src/index.ts +27 -0
  89. package/src/queries/accountQueries.ts +117 -0
  90. package/src/queries/balanceManagerQueries.ts +156 -0
  91. package/src/queries/context.ts +44 -0
  92. package/src/queries/index.ts +16 -0
  93. package/src/queries/marginManagerQueries.ts +575 -0
  94. package/src/queries/marginPoolQueries.ts +226 -0
  95. package/src/queries/orderQueries.ts +202 -0
  96. package/src/queries/poolQueries.ts +266 -0
  97. package/src/queries/priceFeedQueries.ts +141 -0
  98. package/src/queries/quantityQueries.ts +266 -0
  99. package/src/queries/referralQueries.ts +112 -0
  100. package/src/queries/registryQueries.ts +185 -0
  101. package/src/queries/tpslQueries.ts +88 -0
  102. package/src/transactions/balanceManager.ts +5 -4
  103. package/src/transactions/deepbook.ts +98 -84
  104. package/src/transactions/deepbookAdmin.ts +10 -9
  105. package/src/transactions/flashLoans.ts +5 -4
  106. package/src/transactions/governance.ts +5 -4
  107. package/src/transactions/marginAdmin.ts +8 -7
  108. package/src/transactions/marginLiquidations.ts +5 -4
  109. package/src/transactions/marginMaintainer.ts +15 -14
  110. package/src/transactions/marginManager.ts +12 -11
  111. package/src/transactions/marginPool.ts +3 -2
  112. package/src/transactions/marginTPSL.ts +11 -6
  113. package/src/transactions/poolProxy.ts +12 -11
  114. package/src/types/index.ts +200 -53
  115. package/src/utils/constants.ts +10 -0
  116. package/src/utils/conversion.ts +33 -0
package/src/client.ts CHANGED
@@ -1,40 +1,65 @@
1
1
  // Copyright (c) Mysten Labs, Inc.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { bcs } from '@mysten/sui/bcs';
4
- import { Account, Order, OrderDeepPrice, VecSet } from './types/bcs.js';
5
- import type { ClientWithCoreApi, SuiClientRegistration, SuiClientTypes } from '@mysten/sui/client';
6
- import { Transaction } from '@mysten/sui/transactions';
7
- import { normalizeSuiAddress } from '@mysten/sui/utils';
8
3
 
4
+ import type { ClientWithCoreApi, SuiClientRegistration, SuiClientTypes } from '@mysten/sui/client';
5
+ import type { Transaction } from '@mysten/sui/transactions';
6
+
7
+ import type { QueryContext } from './queries/context.js';
8
+ import { AccountQueries } from './queries/accountQueries.js';
9
+ import { BalanceManagerQueries } from './queries/balanceManagerQueries.js';
10
+ import { MarginManagerQueries } from './queries/marginManagerQueries.js';
11
+ import { MarginPoolQueries } from './queries/marginPoolQueries.js';
12
+ import { OrderQueries } from './queries/orderQueries.js';
13
+ import { PoolQueries } from './queries/poolQueries.js';
14
+ import { PriceFeedQueries } from './queries/priceFeedQueries.js';
15
+ import { QuantityQueries } from './queries/quantityQueries.js';
16
+ import { ReferralQueries } from './queries/referralQueries.js';
17
+ import { RegistryQueries } from './queries/registryQueries.js';
18
+ import { TPSLQueries } from './queries/tpslQueries.js';
9
19
  import { BalanceManagerContract } from './transactions/balanceManager.js';
10
20
  import { DeepBookContract } from './transactions/deepbook.js';
11
21
  import { DeepBookAdminContract } from './transactions/deepbookAdmin.js';
12
22
  import { FlashLoanContract } from './transactions/flashLoans.js';
13
23
  import { GovernanceContract } from './transactions/governance.js';
14
- import type {
15
- BalanceManager,
16
- MarginManager,
17
- CanPlaceLimitOrderParams,
18
- CanPlaceMarketOrderParams,
19
- } from './types/index.js';
20
- import {
21
- DEEP_SCALAR,
22
- DeepBookConfig,
23
- FLOAT_SCALAR,
24
- PRICE_INFO_OBJECT_MAX_AGE_MS,
25
- } from './utils/config.js';
26
- import type { CoinMap, PoolMap, DeepbookPackageIds } from './utils/constants.js';
27
24
  import { MarginAdminContract } from './transactions/marginAdmin.js';
25
+ import { MarginLiquidationsContract } from './transactions/marginLiquidations.js';
28
26
  import { MarginMaintainerContract } from './transactions/marginMaintainer.js';
29
- import { MarginPoolContract } from './transactions/marginPool.js';
30
27
  import { MarginManagerContract } from './transactions/marginManager.js';
28
+ import { MarginPoolContract } from './transactions/marginPool.js';
31
29
  import { MarginRegistryContract } from './transactions/marginRegistry.js';
32
- import { MarginLiquidationsContract } from './transactions/marginLiquidations.js';
33
- import { SuiPriceServiceConnection } from './pyth/pyth.js';
34
- import { SuiPythClient } from './pyth/pyth.js';
35
- import { PriceInfoObject } from './contracts/pyth/price_info.js';
36
- import { PoolProxyContract } from './transactions/poolProxy.js';
37
30
  import { MarginTPSLContract } from './transactions/marginTPSL.js';
31
+ import { PoolProxyContract } from './transactions/poolProxy.js';
32
+ import type {
33
+ AccountInfo,
34
+ BalanceManager,
35
+ BaseQuantityIn,
36
+ BaseQuantityOut,
37
+ BorrowedShares,
38
+ CanPlaceLimitOrderParams,
39
+ CanPlaceMarketOrderParams,
40
+ DecodedOrderId,
41
+ Level2Range,
42
+ Level2TicksFromMid,
43
+ LockedBalances,
44
+ ManagerBalance,
45
+ MarginManager,
46
+ MarginManagerAssets,
47
+ MarginManagerBalancesResult,
48
+ MarginManagerDebts,
49
+ MarginManagerState,
50
+ OrderDeepRequiredResult,
51
+ PoolBookParams,
52
+ PoolDeepPrice,
53
+ PoolTradeParams,
54
+ QuantityOut,
55
+ QuoteQuantityIn,
56
+ QuoteQuantityOut,
57
+ ReferralBalances,
58
+ VaultBalances,
59
+ } from './types/index.js';
60
+ import { DeepBookConfig } from './utils/config.js';
61
+ import type { CoinMap, DeepbookPackageIds, PoolMap } from './utils/constants.js';
62
+ import { normalizeSuiAddress } from '@mysten/sui/utils';
38
63
 
39
64
  export interface DeepBookCompatibleClient extends ClientWithCoreApi {}
40
65
 
@@ -77,9 +102,18 @@ export function deepbook<Name extends string = 'deepbook'>({
77
102
  * DeepBookClient class for managing DeepBook operations.
78
103
  */
79
104
  export class DeepBookClient {
80
- #client: DeepBookCompatibleClient;
81
- #config: DeepBookConfig;
82
- #address: string;
105
+ #balanceManagerQueries: BalanceManagerQueries;
106
+ #poolQueries: PoolQueries;
107
+ #quantityQueries: QuantityQueries;
108
+ #orderQueries: OrderQueries;
109
+ #accountQueries: AccountQueries;
110
+ #referralQueries: ReferralQueries;
111
+ #priceFeedQueries: PriceFeedQueries;
112
+ #marginPoolQueries: MarginPoolQueries;
113
+ #marginManagerQueries: MarginManagerQueries;
114
+ #tpslQueries: TPSLQueries;
115
+ #registryQueries: RegistryQueries;
116
+
83
117
  balanceManager: BalanceManagerContract;
84
118
  deepBook: DeepBookContract;
85
119
  deepBookAdmin: DeepBookAdminContract;
@@ -111,10 +145,9 @@ export class DeepBookClient {
111
145
  packageIds,
112
146
  pyth,
113
147
  }: DeepBookClientOptions) {
114
- this.#client = client;
115
- this.#address = normalizeSuiAddress(address);
116
- this.#config = new DeepBookConfig({
117
- address: this.#address,
148
+ const normalizedAddress = normalizeSuiAddress(address);
149
+ const config = new DeepBookConfig({
150
+ address: normalizedAddress,
118
151
  network,
119
152
  balanceManagers,
120
153
  marginManagers,
@@ -126,2779 +159,505 @@ export class DeepBookClient {
126
159
  packageIds,
127
160
  pyth,
128
161
  });
129
- this.balanceManager = new BalanceManagerContract(this.#config);
130
- this.deepBook = new DeepBookContract(this.#config);
131
- this.deepBookAdmin = new DeepBookAdminContract(this.#config);
132
- this.flashLoans = new FlashLoanContract(this.#config);
133
- this.governance = new GovernanceContract(this.#config);
134
- this.marginAdmin = new MarginAdminContract(this.#config);
135
- this.marginMaintainer = new MarginMaintainerContract(this.#config);
136
- this.marginPool = new MarginPoolContract(this.#config);
137
- this.marginManager = new MarginManagerContract(this.#config);
138
- this.marginRegistry = new MarginRegistryContract(this.#config);
139
- this.marginLiquidations = new MarginLiquidationsContract(this.#config);
140
- this.poolProxy = new PoolProxyContract(this.#config);
141
- this.marginTPSL = new MarginTPSLContract(this.#config);
142
- }
143
-
144
- /**
145
- * @description Check the balance of a balance manager for a specific coin
146
- * @param {string} managerKey Key of the balance manager
147
- * @param {string} coinKey Key of the coin
148
- * @returns {Promise<{ coinType: string, balance: number }>} An object with coin type and balance
149
- */
150
- async checkManagerBalance(managerKey: string, coinKey: string) {
151
- const tx = new Transaction();
152
- const coin = this.#config.getCoin(coinKey);
153
-
154
- tx.add(this.balanceManager.checkManagerBalance(managerKey, coinKey));
155
- const res = await this.#client.core.simulateTransaction({
156
- transaction: tx,
157
- include: { commandResults: true, effects: true },
158
- });
159
162
 
160
- const bytes = res.commandResults![0].returnValues[0].bcs;
161
- const parsed_balance = bcs.U64.parse(bytes);
162
- const balanceNumber = Number(parsed_balance);
163
- const adjusted_balance = balanceNumber / coin.scalar;
164
-
165
- return {
166
- coinType: coin.type,
167
- balance: Number(adjusted_balance.toFixed(9)),
163
+ this.balanceManager = new BalanceManagerContract(config);
164
+ this.deepBook = new DeepBookContract(config);
165
+ this.deepBookAdmin = new DeepBookAdminContract(config);
166
+ this.flashLoans = new FlashLoanContract(config);
167
+ this.governance = new GovernanceContract(config);
168
+ this.marginAdmin = new MarginAdminContract(config);
169
+ this.marginMaintainer = new MarginMaintainerContract(config);
170
+ this.marginPool = new MarginPoolContract(config);
171
+ this.marginManager = new MarginManagerContract(config);
172
+ this.marginRegistry = new MarginRegistryContract(config);
173
+ this.marginLiquidations = new MarginLiquidationsContract(config);
174
+ this.poolProxy = new PoolProxyContract(config);
175
+ this.marginTPSL = new MarginTPSLContract(config);
176
+
177
+ const ctx: QueryContext = {
178
+ client,
179
+ config,
180
+ address: normalizedAddress,
181
+ balanceManager: this.balanceManager,
182
+ deepBook: this.deepBook,
183
+ marginManager: this.marginManager,
184
+ marginPool: this.marginPool,
185
+ marginRegistry: this.marginRegistry,
186
+ marginTPSL: this.marginTPSL,
168
187
  };
169
- }
170
-
171
- /**
172
- * @description Check the balance of a BalanceManager by its address directly
173
- * @param {string} managerAddress The on-chain address of the BalanceManager
174
- * @param {string} coinKey Key of the coin
175
- * @returns {Promise<{ coinType: string, balance: number }>} An object with coin type and balance
176
- */
177
- async checkManagerBalanceWithAddress(managerAddress: string, coinKey: string) {
178
- const tx = new Transaction();
179
- const coin = this.#config.getCoin(coinKey);
180
-
181
- tx.moveCall({
182
- target: `${this.#config.DEEPBOOK_PACKAGE_ID}::balance_manager::balance`,
183
- arguments: [tx.object(managerAddress)],
184
- typeArguments: [coin.type],
185
- });
186
-
187
- const res = await this.#client.core.simulateTransaction({
188
- transaction: tx,
189
- include: { commandResults: true, effects: true },
190
- });
191
188
 
192
- const bytes = res.commandResults![0].returnValues[0].bcs;
193
- const parsed_balance = bcs.U64.parse(bytes);
194
- const balanceNumber = Number(parsed_balance);
195
- const adjusted_balance = balanceNumber / coin.scalar;
196
-
197
- return {
198
- coinType: coin.type,
199
- balance: Number(adjusted_balance.toFixed(9)),
200
- };
189
+ this.#balanceManagerQueries = new BalanceManagerQueries(ctx);
190
+ this.#poolQueries = new PoolQueries(ctx);
191
+ this.#quantityQueries = new QuantityQueries(ctx);
192
+ this.#orderQueries = new OrderQueries(ctx);
193
+ this.#accountQueries = new AccountQueries(ctx);
194
+ this.#referralQueries = new ReferralQueries(ctx);
195
+ this.#priceFeedQueries = new PriceFeedQueries(ctx);
196
+ this.#marginPoolQueries = new MarginPoolQueries(ctx);
197
+ this.#marginManagerQueries = new MarginManagerQueries(ctx);
198
+ this.#tpslQueries = new TPSLQueries(ctx);
199
+ this.#registryQueries = new RegistryQueries(ctx);
201
200
  }
202
201
 
203
- /**
204
- * @description Check multiple coin balances for multiple balance managers by address in a single dry run call
205
- * @param {string[]} managerAddresses The on-chain addresses of the BalanceManagers
206
- * @param {string[]} coinKeys Keys of the coins to check balances for
207
- * @returns {Promise<Record<string, Record<string, number>>>} Object keyed by manager address, mapping coinType to balance
208
- */
209
- async checkManagerBalancesWithAddress(managerAddresses: string[], coinKeys: string[]) {
210
- if (managerAddresses.length === 0 || coinKeys.length === 0) {
211
- return {};
212
- }
213
-
214
- const tx = new Transaction();
215
- const coins = coinKeys.map((coinKey) => this.#config.getCoin(coinKey));
216
-
217
- for (const managerAddress of managerAddresses) {
218
- for (const coin of coins) {
219
- tx.moveCall({
220
- target: `${this.#config.DEEPBOOK_PACKAGE_ID}::balance_manager::balance`,
221
- arguments: [tx.object(managerAddress)],
222
- typeArguments: [coin.type],
223
- });
224
- }
225
- }
226
-
227
- const res = await this.#client.core.simulateTransaction({
228
- transaction: tx,
229
- include: { commandResults: true, effects: true },
230
- });
231
-
232
- if (res.FailedTransaction) {
233
- throw new Error(
234
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
235
- );
236
- }
202
+ // === Balance Manager Queries ===
237
203
 
238
- if (!res.commandResults) {
239
- throw new Error('Failed to get manager balances: No command results');
240
- }
241
-
242
- const results: Record<string, Record<string, number>> = {};
204
+ checkManagerBalance(managerKey: string, coinKey: string): Promise<ManagerBalance> {
205
+ return this.#balanceManagerQueries.checkManagerBalance(managerKey, coinKey);
206
+ }
243
207
 
244
- for (let m = 0; m < managerAddresses.length; m++) {
245
- const managerAddress = managerAddresses[m];
246
- const managerBalances: Record<string, number> = {};
208
+ checkManagerBalanceWithAddress(managerAddress: string, coinKey: string): Promise<ManagerBalance> {
209
+ return this.#balanceManagerQueries.checkManagerBalanceWithAddress(managerAddress, coinKey);
210
+ }
247
211
 
248
- for (let c = 0; c < coins.length; c++) {
249
- const coin = coins[c];
250
- const commandResult = res.commandResults[m * coins.length + c];
212
+ checkManagerBalancesWithAddress(
213
+ managerAddresses: string[],
214
+ coinKeys: string[],
215
+ ): Promise<Record<string, Record<string, number>>> {
216
+ return this.#balanceManagerQueries.checkManagerBalancesWithAddress(managerAddresses, coinKeys);
217
+ }
251
218
 
252
- if (!commandResult || !commandResult.returnValues) {
253
- throw new Error(`Failed to get balance for ${coin.type}: No return values`);
254
- }
219
+ getBalanceManagerIds(owner: string): Promise<string[]> {
220
+ return this.#balanceManagerQueries.getBalanceManagerIds(owner);
221
+ }
255
222
 
256
- const bytes = commandResult.returnValues[0].bcs;
257
- const parsed_balance = bcs.U64.parse(bytes);
258
- managerBalances[coin.type] = Number((Number(parsed_balance) / coin.scalar).toFixed(9));
259
- }
223
+ accountExists(poolKey: string, managerKey: string): Promise<boolean> {
224
+ return this.#balanceManagerQueries.accountExists(poolKey, managerKey);
225
+ }
260
226
 
261
- results[managerAddress] = managerBalances;
262
- }
227
+ // === Pool Queries ===
263
228
 
264
- return results;
229
+ whitelisted(poolKey: string): Promise<boolean> {
230
+ return this.#poolQueries.whitelisted(poolKey);
265
231
  }
266
232
 
267
- /**
268
- * @description Check if a pool is whitelisted
269
- * @param {string} poolKey Key of the pool
270
- * @returns {Promise<boolean>} Boolean indicating if the pool is whitelisted
271
- */
272
- async whitelisted(poolKey: string) {
273
- const tx = new Transaction();
274
-
275
- tx.add(this.deepBook.whitelisted(poolKey));
276
- const res = await this.#client.core.simulateTransaction({
277
- transaction: tx,
278
- include: { commandResults: true, effects: true },
279
- });
233
+ vaultBalances(poolKey: string): Promise<VaultBalances> {
234
+ return this.#poolQueries.vaultBalances(poolKey);
235
+ }
280
236
 
281
- const bytes = res.commandResults![0].returnValues[0].bcs;
282
- const whitelisted = bcs.Bool.parse(bytes);
237
+ getPoolIdByAssets(baseType: string, quoteType: string): Promise<string> {
238
+ return this.#poolQueries.getPoolIdByAssets(baseType, quoteType);
239
+ }
283
240
 
284
- return whitelisted;
241
+ midPrice(poolKey: string): Promise<number> {
242
+ return this.#poolQueries.midPrice(poolKey);
285
243
  }
286
244
 
287
- /**
288
- * @description Get the quote quantity out for a given base quantity
289
- * @param {string} poolKey Key of the pool
290
- * @param {number} baseQuantity Base quantity to convert
291
- * @returns {Promise<{ baseQuantity: number, baseOut: number, quoteOut: number, deepRequired: number }>}
292
- * An object with base quantity, base out, quote out, and deep required for the dry run
293
- */
294
- async getQuoteQuantityOut(poolKey: string, baseQuantity: number) {
295
- const tx = new Transaction();
296
- const pool = this.#config.getPool(poolKey);
297
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
298
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
299
-
300
- tx.add(this.deepBook.getQuoteQuantityOut(poolKey, baseQuantity));
301
- const res = await this.#client.core.simulateTransaction({
302
- transaction: tx,
303
- include: { commandResults: true, effects: true },
304
- });
245
+ poolTradeParams(poolKey: string): Promise<PoolTradeParams> {
246
+ return this.#poolQueries.poolTradeParams(poolKey);
247
+ }
305
248
 
306
- const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
307
- const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
308
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
249
+ poolBookParams(poolKey: string): Promise<PoolBookParams> {
250
+ return this.#poolQueries.poolBookParams(poolKey);
251
+ }
309
252
 
310
- return {
311
- baseQuantity,
312
- baseOut: Number((baseOut / baseScalar).toFixed(9)),
313
- quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
314
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
315
- };
253
+ stablePool(poolKey: string): Promise<boolean> {
254
+ return this.#poolQueries.stablePool(poolKey);
316
255
  }
317
256
 
318
- /**
319
- * @description Get the base quantity out for a given quote quantity
320
- * @param {string} poolKey Key of the pool
321
- * @param {number} quoteQuantity Quote quantity to convert
322
- * @returns {Promise<{ quoteQuantity: number, baseOut: number, quoteOut: number, deepRequired: number }>}
323
- * An object with quote quantity, base out, quote out, and deep required for the dry run
324
- */
325
- async getBaseQuantityOut(poolKey: string, quoteQuantity: number) {
326
- const tx = new Transaction();
327
- const pool = this.#config.getPool(poolKey);
328
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
329
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
330
-
331
- tx.add(this.deepBook.getBaseQuantityOut(poolKey, quoteQuantity));
332
- const res = await this.#client.core.simulateTransaction({
333
- transaction: tx,
334
- include: { commandResults: true, effects: true },
335
- });
257
+ registeredPool(poolKey: string): Promise<boolean> {
258
+ return this.#poolQueries.registeredPool(poolKey);
259
+ }
336
260
 
337
- const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
338
- const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
339
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
261
+ poolTradeParamsNext(poolKey: string): Promise<PoolTradeParams> {
262
+ return this.#poolQueries.poolTradeParamsNext(poolKey);
263
+ }
340
264
 
341
- return {
342
- quoteQuantity: quoteQuantity,
343
- baseOut: Number((baseOut / baseScalar).toFixed(9)),
344
- quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
345
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
346
- };
265
+ quorum(poolKey: string): Promise<number> {
266
+ return this.#poolQueries.quorum(poolKey);
347
267
  }
348
268
 
349
- /**
350
- * @description Get the output quantities for given base and quote quantities. Only one quantity can be non-zero
351
- * @param {string} poolKey Key of the pool
352
- * @param {number} baseQuantity Base quantity to convert
353
- * @param {number} quoteQuantity Quote quantity to convert
354
- * @returns {Promise<{ baseQuantity: number, quoteQuantity: number, baseOut: number, quoteOut: number, deepRequired: number }>}
355
- * An object with base quantity, quote quantity, base out, quote out, and deep required for the dry run
356
- */
357
- async getQuantityOut(poolKey: string, baseQuantity: number, quoteQuantity: number) {
358
- const tx = new Transaction();
359
- const pool = this.#config.getPool(poolKey);
360
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
361
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
362
-
363
- tx.add(this.deepBook.getQuantityOut(poolKey, baseQuantity, quoteQuantity));
364
- const res = await this.#client.core.simulateTransaction({
365
- transaction: tx,
366
- include: { commandResults: true, effects: true },
367
- });
269
+ poolId(poolKey: string): Promise<string> {
270
+ return this.#poolQueries.poolId(poolKey);
271
+ }
368
272
 
369
- const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
370
- const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
371
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
273
+ canPlaceLimitOrder(params: CanPlaceLimitOrderParams): Promise<boolean> {
274
+ return this.#poolQueries.canPlaceLimitOrder(params);
275
+ }
372
276
 
373
- return {
374
- baseQuantity,
375
- quoteQuantity,
376
- baseOut: Number((baseOut / baseScalar).toFixed(9)),
377
- quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
378
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
379
- };
277
+ canPlaceMarketOrder(params: CanPlaceMarketOrderParams): Promise<boolean> {
278
+ return this.#poolQueries.canPlaceMarketOrder(params);
380
279
  }
381
280
 
382
- /**
383
- * @description Get open orders for a balance manager in a pool
384
- * @param {string} poolKey Key of the pool
385
- * @param {string} managerKey Key of the balance manager
386
- * @returns {Promise<Array>} An array of open order IDs
387
- */
388
- async accountOpenOrders(poolKey: string, managerKey: string) {
389
- const tx = new Transaction();
281
+ checkMarketOrderParams(poolKey: string, quantity: number | bigint): Promise<boolean> {
282
+ return this.#poolQueries.checkMarketOrderParams(poolKey, quantity);
283
+ }
390
284
 
391
- tx.add(this.deepBook.accountOpenOrders(poolKey, managerKey));
392
- const res = await this.#client.core.simulateTransaction({
393
- transaction: tx,
394
- include: { commandResults: true, effects: true },
395
- });
285
+ checkLimitOrderParams(
286
+ poolKey: string,
287
+ price: number | bigint,
288
+ quantity: number | bigint,
289
+ expireTimestamp: number,
290
+ ): Promise<boolean> {
291
+ return this.#poolQueries.checkLimitOrderParams(poolKey, price, quantity, expireTimestamp);
292
+ }
396
293
 
397
- const order_ids = res.commandResults![0].returnValues[0].bcs;
294
+ // === Quantity Queries ===
398
295
 
399
- return VecSet(bcs.u128()).parse(new Uint8Array(order_ids)).contents;
296
+ getQuoteQuantityOut(poolKey: string, baseQuantity: number | bigint): Promise<QuoteQuantityOut> {
297
+ return this.#quantityQueries.getQuoteQuantityOut(poolKey, baseQuantity);
400
298
  }
401
299
 
402
- /**
403
- * @description Get the order information for a specific order in a pool
404
- * @param {string} poolKey Key of the pool
405
- * @param {string} orderId Order ID
406
- * @returns {Promise<Object>} A promise that resolves to an object containing the order information
407
- */
408
- async getOrder(poolKey: string, orderId: string) {
409
- const tx = new Transaction();
300
+ getBaseQuantityOut(poolKey: string, quoteQuantity: number | bigint): Promise<BaseQuantityOut> {
301
+ return this.#quantityQueries.getBaseQuantityOut(poolKey, quoteQuantity);
302
+ }
410
303
 
411
- tx.add(this.deepBook.getOrder(poolKey, orderId));
412
- const res = await this.#client.core.simulateTransaction({
413
- transaction: tx,
414
- include: { commandResults: true, effects: true },
415
- });
304
+ getQuantityOut(
305
+ poolKey: string,
306
+ baseQuantity: number | bigint,
307
+ quoteQuantity: number | bigint,
308
+ ): Promise<QuantityOut> {
309
+ return this.#quantityQueries.getQuantityOut(poolKey, baseQuantity, quoteQuantity);
310
+ }
416
311
 
417
- try {
418
- const orderInformation = res.commandResults![0].returnValues[0].bcs;
419
- return Order.parse(new Uint8Array(orderInformation));
420
- } catch {
421
- return null;
422
- }
312
+ getQuoteQuantityOutInputFee(
313
+ poolKey: string,
314
+ baseQuantity: number | bigint,
315
+ ): Promise<QuoteQuantityOut> {
316
+ return this.#quantityQueries.getQuoteQuantityOutInputFee(poolKey, baseQuantity);
423
317
  }
424
318
 
425
- /**
426
- * @description Get the order information for a specific order in a pool, with normalized price
427
- * @param {string} poolKey Key of the pool
428
- * @param {string} orderId Order ID
429
- * @returns {Promise<Object>} A promise that resolves to an object containing the order information with normalized price
430
- */
431
- async getOrderNormalized(poolKey: string, orderId: string) {
432
- const tx = new Transaction();
433
- tx.add(this.deepBook.getOrder(poolKey, orderId));
434
- const res = await this.#client.core.simulateTransaction({
435
- transaction: tx,
436
- include: { commandResults: true, effects: true },
437
- });
319
+ getBaseQuantityOutInputFee(
320
+ poolKey: string,
321
+ quoteQuantity: number | bigint,
322
+ ): Promise<BaseQuantityOut> {
323
+ return this.#quantityQueries.getBaseQuantityOutInputFee(poolKey, quoteQuantity);
324
+ }
438
325
 
439
- try {
440
- const orderInformation = res.commandResults![0].returnValues[0].bcs;
441
- const orderInfo = Order.parse(new Uint8Array(orderInformation));
442
-
443
- if (!orderInfo) {
444
- return null;
445
- }
446
- const baseCoin = this.#config.getCoin(this.#config.getPool(poolKey).baseCoin);
447
- const quoteCoin = this.#config.getCoin(this.#config.getPool(poolKey).quoteCoin);
448
- const { isBid, price: rawPrice } = this.decodeOrderId(BigInt(orderInfo.order_id));
449
- const normalizedPrice = (rawPrice * baseCoin.scalar) / quoteCoin.scalar / FLOAT_SCALAR;
450
-
451
- const normalizedOrderInfo = {
452
- ...orderInfo,
453
- quantity: String((Number(orderInfo.quantity) / baseCoin.scalar).toFixed(9)),
454
- filled_quantity: String((Number(orderInfo.filled_quantity) / baseCoin.scalar).toFixed(9)),
455
- order_deep_price: {
456
- ...orderInfo.order_deep_price,
457
- deep_per_asset: String(
458
- (Number(orderInfo.order_deep_price.deep_per_asset) / DEEP_SCALAR).toFixed(9),
459
- ),
460
- },
461
- isBid,
462
- normalized_price: normalizedPrice.toFixed(9),
463
- };
464
- return normalizedOrderInfo;
465
- } catch {
466
- return null;
467
- }
326
+ getQuantityOutInputFee(
327
+ poolKey: string,
328
+ baseQuantity: number | bigint,
329
+ quoteQuantity: number | bigint,
330
+ ): Promise<QuantityOut> {
331
+ return this.#quantityQueries.getQuantityOutInputFee(poolKey, baseQuantity, quoteQuantity);
468
332
  }
469
333
 
470
- /**
471
- * @description Retrieves information for multiple specific orders in a pool.
472
- * @param {string} poolKey - The key identifying the pool from which to retrieve order information.
473
- * @param {string[]} orderIds - List of order IDs to retrieve information for.
474
- * @returns {Promise<Object[] | null>} A promise that resolves to an array of order objects, each containing details such as
475
- * balance manager ID, order ID, client order ID, quantity, filled quantity, fee information, order price, epoch, status,
476
- * and expiration timestamp. Returns `null` if the retrieval fails.
477
- */
478
- async getOrders(poolKey: string, orderIds: string[]) {
479
- const tx = new Transaction();
334
+ getBaseQuantityIn(
335
+ poolKey: string,
336
+ targetQuoteQuantity: number | bigint,
337
+ payWithDeep: boolean,
338
+ ): Promise<BaseQuantityIn> {
339
+ return this.#quantityQueries.getBaseQuantityIn(poolKey, targetQuoteQuantity, payWithDeep);
340
+ }
480
341
 
481
- tx.add(this.deepBook.getOrders(poolKey, orderIds));
482
- const res = await this.#client.core.simulateTransaction({
483
- transaction: tx,
484
- include: { commandResults: true, effects: true },
485
- });
342
+ getQuoteQuantityIn(
343
+ poolKey: string,
344
+ targetBaseQuantity: number | bigint,
345
+ payWithDeep: boolean,
346
+ ): Promise<QuoteQuantityIn> {
347
+ return this.#quantityQueries.getQuoteQuantityIn(poolKey, targetBaseQuantity, payWithDeep);
348
+ }
486
349
 
487
- try {
488
- const orderInformation = res.commandResults![0].returnValues[0].bcs;
489
- return bcs.vector(Order).parse(new Uint8Array(orderInformation));
490
- } catch {
491
- return null;
492
- }
350
+ getOrderDeepRequired(
351
+ poolKey: string,
352
+ baseQuantity: number | bigint,
353
+ price: number | bigint,
354
+ ): Promise<OrderDeepRequiredResult> {
355
+ return this.#quantityQueries.getOrderDeepRequired(poolKey, baseQuantity, price);
493
356
  }
494
357
 
495
- /**
496
- * @description Get level 2 order book specifying range of price
497
- * @param {string} poolKey Key of the pool
498
- * @param {number} priceLow Lower bound of the price range
499
- * @param {number} priceHigh Upper bound of the price range
500
- * @param {boolean} isBid Whether to get bid or ask orders
501
- * @returns {Promise<{ prices: Array<number>, quantities: Array<number> }>}
502
- * An object with arrays of prices and quantities
503
- */
504
- async getLevel2Range(poolKey: string, priceLow: number, priceHigh: number, isBid: boolean) {
505
- const tx = new Transaction();
506
- const pool = this.#config.getPool(poolKey);
507
- const baseCoin = this.#config.getCoin(pool.baseCoin);
508
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
509
-
510
- tx.add(this.deepBook.getLevel2Range(poolKey, priceLow, priceHigh, isBid));
511
- const res = await this.#client.core.simulateTransaction({
512
- transaction: tx,
513
- include: { commandResults: true, effects: true },
514
- });
358
+ // === Order Queries ===
515
359
 
516
- const prices = res.commandResults![0].returnValues[0].bcs;
517
- const parsed_prices = bcs.vector(bcs.u64()).parse(new Uint8Array(prices));
518
- const quantities = res.commandResults![0].returnValues[1].bcs;
519
- const parsed_quantities = bcs.vector(bcs.u64()).parse(new Uint8Array(quantities));
520
-
521
- return {
522
- prices: parsed_prices.map((price) =>
523
- Number(((Number(price) / FLOAT_SCALAR / quoteCoin.scalar) * baseCoin.scalar).toFixed(9)),
524
- ),
525
- quantities: parsed_quantities.map((price) =>
526
- Number((Number(price) / baseCoin.scalar).toFixed(9)),
527
- ),
528
- };
360
+ accountOpenOrders(poolKey: string, managerKey: string): Promise<string[]> {
361
+ return this.#orderQueries.accountOpenOrders(poolKey, managerKey);
529
362
  }
530
363
 
531
- /**
532
- * @description Get level 2 order book ticks from mid-price for a pool
533
- * @param {string} poolKey Key of the pool
534
- * @param {number} ticks Number of ticks from mid-price
535
- * @returns {Promise<{ bid_prices: Array<number>, bid_quantities: Array<number>, ask_prices: Array<number>, ask_quantities: Array<number> }>}
536
- * An object with arrays of prices and quantities
537
- */
538
- async getLevel2TicksFromMid(poolKey: string, ticks: number) {
539
- const tx = new Transaction();
540
- const pool = this.#config.getPool(poolKey);
541
- const baseCoin = this.#config.getCoin(pool.baseCoin);
542
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
543
-
544
- tx.add(this.deepBook.getLevel2TicksFromMid(poolKey, ticks));
545
- const res = await this.#client.core.simulateTransaction({
546
- transaction: tx,
547
- include: { commandResults: true, effects: true },
548
- });
549
-
550
- const bid_prices = res.commandResults![0].returnValues[0].bcs;
551
- const bid_parsed_prices = bcs.vector(bcs.u64()).parse(new Uint8Array(bid_prices));
552
- const bid_quantities = res.commandResults![0].returnValues[1].bcs;
553
- const bid_parsed_quantities = bcs.vector(bcs.u64()).parse(new Uint8Array(bid_quantities));
554
-
555
- const ask_prices = res.commandResults![0].returnValues[2].bcs;
556
- const ask_parsed_prices = bcs.vector(bcs.u64()).parse(new Uint8Array(ask_prices));
557
- const ask_quantities = res.commandResults![0].returnValues[3].bcs;
558
- const ask_parsed_quantities = bcs.vector(bcs.u64()).parse(new Uint8Array(ask_quantities));
559
-
560
- return {
561
- bid_prices: bid_parsed_prices.map((price) =>
562
- Number(((Number(price) / FLOAT_SCALAR / quoteCoin.scalar) * baseCoin.scalar).toFixed(9)),
563
- ),
564
- bid_quantities: bid_parsed_quantities.map((quantity) =>
565
- Number((Number(quantity) / baseCoin.scalar).toFixed(9)),
566
- ),
567
- ask_prices: ask_parsed_prices.map((price) =>
568
- Number(((Number(price) / FLOAT_SCALAR / quoteCoin.scalar) * baseCoin.scalar).toFixed(9)),
569
- ),
570
- ask_quantities: ask_parsed_quantities.map((quantity) =>
571
- Number((Number(quantity) / baseCoin.scalar).toFixed(9)),
572
- ),
573
- };
364
+ getOrder(poolKey: string, orderId: string) {
365
+ return this.#orderQueries.getOrder(poolKey, orderId);
574
366
  }
575
367
 
576
- /**
577
- * @description Get the vault balances for a pool
578
- * @param {string} poolKey Key of the pool
579
- * @returns {Promise<{ base: number, quote: number, deep: number }>}
580
- * An object with base, quote, and deep balances in the vault
581
- */
582
- async vaultBalances(poolKey: string) {
583
- const tx = new Transaction();
584
- const pool = this.#config.getPool(poolKey);
585
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
586
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
587
-
588
- tx.add(this.deepBook.vaultBalances(poolKey));
589
- const res = await this.#client.core.simulateTransaction({
590
- transaction: tx,
591
- include: { commandResults: true, effects: true },
592
- });
368
+ getOrderNormalized(poolKey: string, orderId: string) {
369
+ return this.#orderQueries.getOrderNormalized(poolKey, orderId);
370
+ }
593
371
 
594
- const baseInVault = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
595
- const quoteInVault = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
596
- const deepInVault = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
372
+ getOrders(poolKey: string, orderIds: string[]) {
373
+ return this.#orderQueries.getOrders(poolKey, orderIds);
374
+ }
597
375
 
598
- return {
599
- base: Number((baseInVault / baseScalar).toFixed(9)),
600
- quote: Number((quoteInVault / quoteScalar).toFixed(9)),
601
- deep: Number((deepInVault / DEEP_SCALAR).toFixed(9)),
602
- };
376
+ getLevel2Range(
377
+ poolKey: string,
378
+ priceLow: number | bigint,
379
+ priceHigh: number | bigint,
380
+ isBid: boolean,
381
+ ): Promise<Level2Range> {
382
+ return this.#orderQueries.getLevel2Range(poolKey, priceLow, priceHigh, isBid);
603
383
  }
604
384
 
605
- /**
606
- * @description Get the pool ID by asset types
607
- * @param {string} baseType Type of the base asset
608
- * @param {string} quoteType Type of the quote asset
609
- * @returns {Promise<string>} The address of the pool
610
- */
611
- async getPoolIdByAssets(baseType: string, quoteType: string) {
612
- const tx = new Transaction();
613
- tx.add(this.deepBook.getPoolIdByAssets(baseType, quoteType));
385
+ getLevel2TicksFromMid(poolKey: string, ticks: number): Promise<Level2TicksFromMid> {
386
+ return this.#orderQueries.getLevel2TicksFromMid(poolKey, ticks);
387
+ }
614
388
 
615
- const res = await this.#client.core.simulateTransaction({
616
- transaction: tx,
617
- include: { commandResults: true, effects: true },
618
- });
389
+ getAccountOrderDetails(poolKey: string, managerKey: string) {
390
+ return this.#orderQueries.getAccountOrderDetails(poolKey, managerKey);
391
+ }
619
392
 
620
- const address = bcs.Address.parse(res.commandResults![0].returnValues[0].bcs);
393
+ // === Account Queries ===
621
394
 
622
- return address;
395
+ account(poolKey: string, managerKey: string): Promise<AccountInfo> {
396
+ return this.#accountQueries.account(poolKey, managerKey);
623
397
  }
624
398
 
625
- /**
626
- * @description Get the mid price for a pool
627
- * @param {string} poolKey Key of the pool
628
- * @returns {Promise<number>} The mid price
629
- */
630
- async midPrice(poolKey: string) {
631
- const tx = new Transaction();
632
- const pool = this.#config.getPool(poolKey);
633
- tx.add(this.deepBook.midPrice(poolKey));
634
-
635
- const baseCoin = this.#config.getCoin(pool.baseCoin);
636
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
399
+ lockedBalance(poolKey: string, balanceManagerKey: string): Promise<LockedBalances> {
400
+ return this.#accountQueries.lockedBalance(poolKey, balanceManagerKey);
401
+ }
637
402
 
638
- const res = await this.#client.core.simulateTransaction({
639
- transaction: tx,
640
- include: { commandResults: true, effects: true },
641
- });
403
+ getPoolDeepPrice(poolKey: string): Promise<PoolDeepPrice> {
404
+ return this.#accountQueries.getPoolDeepPrice(poolKey);
405
+ }
642
406
 
643
- const bytes = res.commandResults![0].returnValues[0].bcs;
644
- const parsed_mid_price = Number(bcs.U64.parse(bytes));
645
- const adjusted_mid_price =
646
- (parsed_mid_price * baseCoin.scalar) / quoteCoin.scalar / FLOAT_SCALAR;
407
+ // === Referral Queries ===
647
408
 
648
- return Number(adjusted_mid_price.toFixed(9));
409
+ balanceManagerReferralOwner(referral: string): Promise<string> {
410
+ return this.#referralQueries.balanceManagerReferralOwner(referral);
649
411
  }
650
412
 
651
- /**
652
- * @description Get the trade parameters for a given pool, including taker fee, maker fee, and stake required.
653
- * @param {string} poolKey Key of the pool
654
- * @returns {Promise<{ takerFee: number, makerFee: number, stakeRequired: number }>}
655
- */
656
- async poolTradeParams(poolKey: string) {
657
- const tx = new Transaction();
658
-
659
- tx.add(this.deepBook.poolTradeParams(poolKey));
660
- const res = await this.#client.core.simulateTransaction({
661
- transaction: tx,
662
- include: { commandResults: true, effects: true },
663
- });
413
+ getPoolReferralBalances(poolKey: string, referral: string): Promise<ReferralBalances> {
414
+ return this.#referralQueries.getPoolReferralBalances(poolKey, referral);
415
+ }
664
416
 
665
- const takerFee = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
666
- const makerFee = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
667
- const stakeRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
417
+ balanceManagerReferralPoolId(referral: string): Promise<string> {
418
+ return this.#referralQueries.balanceManagerReferralPoolId(referral);
419
+ }
668
420
 
669
- return {
670
- takerFee: Number(takerFee / FLOAT_SCALAR),
671
- makerFee: Number(makerFee / FLOAT_SCALAR),
672
- stakeRequired: Number(stakeRequired / DEEP_SCALAR),
673
- };
421
+ poolReferralMultiplier(poolKey: string, referral: string): Promise<number> {
422
+ return this.#referralQueries.poolReferralMultiplier(poolKey, referral);
674
423
  }
675
424
 
676
- /**
677
- * @description Get the trade parameters for a given pool, including tick size, lot size, and min size.
678
- * @param {string} poolKey Key of the pool
679
- * @returns {Promise<{ tickSize: number, lotSize: number, minSize: number }>}
680
- */
681
- async poolBookParams(poolKey: string) {
682
- const tx = new Transaction();
683
- const pool = this.#config.getPool(poolKey);
684
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
685
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
686
-
687
- tx.add(this.deepBook.poolBookParams(poolKey));
688
- const res = await this.#client.core.simulateTransaction({
689
- transaction: tx,
690
- include: { commandResults: true, effects: true },
691
- });
425
+ getBalanceManagerReferralId(managerKey: string, poolKey: string): Promise<string | null> {
426
+ return this.#referralQueries.getBalanceManagerReferralId(managerKey, poolKey);
427
+ }
692
428
 
693
- const tickSize = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
694
- const lotSize = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
695
- const minSize = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
429
+ // === Price Feed Queries ===
696
430
 
697
- return {
698
- tickSize: Number((tickSize * baseScalar) / quoteScalar / FLOAT_SCALAR),
699
- lotSize: Number(lotSize / baseScalar),
700
- minSize: Number(minSize / baseScalar),
701
- };
431
+ getPriceInfoObject(tx: Transaction, coinKey: string): Promise<string> {
432
+ return this.#priceFeedQueries.getPriceInfoObject(tx, coinKey);
702
433
  }
703
434
 
704
- /**
705
- * @description Get the account information for a given pool and balance manager
706
- * @param {string} poolKey Key of the pool
707
- * @param {string} managerKey The key of the BalanceManager
708
- * @returns {Promise<Object>} A promise that resolves to an object containing the account information
709
- */
710
- async account(poolKey: string, managerKey: string) {
711
- const tx = new Transaction();
712
- const pool = this.#config.getPool(poolKey);
713
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
714
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
715
-
716
- tx.add(this.deepBook.account(poolKey, managerKey));
717
- const res = await this.#client.core.simulateTransaction({
718
- transaction: tx,
719
- include: { commandResults: true, effects: true },
720
- });
721
-
722
- const accountInformation = res.commandResults![0].returnValues[0].bcs;
723
- const accountInfo = Account.parse(new Uint8Array(accountInformation));
724
-
725
- return {
726
- epoch: accountInfo.epoch,
727
- open_orders: accountInfo.open_orders,
728
- taker_volume: Number(accountInfo.taker_volume) / baseScalar,
729
- maker_volume: Number(accountInfo.maker_volume) / baseScalar,
730
- active_stake: Number(accountInfo.active_stake) / DEEP_SCALAR,
731
- inactive_stake: Number(accountInfo.inactive_stake) / DEEP_SCALAR,
732
- created_proposal: accountInfo.created_proposal,
733
- voted_proposal: accountInfo.voted_proposal,
734
- unclaimed_rebates: {
735
- base: Number(accountInfo.unclaimed_rebates.base) / baseScalar,
736
- quote: Number(accountInfo.unclaimed_rebates.quote) / quoteScalar,
737
- deep: Number(accountInfo.unclaimed_rebates.deep) / DEEP_SCALAR,
738
- },
739
- settled_balances: {
740
- base: Number(accountInfo.settled_balances.base) / baseScalar,
741
- quote: Number(accountInfo.settled_balances.quote) / quoteScalar,
742
- deep: Number(accountInfo.settled_balances.deep) / DEEP_SCALAR,
743
- },
744
- owed_balances: {
745
- base: Number(accountInfo.owed_balances.base) / baseScalar,
746
- quote: Number(accountInfo.owed_balances.quote) / quoteScalar,
747
- deep: Number(accountInfo.owed_balances.deep) / DEEP_SCALAR,
748
- },
749
- };
435
+ getPriceInfoObjects(tx: Transaction, coinKeys: string[]): Promise<Record<string, string>> {
436
+ return this.#priceFeedQueries.getPriceInfoObjects(tx, coinKeys);
750
437
  }
751
438
 
752
- /**
753
- * @description Get the locked balances for a pool and balance manager
754
- * @param {string} poolKey Key of the pool
755
- * @param {string} managerKey The key of the BalanceManager
756
- * @returns {Promise<{ base: number, quote: number, deep: number }>}
757
- * An object with base, quote, and deep locked for the balance manager in the pool
758
- */
759
- async lockedBalance(poolKey: string, balanceManagerKey: string) {
760
- const tx = new Transaction();
761
- const pool = this.#config.getPool(poolKey);
762
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
763
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
764
-
765
- tx.add(this.deepBook.lockedBalance(poolKey, balanceManagerKey));
766
- const res = await this.#client.core.simulateTransaction({
767
- transaction: tx,
768
- include: { commandResults: true, effects: true },
769
- });
439
+ getPriceInfoObjectAge(coinKey: string): Promise<number> {
440
+ return this.#priceFeedQueries.getPriceInfoObjectAge(coinKey);
441
+ }
770
442
 
771
- const baseLocked = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
772
- const quoteLocked = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
773
- const deepLocked = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
443
+ // === Margin Pool Queries ===
774
444
 
775
- return {
776
- base: Number((baseLocked / baseScalar).toFixed(9)),
777
- quote: Number((quoteLocked / quoteScalar).toFixed(9)),
778
- deep: Number((deepLocked / DEEP_SCALAR).toFixed(9)),
779
- };
445
+ getMarginPoolId(coinKey: string): Promise<string> {
446
+ return this.#marginPoolQueries.getMarginPoolId(coinKey);
780
447
  }
781
448
 
782
- /**
783
- * @description Get the DEEP price conversion for a pool
784
- * @param {string} poolKey Key of the pool
785
- * @returns {Promise<{ asset_is_base: bool, deep_per_quote: number }>} Deep price conversion
786
- */
787
- async getPoolDeepPrice(poolKey: string) {
788
- const tx = new Transaction();
789
- const pool = this.#config.getPool(poolKey);
790
- tx.add(this.deepBook.getPoolDeepPrice(poolKey));
791
-
792
- const baseCoin = this.#config.getCoin(pool.baseCoin);
793
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
794
- const deepCoin = this.#config.getCoin('DEEP');
795
-
796
- const res = await this.#client.core.simulateTransaction({
797
- transaction: tx,
798
- include: { commandResults: true, effects: true },
799
- });
800
-
801
- const poolDeepPriceBytes = res.commandResults![0].returnValues[0].bcs;
802
- const poolDeepPrice = OrderDeepPrice.parse(new Uint8Array(poolDeepPriceBytes));
803
-
804
- if (poolDeepPrice.asset_is_base) {
805
- return {
806
- asset_is_base: poolDeepPrice.asset_is_base,
807
- deep_per_base:
808
- ((Number(poolDeepPrice.deep_per_asset) / FLOAT_SCALAR) * baseCoin.scalar) /
809
- deepCoin.scalar,
810
- };
811
- } else {
812
- return {
813
- asset_is_base: poolDeepPrice.asset_is_base,
814
- deep_per_quote:
815
- ((Number(poolDeepPrice.deep_per_asset) / FLOAT_SCALAR) * quoteCoin.scalar) /
816
- deepCoin.scalar,
817
- };
818
- }
449
+ isDeepbookPoolAllowed(coinKey: string, deepbookPoolId: string): Promise<boolean> {
450
+ return this.#marginPoolQueries.isDeepbookPoolAllowed(coinKey, deepbookPoolId);
819
451
  }
820
452
 
821
- /**
822
- * @description Decode the order ID to get bid/ask status, price, and orderId
823
- * @param {bigint} encodedOrderId Encoded order ID
824
- * @returns {Object} Object containing isBid, price, and orderId
825
- */
826
- decodeOrderId(encodedOrderId: bigint): { isBid: boolean; price: number; orderId: number } {
827
- const isBid = encodedOrderId >> 127n === 0n;
828
- const price = Number((encodedOrderId >> 64n) & ((1n << 63n) - 1n));
829
- const orderId = Number(encodedOrderId & ((1n << 64n) - 1n));
453
+ getMarginPoolTotalSupply(coinKey: string, decimals: number = 6): Promise<string> {
454
+ return this.#marginPoolQueries.getMarginPoolTotalSupply(coinKey, decimals);
455
+ }
830
456
 
831
- return { isBid, price, orderId };
457
+ getMarginPoolSupplyShares(coinKey: string, decimals: number = 6): Promise<string> {
458
+ return this.#marginPoolQueries.getMarginPoolSupplyShares(coinKey, decimals);
832
459
  }
833
460
 
834
- /**
835
- * @description Get all balance manager IDs for a given owner
836
- * @param {string} owner The owner address to get balance manager IDs for
837
- * @returns {Promise<string[]>} Array of balance manager ID strings
838
- */
839
- async getBalanceManagerIds(owner: string): Promise<string[]> {
840
- const tx = new Transaction();
841
- tx.add(this.deepBook.getBalanceManagerIds(owner));
461
+ getMarginPoolTotalBorrow(coinKey: string, decimals: number = 6): Promise<string> {
462
+ return this.#marginPoolQueries.getMarginPoolTotalBorrow(coinKey, decimals);
463
+ }
842
464
 
843
- const res = await this.#client.core.simulateTransaction({
844
- transaction: tx,
845
- include: { commandResults: true, effects: true },
846
- });
465
+ getMarginPoolBorrowShares(coinKey: string, decimals: number = 6): Promise<string> {
466
+ return this.#marginPoolQueries.getMarginPoolBorrowShares(coinKey, decimals);
467
+ }
847
468
 
848
- const bytes = res.commandResults![0].returnValues[0].bcs;
849
- const vecOfAddresses = bcs.vector(bcs.Address).parse(bytes);
469
+ getMarginPoolLastUpdateTimestamp(coinKey: string): Promise<number> {
470
+ return this.#marginPoolQueries.getMarginPoolLastUpdateTimestamp(coinKey);
471
+ }
850
472
 
851
- return vecOfAddresses.map((id: string) => normalizeSuiAddress(id));
473
+ getMarginPoolSupplyCap(coinKey: string, decimals: number = 6): Promise<string> {
474
+ return this.#marginPoolQueries.getMarginPoolSupplyCap(coinKey, decimals);
852
475
  }
853
476
 
854
- /**
855
- * @description Get the owner of the referral (DeepBookPoolReferral)
856
- * @param {string} referral The ID of the referral to get the owner of
857
- * @returns {Promise<string>} The owner of the referral
858
- */
859
- async balanceManagerReferralOwner(referral: string) {
860
- const tx = new Transaction();
861
- tx.add(this.balanceManager.balanceManagerReferralOwner(referral));
477
+ getMarginPoolMaxUtilizationRate(coinKey: string): Promise<number> {
478
+ return this.#marginPoolQueries.getMarginPoolMaxUtilizationRate(coinKey);
479
+ }
862
480
 
863
- const res = await this.#client.core.simulateTransaction({
864
- transaction: tx,
865
- include: { commandResults: true, effects: true },
866
- });
481
+ getMarginPoolProtocolSpread(coinKey: string): Promise<number> {
482
+ return this.#marginPoolQueries.getMarginPoolProtocolSpread(coinKey);
483
+ }
867
484
 
868
- const bytes = res.commandResults![0].returnValues[0].bcs;
869
- const owner = bcs.Address.parse(bytes);
485
+ getMarginPoolMinBorrow(coinKey: string, decimals: number = 6): Promise<string> {
486
+ return this.#marginPoolQueries.getMarginPoolMinBorrow(coinKey, decimals);
487
+ }
870
488
 
871
- return owner;
489
+ getMarginPoolInterestRate(coinKey: string): Promise<number> {
490
+ return this.#marginPoolQueries.getMarginPoolInterestRate(coinKey);
872
491
  }
873
492
 
874
- /**
875
- * @description Get the referral balances for a pool and referral (DeepBookPoolReferral)
876
- * @param {string} poolKey Key of the pool
877
- * @param {string} referral The referral ID to get balances for
878
- * @returns {Promise<{ base: number, quote: number, deep: number }>} Object with base, quote, and deep balances
879
- */
880
- async getPoolReferralBalances(
881
- poolKey: string,
882
- referral: string,
883
- ): Promise<{ base: number; quote: number; deep: number }> {
884
- const tx = new Transaction();
885
- const pool = this.#config.getPool(poolKey);
886
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
887
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
888
-
889
- tx.add(this.deepBook.getPoolReferralBalances(poolKey, referral));
890
-
891
- const res = await this.#client.core.simulateTransaction({
892
- transaction: tx,
893
- include: { commandResults: true, effects: true },
894
- });
493
+ getUserSupplyShares(
494
+ coinKey: string,
495
+ supplierCapId: string,
496
+ decimals: number = 6,
497
+ ): Promise<string> {
498
+ return this.#marginPoolQueries.getUserSupplyShares(coinKey, supplierCapId, decimals);
499
+ }
895
500
 
896
- // The function returns three u64 values: (base, quote, deep)
897
- const baseBytes = res.commandResults![0].returnValues[0].bcs;
898
- const quoteBytes = res.commandResults![0].returnValues[1].bcs;
899
- const deepBytes = res.commandResults![0].returnValues[2].bcs;
501
+ getUserSupplyAmount(
502
+ coinKey: string,
503
+ supplierCapId: string,
504
+ decimals: number = 6,
505
+ ): Promise<string> {
506
+ return this.#marginPoolQueries.getUserSupplyAmount(coinKey, supplierCapId, decimals);
507
+ }
900
508
 
901
- const baseBalance = Number(bcs.U64.parse(baseBytes));
902
- const quoteBalance = Number(bcs.U64.parse(quoteBytes));
903
- const deepBalance = Number(bcs.U64.parse(deepBytes));
509
+ // === Margin Manager Queries ===
904
510
 
905
- return {
906
- base: baseBalance / baseScalar,
907
- quote: quoteBalance / quoteScalar,
908
- deep: deepBalance / DEEP_SCALAR,
909
- };
511
+ getMarginManagerOwner(marginManagerKey: string): Promise<string> {
512
+ return this.#marginManagerQueries.getMarginManagerOwner(marginManagerKey);
910
513
  }
911
514
 
912
- /**
913
- * @description Get the pool ID associated with a referral (DeepBookPoolReferral)
914
- * @param {string} referral The referral (DeepBookPoolReferral) to get the pool ID for
915
- * @returns {Promise<string>} The pool ID
916
- */
917
- async balanceManagerReferralPoolId(referral: string): Promise<string> {
918
- const tx = new Transaction();
919
-
920
- tx.add(this.balanceManager.balanceManagerReferralPoolId(referral));
515
+ getMarginManagerDeepbookPool(marginManagerKey: string): Promise<string> {
516
+ return this.#marginManagerQueries.getMarginManagerDeepbookPool(marginManagerKey);
517
+ }
921
518
 
922
- const res = await this.#client.core.simulateTransaction({
923
- transaction: tx,
924
- include: { commandResults: true, effects: true },
925
- });
519
+ getMarginManagerMarginPoolId(marginManagerKey: string): Promise<string | null> {
520
+ return this.#marginManagerQueries.getMarginManagerMarginPoolId(marginManagerKey);
521
+ }
926
522
 
927
- const bytes = res.commandResults![0].returnValues[0].bcs;
928
- const poolId = bcs.Address.parse(bytes);
523
+ getMarginManagerBorrowedShares(marginManagerKey: string): Promise<BorrowedShares> {
524
+ return this.#marginManagerQueries.getMarginManagerBorrowedShares(marginManagerKey);
525
+ }
929
526
 
930
- return normalizeSuiAddress(poolId);
527
+ getMarginManagerBorrowedBaseShares(marginManagerKey: string): Promise<string> {
528
+ return this.#marginManagerQueries.getMarginManagerBorrowedBaseShares(marginManagerKey);
931
529
  }
932
530
 
933
- /**
934
- * @description Get the multiplier for a referral (DeepBookPoolReferral)
935
- * @param {string} poolKey Key of the pool
936
- * @param {string} referral The referral (DeepBookPoolReferral) to get the multiplier for
937
- * @returns {Promise<number>} The multiplier value
938
- */
939
- async poolReferralMultiplier(poolKey: string, referral: string): Promise<number> {
940
- const tx = new Transaction();
531
+ getMarginManagerBorrowedQuoteShares(marginManagerKey: string): Promise<string> {
532
+ return this.#marginManagerQueries.getMarginManagerBorrowedQuoteShares(marginManagerKey);
533
+ }
941
534
 
942
- tx.add(this.deepBook.poolReferralMultiplier(poolKey, referral));
535
+ getMarginManagerHasBaseDebt(marginManagerKey: string): Promise<boolean> {
536
+ return this.#marginManagerQueries.getMarginManagerHasBaseDebt(marginManagerKey);
537
+ }
943
538
 
944
- const res = await this.#client.core.simulateTransaction({
945
- transaction: tx,
946
- include: { commandResults: true, effects: true },
947
- });
539
+ getMarginManagerBalanceManagerId(marginManagerAddress: string): Promise<string> {
540
+ return this.#marginManagerQueries.getMarginManagerBalanceManagerId(marginManagerAddress);
541
+ }
948
542
 
949
- const bytes = res.commandResults![0].returnValues[0].bcs;
950
- const multiplier = Number(bcs.U64.parse(bytes));
543
+ getMarginManagerAssets(
544
+ marginManagerKey: string,
545
+ decimals: number = 6,
546
+ ): Promise<MarginManagerAssets> {
547
+ return this.#marginManagerQueries.getMarginManagerAssets(marginManagerKey, decimals);
548
+ }
951
549
 
952
- return multiplier / FLOAT_SCALAR;
550
+ getMarginManagerDebts(
551
+ marginManagerKey: string,
552
+ decimals: number = 6,
553
+ ): Promise<MarginManagerDebts> {
554
+ return this.#marginManagerQueries.getMarginManagerDebts(marginManagerKey, decimals);
953
555
  }
954
556
 
955
- /**
956
- * @description Get the referral ID from a balance manager for a specific pool
957
- * @param {string} managerKey Key of the balance manager
958
- * @param {string} poolKey Key of the pool to get the referral for
959
- * @returns {Promise<string | null>} The referral ID or null if not set
960
- */
961
- async getBalanceManagerReferralId(managerKey: string, poolKey: string): Promise<string | null> {
962
- const tx = new Transaction();
963
- tx.add(this.balanceManager.getBalanceManagerReferralId(managerKey, poolKey));
557
+ getMarginManagerState(
558
+ marginManagerKey: string,
559
+ decimals: number = 6,
560
+ ): Promise<MarginManagerState> {
561
+ return this.#marginManagerQueries.getMarginManagerState(marginManagerKey, decimals);
562
+ }
964
563
 
965
- const res = await this.#client.core.simulateTransaction({
966
- transaction: tx,
967
- include: { commandResults: true, effects: true },
968
- });
564
+ getMarginManagerStates(
565
+ marginManagers: Record<string, string>,
566
+ decimals: number = 6,
567
+ ): Promise<Record<string, MarginManagerState>> {
568
+ return this.#marginManagerQueries.getMarginManagerStates(marginManagers, decimals);
569
+ }
969
570
 
970
- try {
971
- const bytes = res.commandResults![0].returnValues[0].bcs;
972
- const optionId = bcs.option(bcs.Address).parse(bytes);
973
- if (optionId === null) {
974
- return null;
975
- }
976
- return normalizeSuiAddress(optionId);
977
- } catch {
978
- return null;
979
- }
980
- }
981
-
982
- async getPriceInfoObject(tx: Transaction, coinKey: string): Promise<string> {
983
- this.#config.requirePyth();
984
- const currentTime = Date.now();
985
- const priceInfoObjectAge = await this.getPriceInfoObjectAge(coinKey);
986
- if (
987
- priceInfoObjectAge &&
988
- currentTime - priceInfoObjectAge * 1000 < PRICE_INFO_OBJECT_MAX_AGE_MS
989
- ) {
990
- return await this.#config.getCoin(coinKey).priceInfoObjectId!;
991
- }
992
-
993
- // Initialize connection to the Sui Price Service
994
- const endpoint =
995
- this.#config.network === 'testnet'
996
- ? 'https://hermes-beta.pyth.network'
997
- : 'https://hermes.pyth.network';
998
- const connection = new SuiPriceServiceConnection(endpoint);
999
-
1000
- // List of price feed IDs
1001
- const priceIDs = [
1002
- this.#config.getCoin(coinKey).feed!, // ASSET/USD price ID
1003
- ];
1004
-
1005
- // Fetch price feed update data
1006
- const priceUpdateData = await connection.getPriceFeedsUpdateData(priceIDs);
1007
-
1008
- // Initialize Sui Client and Pyth Client
1009
- const wormholeStateId = this.#config.pyth.wormholeStateId;
1010
- const pythStateId = this.#config.pyth.pythStateId;
1011
-
1012
- const client = new SuiPythClient(this.#client, pythStateId, wormholeStateId);
1013
-
1014
- return (await client.updatePriceFeeds(tx, priceUpdateData, priceIDs))[0]; // returns priceInfoObjectIds
571
+ getMarginManagerBaseBalance(marginManagerKey: string, decimals: number = 9): Promise<string> {
572
+ return this.#marginManagerQueries.getMarginManagerBaseBalance(marginManagerKey, decimals);
1015
573
  }
1016
574
 
1017
- /**
1018
- * @description Batch update price info objects for multiple coins. Only updates stale feeds.
1019
- * This is more efficient than calling getPriceInfoObject multiple times as it:
1020
- * 1. Batch fetches all price info object ages in one RPC call
1021
- * 2. Fetches all stale price updates from Pyth in a single API call
1022
- * @param {Transaction} tx Transaction to add price update commands to
1023
- * @param {string[]} coinKeys Array of coin keys to update prices for
1024
- * @returns {Promise<Record<string, string>>} Map of coinKey -> priceInfoObjectId
1025
- */
1026
- async getPriceInfoObjects(tx: Transaction, coinKeys: string[]): Promise<Record<string, string>> {
1027
- this.#config.requirePyth();
1028
- if (coinKeys.length === 0) {
1029
- return {};
1030
- }
1031
-
1032
- const currentTime = Date.now();
1033
-
1034
- // Build map of coinKey -> priceInfoObjectId and collect all object IDs
1035
- const coinToObjectId: Record<string, string> = {};
1036
- const objectIds: string[] = [];
1037
- for (const coinKey of coinKeys) {
1038
- const priceInfoObjectId = this.#config.getCoin(coinKey).priceInfoObjectId!;
1039
- coinToObjectId[coinKey] = priceInfoObjectId;
1040
- objectIds.push(priceInfoObjectId);
1041
- }
1042
-
1043
- // Batch fetch all price info objects in one RPC call
1044
- const res = await this.#client.core.getObjects({
1045
- objectIds,
1046
- include: { content: true },
1047
- });
575
+ getMarginManagerQuoteBalance(marginManagerKey: string, decimals: number = 9): Promise<string> {
576
+ return this.#marginManagerQueries.getMarginManagerQuoteBalance(marginManagerKey, decimals);
577
+ }
1048
578
 
1049
- // Parse each object and determine which are stale
1050
- const staleCoinKeys: string[] = [];
1051
- const result: Record<string, string> = {};
1052
-
1053
- for (let i = 0; i < coinKeys.length; i++) {
1054
- const coinKey = coinKeys[i];
1055
- const obj = res.objects[i];
1056
-
1057
- if (obj instanceof Error || !obj?.content) {
1058
- // If we can't fetch the object, mark it as stale to force update
1059
- staleCoinKeys.push(coinKey);
1060
- continue;
1061
- }
1062
-
1063
- const priceInfoObject = PriceInfoObject.parse(obj.content);
1064
- const arrivalTime = Number(priceInfoObject.price_info.arrival_time);
1065
- const age = currentTime - arrivalTime * 1000;
1066
-
1067
- if (age >= PRICE_INFO_OBJECT_MAX_AGE_MS) {
1068
- staleCoinKeys.push(coinKey);
1069
- } else {
1070
- // Fresh price, just return the existing object ID
1071
- result[coinKey] = coinToObjectId[coinKey];
1072
- }
1073
- }
1074
-
1075
- // If no stale feeds, return early
1076
- if (staleCoinKeys.length === 0) {
1077
- return result;
1078
- }
1079
-
1080
- // Collect all feed IDs for stale coins
1081
- const staleFeedIds: string[] = [];
1082
- const feedIdToCoinKey: Record<string, string> = {};
1083
- for (const coinKey of staleCoinKeys) {
1084
- const feedId = this.#config.getCoin(coinKey).feed!;
1085
- staleFeedIds.push(feedId);
1086
- feedIdToCoinKey[feedId] = coinKey;
1087
- }
1088
-
1089
- // Initialize connection to the Sui Price Service
1090
- const endpoint =
1091
- this.#config.network === 'testnet'
1092
- ? 'https://hermes-beta.pyth.network'
1093
- : 'https://hermes.pyth.network';
1094
- const connection = new SuiPriceServiceConnection(endpoint);
1095
-
1096
- // Fetch all stale price updates from Pyth in a single API call
1097
- const priceUpdateData = await connection.getPriceFeedsUpdateData(staleFeedIds);
1098
-
1099
- // Initialize Pyth Client
1100
- const wormholeStateId = this.#config.pyth.wormholeStateId;
1101
- const pythStateId = this.#config.pyth.pythStateId;
1102
- const pythClient = new SuiPythClient(this.#client, pythStateId, wormholeStateId);
1103
-
1104
- // Update all stale feeds in the transaction
1105
- const updatedObjectIds = await pythClient.updatePriceFeeds(tx, priceUpdateData, staleFeedIds);
1106
-
1107
- // Map the updated object IDs back to coin keys
1108
- for (let i = 0; i < staleFeedIds.length; i++) {
1109
- const coinKey = feedIdToCoinKey[staleFeedIds[i]];
1110
- result[coinKey] = updatedObjectIds[i];
1111
- }
1112
-
1113
- return result;
579
+ getMarginManagerDeepBalance(marginManagerKey: string, decimals: number = 6): Promise<string> {
580
+ return this.#marginManagerQueries.getMarginManagerDeepBalance(marginManagerKey, decimals);
1114
581
  }
1115
582
 
1116
- /**
1117
- * @description Get the age of the price info object for a specific coin
1118
- * @param {string} coinKey Key of the coin
1119
- * @returns {Promise<number>} The arrival time of the price info object
1120
- */
1121
- async getPriceInfoObjectAge(coinKey: string) {
1122
- const priceInfoObjectId = this.#config.getCoin(coinKey).priceInfoObjectId!;
1123
- const res = await this.#client.core.getObject({
1124
- objectId: priceInfoObjectId,
1125
- include: {
1126
- content: true,
1127
- },
1128
- });
583
+ getMarginManagerBalances(
584
+ marginManagers: Record<string, string>,
585
+ decimals: number = 9,
586
+ ): Promise<Record<string, MarginManagerBalancesResult>> {
587
+ return this.#marginManagerQueries.getMarginManagerBalances(marginManagers, decimals);
588
+ }
1129
589
 
1130
- if (!res.object?.content) {
1131
- throw new Error(`Price info object not found for ${coinKey}`);
1132
- }
590
+ // === TPSL Queries ===
1133
591
 
1134
- const priceInfoObject = PriceInfoObject.parse(res.object.content);
1135
- return Number(priceInfoObject.price_info.arrival_time);
592
+ getConditionalOrderIds(marginManagerKey: string): Promise<string[]> {
593
+ return this.#tpslQueries.getConditionalOrderIds(marginManagerKey);
1136
594
  }
1137
595
 
1138
- // === Margin Pool View Methods ===
596
+ getLowestTriggerAbovePrice(marginManagerKey: string): Promise<bigint> {
597
+ return this.#tpslQueries.getLowestTriggerAbovePrice(marginManagerKey);
598
+ }
1139
599
 
1140
- /**
1141
- * @description Get the margin pool ID
1142
- * @param {string} coinKey The key to identify the margin pool
1143
- * @returns {Promise<string>} The margin pool ID
1144
- */
1145
- async getMarginPoolId(coinKey: string): Promise<string> {
1146
- const tx = new Transaction();
1147
- tx.add(this.marginPool.getId(coinKey));
600
+ getHighestTriggerBelowPrice(marginManagerKey: string): Promise<bigint> {
601
+ return this.#tpslQueries.getHighestTriggerBelowPrice(marginManagerKey);
602
+ }
1148
603
 
1149
- const res = await this.#client.core.simulateTransaction({
1150
- transaction: tx,
1151
- include: { commandResults: true, effects: true },
1152
- });
604
+ // === Registry Queries ===
1153
605
 
1154
- const bytes = res.commandResults![0].returnValues[0].bcs;
1155
- return bcs.Address.parse(bytes);
606
+ isPoolEnabledForMargin(poolKey: string): Promise<boolean> {
607
+ return this.#registryQueries.isPoolEnabledForMargin(poolKey);
1156
608
  }
1157
609
 
1158
- /**
1159
- * @description Check if a deepbook pool is allowed for borrowing from margin pool
1160
- * @param {string} coinKey The key to identify the margin pool
1161
- * @param {string} deepbookPoolId The ID of the deepbook pool
1162
- * @returns {Promise<boolean>} Whether the deepbook pool is allowed
1163
- */
1164
- async isDeepbookPoolAllowed(coinKey: string, deepbookPoolId: string): Promise<boolean> {
1165
- const tx = new Transaction();
1166
- tx.add(this.marginPool.deepbookPoolAllowed(coinKey, deepbookPoolId));
1167
-
1168
- const res = await this.#client.core.simulateTransaction({
1169
- transaction: tx,
1170
- include: { commandResults: true, effects: true },
1171
- });
610
+ getMarginManagerIdsForOwner(owner: string): Promise<string[]> {
611
+ return this.#registryQueries.getMarginManagerIdsForOwner(owner);
612
+ }
1172
613
 
1173
- const bytes = res.commandResults![0].returnValues[0].bcs;
1174
- return bcs.bool().parse(bytes);
614
+ getBaseMarginPoolId(poolKey: string): Promise<string> {
615
+ return this.#registryQueries.getBaseMarginPoolId(poolKey);
1175
616
  }
1176
617
 
1177
- /**
1178
- * @description Get the total supply amount in the margin pool
1179
- * @param {string} coinKey The key to identify the margin pool
1180
- * @param {number} decimals Number of decimal places to show (default: 6)
1181
- * @returns {Promise<string>} The total supply amount as a string
1182
- */
1183
- async getMarginPoolTotalSupply(coinKey: string, decimals: number = 6): Promise<string> {
1184
- const tx = new Transaction();
1185
- tx.add(this.marginPool.totalSupply(coinKey));
618
+ getQuoteMarginPoolId(poolKey: string): Promise<string> {
619
+ return this.#registryQueries.getQuoteMarginPoolId(poolKey);
620
+ }
1186
621
 
1187
- const res = await this.#client.core.simulateTransaction({
1188
- transaction: tx,
1189
- include: { commandResults: true, effects: true },
1190
- });
622
+ getMinWithdrawRiskRatio(poolKey: string): Promise<number> {
623
+ return this.#registryQueries.getMinWithdrawRiskRatio(poolKey);
624
+ }
1191
625
 
1192
- const bytes = res.commandResults![0].returnValues[0].bcs;
1193
- const rawAmount = BigInt(bcs.U64.parse(bytes));
1194
- const coin = this.#config.getCoin(coinKey);
1195
- return this.#formatTokenAmount(rawAmount, coin.scalar, decimals);
626
+ getMinBorrowRiskRatio(poolKey: string): Promise<number> {
627
+ return this.#registryQueries.getMinBorrowRiskRatio(poolKey);
1196
628
  }
1197
629
 
1198
- /**
1199
- * @description Get the total supply shares in the margin pool
1200
- * @param {string} coinKey The key to identify the margin pool
1201
- * @param {number} decimals Number of decimal places to show (default: 6)
1202
- * @returns {Promise<string>} The total supply shares as a string
1203
- */
1204
- async getMarginPoolSupplyShares(coinKey: string, decimals: number = 6): Promise<string> {
1205
- const tx = new Transaction();
1206
- tx.add(this.marginPool.supplyShares(coinKey));
630
+ getLiquidationRiskRatio(poolKey: string): Promise<number> {
631
+ return this.#registryQueries.getLiquidationRiskRatio(poolKey);
632
+ }
1207
633
 
1208
- const res = await this.#client.core.simulateTransaction({
1209
- transaction: tx,
1210
- include: { commandResults: true, effects: true },
1211
- });
634
+ getTargetLiquidationRiskRatio(poolKey: string): Promise<number> {
635
+ return this.#registryQueries.getTargetLiquidationRiskRatio(poolKey);
636
+ }
1212
637
 
1213
- const bytes = res.commandResults![0].returnValues[0].bcs;
1214
- const rawShares = BigInt(bcs.U64.parse(bytes));
1215
- const coin = this.#config.getCoin(coinKey);
1216
- return this.#formatTokenAmount(rawShares, coin.scalar, decimals);
638
+ getUserLiquidationReward(poolKey: string): Promise<number> {
639
+ return this.#registryQueries.getUserLiquidationReward(poolKey);
1217
640
  }
1218
641
 
1219
- /**
1220
- * @description Get the total borrow amount in the margin pool
1221
- * @param {string} coinKey The key to identify the margin pool
1222
- * @param {number} decimals Number of decimal places to show (default: 6)
1223
- * @returns {Promise<string>} The total borrow amount as a string
1224
- */
1225
- async getMarginPoolTotalBorrow(coinKey: string, decimals: number = 6): Promise<string> {
1226
- const tx = new Transaction();
1227
- tx.add(this.marginPool.totalBorrow(coinKey));
642
+ getPoolLiquidationReward(poolKey: string): Promise<number> {
643
+ return this.#registryQueries.getPoolLiquidationReward(poolKey);
644
+ }
1228
645
 
1229
- const res = await this.#client.core.simulateTransaction({
1230
- transaction: tx,
1231
- include: { commandResults: true, effects: true },
1232
- });
646
+ getAllowedMaintainers(): Promise<string[]> {
647
+ return this.#registryQueries.getAllowedMaintainers();
648
+ }
1233
649
 
1234
- const bytes = res.commandResults![0].returnValues[0].bcs;
1235
- const rawAmount = BigInt(bcs.U64.parse(bytes));
1236
- const coin = this.#config.getCoin(coinKey);
1237
- return this.#formatTokenAmount(rawAmount, coin.scalar, decimals);
650
+ getAllowedPauseCaps(): Promise<string[]> {
651
+ return this.#registryQueries.getAllowedPauseCaps();
1238
652
  }
1239
653
 
1240
- /**
1241
- * @description Get the total borrow shares in the margin pool
1242
- * @param {string} coinKey The key to identify the margin pool
1243
- * @param {number} decimals Number of decimal places to show (default: 6)
1244
- * @returns {Promise<string>} The total borrow shares as a string
1245
- */
1246
- async getMarginPoolBorrowShares(coinKey: string, decimals: number = 6): Promise<string> {
1247
- const tx = new Transaction();
1248
- tx.add(this.marginPool.borrowShares(coinKey));
654
+ // === Synchronous Utilities ===
1249
655
 
1250
- const res = await this.#client.core.simulateTransaction({
1251
- transaction: tx,
1252
- include: { commandResults: true, effects: true },
1253
- });
656
+ decodeOrderId(encodedOrderId: bigint): DecodedOrderId {
657
+ const isBid = encodedOrderId >> 127n === 0n;
658
+ const price = Number((encodedOrderId >> 64n) & ((1n << 63n) - 1n));
659
+ const orderId = Number(encodedOrderId & ((1n << 64n) - 1n));
1254
660
 
1255
- const bytes = res.commandResults![0].returnValues[0].bcs;
1256
- const rawShares = BigInt(bcs.U64.parse(bytes));
1257
- const coin = this.#config.getCoin(coinKey);
1258
- return this.#formatTokenAmount(rawShares, coin.scalar, decimals);
1259
- }
1260
-
1261
- /**
1262
- * @description Get the last update timestamp of the margin pool
1263
- * @param {string} coinKey The key to identify the margin pool
1264
- * @returns {Promise<number>} The last update timestamp in milliseconds
1265
- */
1266
- async getMarginPoolLastUpdateTimestamp(coinKey: string): Promise<number> {
1267
- const tx = new Transaction();
1268
- tx.add(this.marginPool.lastUpdateTimestamp(coinKey));
1269
-
1270
- const res = await this.#client.core.simulateTransaction({
1271
- transaction: tx,
1272
- include: { commandResults: true, effects: true },
1273
- });
1274
-
1275
- const bytes = res.commandResults![0].returnValues[0].bcs;
1276
- return Number(bcs.U64.parse(bytes));
1277
- }
1278
-
1279
- /**
1280
- * @description Get the supply cap of the margin pool
1281
- * @param {string} coinKey The key to identify the margin pool
1282
- * @param {number} decimals Number of decimal places to show (default: 6)
1283
- * @returns {Promise<string>} The supply cap as a string
1284
- */
1285
- async getMarginPoolSupplyCap(coinKey: string, decimals: number = 6): Promise<string> {
1286
- const tx = new Transaction();
1287
- tx.add(this.marginPool.supplyCap(coinKey));
1288
-
1289
- const res = await this.#client.core.simulateTransaction({
1290
- transaction: tx,
1291
- include: { commandResults: true, effects: true },
1292
- });
1293
-
1294
- const bytes = res.commandResults![0].returnValues[0].bcs;
1295
- const rawAmount = BigInt(bcs.U64.parse(bytes));
1296
- const coin = this.#config.getCoin(coinKey);
1297
- return this.#formatTokenAmount(rawAmount, coin.scalar, decimals);
1298
- }
1299
-
1300
- /**
1301
- * @description Get the max utilization rate of the margin pool
1302
- * @param {string} coinKey The key to identify the margin pool
1303
- * @returns {Promise<number>} The max utilization rate (as a decimal, e.g., 0.95 for 95%)
1304
- */
1305
- async getMarginPoolMaxUtilizationRate(coinKey: string): Promise<number> {
1306
- const tx = new Transaction();
1307
- tx.add(this.marginPool.maxUtilizationRate(coinKey));
1308
-
1309
- const res = await this.#client.core.simulateTransaction({
1310
- transaction: tx,
1311
- include: { commandResults: true, effects: true },
1312
- });
1313
-
1314
- const bytes = res.commandResults![0].returnValues[0].bcs;
1315
- const rawRate = Number(bcs.U64.parse(bytes));
1316
- return rawRate / FLOAT_SCALAR;
1317
- }
1318
-
1319
- /**
1320
- * @description Get the protocol spread of the margin pool
1321
- * @param {string} coinKey The key to identify the margin pool
1322
- * @returns {Promise<number>} The protocol spread (as a decimal)
1323
- */
1324
- async getMarginPoolProtocolSpread(coinKey: string): Promise<number> {
1325
- const tx = new Transaction();
1326
- tx.add(this.marginPool.protocolSpread(coinKey));
1327
-
1328
- const res = await this.#client.core.simulateTransaction({
1329
- transaction: tx,
1330
- include: { commandResults: true, effects: true },
1331
- });
1332
-
1333
- const bytes = res.commandResults![0].returnValues[0].bcs;
1334
- const rawSpread = Number(bcs.U64.parse(bytes));
1335
- return rawSpread / FLOAT_SCALAR;
1336
- }
1337
-
1338
- /**
1339
- * @description Get the minimum borrow amount for the margin pool
1340
- * @param {string} coinKey The key to identify the margin pool
1341
- * @param {number} decimals Number of decimal places to show (default: 6)
1342
- * @returns {Promise<string>} The minimum borrow amount as a string
1343
- */
1344
- async getMarginPoolMinBorrow(coinKey: string, decimals: number = 6): Promise<string> {
1345
- const tx = new Transaction();
1346
- tx.add(this.marginPool.minBorrow(coinKey));
1347
-
1348
- const res = await this.#client.core.simulateTransaction({
1349
- transaction: tx,
1350
- include: { commandResults: true, effects: true },
1351
- });
1352
-
1353
- const bytes = res.commandResults![0].returnValues[0].bcs;
1354
- const rawAmount = BigInt(bcs.U64.parse(bytes));
1355
- const coin = this.#config.getCoin(coinKey);
1356
- return this.#formatTokenAmount(rawAmount, coin.scalar, decimals);
1357
- }
1358
-
1359
- /**
1360
- * @description Get the current interest rate of the margin pool
1361
- * @param {string} coinKey The key to identify the margin pool
1362
- * @returns {Promise<number>} The current interest rate (as a decimal)
1363
- */
1364
- async getMarginPoolInterestRate(coinKey: string): Promise<number> {
1365
- const tx = new Transaction();
1366
- tx.add(this.marginPool.interestRate(coinKey));
1367
-
1368
- const res = await this.#client.core.simulateTransaction({
1369
- transaction: tx,
1370
- include: { commandResults: true, effects: true },
1371
- });
1372
-
1373
- const bytes = res.commandResults![0].returnValues[0].bcs;
1374
- const rawRate = Number(bcs.U64.parse(bytes));
1375
- return rawRate / FLOAT_SCALAR;
1376
- }
1377
-
1378
- /**
1379
- * @description Get user supply shares for a supplier cap
1380
- * @param {string} coinKey The key to identify the margin pool
1381
- * @param {string} supplierCapId The ID of the supplier cap
1382
- * @param {number} decimals Number of decimal places to show (default: 6)
1383
- * @returns {Promise<string>} The user's supply shares as a string
1384
- */
1385
- async getUserSupplyShares(
1386
- coinKey: string,
1387
- supplierCapId: string,
1388
- decimals: number = 6,
1389
- ): Promise<string> {
1390
- const tx = new Transaction();
1391
- tx.add(this.marginPool.userSupplyShares(coinKey, supplierCapId));
1392
-
1393
- const res = await this.#client.core.simulateTransaction({
1394
- transaction: tx,
1395
- include: { commandResults: true, effects: true },
1396
- });
1397
-
1398
- const bytes = res.commandResults![0].returnValues[0].bcs;
1399
- const rawShares = BigInt(bcs.U64.parse(bytes));
1400
- const coin = this.#config.getCoin(coinKey);
1401
- return this.#formatTokenAmount(rawShares, coin.scalar, decimals);
1402
- }
1403
-
1404
- /**
1405
- * @description Get user supply amount for a supplier cap
1406
- * @param {string} coinKey The key to identify the margin pool
1407
- * @param {string} supplierCapId The ID of the supplier cap
1408
- * @param {number} decimals Number of decimal places to show (default: 6)
1409
- * @returns {Promise<string>} The user's supply amount as a string
1410
- */
1411
- async getUserSupplyAmount(
1412
- coinKey: string,
1413
- supplierCapId: string,
1414
- decimals: number = 6,
1415
- ): Promise<string> {
1416
- const tx = new Transaction();
1417
- tx.add(this.marginPool.userSupplyAmount(coinKey, supplierCapId));
1418
-
1419
- const res = await this.#client.core.simulateTransaction({
1420
- transaction: tx,
1421
- include: { commandResults: true, effects: true },
1422
- });
1423
-
1424
- const bytes = res.commandResults![0].returnValues[0].bcs;
1425
- const rawAmount = BigInt(bcs.U64.parse(bytes));
1426
- const coin = this.#config.getCoin(coinKey);
1427
- return this.#formatTokenAmount(rawAmount, coin.scalar, decimals);
1428
- }
1429
-
1430
- // === Margin Manager Read-Only Functions ===
1431
-
1432
- /**
1433
- * @description Get the owner address of a margin manager
1434
- * @param {string} marginManagerKey The key to identify the margin manager
1435
- * @returns {Promise<string>} The owner address
1436
- */
1437
- async getMarginManagerOwner(marginManagerKey: string): Promise<string> {
1438
- const manager = this.#config.getMarginManager(marginManagerKey);
1439
- const tx = new Transaction();
1440
- tx.add(this.marginManager.ownerByPoolKey(manager.poolKey, manager.address));
1441
-
1442
- const res = await this.#client.core.simulateTransaction({
1443
- transaction: tx,
1444
- include: { commandResults: true, effects: true },
1445
- });
1446
-
1447
- const bytes = res.commandResults![0].returnValues[0].bcs;
1448
- return normalizeSuiAddress(bcs.Address.parse(bytes));
1449
- }
1450
-
1451
- /**
1452
- * @description Get the DeepBook pool ID associated with a margin manager
1453
- * @param {string} marginManagerKey The key to identify the margin manager
1454
- * @returns {Promise<string>} The DeepBook pool ID
1455
- */
1456
- async getMarginManagerDeepbookPool(marginManagerKey: string): Promise<string> {
1457
- const manager = this.#config.getMarginManager(marginManagerKey);
1458
- const tx = new Transaction();
1459
- tx.add(this.marginManager.deepbookPool(manager.poolKey, manager.address));
1460
-
1461
- const res = await this.#client.core.simulateTransaction({
1462
- transaction: tx,
1463
- include: { commandResults: true, effects: true },
1464
- });
1465
-
1466
- const bytes = res.commandResults![0].returnValues[0].bcs;
1467
- return normalizeSuiAddress(bcs.Address.parse(bytes));
1468
- }
1469
-
1470
- /**
1471
- * @description Get the margin pool ID (if any) associated with a margin manager
1472
- * @param {string} marginManagerKey The key to identify the margin manager
1473
- * @returns {Promise<string | null>} The margin pool ID or null if no active loan
1474
- */
1475
- async getMarginManagerMarginPoolId(marginManagerKey: string): Promise<string | null> {
1476
- const manager = this.#config.getMarginManager(marginManagerKey);
1477
- const tx = new Transaction();
1478
- tx.add(this.marginManager.marginPoolId(manager.poolKey, manager.address));
1479
-
1480
- const res = await this.#client.core.simulateTransaction({
1481
- transaction: tx,
1482
- include: { commandResults: true, effects: true },
1483
- });
1484
-
1485
- const bytes = res.commandResults![0].returnValues[0].bcs;
1486
- const option = bcs.option(bcs.Address).parse(bytes);
1487
- return option ? normalizeSuiAddress(option) : null;
1488
- }
1489
-
1490
- /**
1491
- * @description Get borrowed shares for both base and quote assets
1492
- * @param {string} marginManagerKey The key to identify the margin manager
1493
- * @returns {Promise<{baseShares: string, quoteShares: string}>} The borrowed shares
1494
- */
1495
- async getMarginManagerBorrowedShares(
1496
- marginManagerKey: string,
1497
- ): Promise<{ baseShares: string; quoteShares: string }> {
1498
- const manager = this.#config.getMarginManager(marginManagerKey);
1499
- const tx = new Transaction();
1500
- tx.add(this.marginManager.borrowedShares(manager.poolKey, manager.address));
1501
-
1502
- const res = await this.#client.core.simulateTransaction({
1503
- transaction: tx,
1504
- include: { commandResults: true, effects: true },
1505
- });
1506
-
1507
- const baseBytes = res.commandResults![0].returnValues[0].bcs;
1508
- const quoteBytes = res.commandResults![0].returnValues[1].bcs;
1509
- const baseShares = bcs.U64.parse(baseBytes).toString();
1510
- const quoteShares = bcs.U64.parse(quoteBytes).toString();
1511
-
1512
- return { baseShares, quoteShares };
1513
- }
1514
-
1515
- /**
1516
- * @description Get borrowed base shares
1517
- * @param {string} marginManagerKey The key to identify the margin manager
1518
- * @returns {Promise<string>} The borrowed base shares
1519
- */
1520
- async getMarginManagerBorrowedBaseShares(marginManagerKey: string): Promise<string> {
1521
- const manager = this.#config.getMarginManager(marginManagerKey);
1522
- const tx = new Transaction();
1523
- tx.add(this.marginManager.borrowedBaseShares(manager.poolKey, manager.address));
1524
-
1525
- const res = await this.#client.core.simulateTransaction({
1526
- transaction: tx,
1527
- include: { commandResults: true, effects: true },
1528
- });
1529
-
1530
- const bytes = res.commandResults![0].returnValues[0].bcs;
1531
- return bcs.U64.parse(bytes).toString();
1532
- }
1533
-
1534
- /**
1535
- * @description Get borrowed quote shares
1536
- * @param {string} marginManagerKey The key to identify the margin manager
1537
- * @returns {Promise<string>} The borrowed quote shares
1538
- */
1539
- async getMarginManagerBorrowedQuoteShares(marginManagerKey: string): Promise<string> {
1540
- const manager = this.#config.getMarginManager(marginManagerKey);
1541
- const tx = new Transaction();
1542
- tx.add(this.marginManager.borrowedQuoteShares(manager.poolKey, manager.address));
1543
-
1544
- const res = await this.#client.core.simulateTransaction({
1545
- transaction: tx,
1546
- include: { commandResults: true, effects: true },
1547
- });
1548
-
1549
- const bytes = res.commandResults![0].returnValues[0].bcs;
1550
- return bcs.U64.parse(bytes).toString();
1551
- }
1552
-
1553
- /**
1554
- * @description Check if margin manager has base asset debt
1555
- * @param {string} marginManagerKey The key to identify the margin manager
1556
- * @returns {Promise<boolean>} True if has base debt, false otherwise
1557
- */
1558
- async getMarginManagerHasBaseDebt(marginManagerKey: string): Promise<boolean> {
1559
- const manager = this.#config.getMarginManager(marginManagerKey);
1560
- const tx = new Transaction();
1561
- tx.add(this.marginManager.hasBaseDebt(manager.poolKey, manager.address));
1562
-
1563
- const res = await this.#client.core.simulateTransaction({
1564
- transaction: tx,
1565
- include: { commandResults: true, effects: true },
1566
- });
1567
-
1568
- const bytes = res.commandResults![0].returnValues[0].bcs;
1569
- return bcs.bool().parse(bytes);
1570
- }
1571
-
1572
- /**
1573
- * @description Get the balance manager ID for a margin manager
1574
- * @param {string} marginManagerAddress The object ID of the margin manager
1575
- * @returns {Promise<string>} The balance manager ID
1576
- */
1577
- async getMarginManagerBalanceManagerId(marginManagerAddress: string): Promise<string> {
1578
- const res = await this.#client.core.getObject({
1579
- objectId: marginManagerAddress,
1580
- include: { content: true },
1581
- });
1582
-
1583
- if (!res.object?.content) {
1584
- throw new Error(`Margin manager not found: ${marginManagerAddress}`);
1585
- }
1586
-
1587
- // MarginManager struct field order: id, owner, deepbook_pool, margin_pool_id, balance_manager
1588
- // We only need to parse up to balance_manager's id (first field of BalanceManager)
1589
- const MarginManagerBalanceManagerId = bcs.struct('MarginManagerBalanceManagerId', {
1590
- id: bcs.Address,
1591
- owner: bcs.Address,
1592
- deepbook_pool: bcs.Address,
1593
- margin_pool_id: bcs.option(bcs.Address),
1594
- balance_manager_id: bcs.Address,
1595
- });
1596
-
1597
- const parsed = MarginManagerBalanceManagerId.parse(res.object.content);
1598
- return normalizeSuiAddress(parsed.balance_manager_id);
1599
- }
1600
-
1601
- /**
1602
- * @description Calculate assets (base and quote) for a margin manager
1603
- * @param {string} marginManagerKey The key to identify the margin manager
1604
- * @param {number} decimals Number of decimal places to show (default: 6)
1605
- * @returns {Promise<{baseAsset: string, quoteAsset: string}>} The base and quote assets
1606
- */
1607
- async getMarginManagerAssets(
1608
- marginManagerKey: string,
1609
- decimals: number = 6,
1610
- ): Promise<{ baseAsset: string; quoteAsset: string }> {
1611
- const manager = this.#config.getMarginManager(marginManagerKey);
1612
- const tx = new Transaction();
1613
- tx.add(this.marginManager.calculateAssets(manager.poolKey, manager.address));
1614
-
1615
- const res = await this.#client.core.simulateTransaction({
1616
- transaction: tx,
1617
- include: { commandResults: true, effects: true },
1618
- });
1619
-
1620
- const baseBytes = res.commandResults![0].returnValues[0].bcs;
1621
- const quoteBytes = res.commandResults![0].returnValues[1].bcs;
1622
- const pool = this.#config.getPool(manager.poolKey);
1623
- const baseCoin = this.#config.getCoin(pool.baseCoin);
1624
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
1625
-
1626
- const baseAsset = this.#formatTokenAmount(
1627
- BigInt(bcs.U64.parse(baseBytes)),
1628
- baseCoin.scalar,
1629
- decimals,
1630
- );
1631
- const quoteAsset = this.#formatTokenAmount(
1632
- BigInt(bcs.U64.parse(quoteBytes)),
1633
- quoteCoin.scalar,
1634
- decimals,
1635
- );
1636
-
1637
- return { baseAsset, quoteAsset };
1638
- }
1639
-
1640
- /**
1641
- * @description Calculate debts (base and quote) for a margin manager
1642
- * NOTE: This function automatically determines whether to use base or quote margin pool
1643
- * based on hasBaseDebt. You don't need to specify the debt coin type.
1644
- * @param {string} marginManagerKey The key to identify the margin manager
1645
- * @param {number} decimals Number of decimal places to show (default: 6)
1646
- * @returns {Promise<{baseDebt: string, quoteDebt: string}>} The base and quote debts
1647
- */
1648
- async getMarginManagerDebts(
1649
- marginManagerKey: string,
1650
- decimals: number = 6,
1651
- ): Promise<{ baseDebt: string; quoteDebt: string }> {
1652
- // First check if the margin manager has base debt
1653
- const hasBaseDebt = await this.getMarginManagerHasBaseDebt(marginManagerKey);
1654
-
1655
- // Get the manager and pool configuration
1656
- const manager = this.#config.getMarginManager(marginManagerKey);
1657
- const pool = this.#config.getPool(manager.poolKey);
1658
- const debtCoinKey = hasBaseDebt ? pool.baseCoin : pool.quoteCoin;
1659
-
1660
- // Now call calculateDebts with the correct debt coin
1661
- const tx = new Transaction();
1662
- tx.add(this.marginManager.calculateDebts(manager.poolKey, debtCoinKey, manager.address));
1663
-
1664
- const res = await this.#client.core.simulateTransaction({
1665
- transaction: tx,
1666
- include: { commandResults: true, effects: true },
1667
- });
1668
-
1669
- if (res.FailedTransaction) {
1670
- throw new Error(
1671
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
1672
- );
1673
- }
1674
-
1675
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
1676
- throw new Error(`Failed to get margin manager debts: ${'Unknown error'}`);
1677
- }
1678
-
1679
- // The Move function returns a tuple (u64, u64), so returnValues has 2 elements
1680
- const baseBytes = res.commandResults[0].returnValues[0].bcs;
1681
- const quoteBytes = res.commandResults[0].returnValues[1].bcs;
1682
- const debtCoin = this.#config.getCoin(debtCoinKey);
1683
-
1684
- const baseDebt = this.#formatTokenAmount(
1685
- BigInt(bcs.U64.parse(baseBytes)),
1686
- debtCoin.scalar,
1687
- decimals,
1688
- );
1689
- const quoteDebt = this.#formatTokenAmount(
1690
- BigInt(bcs.U64.parse(quoteBytes)),
1691
- debtCoin.scalar,
1692
- decimals,
1693
- );
1694
-
1695
- return { baseDebt, quoteDebt };
1696
- }
1697
-
1698
- /**
1699
- * @description Get comprehensive state information for a margin manager
1700
- * @param {string} marginManagerKey The key to identify the margin manager
1701
- * @param {number} decimals Number of decimal places to show (default: 6)
1702
- * @returns {Promise<{
1703
- * managerId: string,
1704
- * deepbookPoolId: string,
1705
- * riskRatio: number,
1706
- * baseAsset: string,
1707
- * quoteAsset: string,
1708
- * baseDebt: string,
1709
- * quoteDebt: string,
1710
- * basePythPrice: string,
1711
- * basePythDecimals: number,
1712
- * quotePythPrice: string,
1713
- * quotePythDecimals: number
1714
- * }>} Comprehensive margin manager state
1715
- */
1716
- async getMarginManagerState(
1717
- marginManagerKey: string,
1718
- decimals: number = 6,
1719
- ): Promise<{
1720
- managerId: string;
1721
- deepbookPoolId: string;
1722
- riskRatio: number;
1723
- baseAsset: string;
1724
- quoteAsset: string;
1725
- baseDebt: string;
1726
- quoteDebt: string;
1727
- basePythPrice: string;
1728
- basePythDecimals: number;
1729
- quotePythPrice: string;
1730
- quotePythDecimals: number;
1731
- currentPrice: bigint;
1732
- lowestTriggerAbovePrice: bigint;
1733
- highestTriggerBelowPrice: bigint;
1734
- }> {
1735
- const manager = this.#config.getMarginManager(marginManagerKey);
1736
- const tx = new Transaction();
1737
- tx.add(this.marginManager.managerState(manager.poolKey, manager.address));
1738
-
1739
- const res = await this.#client.core.simulateTransaction({
1740
- transaction: tx,
1741
- include: { commandResults: true, effects: true },
1742
- });
1743
-
1744
- if (res.FailedTransaction) {
1745
- throw new Error(
1746
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
1747
- );
1748
- }
1749
-
1750
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
1751
- throw new Error(`Failed to get margin manager state: Unknown error`);
1752
- }
1753
-
1754
- const pool = this.#config.getPool(manager.poolKey);
1755
- const baseCoin = this.#config.getCoin(pool.baseCoin);
1756
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
1757
-
1758
- // Parse all 11 return values
1759
- const managerId = normalizeSuiAddress(
1760
- bcs.Address.parse(res.commandResults[0].returnValues[0].bcs),
1761
- );
1762
- const deepbookPoolId = normalizeSuiAddress(
1763
- bcs.Address.parse(res.commandResults[0].returnValues[1].bcs),
1764
- );
1765
- const riskRatio =
1766
- Number(bcs.U64.parse(res.commandResults[0].returnValues[2].bcs)) / FLOAT_SCALAR;
1767
- const baseAsset = this.#formatTokenAmount(
1768
- BigInt(bcs.U64.parse(res.commandResults[0].returnValues[3].bcs)),
1769
- baseCoin.scalar,
1770
- decimals,
1771
- );
1772
- const quoteAsset = this.#formatTokenAmount(
1773
- BigInt(bcs.U64.parse(res.commandResults[0].returnValues[4].bcs)),
1774
- quoteCoin.scalar,
1775
- decimals,
1776
- );
1777
- const baseDebt = this.#formatTokenAmount(
1778
- BigInt(bcs.U64.parse(res.commandResults[0].returnValues[5].bcs)),
1779
- baseCoin.scalar,
1780
- decimals,
1781
- );
1782
- const quoteDebt = this.#formatTokenAmount(
1783
- BigInt(bcs.U64.parse(res.commandResults[0].returnValues[6].bcs)),
1784
- quoteCoin.scalar,
1785
- decimals,
1786
- );
1787
- const basePythPrice = bcs.U64.parse(res.commandResults[0].returnValues[7].bcs);
1788
- const basePythDecimals = Number(
1789
- bcs.u8().parse(new Uint8Array(res.commandResults[0].returnValues[8].bcs)),
1790
- );
1791
- const quotePythPrice = bcs.U64.parse(res.commandResults[0].returnValues[9].bcs);
1792
- const quotePythDecimals = Number(
1793
- bcs.u8().parse(new Uint8Array(res.commandResults[0].returnValues[10].bcs)),
1794
- );
1795
- const currentPrice = BigInt(bcs.U64.parse(res.commandResults[0].returnValues[11].bcs));
1796
- const lowestTriggerAbovePrice = BigInt(
1797
- bcs.U64.parse(res.commandResults[0].returnValues[12].bcs),
1798
- );
1799
- const highestTriggerBelowPrice = BigInt(
1800
- bcs.U64.parse(res.commandResults[0].returnValues[13].bcs),
1801
- );
1802
-
1803
- return {
1804
- managerId,
1805
- deepbookPoolId,
1806
- riskRatio,
1807
- baseAsset,
1808
- quoteAsset,
1809
- baseDebt,
1810
- quoteDebt,
1811
- basePythPrice: basePythPrice.toString(),
1812
- basePythDecimals,
1813
- quotePythPrice: quotePythPrice.toString(),
1814
- quotePythDecimals,
1815
- currentPrice,
1816
- lowestTriggerAbovePrice,
1817
- highestTriggerBelowPrice,
1818
- };
1819
- }
1820
-
1821
- /**
1822
- * @description Get comprehensive state information for multiple margin managers.
1823
- * @param {Record<string, string>} marginManagers Map of marginManagerId -> poolKey
1824
- * @param {number} decimals Number of decimal places for formatting (default: 6)
1825
- * @returns {Promise<Record<string, {...}>>} Object keyed by managerId with state data
1826
- */
1827
- async getMarginManagerStates(
1828
- marginManagers: Record<string, string>,
1829
- decimals: number = 6,
1830
- ): Promise<
1831
- Record<
1832
- string,
1833
- {
1834
- managerId: string;
1835
- deepbookPoolId: string;
1836
- riskRatio: number;
1837
- baseAsset: string;
1838
- quoteAsset: string;
1839
- baseDebt: string;
1840
- quoteDebt: string;
1841
- basePythPrice: string;
1842
- basePythDecimals: number;
1843
- quotePythPrice: string;
1844
- quotePythDecimals: number;
1845
- currentPrice: bigint;
1846
- lowestTriggerAbovePrice: bigint;
1847
- highestTriggerBelowPrice: bigint;
1848
- }
1849
- >
1850
- > {
1851
- const entries = Object.entries(marginManagers);
1852
- if (entries.length === 0) {
1853
- return {};
1854
- }
1855
-
1856
- const tx = new Transaction();
1857
-
1858
- // Add a managerState call for each margin manager
1859
- for (const [managerId, poolKey] of entries) {
1860
- tx.add(this.marginManager.managerState(poolKey, managerId));
1861
- }
1862
-
1863
- const res = await this.#client.core.simulateTransaction({
1864
- transaction: tx,
1865
- include: { commandResults: true, effects: true },
1866
- });
1867
-
1868
- if (res.FailedTransaction) {
1869
- throw new Error(
1870
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
1871
- );
1872
- }
1873
-
1874
- if (!res.commandResults) {
1875
- throw new Error(`Failed to get margin manager states: Unknown error`);
1876
- }
1877
-
1878
- const results: Record<
1879
- string,
1880
- {
1881
- managerId: string;
1882
- deepbookPoolId: string;
1883
- riskRatio: number;
1884
- baseAsset: string;
1885
- quoteAsset: string;
1886
- baseDebt: string;
1887
- quoteDebt: string;
1888
- basePythPrice: string;
1889
- basePythDecimals: number;
1890
- quotePythPrice: string;
1891
- quotePythDecimals: number;
1892
- currentPrice: bigint;
1893
- lowestTriggerAbovePrice: bigint;
1894
- highestTriggerBelowPrice: bigint;
1895
- }
1896
- > = {};
1897
-
1898
- // Parse each command result
1899
- for (let i = 0; i < entries.length; i++) {
1900
- const commandResult = res.commandResults[i];
1901
- if (!commandResult || !commandResult.returnValues) {
1902
- throw new Error(`Failed to get margin manager state for index ${i}: No return values`);
1903
- }
1904
-
1905
- const [, poolKey] = entries[i];
1906
- const pool = this.#config.getPool(poolKey);
1907
- const baseCoin = this.#config.getCoin(pool.baseCoin);
1908
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
1909
-
1910
- const managerId = normalizeSuiAddress(bcs.Address.parse(commandResult.returnValues[0].bcs));
1911
- const deepbookPoolId = normalizeSuiAddress(
1912
- bcs.Address.parse(commandResult.returnValues[1].bcs),
1913
- );
1914
- const riskRatio = Number(bcs.U64.parse(commandResult.returnValues[2].bcs)) / FLOAT_SCALAR;
1915
- const baseAsset = this.#formatTokenAmount(
1916
- BigInt(bcs.U64.parse(commandResult.returnValues[3].bcs)),
1917
- baseCoin.scalar,
1918
- decimals,
1919
- );
1920
- const quoteAsset = this.#formatTokenAmount(
1921
- BigInt(bcs.U64.parse(commandResult.returnValues[4].bcs)),
1922
- quoteCoin.scalar,
1923
- decimals,
1924
- );
1925
- const baseDebt = this.#formatTokenAmount(
1926
- BigInt(bcs.U64.parse(commandResult.returnValues[5].bcs)),
1927
- baseCoin.scalar,
1928
- decimals,
1929
- );
1930
- const quoteDebt = this.#formatTokenAmount(
1931
- BigInt(bcs.U64.parse(commandResult.returnValues[6].bcs)),
1932
- quoteCoin.scalar,
1933
- decimals,
1934
- );
1935
- const basePythPrice = bcs.U64.parse(commandResult.returnValues[7].bcs);
1936
- const basePythDecimals = Number(
1937
- bcs.u8().parse(new Uint8Array(commandResult.returnValues[8].bcs)),
1938
- );
1939
- const quotePythPrice = bcs.U64.parse(commandResult.returnValues[9].bcs);
1940
- const quotePythDecimals = Number(
1941
- bcs.u8().parse(new Uint8Array(commandResult.returnValues[10].bcs)),
1942
- );
1943
- const currentPrice = BigInt(bcs.U64.parse(commandResult.returnValues[11].bcs));
1944
- const lowestTriggerAbovePrice = BigInt(bcs.U64.parse(commandResult.returnValues[12].bcs));
1945
- const highestTriggerBelowPrice = BigInt(bcs.U64.parse(commandResult.returnValues[13].bcs));
1946
-
1947
- results[managerId] = {
1948
- managerId,
1949
- deepbookPoolId,
1950
- riskRatio,
1951
- baseAsset,
1952
- quoteAsset,
1953
- baseDebt,
1954
- quoteDebt,
1955
- basePythPrice: basePythPrice.toString(),
1956
- basePythDecimals,
1957
- quotePythPrice: quotePythPrice.toString(),
1958
- quotePythDecimals,
1959
- currentPrice,
1960
- lowestTriggerAbovePrice,
1961
- highestTriggerBelowPrice,
1962
- };
1963
- }
1964
-
1965
- return results;
1966
- }
1967
-
1968
- /**
1969
- * @description Get the base asset balance of a margin manager
1970
- * @param {string} marginManagerKey The key to identify the margin manager
1971
- * @param {number} decimals Number of decimal places to show (default: 6)
1972
- * @returns {Promise<string>} The base asset balance
1973
- */
1974
- async getMarginManagerBaseBalance(
1975
- marginManagerKey: string,
1976
- decimals: number = 9,
1977
- ): Promise<string> {
1978
- const manager = this.#config.getMarginManager(marginManagerKey);
1979
- const tx = new Transaction();
1980
- tx.add(this.marginManager.baseBalance(manager.poolKey, manager.address));
1981
-
1982
- const res = await this.#client.core.simulateTransaction({
1983
- transaction: tx,
1984
- include: { commandResults: true, effects: true },
1985
- });
1986
-
1987
- if (res.FailedTransaction) {
1988
- throw new Error(
1989
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
1990
- );
1991
- }
1992
-
1993
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
1994
- throw new Error(`Failed to get margin manager base balance: Unknown error`);
1995
- }
1996
-
1997
- const bytes = res.commandResults[0].returnValues[0].bcs;
1998
- const pool = this.#config.getPool(manager.poolKey);
1999
- const baseCoin = this.#config.getCoin(pool.baseCoin);
2000
-
2001
- return this.#formatTokenAmount(BigInt(bcs.U64.parse(bytes)), baseCoin.scalar, decimals);
2002
- }
2003
-
2004
- /**
2005
- * @description Get the quote asset balance of a margin manager
2006
- * @param {string} marginManagerKey The key to identify the margin manager
2007
- * @param {number} decimals Number of decimal places to show (default: 6)
2008
- * @returns {Promise<string>} The quote asset balance
2009
- */
2010
- async getMarginManagerQuoteBalance(
2011
- marginManagerKey: string,
2012
- decimals: number = 9,
2013
- ): Promise<string> {
2014
- const manager = this.#config.getMarginManager(marginManagerKey);
2015
- const tx = new Transaction();
2016
- tx.add(this.marginManager.quoteBalance(manager.poolKey, manager.address));
2017
-
2018
- const res = await this.#client.core.simulateTransaction({
2019
- transaction: tx,
2020
- include: { commandResults: true, effects: true },
2021
- });
2022
-
2023
- if (res.FailedTransaction) {
2024
- throw new Error(
2025
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
2026
- );
2027
- }
2028
-
2029
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
2030
- throw new Error(`Failed to get margin manager quote balance: Unknown error`);
2031
- }
2032
-
2033
- const bytes = res.commandResults[0].returnValues[0].bcs;
2034
- const pool = this.#config.getPool(manager.poolKey);
2035
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
2036
-
2037
- return this.#formatTokenAmount(BigInt(bcs.U64.parse(bytes)), quoteCoin.scalar, decimals);
2038
- }
2039
-
2040
- /**
2041
- * @description Get the DEEP token balance of a margin manager
2042
- * @param {string} marginManagerKey The key to identify the margin manager
2043
- * @param {number} decimals Number of decimal places to show (default: 6)
2044
- * @returns {Promise<string>} The DEEP token balance
2045
- */
2046
- async getMarginManagerDeepBalance(
2047
- marginManagerKey: string,
2048
- decimals: number = 6,
2049
- ): Promise<string> {
2050
- const manager = this.#config.getMarginManager(marginManagerKey);
2051
- const tx = new Transaction();
2052
- tx.add(this.marginManager.deepBalance(manager.poolKey, manager.address));
2053
-
2054
- const res = await this.#client.core.simulateTransaction({
2055
- transaction: tx,
2056
- include: { commandResults: true, effects: true },
2057
- });
2058
-
2059
- if (res.FailedTransaction) {
2060
- throw new Error(
2061
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
2062
- );
2063
- }
2064
-
2065
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
2066
- throw new Error(`Failed to get margin manager DEEP balance: Unknown error`);
2067
- }
2068
-
2069
- const bytes = res.commandResults[0].returnValues[0].bcs;
2070
- const deepCoin = this.#config.getCoin('DEEP');
2071
-
2072
- return this.#formatTokenAmount(BigInt(bcs.U64.parse(bytes)), deepCoin.scalar, decimals);
2073
- }
2074
-
2075
- /**
2076
- * @description Get base, quote, and DEEP balances for multiple margin managers in a single dry run call
2077
- * @param {Record<string, string>} marginManagers Map of marginManagerId -> poolKey
2078
- * @param {number} decimals Number of decimal places for formatting (default: 9)
2079
- * @returns {Promise<Record<string, { base: string, quote: string, deep: string }>>} Object keyed by managerId
2080
- */
2081
- async getMarginManagerBalances(
2082
- marginManagers: Record<string, string>,
2083
- decimals: number = 9,
2084
- ): Promise<Record<string, { base: string; quote: string; deep: string }>> {
2085
- const entries = Object.entries(marginManagers);
2086
- if (entries.length === 0) {
2087
- return {};
2088
- }
2089
-
2090
- const tx = new Transaction();
2091
-
2092
- // 3 calls per manager: base, quote, deep
2093
- for (const [managerId, poolKey] of entries) {
2094
- tx.add(this.marginManager.baseBalance(poolKey, managerId));
2095
- tx.add(this.marginManager.quoteBalance(poolKey, managerId));
2096
- tx.add(this.marginManager.deepBalance(poolKey, managerId));
2097
- }
2098
-
2099
- const res = await this.#client.core.simulateTransaction({
2100
- transaction: tx,
2101
- include: { commandResults: true, effects: true },
2102
- });
2103
-
2104
- if (res.FailedTransaction) {
2105
- throw new Error(
2106
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
2107
- );
2108
- }
2109
-
2110
- if (!res.commandResults) {
2111
- throw new Error('Failed to get margin manager balances: No command results');
2112
- }
2113
-
2114
- const results: Record<string, { base: string; quote: string; deep: string }> = {};
2115
- const deepCoin = this.#config.getCoin('DEEP');
2116
-
2117
- for (let i = 0; i < entries.length; i++) {
2118
- const [managerId, poolKey] = entries[i];
2119
- const pool = this.#config.getPool(poolKey);
2120
- const baseCoin = this.#config.getCoin(pool.baseCoin);
2121
- const quoteCoin = this.#config.getCoin(pool.quoteCoin);
2122
-
2123
- const baseResult = res.commandResults[i * 3];
2124
- const quoteResult = res.commandResults[i * 3 + 1];
2125
- const deepResult = res.commandResults[i * 3 + 2];
2126
-
2127
- if (!baseResult?.returnValues || !quoteResult?.returnValues || !deepResult?.returnValues) {
2128
- throw new Error(`Failed to get balances for margin manager ${managerId}: No return values`);
2129
- }
2130
-
2131
- results[managerId] = {
2132
- base: this.#formatTokenAmount(
2133
- BigInt(bcs.U64.parse(baseResult.returnValues[0].bcs)),
2134
- baseCoin.scalar,
2135
- decimals,
2136
- ),
2137
- quote: this.#formatTokenAmount(
2138
- BigInt(bcs.U64.parse(quoteResult.returnValues[0].bcs)),
2139
- quoteCoin.scalar,
2140
- decimals,
2141
- ),
2142
- deep: this.#formatTokenAmount(
2143
- BigInt(bcs.U64.parse(deepResult.returnValues[0].bcs)),
2144
- deepCoin.scalar,
2145
- decimals,
2146
- ),
2147
- };
2148
- }
2149
-
2150
- return results;
2151
- }
2152
-
2153
- // === Margin TPSL (Take Profit / Stop Loss) Read-Only Functions ===
2154
-
2155
- /**
2156
- * @description Get all conditional order IDs for a margin manager
2157
- * @param {string} marginManagerKey The key to identify the margin manager
2158
- * @returns {Promise<string[]>} Array of conditional order IDs
2159
- */
2160
- async getConditionalOrderIds(marginManagerKey: string): Promise<string[]> {
2161
- const manager = this.#config.getMarginManager(marginManagerKey);
2162
- const tx = new Transaction();
2163
- tx.add(this.marginTPSL.conditionalOrderIds(manager.poolKey, manager.address));
2164
-
2165
- const res = await this.#client.core.simulateTransaction({
2166
- transaction: tx,
2167
- include: { commandResults: true, effects: true },
2168
- });
2169
-
2170
- if (res.FailedTransaction) {
2171
- throw new Error(
2172
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
2173
- );
2174
- }
2175
-
2176
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
2177
- throw new Error(`Failed to get conditional order IDs: Unknown error`);
2178
- }
2179
-
2180
- const bytes = res.commandResults[0].returnValues[0].bcs;
2181
- const orderIds = bcs.vector(bcs.u64()).parse(bytes);
2182
- return orderIds.map((id) => id.toString());
2183
- }
2184
-
2185
- /**
2186
- * @description Get the lowest trigger price for trigger_above orders
2187
- * Returns MAX_U64 if there are no trigger_above orders
2188
- * @param {string} marginManagerKey The key to identify the margin manager
2189
- * @returns {Promise<bigint>} The lowest trigger above price
2190
- */
2191
- async getLowestTriggerAbovePrice(marginManagerKey: string): Promise<bigint> {
2192
- const manager = this.#config.getMarginManager(marginManagerKey);
2193
- const tx = new Transaction();
2194
- tx.add(this.marginTPSL.lowestTriggerAbovePrice(manager.poolKey, manager.address));
2195
-
2196
- const res = await this.#client.core.simulateTransaction({
2197
- transaction: tx,
2198
- include: { commandResults: true, effects: true },
2199
- });
2200
-
2201
- if (res.FailedTransaction) {
2202
- throw new Error(
2203
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
2204
- );
2205
- }
2206
-
2207
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
2208
- throw new Error(`Failed to get lowest trigger above price: Unknown error`);
2209
- }
2210
-
2211
- const bytes = res.commandResults[0].returnValues[0].bcs;
2212
- return BigInt(bcs.U64.parse(bytes));
2213
- }
2214
-
2215
- /**
2216
- * @description Get the highest trigger price for trigger_below orders
2217
- * Returns 0 if there are no trigger_below orders
2218
- * @param {string} marginManagerKey The key to identify the margin manager
2219
- * @returns {Promise<bigint>} The highest trigger below price
2220
- */
2221
- async getHighestTriggerBelowPrice(marginManagerKey: string): Promise<bigint> {
2222
- const manager = this.#config.getMarginManager(marginManagerKey);
2223
- const tx = new Transaction();
2224
- tx.add(this.marginTPSL.highestTriggerBelowPrice(manager.poolKey, manager.address));
2225
-
2226
- const res = await this.#client.core.simulateTransaction({
2227
- transaction: tx,
2228
- include: { commandResults: true, effects: true },
2229
- });
2230
-
2231
- if (res.FailedTransaction) {
2232
- throw new Error(
2233
- `Transaction failed: ${res.FailedTransaction.status.error?.message || 'Unknown error'}`,
2234
- );
2235
- }
2236
-
2237
- if (!res.commandResults || !res.commandResults[0] || !res.commandResults[0].returnValues) {
2238
- throw new Error(`Failed to get highest trigger below price: Unknown error`);
2239
- }
2240
-
2241
- const bytes = res.commandResults[0].returnValues[0].bcs;
2242
- return BigInt(bcs.U64.parse(bytes));
2243
- }
2244
-
2245
- // === Margin Registry Functions ===
2246
-
2247
- /**
2248
- * @description Check if a deepbook pool is enabled for margin trading
2249
- * @param {string} poolKey The key to identify the pool
2250
- * @returns {Promise<boolean>} True if the pool is enabled for margin trading
2251
- */
2252
- async isPoolEnabledForMargin(poolKey: string): Promise<boolean> {
2253
- const tx = new Transaction();
2254
- tx.add(this.marginRegistry.poolEnabled(poolKey));
2255
-
2256
- const res = await this.#client.core.simulateTransaction({
2257
- transaction: tx,
2258
- include: { commandResults: true, effects: true },
2259
- });
2260
-
2261
- const bytes = res.commandResults![0].returnValues[0].bcs;
2262
- return bcs.Bool.parse(bytes);
2263
- }
2264
-
2265
- /**
2266
- * @description Get the margin manager IDs for a given owner address
2267
- * @param {string} owner The owner address
2268
- * @returns {Promise<string[]>} Array of margin manager IDs
2269
- */
2270
- async getMarginManagerIdsForOwner(owner: string): Promise<string[]> {
2271
- const tx = new Transaction();
2272
- tx.add(this.marginRegistry.getMarginManagerIds(owner));
2273
-
2274
- const res = await this.#client.core.simulateTransaction({
2275
- transaction: tx,
2276
- include: { commandResults: true, effects: true },
2277
- });
2278
-
2279
- const bytes = res.commandResults![0].returnValues[0].bcs;
2280
- const vecSet = VecSet(bcs.Address).parse(bytes);
2281
- return vecSet.contents.map((id) => normalizeSuiAddress(id));
2282
- }
2283
-
2284
- /**
2285
- * @description Get the base margin pool ID for a deepbook pool
2286
- * @param {string} poolKey The key to identify the pool
2287
- * @returns {Promise<string>} The base margin pool ID
2288
- */
2289
- async getBaseMarginPoolId(poolKey: string): Promise<string> {
2290
- const tx = new Transaction();
2291
- tx.add(this.marginRegistry.baseMarginPoolId(poolKey));
2292
-
2293
- const res = await this.#client.core.simulateTransaction({
2294
- transaction: tx,
2295
- include: { commandResults: true, effects: true },
2296
- });
2297
-
2298
- const bytes = res.commandResults![0].returnValues[0].bcs;
2299
- const id = bcs.Address.parse(bytes);
2300
- return '0x' + id;
2301
- }
2302
-
2303
- /**
2304
- * @description Get the quote margin pool ID for a deepbook pool
2305
- * @param {string} poolKey The key to identify the pool
2306
- * @returns {Promise<string>} The quote margin pool ID
2307
- */
2308
- async getQuoteMarginPoolId(poolKey: string): Promise<string> {
2309
- const tx = new Transaction();
2310
- tx.add(this.marginRegistry.quoteMarginPoolId(poolKey));
2311
-
2312
- const res = await this.#client.core.simulateTransaction({
2313
- transaction: tx,
2314
- include: { commandResults: true, effects: true },
2315
- });
2316
-
2317
- const bytes = res.commandResults![0].returnValues[0].bcs;
2318
- const id = bcs.Address.parse(bytes);
2319
- return '0x' + id;
2320
- }
2321
-
2322
- /**
2323
- * @description Get the minimum withdraw risk ratio for a deepbook pool
2324
- * @param {string} poolKey The key to identify the pool
2325
- * @returns {Promise<number>} The minimum withdraw risk ratio as a decimal (e.g., 1.5 for 150%)
2326
- */
2327
- async getMinWithdrawRiskRatio(poolKey: string): Promise<number> {
2328
- const tx = new Transaction();
2329
- tx.add(this.marginRegistry.minWithdrawRiskRatio(poolKey));
2330
-
2331
- const res = await this.#client.core.simulateTransaction({
2332
- transaction: tx,
2333
- include: { commandResults: true, effects: true },
2334
- });
2335
-
2336
- const bytes = res.commandResults![0].returnValues[0].bcs;
2337
- const ratio = Number(bcs.U64.parse(bytes));
2338
- return ratio / FLOAT_SCALAR;
2339
- }
2340
-
2341
- /**
2342
- * @description Get the minimum borrow risk ratio for a deepbook pool
2343
- * @param {string} poolKey The key to identify the pool
2344
- * @returns {Promise<number>} The minimum borrow risk ratio as a decimal (e.g., 1.25 for 125%)
2345
- */
2346
- async getMinBorrowRiskRatio(poolKey: string): Promise<number> {
2347
- const tx = new Transaction();
2348
- tx.add(this.marginRegistry.minBorrowRiskRatio(poolKey));
2349
-
2350
- const res = await this.#client.core.simulateTransaction({
2351
- transaction: tx,
2352
- include: { commandResults: true, effects: true },
2353
- });
2354
-
2355
- const bytes = res.commandResults![0].returnValues[0].bcs;
2356
- const ratio = Number(bcs.U64.parse(bytes));
2357
- return ratio / FLOAT_SCALAR;
2358
- }
2359
-
2360
- /**
2361
- * @description Get the liquidation risk ratio for a deepbook pool
2362
- * @param {string} poolKey The key to identify the pool
2363
- * @returns {Promise<number>} The liquidation risk ratio as a decimal (e.g., 1.125 for 112.5%)
2364
- */
2365
- async getLiquidationRiskRatio(poolKey: string): Promise<number> {
2366
- const tx = new Transaction();
2367
- tx.add(this.marginRegistry.liquidationRiskRatio(poolKey));
2368
-
2369
- const res = await this.#client.core.simulateTransaction({
2370
- transaction: tx,
2371
- include: { commandResults: true, effects: true },
2372
- });
2373
-
2374
- const bytes = res.commandResults![0].returnValues[0].bcs;
2375
- const ratio = Number(bcs.U64.parse(bytes));
2376
- return ratio / FLOAT_SCALAR;
2377
- }
2378
-
2379
- /**
2380
- * @description Get the target liquidation risk ratio for a deepbook pool
2381
- * @param {string} poolKey The key to identify the pool
2382
- * @returns {Promise<number>} The target liquidation risk ratio as a decimal (e.g., 1.25 for 125%)
2383
- */
2384
- async getTargetLiquidationRiskRatio(poolKey: string): Promise<number> {
2385
- const tx = new Transaction();
2386
- tx.add(this.marginRegistry.targetLiquidationRiskRatio(poolKey));
2387
-
2388
- const res = await this.#client.core.simulateTransaction({
2389
- transaction: tx,
2390
- include: { commandResults: true, effects: true },
2391
- });
2392
-
2393
- const bytes = res.commandResults![0].returnValues[0].bcs;
2394
- const ratio = Number(bcs.U64.parse(bytes));
2395
- return ratio / FLOAT_SCALAR;
2396
- }
2397
-
2398
- /**
2399
- * @description Get the user liquidation reward for a deepbook pool
2400
- * @param {string} poolKey The key to identify the pool
2401
- * @returns {Promise<number>} The user liquidation reward as a decimal (e.g., 0.05 for 5%)
2402
- */
2403
- async getUserLiquidationReward(poolKey: string): Promise<number> {
2404
- const tx = new Transaction();
2405
- tx.add(this.marginRegistry.userLiquidationReward(poolKey));
2406
-
2407
- const res = await this.#client.core.simulateTransaction({
2408
- transaction: tx,
2409
- include: { commandResults: true, effects: true },
2410
- });
2411
-
2412
- const bytes = res.commandResults![0].returnValues[0].bcs;
2413
- const reward = Number(bcs.U64.parse(bytes));
2414
- return reward / FLOAT_SCALAR;
2415
- }
2416
-
2417
- /**
2418
- * @description Get the pool liquidation reward for a deepbook pool
2419
- * @param {string} poolKey The key to identify the pool
2420
- * @returns {Promise<number>} The pool liquidation reward as a decimal (e.g., 0.05 for 5%)
2421
- */
2422
- async getPoolLiquidationReward(poolKey: string): Promise<number> {
2423
- const tx = new Transaction();
2424
- tx.add(this.marginRegistry.poolLiquidationReward(poolKey));
2425
-
2426
- const res = await this.#client.core.simulateTransaction({
2427
- transaction: tx,
2428
- include: { commandResults: true, effects: true },
2429
- });
2430
-
2431
- const bytes = res.commandResults![0].returnValues[0].bcs;
2432
- const reward = Number(bcs.U64.parse(bytes));
2433
- return reward / FLOAT_SCALAR;
2434
- }
2435
-
2436
- /**
2437
- * @description Get all allowed maintainer cap IDs
2438
- * @returns {Promise<string[]>} Array of allowed maintainer cap IDs
2439
- */
2440
- async getAllowedMaintainers(): Promise<string[]> {
2441
- const tx = new Transaction();
2442
- tx.add(this.marginRegistry.allowedMaintainers());
2443
-
2444
- const res = await this.#client.core.simulateTransaction({
2445
- transaction: tx,
2446
- include: { commandResults: true, effects: true },
2447
- });
2448
-
2449
- const bytes = res.commandResults![0].returnValues[0].bcs;
2450
- const vecSet = VecSet(bcs.Address).parse(bytes);
2451
- return vecSet.contents.map((id) => normalizeSuiAddress(id));
2452
- }
2453
-
2454
- /**
2455
- * @description Get all allowed pause cap IDs
2456
- * @returns {Promise<string[]>} Array of allowed pause cap IDs
2457
- */
2458
- async getAllowedPauseCaps(): Promise<string[]> {
2459
- const tx = new Transaction();
2460
- tx.add(this.marginRegistry.allowedPauseCaps());
2461
-
2462
- const res = await this.#client.core.simulateTransaction({
2463
- transaction: tx,
2464
- include: { commandResults: true, effects: true },
2465
- });
2466
-
2467
- const bytes = res.commandResults![0].returnValues[0].bcs;
2468
- const vecSet = VecSet(bcs.Address).parse(bytes);
2469
- return vecSet.contents.map((id) => normalizeSuiAddress(id));
2470
- }
2471
-
2472
- /**
2473
- * @description Check if a pool is a stable pool
2474
- * @param {string} poolKey Key of the pool
2475
- * @returns {Promise<boolean>} Whether the pool is a stable pool
2476
- */
2477
- async stablePool(poolKey: string): Promise<boolean> {
2478
- const tx = new Transaction();
2479
- tx.add(this.deepBook.stablePool(poolKey));
2480
-
2481
- const res = await this.#client.core.simulateTransaction({
2482
- transaction: tx,
2483
- include: { commandResults: true, effects: true },
2484
- });
2485
-
2486
- const bytes = res.commandResults![0].returnValues[0].bcs;
2487
- return bcs.bool().parse(bytes);
2488
- }
2489
-
2490
- /**
2491
- * @description Check if a pool is registered
2492
- * @param {string} poolKey Key of the pool
2493
- * @returns {Promise<boolean>} Whether the pool is registered
2494
- */
2495
- async registeredPool(poolKey: string): Promise<boolean> {
2496
- const tx = new Transaction();
2497
- tx.add(this.deepBook.registeredPool(poolKey));
2498
-
2499
- const res = await this.#client.core.simulateTransaction({
2500
- transaction: tx,
2501
- include: { commandResults: true, effects: true },
2502
- });
2503
-
2504
- const bytes = res.commandResults![0].returnValues[0].bcs;
2505
- return bcs.bool().parse(bytes);
2506
- }
2507
-
2508
- /**
2509
- * @description Get the quote quantity out using input token as fee
2510
- * @param {string} poolKey Key of the pool
2511
- * @param {number} baseQuantity Base quantity
2512
- * @returns {Promise<{baseQuantity: number, baseOut: number, quoteOut: number, deepRequired: number}>}
2513
- */
2514
- async getQuoteQuantityOutInputFee(poolKey: string, baseQuantity: number) {
2515
- const tx = new Transaction();
2516
- const pool = this.#config.getPool(poolKey);
2517
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
2518
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
2519
-
2520
- tx.add(this.deepBook.getQuoteQuantityOutInputFee(poolKey, baseQuantity));
2521
- const res = await this.#client.core.simulateTransaction({
2522
- transaction: tx,
2523
- include: { commandResults: true, effects: true },
2524
- });
2525
-
2526
- const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
2527
- const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
2528
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
2529
-
2530
- return {
2531
- baseQuantity,
2532
- baseOut: Number((baseOut / baseScalar).toFixed(9)),
2533
- quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
2534
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
2535
- };
2536
- }
2537
-
2538
- /**
2539
- * @description Get the base quantity out using input token as fee
2540
- * @param {string} poolKey Key of the pool
2541
- * @param {number} quoteQuantity Quote quantity
2542
- * @returns {Promise<{quoteQuantity: number, baseOut: number, quoteOut: number, deepRequired: number}>}
2543
- */
2544
- async getBaseQuantityOutInputFee(poolKey: string, quoteQuantity: number) {
2545
- const tx = new Transaction();
2546
- const pool = this.#config.getPool(poolKey);
2547
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
2548
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
2549
-
2550
- tx.add(this.deepBook.getBaseQuantityOutInputFee(poolKey, quoteQuantity));
2551
- const res = await this.#client.core.simulateTransaction({
2552
- transaction: tx,
2553
- include: { commandResults: true, effects: true },
2554
- });
2555
-
2556
- const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
2557
- const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
2558
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
2559
-
2560
- return {
2561
- quoteQuantity,
2562
- baseOut: Number((baseOut / baseScalar).toFixed(9)),
2563
- quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
2564
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
2565
- };
2566
- }
2567
-
2568
- /**
2569
- * @description Get the quantity out using input token as fee
2570
- * @param {string} poolKey Key of the pool
2571
- * @param {number} baseQuantity Base quantity
2572
- * @param {number} quoteQuantity Quote quantity
2573
- * @returns {Promise<{baseQuantity: number, quoteQuantity: number, baseOut: number, quoteOut: number, deepRequired: number}>}
2574
- */
2575
- async getQuantityOutInputFee(poolKey: string, baseQuantity: number, quoteQuantity: number) {
2576
- const tx = new Transaction();
2577
- const pool = this.#config.getPool(poolKey);
2578
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
2579
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
2580
-
2581
- tx.add(this.deepBook.getQuantityOutInputFee(poolKey, baseQuantity, quoteQuantity));
2582
- const res = await this.#client.core.simulateTransaction({
2583
- transaction: tx,
2584
- include: { commandResults: true, effects: true },
2585
- });
2586
-
2587
- const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
2588
- const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
2589
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
2590
-
2591
- return {
2592
- baseQuantity,
2593
- quoteQuantity,
2594
- baseOut: Number((baseOut / baseScalar).toFixed(9)),
2595
- quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
2596
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
2597
- };
2598
- }
2599
-
2600
- /**
2601
- * @description Get the base quantity needed to receive target quote quantity
2602
- * @param {string} poolKey Key of the pool
2603
- * @param {number} targetQuoteQuantity Target quote quantity
2604
- * @param {boolean} payWithDeep Whether to pay fees with DEEP
2605
- * @returns {Promise<{baseIn: number, quoteOut: number, deepRequired: number}>}
2606
- */
2607
- async getBaseQuantityIn(poolKey: string, targetQuoteQuantity: number, payWithDeep: boolean) {
2608
- const tx = new Transaction();
2609
- const pool = this.#config.getPool(poolKey);
2610
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
2611
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
2612
-
2613
- tx.add(this.deepBook.getBaseQuantityIn(poolKey, targetQuoteQuantity, payWithDeep));
2614
- const res = await this.#client.core.simulateTransaction({
2615
- transaction: tx,
2616
- include: { commandResults: true, effects: true },
2617
- });
2618
-
2619
- const baseIn = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
2620
- const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
2621
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
2622
-
2623
- return {
2624
- baseIn: Number((baseIn / baseScalar).toFixed(9)),
2625
- quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
2626
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
2627
- };
2628
- }
2629
-
2630
- /**
2631
- * @description Get the quote quantity needed to receive target base quantity
2632
- * @param {string} poolKey Key of the pool
2633
- * @param {number} targetBaseQuantity Target base quantity
2634
- * @param {boolean} payWithDeep Whether to pay fees with DEEP
2635
- * @returns {Promise<{baseOut: number, quoteIn: number, deepRequired: number}>}
2636
- */
2637
- async getQuoteQuantityIn(poolKey: string, targetBaseQuantity: number, payWithDeep: boolean) {
2638
- const tx = new Transaction();
2639
- const pool = this.#config.getPool(poolKey);
2640
- const baseScalar = this.#config.getCoin(pool.baseCoin).scalar;
2641
- const quoteScalar = this.#config.getCoin(pool.quoteCoin).scalar;
2642
-
2643
- tx.add(this.deepBook.getQuoteQuantityIn(poolKey, targetBaseQuantity, payWithDeep));
2644
- const res = await this.#client.core.simulateTransaction({
2645
- transaction: tx,
2646
- include: { commandResults: true, effects: true },
2647
- });
2648
-
2649
- const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
2650
- const quoteIn = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
2651
- const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
2652
-
2653
- return {
2654
- baseOut: Number((baseOut / baseScalar).toFixed(9)),
2655
- quoteIn: Number((quoteIn / quoteScalar).toFixed(9)),
2656
- deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
2657
- };
2658
- }
2659
-
2660
- /**
2661
- * @description Get account order details for a balance manager
2662
- * @param {string} poolKey Key of the pool
2663
- * @param {string} managerKey Key of the balance manager
2664
- * @returns {Promise<Array>} Array of order details
2665
- */
2666
- async getAccountOrderDetails(poolKey: string, managerKey: string) {
2667
- const tx = new Transaction();
2668
- tx.add(this.deepBook.getAccountOrderDetails(poolKey, managerKey));
2669
-
2670
- const res = await this.#client.core.simulateTransaction({
2671
- transaction: tx,
2672
- include: { commandResults: true, effects: true },
2673
- });
2674
-
2675
- try {
2676
- const orderInformation = res.commandResults![0].returnValues[0].bcs;
2677
- return bcs.vector(Order).parse(new Uint8Array(orderInformation));
2678
- } catch {
2679
- return [];
2680
- }
2681
- }
2682
-
2683
- /**
2684
- * @description Get the DEEP required for an order
2685
- * @param {string} poolKey Key of the pool
2686
- * @param {number} baseQuantity Base quantity
2687
- * @param {number} price Price
2688
- * @returns {Promise<{deepRequiredTaker: number, deepRequiredMaker: number}>}
2689
- */
2690
- async getOrderDeepRequired(poolKey: string, baseQuantity: number, price: number) {
2691
- const tx = new Transaction();
2692
- tx.add(this.deepBook.getOrderDeepRequired(poolKey, baseQuantity, price));
2693
-
2694
- const res = await this.#client.core.simulateTransaction({
2695
- transaction: tx,
2696
- include: { commandResults: true, effects: true },
2697
- });
2698
-
2699
- const deepRequiredTaker = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
2700
- const deepRequiredMaker = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
2701
-
2702
- return {
2703
- deepRequiredTaker: Number((deepRequiredTaker / DEEP_SCALAR).toFixed(9)),
2704
- deepRequiredMaker: Number((deepRequiredMaker / DEEP_SCALAR).toFixed(9)),
2705
- };
2706
- }
2707
-
2708
- /**
2709
- * @description Check if account exists for a balance manager
2710
- * @param {string} poolKey Key of the pool
2711
- * @param {string} managerKey Key of the balance manager
2712
- * @returns {Promise<boolean>} Whether account exists
2713
- */
2714
- async accountExists(poolKey: string, managerKey: string): Promise<boolean> {
2715
- const tx = new Transaction();
2716
- tx.add(this.deepBook.accountExists(poolKey, managerKey));
2717
-
2718
- const res = await this.#client.core.simulateTransaction({
2719
- transaction: tx,
2720
- include: { commandResults: true, effects: true },
2721
- });
2722
-
2723
- const bytes = res.commandResults![0].returnValues[0].bcs;
2724
- return bcs.bool().parse(bytes);
2725
- }
2726
-
2727
- /**
2728
- * @description Get the next epoch trade parameters
2729
- * @param {string} poolKey Key of the pool
2730
- * @returns {Promise<{takerFee: number, makerFee: number, stakeRequired: number}>}
2731
- */
2732
- async poolTradeParamsNext(poolKey: string) {
2733
- const tx = new Transaction();
2734
- tx.add(this.deepBook.poolTradeParamsNext(poolKey));
2735
-
2736
- const res = await this.#client.core.simulateTransaction({
2737
- transaction: tx,
2738
- include: { commandResults: true, effects: true },
2739
- });
2740
-
2741
- const takerFee = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
2742
- const makerFee = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
2743
- const stakeRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
2744
-
2745
- return {
2746
- takerFee: takerFee / FLOAT_SCALAR,
2747
- makerFee: makerFee / FLOAT_SCALAR,
2748
- stakeRequired: stakeRequired / DEEP_SCALAR,
2749
- };
2750
- }
2751
-
2752
- /**
2753
- * @description Get the quorum for a pool
2754
- * @param {string} poolKey Key of the pool
2755
- * @returns {Promise<number>} The quorum amount in DEEP
2756
- */
2757
- async quorum(poolKey: string): Promise<number> {
2758
- const tx = new Transaction();
2759
- tx.add(this.deepBook.quorum(poolKey));
2760
-
2761
- const res = await this.#client.core.simulateTransaction({
2762
- transaction: tx,
2763
- include: { commandResults: true, effects: true },
2764
- });
2765
-
2766
- const bytes = res.commandResults![0].returnValues[0].bcs;
2767
- const quorum = Number(bcs.U64.parse(bytes));
2768
- return quorum / DEEP_SCALAR;
2769
- }
2770
-
2771
- /**
2772
- * @description Get the pool ID
2773
- * @param {string} poolKey Key of the pool
2774
- * @returns {Promise<string>} The pool ID
2775
- */
2776
- async poolId(poolKey: string): Promise<string> {
2777
- const tx = new Transaction();
2778
- tx.add(this.deepBook.poolId(poolKey));
2779
-
2780
- const res = await this.#client.core.simulateTransaction({
2781
- transaction: tx,
2782
- include: { commandResults: true, effects: true },
2783
- });
2784
-
2785
- const bytes = res.commandResults![0].returnValues[0].bcs;
2786
- return normalizeSuiAddress(bcs.Address.parse(bytes));
2787
- }
2788
-
2789
- /**
2790
- * @description Check if a limit order can be placed
2791
- * @param {CanPlaceLimitOrderParams} params Parameters for checking limit order placement
2792
- * @returns {Promise<boolean>} Whether order can be placed
2793
- */
2794
- async canPlaceLimitOrder(params: CanPlaceLimitOrderParams): Promise<boolean> {
2795
- const tx = new Transaction();
2796
- tx.add(this.deepBook.canPlaceLimitOrder(params));
2797
-
2798
- const res = await this.#client.core.simulateTransaction({
2799
- transaction: tx,
2800
- include: { commandResults: true, effects: true },
2801
- });
2802
-
2803
- const bytes = res.commandResults![0].returnValues[0].bcs;
2804
- return bcs.bool().parse(bytes);
2805
- }
2806
-
2807
- /**
2808
- * @description Check if a market order can be placed
2809
- * @param {CanPlaceMarketOrderParams} params Parameters for checking market order placement
2810
- * @returns {Promise<boolean>} Whether order can be placed
2811
- */
2812
- async canPlaceMarketOrder(params: CanPlaceMarketOrderParams): Promise<boolean> {
2813
- const tx = new Transaction();
2814
- tx.add(this.deepBook.canPlaceMarketOrder(params));
2815
-
2816
- const res = await this.#client.core.simulateTransaction({
2817
- transaction: tx,
2818
- include: { commandResults: true, effects: true },
2819
- });
2820
-
2821
- const bytes = res.commandResults![0].returnValues[0].bcs;
2822
- return bcs.bool().parse(bytes);
2823
- }
2824
-
2825
- /**
2826
- * @description Check if market order params are valid
2827
- * @param {string} poolKey Key of the pool
2828
- * @param {number} quantity Quantity
2829
- * @returns {Promise<boolean>} Whether params are valid
2830
- */
2831
- async checkMarketOrderParams(poolKey: string, quantity: number): Promise<boolean> {
2832
- const tx = new Transaction();
2833
- tx.add(this.deepBook.checkMarketOrderParams(poolKey, quantity));
2834
-
2835
- const res = await this.#client.core.simulateTransaction({
2836
- transaction: tx,
2837
- include: { commandResults: true, effects: true },
2838
- });
2839
-
2840
- const bytes = res.commandResults![0].returnValues[0].bcs;
2841
- return bcs.bool().parse(bytes);
2842
- }
2843
-
2844
- /**
2845
- * @description Check if limit order params are valid
2846
- * @param {string} poolKey Key of the pool
2847
- * @param {number} price Price
2848
- * @param {number} quantity Quantity
2849
- * @param {number} expireTimestamp Expiration timestamp
2850
- * @returns {Promise<boolean>} Whether params are valid
2851
- */
2852
- async checkLimitOrderParams(
2853
- poolKey: string,
2854
- price: number,
2855
- quantity: number,
2856
- expireTimestamp: number,
2857
- ): Promise<boolean> {
2858
- const tx = new Transaction();
2859
- tx.add(this.deepBook.checkLimitOrderParams(poolKey, price, quantity, expireTimestamp));
2860
-
2861
- const res = await this.#client.core.simulateTransaction({
2862
- transaction: tx,
2863
- include: { commandResults: true, effects: true },
2864
- });
2865
-
2866
- const bytes = res.commandResults![0].returnValues[0].bcs;
2867
- return bcs.bool().parse(bytes);
2868
- }
2869
-
2870
- /**
2871
- * @description Helper function to format token amounts without floating point errors
2872
- * @param {bigint} rawAmount The raw amount as bigint
2873
- * @param {number} scalar The token scalar (e.g., 1000000000 for 9 decimals)
2874
- * @param {number} decimals Number of decimal places to show
2875
- * @returns {string} Formatted amount as string
2876
- */
2877
- #formatTokenAmount(rawAmount: bigint, scalar: number, decimals: number): string {
2878
- const scalarBigInt = BigInt(scalar);
2879
- const integerPart = rawAmount / scalarBigInt;
2880
- const fractionalPart = rawAmount % scalarBigInt;
2881
-
2882
- // If no fractional part, return just the integer
2883
- if (fractionalPart === 0n) {
2884
- return integerPart.toString();
2885
- }
2886
-
2887
- // Convert fractional part to string with leading zeros
2888
- const scalarDigits = scalar.toString().length - 1;
2889
- const fractionalStr = fractionalPart.toString().padStart(scalarDigits, '0');
2890
-
2891
- // Truncate to desired decimal places
2892
- const truncated = fractionalStr.slice(0, decimals);
2893
-
2894
- // Remove trailing zeros for cleaner output
2895
- const trimmed = truncated.replace(/0+$/, '');
2896
-
2897
- // If nothing left after trimming, return just integer
2898
- if (!trimmed) {
2899
- return integerPart.toString();
2900
- }
2901
-
2902
- return `${integerPart}.${trimmed}`;
661
+ return { isBid, price, orderId };
2903
662
  }
2904
663
  }