@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
@@ -0,0 +1,141 @@
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { Transaction } from '@mysten/sui/transactions';
5
+
6
+ import { PriceInfoObject } from '../contracts/pyth/price_info.js';
7
+ import { SuiPriceServiceConnection, SuiPythClient } from '../pyth/pyth.js';
8
+ import { PRICE_INFO_OBJECT_MAX_AGE_MS } from '../utils/config.js';
9
+ import type { QueryContext } from './context.js';
10
+
11
+ export class PriceFeedQueries {
12
+ #ctx: QueryContext;
13
+
14
+ constructor(ctx: QueryContext) {
15
+ this.#ctx = ctx;
16
+ }
17
+
18
+ async getPriceInfoObject(tx: Transaction, coinKey: string): Promise<string> {
19
+ this.#ctx.config.requirePyth();
20
+ const currentTime = Date.now();
21
+ const priceInfoObjectAge = await this.getPriceInfoObjectAge(coinKey);
22
+ if (
23
+ priceInfoObjectAge &&
24
+ currentTime - priceInfoObjectAge * 1000 < PRICE_INFO_OBJECT_MAX_AGE_MS
25
+ ) {
26
+ return await this.#ctx.config.getCoin(coinKey).priceInfoObjectId!;
27
+ }
28
+
29
+ const endpoint =
30
+ this.#ctx.config.network === 'testnet'
31
+ ? 'https://hermes-beta.pyth.network'
32
+ : 'https://hermes.pyth.network';
33
+ const connection = new SuiPriceServiceConnection(endpoint);
34
+
35
+ const priceIDs = [this.#ctx.config.getCoin(coinKey).feed!];
36
+
37
+ const priceUpdateData = await connection.getPriceFeedsUpdateData(priceIDs);
38
+
39
+ const wormholeStateId = this.#ctx.config.pyth.wormholeStateId;
40
+ const pythStateId = this.#ctx.config.pyth.pythStateId;
41
+
42
+ const client = new SuiPythClient(this.#ctx.client, pythStateId, wormholeStateId);
43
+
44
+ return (await client.updatePriceFeeds(tx, priceUpdateData, priceIDs))[0];
45
+ }
46
+
47
+ async getPriceInfoObjects(tx: Transaction, coinKeys: string[]): Promise<Record<string, string>> {
48
+ this.#ctx.config.requirePyth();
49
+ if (coinKeys.length === 0) {
50
+ return {};
51
+ }
52
+
53
+ const currentTime = Date.now();
54
+
55
+ const coinToObjectId: Record<string, string> = {};
56
+ const objectIds: string[] = [];
57
+ for (const coinKey of coinKeys) {
58
+ const priceInfoObjectId = this.#ctx.config.getCoin(coinKey).priceInfoObjectId!;
59
+ coinToObjectId[coinKey] = priceInfoObjectId;
60
+ objectIds.push(priceInfoObjectId);
61
+ }
62
+
63
+ const res = await this.#ctx.client.core.getObjects({
64
+ objectIds,
65
+ include: { content: true },
66
+ });
67
+
68
+ const staleCoinKeys: string[] = [];
69
+ const result: Record<string, string> = {};
70
+
71
+ for (let i = 0; i < coinKeys.length; i++) {
72
+ const coinKey = coinKeys[i];
73
+ const obj = res.objects[i];
74
+
75
+ if (obj instanceof Error || !obj?.content) {
76
+ staleCoinKeys.push(coinKey);
77
+ continue;
78
+ }
79
+
80
+ const priceInfoObject = PriceInfoObject.parse(obj.content);
81
+ const arrivalTime = Number(priceInfoObject.price_info.arrival_time);
82
+ const age = currentTime - arrivalTime * 1000;
83
+
84
+ if (age >= PRICE_INFO_OBJECT_MAX_AGE_MS) {
85
+ staleCoinKeys.push(coinKey);
86
+ } else {
87
+ result[coinKey] = coinToObjectId[coinKey];
88
+ }
89
+ }
90
+
91
+ if (staleCoinKeys.length === 0) {
92
+ return result;
93
+ }
94
+
95
+ const staleFeedIds: string[] = [];
96
+ const feedIdToCoinKey: Record<string, string> = {};
97
+ for (const coinKey of staleCoinKeys) {
98
+ const feedId = this.#ctx.config.getCoin(coinKey).feed!;
99
+ staleFeedIds.push(feedId);
100
+ feedIdToCoinKey[feedId] = coinKey;
101
+ }
102
+
103
+ const endpoint =
104
+ this.#ctx.config.network === 'testnet'
105
+ ? 'https://hermes-beta.pyth.network'
106
+ : 'https://hermes.pyth.network';
107
+ const connection = new SuiPriceServiceConnection(endpoint);
108
+
109
+ const priceUpdateData = await connection.getPriceFeedsUpdateData(staleFeedIds);
110
+
111
+ const wormholeStateId = this.#ctx.config.pyth.wormholeStateId;
112
+ const pythStateId = this.#ctx.config.pyth.pythStateId;
113
+ const pythClient = new SuiPythClient(this.#ctx.client, pythStateId, wormholeStateId);
114
+
115
+ const updatedObjectIds = await pythClient.updatePriceFeeds(tx, priceUpdateData, staleFeedIds);
116
+
117
+ for (let i = 0; i < staleFeedIds.length; i++) {
118
+ const coinKey = feedIdToCoinKey[staleFeedIds[i]];
119
+ result[coinKey] = updatedObjectIds[i];
120
+ }
121
+
122
+ return result;
123
+ }
124
+
125
+ async getPriceInfoObjectAge(coinKey: string): Promise<number> {
126
+ const priceInfoObjectId = this.#ctx.config.getCoin(coinKey).priceInfoObjectId!;
127
+ const res = await this.#ctx.client.core.getObject({
128
+ objectId: priceInfoObjectId,
129
+ include: {
130
+ content: true,
131
+ },
132
+ });
133
+
134
+ if (!res.object?.content) {
135
+ throw new Error(`Price info object not found for ${coinKey}`);
136
+ }
137
+
138
+ const priceInfoObject = PriceInfoObject.parse(res.object.content);
139
+ return Number(priceInfoObject.price_info.arrival_time);
140
+ }
141
+ }
@@ -0,0 +1,266 @@
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { bcs } from '@mysten/sui/bcs';
5
+ import { Transaction } from '@mysten/sui/transactions';
6
+
7
+ import type {
8
+ BaseQuantityIn,
9
+ BaseQuantityOut,
10
+ OrderDeepRequiredResult,
11
+ QuantityOut,
12
+ QuoteQuantityIn,
13
+ QuoteQuantityOut,
14
+ } from '../types/index.js';
15
+ import { DEEP_SCALAR } from '../utils/config.js';
16
+ import type { QueryContext } from './context.js';
17
+
18
+ export class QuantityQueries {
19
+ #ctx: QueryContext;
20
+
21
+ constructor(ctx: QueryContext) {
22
+ this.#ctx = ctx;
23
+ }
24
+
25
+ async getQuoteQuantityOut(
26
+ poolKey: string,
27
+ baseQuantity: number | bigint,
28
+ ): Promise<QuoteQuantityOut> {
29
+ const tx = new Transaction();
30
+ const pool = this.#ctx.config.getPool(poolKey);
31
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
32
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
33
+
34
+ tx.add(this.#ctx.deepBook.getQuoteQuantityOut(poolKey, baseQuantity));
35
+ const res = await this.#ctx.client.core.simulateTransaction({
36
+ transaction: tx,
37
+ include: { commandResults: true, effects: true },
38
+ });
39
+
40
+ const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
41
+ const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
42
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
43
+
44
+ return {
45
+ baseQuantity: Number(baseQuantity),
46
+ baseOut: Number((baseOut / baseScalar).toFixed(9)),
47
+ quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
48
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
49
+ };
50
+ }
51
+
52
+ async getBaseQuantityOut(
53
+ poolKey: string,
54
+ quoteQuantity: number | bigint,
55
+ ): Promise<BaseQuantityOut> {
56
+ const tx = new Transaction();
57
+ const pool = this.#ctx.config.getPool(poolKey);
58
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
59
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
60
+
61
+ tx.add(this.#ctx.deepBook.getBaseQuantityOut(poolKey, quoteQuantity));
62
+ const res = await this.#ctx.client.core.simulateTransaction({
63
+ transaction: tx,
64
+ include: { commandResults: true, effects: true },
65
+ });
66
+
67
+ const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
68
+ const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
69
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
70
+
71
+ return {
72
+ quoteQuantity: Number(quoteQuantity),
73
+ baseOut: Number((baseOut / baseScalar).toFixed(9)),
74
+ quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
75
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
76
+ };
77
+ }
78
+
79
+ async getQuantityOut(
80
+ poolKey: string,
81
+ baseQuantity: number | bigint,
82
+ quoteQuantity: number | bigint,
83
+ ): Promise<QuantityOut> {
84
+ const tx = new Transaction();
85
+ const pool = this.#ctx.config.getPool(poolKey);
86
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
87
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
88
+
89
+ tx.add(this.#ctx.deepBook.getQuantityOut(poolKey, baseQuantity, quoteQuantity));
90
+ const res = await this.#ctx.client.core.simulateTransaction({
91
+ transaction: tx,
92
+ include: { commandResults: true, effects: true },
93
+ });
94
+
95
+ const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
96
+ const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
97
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
98
+
99
+ return {
100
+ baseQuantity: Number(baseQuantity),
101
+ quoteQuantity: Number(quoteQuantity),
102
+ baseOut: Number((baseOut / baseScalar).toFixed(9)),
103
+ quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
104
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
105
+ };
106
+ }
107
+
108
+ async getQuoteQuantityOutInputFee(
109
+ poolKey: string,
110
+ baseQuantity: number | bigint,
111
+ ): Promise<QuoteQuantityOut> {
112
+ const tx = new Transaction();
113
+ const pool = this.#ctx.config.getPool(poolKey);
114
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
115
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
116
+
117
+ tx.add(this.#ctx.deepBook.getQuoteQuantityOutInputFee(poolKey, baseQuantity));
118
+ const res = await this.#ctx.client.core.simulateTransaction({
119
+ transaction: tx,
120
+ include: { commandResults: true, effects: true },
121
+ });
122
+
123
+ const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
124
+ const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
125
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
126
+
127
+ return {
128
+ baseQuantity: Number(baseQuantity),
129
+ baseOut: Number((baseOut / baseScalar).toFixed(9)),
130
+ quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
131
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
132
+ };
133
+ }
134
+
135
+ async getBaseQuantityOutInputFee(
136
+ poolKey: string,
137
+ quoteQuantity: number | bigint,
138
+ ): Promise<BaseQuantityOut> {
139
+ const tx = new Transaction();
140
+ const pool = this.#ctx.config.getPool(poolKey);
141
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
142
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
143
+
144
+ tx.add(this.#ctx.deepBook.getBaseQuantityOutInputFee(poolKey, quoteQuantity));
145
+ const res = await this.#ctx.client.core.simulateTransaction({
146
+ transaction: tx,
147
+ include: { commandResults: true, effects: true },
148
+ });
149
+
150
+ const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
151
+ const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
152
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
153
+
154
+ return {
155
+ quoteQuantity: Number(quoteQuantity),
156
+ baseOut: Number((baseOut / baseScalar).toFixed(9)),
157
+ quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
158
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
159
+ };
160
+ }
161
+
162
+ async getQuantityOutInputFee(
163
+ poolKey: string,
164
+ baseQuantity: number | bigint,
165
+ quoteQuantity: number | bigint,
166
+ ): Promise<QuantityOut> {
167
+ const tx = new Transaction();
168
+ const pool = this.#ctx.config.getPool(poolKey);
169
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
170
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
171
+
172
+ tx.add(this.#ctx.deepBook.getQuantityOutInputFee(poolKey, baseQuantity, quoteQuantity));
173
+ const res = await this.#ctx.client.core.simulateTransaction({
174
+ transaction: tx,
175
+ include: { commandResults: true, effects: true },
176
+ });
177
+
178
+ const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
179
+ const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
180
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
181
+
182
+ return {
183
+ baseQuantity: Number(baseQuantity),
184
+ quoteQuantity: Number(quoteQuantity),
185
+ baseOut: Number((baseOut / baseScalar).toFixed(9)),
186
+ quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
187
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
188
+ };
189
+ }
190
+
191
+ async getBaseQuantityIn(
192
+ poolKey: string,
193
+ targetQuoteQuantity: number | bigint,
194
+ payWithDeep: boolean,
195
+ ): Promise<BaseQuantityIn> {
196
+ const tx = new Transaction();
197
+ const pool = this.#ctx.config.getPool(poolKey);
198
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
199
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
200
+
201
+ tx.add(this.#ctx.deepBook.getBaseQuantityIn(poolKey, targetQuoteQuantity, payWithDeep));
202
+ const res = await this.#ctx.client.core.simulateTransaction({
203
+ transaction: tx,
204
+ include: { commandResults: true, effects: true },
205
+ });
206
+
207
+ const baseIn = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
208
+ const quoteOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
209
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
210
+
211
+ return {
212
+ baseIn: Number((baseIn / baseScalar).toFixed(9)),
213
+ quoteOut: Number((quoteOut / quoteScalar).toFixed(9)),
214
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
215
+ };
216
+ }
217
+
218
+ async getQuoteQuantityIn(
219
+ poolKey: string,
220
+ targetBaseQuantity: number | bigint,
221
+ payWithDeep: boolean,
222
+ ): Promise<QuoteQuantityIn> {
223
+ const tx = new Transaction();
224
+ const pool = this.#ctx.config.getPool(poolKey);
225
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
226
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
227
+
228
+ tx.add(this.#ctx.deepBook.getQuoteQuantityIn(poolKey, targetBaseQuantity, payWithDeep));
229
+ const res = await this.#ctx.client.core.simulateTransaction({
230
+ transaction: tx,
231
+ include: { commandResults: true, effects: true },
232
+ });
233
+
234
+ const baseOut = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
235
+ const quoteIn = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
236
+ const deepRequired = Number(bcs.U64.parse(res.commandResults![0].returnValues[2].bcs));
237
+
238
+ return {
239
+ baseOut: Number((baseOut / baseScalar).toFixed(9)),
240
+ quoteIn: Number((quoteIn / quoteScalar).toFixed(9)),
241
+ deepRequired: Number((deepRequired / DEEP_SCALAR).toFixed(9)),
242
+ };
243
+ }
244
+
245
+ async getOrderDeepRequired(
246
+ poolKey: string,
247
+ baseQuantity: number | bigint,
248
+ price: number | bigint,
249
+ ): Promise<OrderDeepRequiredResult> {
250
+ const tx = new Transaction();
251
+ tx.add(this.#ctx.deepBook.getOrderDeepRequired(poolKey, baseQuantity, price));
252
+
253
+ const res = await this.#ctx.client.core.simulateTransaction({
254
+ transaction: tx,
255
+ include: { commandResults: true, effects: true },
256
+ });
257
+
258
+ const deepRequiredTaker = Number(bcs.U64.parse(res.commandResults![0].returnValues[0].bcs));
259
+ const deepRequiredMaker = Number(bcs.U64.parse(res.commandResults![0].returnValues[1].bcs));
260
+
261
+ return {
262
+ deepRequiredTaker: Number((deepRequiredTaker / DEEP_SCALAR).toFixed(9)),
263
+ deepRequiredMaker: Number((deepRequiredMaker / DEEP_SCALAR).toFixed(9)),
264
+ };
265
+ }
266
+ }
@@ -0,0 +1,112 @@
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { bcs } from '@mysten/sui/bcs';
5
+ import { Transaction } from '@mysten/sui/transactions';
6
+ import { normalizeSuiAddress } from '@mysten/sui/utils';
7
+
8
+ import type { ReferralBalances } from '../types/index.js';
9
+ import { DEEP_SCALAR, FLOAT_SCALAR } from '../utils/config.js';
10
+ import type { QueryContext } from './context.js';
11
+
12
+ export class ReferralQueries {
13
+ #ctx: QueryContext;
14
+
15
+ constructor(ctx: QueryContext) {
16
+ this.#ctx = ctx;
17
+ }
18
+
19
+ async balanceManagerReferralOwner(referral: string): Promise<string> {
20
+ const tx = new Transaction();
21
+ tx.add(this.#ctx.balanceManager.balanceManagerReferralOwner(referral));
22
+
23
+ const res = await this.#ctx.client.core.simulateTransaction({
24
+ transaction: tx,
25
+ include: { commandResults: true, effects: true },
26
+ });
27
+
28
+ const bytes = res.commandResults![0].returnValues[0].bcs;
29
+ return bcs.Address.parse(bytes);
30
+ }
31
+
32
+ async getPoolReferralBalances(poolKey: string, referral: string): Promise<ReferralBalances> {
33
+ const tx = new Transaction();
34
+ const pool = this.#ctx.config.getPool(poolKey);
35
+ const baseScalar = this.#ctx.config.getCoin(pool.baseCoin).scalar;
36
+ const quoteScalar = this.#ctx.config.getCoin(pool.quoteCoin).scalar;
37
+
38
+ tx.add(this.#ctx.deepBook.getPoolReferralBalances(poolKey, referral));
39
+
40
+ const res = await this.#ctx.client.core.simulateTransaction({
41
+ transaction: tx,
42
+ include: { commandResults: true, effects: true },
43
+ });
44
+
45
+ const baseBytes = res.commandResults![0].returnValues[0].bcs;
46
+ const quoteBytes = res.commandResults![0].returnValues[1].bcs;
47
+ const deepBytes = res.commandResults![0].returnValues[2].bcs;
48
+
49
+ const baseBalance = Number(bcs.U64.parse(baseBytes));
50
+ const quoteBalance = Number(bcs.U64.parse(quoteBytes));
51
+ const deepBalance = Number(bcs.U64.parse(deepBytes));
52
+
53
+ return {
54
+ base: baseBalance / baseScalar,
55
+ quote: quoteBalance / quoteScalar,
56
+ deep: deepBalance / DEEP_SCALAR,
57
+ };
58
+ }
59
+
60
+ async balanceManagerReferralPoolId(referral: string): Promise<string> {
61
+ const tx = new Transaction();
62
+
63
+ tx.add(this.#ctx.balanceManager.balanceManagerReferralPoolId(referral));
64
+
65
+ const res = await this.#ctx.client.core.simulateTransaction({
66
+ transaction: tx,
67
+ include: { commandResults: true, effects: true },
68
+ });
69
+
70
+ const bytes = res.commandResults![0].returnValues[0].bcs;
71
+ const poolId = bcs.Address.parse(bytes);
72
+
73
+ return normalizeSuiAddress(poolId);
74
+ }
75
+
76
+ async poolReferralMultiplier(poolKey: string, referral: string): Promise<number> {
77
+ const tx = new Transaction();
78
+
79
+ tx.add(this.#ctx.deepBook.poolReferralMultiplier(poolKey, referral));
80
+
81
+ const res = await this.#ctx.client.core.simulateTransaction({
82
+ transaction: tx,
83
+ include: { commandResults: true, effects: true },
84
+ });
85
+
86
+ const bytes = res.commandResults![0].returnValues[0].bcs;
87
+ const multiplier = Number(bcs.U64.parse(bytes));
88
+
89
+ return multiplier / FLOAT_SCALAR;
90
+ }
91
+
92
+ async getBalanceManagerReferralId(managerKey: string, poolKey: string): Promise<string | null> {
93
+ const tx = new Transaction();
94
+ tx.add(this.#ctx.balanceManager.getBalanceManagerReferralId(managerKey, poolKey));
95
+
96
+ const res = await this.#ctx.client.core.simulateTransaction({
97
+ transaction: tx,
98
+ include: { commandResults: true, effects: true },
99
+ });
100
+
101
+ try {
102
+ const bytes = res.commandResults![0].returnValues[0].bcs;
103
+ const optionId = bcs.option(bcs.Address).parse(bytes);
104
+ if (optionId === null) {
105
+ return null;
106
+ }
107
+ return normalizeSuiAddress(optionId);
108
+ } catch {
109
+ return null;
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,185 @@
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { bcs } from '@mysten/sui/bcs';
5
+ import { Transaction } from '@mysten/sui/transactions';
6
+ import { normalizeSuiAddress } from '@mysten/sui/utils';
7
+
8
+ import { VecSet } from '../types/bcs.js';
9
+ import { FLOAT_SCALAR } from '../utils/config.js';
10
+ import type { QueryContext } from './context.js';
11
+
12
+ export class RegistryQueries {
13
+ #ctx: QueryContext;
14
+
15
+ constructor(ctx: QueryContext) {
16
+ this.#ctx = ctx;
17
+ }
18
+
19
+ async isPoolEnabledForMargin(poolKey: string): Promise<boolean> {
20
+ const tx = new Transaction();
21
+ tx.add(this.#ctx.marginRegistry.poolEnabled(poolKey));
22
+
23
+ const res = await this.#ctx.client.core.simulateTransaction({
24
+ transaction: tx,
25
+ include: { commandResults: true, effects: true },
26
+ });
27
+
28
+ const bytes = res.commandResults![0].returnValues[0].bcs;
29
+ return bcs.Bool.parse(bytes);
30
+ }
31
+
32
+ async getMarginManagerIdsForOwner(owner: string): Promise<string[]> {
33
+ const tx = new Transaction();
34
+ tx.add(this.#ctx.marginRegistry.getMarginManagerIds(owner));
35
+
36
+ const res = await this.#ctx.client.core.simulateTransaction({
37
+ transaction: tx,
38
+ include: { commandResults: true, effects: true },
39
+ });
40
+
41
+ const bytes = res.commandResults![0].returnValues[0].bcs;
42
+ const vecSet = VecSet(bcs.Address).parse(bytes);
43
+ return vecSet.contents.map((id) => normalizeSuiAddress(id));
44
+ }
45
+
46
+ async getBaseMarginPoolId(poolKey: string): Promise<string> {
47
+ const tx = new Transaction();
48
+ tx.add(this.#ctx.marginRegistry.baseMarginPoolId(poolKey));
49
+
50
+ const res = await this.#ctx.client.core.simulateTransaction({
51
+ transaction: tx,
52
+ include: { commandResults: true, effects: true },
53
+ });
54
+
55
+ const bytes = res.commandResults![0].returnValues[0].bcs;
56
+ const id = bcs.Address.parse(bytes);
57
+ return '0x' + id;
58
+ }
59
+
60
+ async getQuoteMarginPoolId(poolKey: string): Promise<string> {
61
+ const tx = new Transaction();
62
+ tx.add(this.#ctx.marginRegistry.quoteMarginPoolId(poolKey));
63
+
64
+ const res = await this.#ctx.client.core.simulateTransaction({
65
+ transaction: tx,
66
+ include: { commandResults: true, effects: true },
67
+ });
68
+
69
+ const bytes = res.commandResults![0].returnValues[0].bcs;
70
+ const id = bcs.Address.parse(bytes);
71
+ return '0x' + id;
72
+ }
73
+
74
+ async getMinWithdrawRiskRatio(poolKey: string): Promise<number> {
75
+ const tx = new Transaction();
76
+ tx.add(this.#ctx.marginRegistry.minWithdrawRiskRatio(poolKey));
77
+
78
+ const res = await this.#ctx.client.core.simulateTransaction({
79
+ transaction: tx,
80
+ include: { commandResults: true, effects: true },
81
+ });
82
+
83
+ const bytes = res.commandResults![0].returnValues[0].bcs;
84
+ const ratio = Number(bcs.U64.parse(bytes));
85
+ return ratio / FLOAT_SCALAR;
86
+ }
87
+
88
+ async getMinBorrowRiskRatio(poolKey: string): Promise<number> {
89
+ const tx = new Transaction();
90
+ tx.add(this.#ctx.marginRegistry.minBorrowRiskRatio(poolKey));
91
+
92
+ const res = await this.#ctx.client.core.simulateTransaction({
93
+ transaction: tx,
94
+ include: { commandResults: true, effects: true },
95
+ });
96
+
97
+ const bytes = res.commandResults![0].returnValues[0].bcs;
98
+ const ratio = Number(bcs.U64.parse(bytes));
99
+ return ratio / FLOAT_SCALAR;
100
+ }
101
+
102
+ async getLiquidationRiskRatio(poolKey: string): Promise<number> {
103
+ const tx = new Transaction();
104
+ tx.add(this.#ctx.marginRegistry.liquidationRiskRatio(poolKey));
105
+
106
+ const res = await this.#ctx.client.core.simulateTransaction({
107
+ transaction: tx,
108
+ include: { commandResults: true, effects: true },
109
+ });
110
+
111
+ const bytes = res.commandResults![0].returnValues[0].bcs;
112
+ const ratio = Number(bcs.U64.parse(bytes));
113
+ return ratio / FLOAT_SCALAR;
114
+ }
115
+
116
+ async getTargetLiquidationRiskRatio(poolKey: string): Promise<number> {
117
+ const tx = new Transaction();
118
+ tx.add(this.#ctx.marginRegistry.targetLiquidationRiskRatio(poolKey));
119
+
120
+ const res = await this.#ctx.client.core.simulateTransaction({
121
+ transaction: tx,
122
+ include: { commandResults: true, effects: true },
123
+ });
124
+
125
+ const bytes = res.commandResults![0].returnValues[0].bcs;
126
+ const ratio = Number(bcs.U64.parse(bytes));
127
+ return ratio / FLOAT_SCALAR;
128
+ }
129
+
130
+ async getUserLiquidationReward(poolKey: string): Promise<number> {
131
+ const tx = new Transaction();
132
+ tx.add(this.#ctx.marginRegistry.userLiquidationReward(poolKey));
133
+
134
+ const res = await this.#ctx.client.core.simulateTransaction({
135
+ transaction: tx,
136
+ include: { commandResults: true, effects: true },
137
+ });
138
+
139
+ const bytes = res.commandResults![0].returnValues[0].bcs;
140
+ const reward = Number(bcs.U64.parse(bytes));
141
+ return reward / FLOAT_SCALAR;
142
+ }
143
+
144
+ async getPoolLiquidationReward(poolKey: string): Promise<number> {
145
+ const tx = new Transaction();
146
+ tx.add(this.#ctx.marginRegistry.poolLiquidationReward(poolKey));
147
+
148
+ const res = await this.#ctx.client.core.simulateTransaction({
149
+ transaction: tx,
150
+ include: { commandResults: true, effects: true },
151
+ });
152
+
153
+ const bytes = res.commandResults![0].returnValues[0].bcs;
154
+ const reward = Number(bcs.U64.parse(bytes));
155
+ return reward / FLOAT_SCALAR;
156
+ }
157
+
158
+ async getAllowedMaintainers(): Promise<string[]> {
159
+ const tx = new Transaction();
160
+ tx.add(this.#ctx.marginRegistry.allowedMaintainers());
161
+
162
+ const res = await this.#ctx.client.core.simulateTransaction({
163
+ transaction: tx,
164
+ include: { commandResults: true, effects: true },
165
+ });
166
+
167
+ const bytes = res.commandResults![0].returnValues[0].bcs;
168
+ const vecSet = VecSet(bcs.Address).parse(bytes);
169
+ return vecSet.contents.map((id) => normalizeSuiAddress(id));
170
+ }
171
+
172
+ async getAllowedPauseCaps(): Promise<string[]> {
173
+ const tx = new Transaction();
174
+ tx.add(this.#ctx.marginRegistry.allowedPauseCaps());
175
+
176
+ const res = await this.#ctx.client.core.simulateTransaction({
177
+ transaction: tx,
178
+ include: { commandResults: true, effects: true },
179
+ });
180
+
181
+ const bytes = res.commandResults![0].returnValues[0].bcs;
182
+ const vecSet = VecSet(bcs.Address).parse(bytes);
183
+ return vecSet.contents.map((id) => normalizeSuiAddress(id));
184
+ }
185
+ }