@mysten/deepbook-v3 1.6.7 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/_virtual/rolldown_runtime.mjs +18 -0
  3. package/dist/client.d.mts +9 -6
  4. package/dist/client.d.mts.map +1 -1
  5. package/dist/client.mjs +3 -2
  6. package/dist/client.mjs.map +1 -1
  7. package/dist/contracts/deepbook/account.d.mts +18 -18
  8. package/dist/contracts/deepbook/account.d.mts.map +1 -1
  9. package/dist/contracts/deepbook/balance_manager.mjs.map +1 -1
  10. package/dist/contracts/deepbook/balances.d.mts +4 -4
  11. package/dist/contracts/deepbook/balances.d.mts.map +1 -1
  12. package/dist/contracts/deepbook/deep_price.d.mts +3 -3
  13. package/dist/contracts/deepbook/deep_price.d.mts.map +1 -1
  14. package/dist/contracts/deepbook/order.d.mts +12 -12
  15. package/dist/contracts/deepbook/pool.mjs.map +1 -1
  16. package/dist/contracts/deepbook/registry.mjs.map +1 -1
  17. package/dist/contracts/deepbook_margin/margin_manager.mjs +1 -319
  18. package/dist/contracts/deepbook_margin/margin_manager.mjs.map +1 -1
  19. package/dist/contracts/deepbook_margin/margin_manager_upgraded.mjs +386 -0
  20. package/dist/contracts/deepbook_margin/margin_manager_upgraded.mjs.map +1 -0
  21. package/dist/contracts/deepbook_margin/margin_pool.mjs.map +1 -1
  22. package/dist/contracts/deepbook_margin/margin_registry.mjs.map +1 -1
  23. package/dist/contracts/deepbook_margin/oracle.mjs +9 -0
  24. package/dist/contracts/deepbook_margin/oracle.mjs.map +1 -1
  25. package/dist/contracts/deepbook_margin/pool_proxy.mjs +1 -383
  26. package/dist/contracts/deepbook_margin/pool_proxy.mjs.map +1 -1
  27. package/dist/contracts/deepbook_margin/pool_proxy_upgraded.mjs +340 -0
  28. package/dist/contracts/deepbook_margin/pool_proxy_upgraded.mjs.map +1 -0
  29. package/dist/contracts/deepbook_margin/protocol_config.mjs.map +1 -1
  30. package/dist/contracts/deepbook_margin/tpsl.mjs.map +1 -1
  31. package/dist/contracts/margin_liquidation/liquidation_vault.mjs +33 -17
  32. package/dist/contracts/margin_liquidation/liquidation_vault.mjs.map +1 -1
  33. package/dist/index.d.mts +4 -3
  34. package/dist/index.mjs +2 -2
  35. package/dist/pyth/PriceServiceConnection.d.mts +18 -3
  36. package/dist/pyth/PriceServiceConnection.d.mts.map +1 -1
  37. package/dist/pyth/PriceServiceConnection.mjs +35 -4
  38. package/dist/pyth/PriceServiceConnection.mjs.map +1 -1
  39. package/dist/queries/priceFeedQueries.mjs +50 -18
  40. package/dist/queries/priceFeedQueries.mjs.map +1 -1
  41. package/dist/transactions/balanceManager.d.mts +12 -12
  42. package/dist/transactions/balanceManager.d.mts.map +1 -1
  43. package/dist/transactions/deepbook.d.mts +20 -20
  44. package/dist/transactions/deepbook.d.mts.map +1 -1
  45. package/dist/transactions/deepbookAdmin.d.mts +4 -4
  46. package/dist/transactions/marginAdmin.d.mts +7 -7
  47. package/dist/transactions/marginAdmin.d.mts.map +1 -1
  48. package/dist/transactions/marginAdmin.mjs +2 -2
  49. package/dist/transactions/marginAdmin.mjs.map +1 -1
  50. package/dist/transactions/marginLiquidations.d.mts.map +1 -1
  51. package/dist/transactions/marginLiquidations.mjs +19 -7
  52. package/dist/transactions/marginLiquidations.mjs.map +1 -1
  53. package/dist/transactions/marginMaintainer.d.mts +5 -5
  54. package/dist/transactions/marginManager.d.mts +32 -32
  55. package/dist/transactions/marginManager.d.mts.map +1 -1
  56. package/dist/transactions/marginManager.mjs +43 -34
  57. package/dist/transactions/marginManager.mjs.map +1 -1
  58. package/dist/transactions/marginPool.d.mts +18 -18
  59. package/dist/transactions/marginTPSL.d.mts +10 -10
  60. package/dist/transactions/marginTPSL.d.mts.map +1 -1
  61. package/dist/transactions/marginTPSL.mjs +19 -10
  62. package/dist/transactions/marginTPSL.mjs.map +1 -1
  63. package/dist/transactions/poolProxy.d.mts +8 -8
  64. package/dist/transactions/poolProxy.d.mts.map +1 -1
  65. package/dist/transactions/poolProxy.mjs +34 -27
  66. package/dist/transactions/poolProxy.mjs.map +1 -1
  67. package/dist/types/index.d.mts +16 -1
  68. package/dist/types/index.d.mts.map +1 -1
  69. package/dist/types/index.mjs.map +1 -1
  70. package/dist/utils/config.d.mts +30 -10
  71. package/dist/utils/config.d.mts.map +1 -1
  72. package/dist/utils/config.mjs +33 -4
  73. package/dist/utils/config.mjs.map +1 -1
  74. package/dist/utils/constants.d.mts +32 -1
  75. package/dist/utils/constants.d.mts.map +1 -1
  76. package/dist/utils/constants.mjs +55 -24
  77. package/dist/utils/constants.mjs.map +1 -1
  78. package/package.json +10 -10
  79. package/src/client.ts +9 -1
  80. package/src/contracts/deepbook/balance_manager.ts +1 -2
  81. package/src/contracts/deepbook/pool.ts +12 -24
  82. package/src/contracts/deepbook/registry.ts +1 -2
  83. package/src/contracts/deepbook_margin/margin_manager.ts +149 -28
  84. package/src/contracts/deepbook_margin/margin_manager_upgraded.ts +646 -0
  85. package/src/contracts/deepbook_margin/margin_pool.ts +2 -4
  86. package/src/contracts/deepbook_margin/margin_registry.ts +3 -6
  87. package/src/contracts/deepbook_margin/oracle.ts +59 -0
  88. package/src/contracts/deepbook_margin/pool_proxy.ts +597 -584
  89. package/src/contracts/deepbook_margin/pool_proxy_upgraded.ts +614 -0
  90. package/src/contracts/deepbook_margin/protocol_config.ts +1 -2
  91. package/src/contracts/deepbook_margin/tpsl.ts +1 -2
  92. package/src/contracts/margin_liquidation/liquidation_vault.ts +144 -4
  93. package/src/contracts/pyth/pyth.ts +2 -4
  94. package/src/index.ts +4 -0
  95. package/src/pyth/PriceServiceConnection.ts +69 -8
  96. package/src/queries/priceFeedQueries.ts +74 -24
  97. package/src/transactions/marginAdmin.ts +2 -4
  98. package/src/transactions/marginLiquidations.ts +20 -6
  99. package/src/transactions/marginManager.ts +43 -33
  100. package/src/transactions/marginTPSL.ts +19 -9
  101. package/src/transactions/poolProxy.ts +34 -30
  102. package/src/types/index.ts +17 -2
  103. package/src/utils/config.ts +69 -9
  104. package/src/utils/constants.ts +83 -26
@@ -8,6 +8,7 @@ import type { DepositParams, DepositDuringInitParams } from '../types/index.js';
8
8
  import { FLOAT_SCALAR } from '../utils/config.js';
9
9
  import { convertPrice, convertQuantity } from '../utils/conversion.js';
10
10
  import * as marginManagerMoveCalls from '../contracts/deepbook_margin/margin_manager.js';
11
+ import * as marginManagerUpgradedMoveCalls from '../contracts/deepbook_margin/margin_manager_upgraded.js';
11
12
 
12
13
  /**
13
14
  * MarginManagerContract class for managing MarginManager operations.
@@ -22,6 +23,15 @@ export class MarginManagerContract {
22
23
  this.#config = config;
23
24
  }
24
25
 
26
+ /**
27
+ * Oracle-taking entrypoints live in the parallel `_upgraded` module, which takes Pyth's
28
+ * upgraded-Core `PriceInfoObject`. Entrypoints with no oracle argument stay on the base
29
+ * module, which is the only place they exist.
30
+ */
31
+ get #oracleCalls() {
32
+ return marginManagerUpgradedMoveCalls;
33
+ }
34
+
25
35
  /**
26
36
  * @description Create a new margin manager
27
37
  * @param {string} poolKey The key to identify the pool
@@ -155,13 +165,13 @@ export class MarginManagerContract {
155
165
  : params.coin;
156
166
 
157
167
  tx.add(
158
- marginManagerMoveCalls.deposit({
168
+ this.#oracleCalls.deposit({
159
169
  package: this.#config.MARGIN_PACKAGE_ID,
160
170
  arguments: {
161
171
  self: manager,
162
172
  registry: this.#config.MARGIN_REGISTRY_ID,
163
- baseOracle: baseCoin.priceInfoObjectId!,
164
- quoteOracle: quoteCoin.priceInfoObjectId!,
173
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
174
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
165
175
  coin,
166
176
  },
167
177
  typeArguments: [baseCoin.type, quoteCoin.type, depositCoin.type],
@@ -188,13 +198,13 @@ export class MarginManagerContract {
188
198
  })
189
199
  : params.coin;
190
200
  tx.add(
191
- marginManagerMoveCalls.deposit({
201
+ this.#oracleCalls.deposit({
192
202
  package: this.#config.MARGIN_PACKAGE_ID,
193
203
  arguments: {
194
204
  self: manager.address,
195
205
  registry: this.#config.MARGIN_REGISTRY_ID,
196
- baseOracle: baseCoin.priceInfoObjectId!,
197
- quoteOracle: quoteCoin.priceInfoObjectId!,
206
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
207
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
198
208
  coin,
199
209
  },
200
210
  typeArguments: [baseCoin.type, quoteCoin.type, baseCoin.type],
@@ -221,13 +231,13 @@ export class MarginManagerContract {
221
231
  })
222
232
  : params.coin;
223
233
  tx.add(
224
- marginManagerMoveCalls.deposit({
234
+ this.#oracleCalls.deposit({
225
235
  package: this.#config.MARGIN_PACKAGE_ID,
226
236
  arguments: {
227
237
  self: manager.address,
228
238
  registry: this.#config.MARGIN_REGISTRY_ID,
229
- baseOracle: baseCoin.priceInfoObjectId!,
230
- quoteOracle: quoteCoin.priceInfoObjectId!,
239
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
240
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
231
241
  coin,
232
242
  },
233
243
  typeArguments: [baseCoin.type, quoteCoin.type, quoteCoin.type],
@@ -255,13 +265,13 @@ export class MarginManagerContract {
255
265
  })
256
266
  : params.coin;
257
267
  tx.add(
258
- marginManagerMoveCalls.deposit({
268
+ this.#oracleCalls.deposit({
259
269
  package: this.#config.MARGIN_PACKAGE_ID,
260
270
  arguments: {
261
271
  self: manager.address,
262
272
  registry: this.#config.MARGIN_REGISTRY_ID,
263
- baseOracle: baseCoin.priceInfoObjectId!,
264
- quoteOracle: quoteCoin.priceInfoObjectId!,
273
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
274
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
265
275
  coin,
266
276
  },
267
277
  typeArguments: [baseCoin.type, quoteCoin.type, deepCoin.type],
@@ -283,15 +293,15 @@ export class MarginManagerContract {
283
293
  const baseMarginPool = this.#config.getMarginPool(pool.baseCoin);
284
294
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
285
295
  return tx.add(
286
- marginManagerMoveCalls.withdraw({
296
+ this.#oracleCalls.withdraw({
287
297
  package: this.#config.MARGIN_PACKAGE_ID,
288
298
  arguments: {
289
299
  self: manager.address,
290
300
  registry: this.#config.MARGIN_REGISTRY_ID,
291
301
  baseMarginPool: baseMarginPool.address,
292
302
  quoteMarginPool: quoteMarginPool.address,
293
- baseOracle: baseCoin.priceInfoObjectId!,
294
- quoteOracle: quoteCoin.priceInfoObjectId!,
303
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
304
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
295
305
  pool: pool.address,
296
306
  withdrawAmount: convertQuantity(amount, baseCoin.scalar),
297
307
  },
@@ -314,15 +324,15 @@ export class MarginManagerContract {
314
324
  const baseMarginPool = this.#config.getMarginPool(pool.baseCoin);
315
325
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
316
326
  return tx.add(
317
- marginManagerMoveCalls.withdraw({
327
+ this.#oracleCalls.withdraw({
318
328
  package: this.#config.MARGIN_PACKAGE_ID,
319
329
  arguments: {
320
330
  self: manager.address,
321
331
  registry: this.#config.MARGIN_REGISTRY_ID,
322
332
  baseMarginPool: baseMarginPool.address,
323
333
  quoteMarginPool: quoteMarginPool.address,
324
- baseOracle: baseCoin.priceInfoObjectId!,
325
- quoteOracle: quoteCoin.priceInfoObjectId!,
334
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
335
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
326
336
  pool: pool.address,
327
337
  withdrawAmount: convertQuantity(amount, quoteCoin.scalar),
328
338
  },
@@ -346,15 +356,15 @@ export class MarginManagerContract {
346
356
  const baseMarginPool = this.#config.getMarginPool(pool.baseCoin);
347
357
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
348
358
  return tx.add(
349
- marginManagerMoveCalls.withdraw({
359
+ this.#oracleCalls.withdraw({
350
360
  package: this.#config.MARGIN_PACKAGE_ID,
351
361
  arguments: {
352
362
  self: manager.address,
353
363
  registry: this.#config.MARGIN_REGISTRY_ID,
354
364
  baseMarginPool: baseMarginPool.address,
355
365
  quoteMarginPool: quoteMarginPool.address,
356
- baseOracle: baseCoin.priceInfoObjectId!,
357
- quoteOracle: quoteCoin.priceInfoObjectId!,
366
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
367
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
358
368
  pool: pool.address,
359
369
  withdrawAmount: convertQuantity(amount, deepCoin.scalar),
360
370
  },
@@ -376,14 +386,14 @@ export class MarginManagerContract {
376
386
  const quoteCoin = this.#config.getCoin(pool.quoteCoin);
377
387
  const baseMarginPool = this.#config.getMarginPool(pool.baseCoin);
378
388
  return tx.add(
379
- marginManagerMoveCalls.borrowBase({
389
+ this.#oracleCalls.borrowBase({
380
390
  package: this.#config.MARGIN_PACKAGE_ID,
381
391
  arguments: {
382
392
  self: manager.address,
383
393
  registry: this.#config.MARGIN_REGISTRY_ID,
384
394
  baseMarginPool: baseMarginPool.address,
385
- baseOracle: baseCoin.priceInfoObjectId!,
386
- quoteOracle: quoteCoin.priceInfoObjectId!,
395
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
396
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
387
397
  pool: pool.address,
388
398
  loanAmount: convertQuantity(amount, baseCoin.scalar),
389
399
  },
@@ -405,14 +415,14 @@ export class MarginManagerContract {
405
415
  const quoteCoin = this.#config.getCoin(pool.quoteCoin);
406
416
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
407
417
  return tx.add(
408
- marginManagerMoveCalls.borrowQuote({
418
+ this.#oracleCalls.borrowQuote({
409
419
  package: this.#config.MARGIN_PACKAGE_ID,
410
420
  arguments: {
411
421
  self: manager.address,
412
422
  registry: this.#config.MARGIN_REGISTRY_ID,
413
423
  quoteMarginPool: quoteMarginPool.address,
414
- baseOracle: baseCoin.priceInfoObjectId!,
415
- quoteOracle: quoteCoin.priceInfoObjectId!,
424
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
425
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
416
426
  pool: pool.address,
417
427
  loanAmount: convertQuantity(amount, quoteCoin.scalar),
418
428
  },
@@ -496,13 +506,13 @@ export class MarginManagerContract {
496
506
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
497
507
  const marginPool = debtIsBase ? baseMarginPool : quoteMarginPool;
498
508
  return tx.add(
499
- marginManagerMoveCalls.liquidate({
509
+ this.#oracleCalls.liquidate({
500
510
  package: this.#config.MARGIN_PACKAGE_ID,
501
511
  arguments: {
502
512
  self: managerAddress,
503
513
  registry: this.#config.MARGIN_REGISTRY_ID,
504
- baseOracle: baseCoin.priceInfoObjectId!,
505
- quoteOracle: quoteCoin.priceInfoObjectId!,
514
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
515
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
506
516
  marginPool: marginPool.address,
507
517
  pool: pool.address,
508
518
  repayCoin,
@@ -770,13 +780,13 @@ export class MarginManagerContract {
770
780
  const baseMarginPool = this.#config.getMarginPool(pool.baseCoin);
771
781
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
772
782
  return tx.add(
773
- marginManagerMoveCalls.managerState({
783
+ this.#oracleCalls.managerState({
774
784
  package: this.#config.MARGIN_PACKAGE_ID,
775
785
  arguments: {
776
786
  self: marginManagerId,
777
787
  registry: this.#config.MARGIN_REGISTRY_ID,
778
- baseOracle: baseCoin.priceInfoObjectId!,
779
- quoteOracle: quoteCoin.priceInfoObjectId!,
788
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
789
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
780
790
  pool: pool.address,
781
791
  baseMarginPool: baseMarginPool.address,
782
792
  quoteMarginPool: quoteMarginPool.address,
@@ -12,6 +12,7 @@ import { OrderType, SelfMatchingOptions } from '../types/index.js';
12
12
  import { MAX_TIMESTAMP, FLOAT_SCALAR } from '../utils/config.js';
13
13
  import { convertQuantity, convertPrice } from '../utils/conversion.js';
14
14
  import * as marginManagerMoveCalls from '../contracts/deepbook_margin/margin_manager.js';
15
+ import * as marginManagerUpgradedMoveCalls from '../contracts/deepbook_margin/margin_manager_upgraded.js';
15
16
  import * as tpslMoveCalls from '../contracts/deepbook_margin/tpsl.js';
16
17
 
17
18
  /**
@@ -27,6 +28,15 @@ export class MarginTPSLContract {
27
28
  this.#config = config;
28
29
  }
29
30
 
31
+ /**
32
+ * Oracle-taking entrypoints live in the parallel `_upgraded` module, which takes Pyth's
33
+ * upgraded-Core `PriceInfoObject`. Entrypoints with no oracle argument stay on the base
34
+ * module, which is the only place they exist.
35
+ */
36
+ get #oracleCalls() {
37
+ return marginManagerUpgradedMoveCalls;
38
+ }
39
+
30
40
  // === Helper Functions ===
31
41
 
32
42
  /**
@@ -153,13 +163,13 @@ export class MarginTPSLContract {
153
163
  : this.newPendingMarketOrder(manager.poolKey, pendingOrder as PendingMarketOrderParams)(tx);
154
164
 
155
165
  tx.add(
156
- marginManagerMoveCalls.addConditionalOrder({
166
+ this.#oracleCalls.addConditionalOrder({
157
167
  package: this.#config.MARGIN_PACKAGE_ID,
158
168
  arguments: {
159
169
  self: manager.address,
160
170
  pool: pool.address,
161
- basePriceInfoObject: baseCoin.priceInfoObjectId!,
162
- quotePriceInfoObject: quoteCoin.priceInfoObjectId!,
171
+ basePriceInfoObject: this.#config.getPriceInfoObjectId(pool.baseCoin),
172
+ quotePriceInfoObject: this.#config.getPriceInfoObjectId(pool.quoteCoin),
163
173
  registry: this.#config.MARGIN_REGISTRY_ID,
164
174
  conditionalOrderId: BigInt(conditionalOrderId),
165
175
  condition,
@@ -229,15 +239,15 @@ export class MarginTPSLContract {
229
239
  const baseMarginPool = this.#config.getMarginPool(pool.baseCoin);
230
240
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
231
241
  return tx.add(
232
- marginManagerMoveCalls.executeConditionalOrdersV2({
242
+ this.#oracleCalls.executeConditionalOrdersV2({
233
243
  package: this.#config.MARGIN_PACKAGE_ID,
234
244
  arguments: {
235
245
  self: managerAddress,
236
246
  pool: pool.address,
237
247
  baseMarginPool: baseMarginPool.address,
238
248
  quoteMarginPool: quoteMarginPool.address,
239
- basePriceInfoObject: baseCoin.priceInfoObjectId!,
240
- quotePriceInfoObject: quoteCoin.priceInfoObjectId!,
249
+ basePriceInfoObject: this.#config.getPriceInfoObjectId(pool.baseCoin),
250
+ quotePriceInfoObject: this.#config.getPriceInfoObjectId(pool.quoteCoin),
241
251
  registry: this.#config.MARGIN_REGISTRY_ID,
242
252
  maxOrdersToExecute,
243
253
  },
@@ -271,15 +281,15 @@ export class MarginTPSLContract {
271
281
  const baseMarginPool = this.#config.getMarginPool(pool.baseCoin);
272
282
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
273
283
  return tx.add(
274
- marginManagerMoveCalls.executeConditionalOrdersV3({
284
+ this.#oracleCalls.executeConditionalOrdersV3({
275
285
  package: this.#config.MARGIN_PACKAGE_ID,
276
286
  arguments: {
277
287
  self: managerAddress,
278
288
  pool: pool.address,
279
289
  baseMarginPool: baseMarginPool.address,
280
290
  quoteMarginPool: quoteMarginPool.address,
281
- basePriceInfoObject: baseCoin.priceInfoObjectId!,
282
- quotePriceInfoObject: quoteCoin.priceInfoObjectId!,
291
+ basePriceInfoObject: this.#config.getPriceInfoObjectId(pool.baseCoin),
292
+ quotePriceInfoObject: this.#config.getPriceInfoObjectId(pool.quoteCoin),
283
293
  registry: this.#config.MARGIN_REGISTRY_ID,
284
294
  maxOrdersToExecute,
285
295
  },
@@ -12,6 +12,7 @@ import { OrderType, SelfMatchingOptions } from '../types/index.js';
12
12
  import { MAX_TIMESTAMP, FLOAT_SCALAR } from '../utils/config.js';
13
13
  import { convertQuantity, convertPrice, convertRate } from '../utils/conversion.js';
14
14
  import * as poolProxyMoveCalls from '../contracts/deepbook_margin/pool_proxy.js';
15
+ import * as poolProxyUpgradedMoveCalls from '../contracts/deepbook_margin/pool_proxy_upgraded.js';
15
16
 
16
17
  /**
17
18
  * PoolProxyContract class for managing PoolProxy operations.
@@ -26,6 +27,15 @@ export class PoolProxyContract {
26
27
  this.#config = config;
27
28
  }
28
29
 
30
+ /**
31
+ * Oracle-taking entrypoints live in the parallel `_upgraded` module, which takes Pyth's
32
+ * upgraded-Core `PriceInfoObject`. Entrypoints with no oracle argument stay on the base
33
+ * module, which is the only place they exist.
34
+ */
35
+ get #oracleCalls() {
36
+ return poolProxyUpgradedMoveCalls;
37
+ }
38
+
29
39
  /**
30
40
  * @description Place a limit order. Enforces a post-trade `risk_ratio >=
31
41
  * min_borrow_risk_ratio` invariant on the manager (skipped when the manager
@@ -55,7 +65,7 @@ export class PoolProxyContract {
55
65
  const inputPrice = convertPrice(price, FLOAT_SCALAR, quoteCoin.scalar, baseCoin.scalar);
56
66
  const inputQuantity = convertQuantity(quantity, baseCoin.scalar);
57
67
  return tx.add(
58
- poolProxyMoveCalls.placeLimitOrderV2({
68
+ this.#oracleCalls.placeLimitOrderV2({
59
69
  package: this.#config.MARGIN_PACKAGE_ID,
60
70
  arguments: {
61
71
  registry: this.#config.MARGIN_REGISTRY_ID,
@@ -63,8 +73,8 @@ export class PoolProxyContract {
63
73
  pool: pool.address,
64
74
  baseMarginPool: baseMarginPool.address,
65
75
  quoteMarginPool: quoteMarginPool.address,
66
- baseOracle: baseCoin.priceInfoObjectId!,
67
- quoteOracle: quoteCoin.priceInfoObjectId!,
76
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
77
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
68
78
  clientOrderId: BigInt(clientOrderId),
69
79
  orderType,
70
80
  selfMatchingOption,
@@ -104,7 +114,7 @@ export class PoolProxyContract {
104
114
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
105
115
  const inputQuantity = convertQuantity(quantity, baseCoin.scalar);
106
116
  return tx.add(
107
- poolProxyMoveCalls.placeMarketOrderV2({
117
+ this.#oracleCalls.placeMarketOrderV2({
108
118
  package: this.#config.MARGIN_PACKAGE_ID,
109
119
  arguments: {
110
120
  registry: this.#config.MARGIN_REGISTRY_ID,
@@ -112,8 +122,8 @@ export class PoolProxyContract {
112
122
  pool: pool.address,
113
123
  baseMarginPool: baseMarginPool.address,
114
124
  quoteMarginPool: quoteMarginPool.address,
115
- baseOracle: baseCoin.priceInfoObjectId!,
116
- quoteOracle: quoteCoin.priceInfoObjectId!,
125
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
126
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
117
127
  clientOrderId: BigInt(clientOrderId),
118
128
  selfMatchingOption,
119
129
  quantity: inputQuantity,
@@ -155,7 +165,7 @@ export class PoolProxyContract {
155
165
  const inputPrice = convertPrice(price, FLOAT_SCALAR, quoteCoin.scalar, baseCoin.scalar);
156
166
  const inputQuantity = convertQuantity(quantity, baseCoin.scalar);
157
167
  return tx.add(
158
- poolProxyMoveCalls.placeReduceOnlyLimitOrderV2({
168
+ this.#oracleCalls.placeReduceOnlyLimitOrderV2({
159
169
  package: this.#config.MARGIN_PACKAGE_ID,
160
170
  arguments: {
161
171
  registry: this.#config.MARGIN_REGISTRY_ID,
@@ -163,8 +173,8 @@ export class PoolProxyContract {
163
173
  pool: pool.address,
164
174
  baseMarginPool: baseMarginPool.address,
165
175
  quoteMarginPool: quoteMarginPool.address,
166
- baseOracle: baseCoin.priceInfoObjectId!,
167
- quoteOracle: quoteCoin.priceInfoObjectId!,
176
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
177
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
168
178
  clientOrderId: BigInt(clientOrderId),
169
179
  orderType,
170
180
  selfMatchingOption,
@@ -205,7 +215,7 @@ export class PoolProxyContract {
205
215
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
206
216
  const inputQuantity = convertQuantity(quantity, baseCoin.scalar);
207
217
  return tx.add(
208
- poolProxyMoveCalls.placeReduceOnlyMarketOrderV2({
218
+ this.#oracleCalls.placeReduceOnlyMarketOrderV2({
209
219
  package: this.#config.MARGIN_PACKAGE_ID,
210
220
  arguments: {
211
221
  registry: this.#config.MARGIN_REGISTRY_ID,
@@ -213,8 +223,8 @@ export class PoolProxyContract {
213
223
  pool: pool.address,
214
224
  baseMarginPool: baseMarginPool.address,
215
225
  quoteMarginPool: quoteMarginPool.address,
216
- baseOracle: baseCoin.priceInfoObjectId!,
217
- quoteOracle: quoteCoin.priceInfoObjectId!,
226
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
227
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
218
228
  clientOrderId: BigInt(clientOrderId),
219
229
  selfMatchingOption,
220
230
  quantity: inputQuantity,
@@ -255,7 +265,7 @@ export class PoolProxyContract {
255
265
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
256
266
  const inputQuantity = convertQuantity(quantity, baseCoin.scalar);
257
267
  return tx.add(
258
- poolProxyMoveCalls.placeMarketOrderAndRepayLoan({
268
+ this.#oracleCalls.placeMarketOrderAndRepayLoan({
259
269
  package: this.#config.MARGIN_PACKAGE_ID,
260
270
  arguments: {
261
271
  registry: this.#config.MARGIN_REGISTRY_ID,
@@ -263,8 +273,8 @@ export class PoolProxyContract {
263
273
  pool: pool.address,
264
274
  baseMarginPool: baseMarginPool.address,
265
275
  quoteMarginPool: quoteMarginPool.address,
266
- baseOracle: baseCoin.priceInfoObjectId!,
267
- quoteOracle: quoteCoin.priceInfoObjectId!,
276
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
277
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
268
278
  clientOrderId: BigInt(clientOrderId),
269
279
  selfMatchingOption,
270
280
  quantity: inputQuantity,
@@ -308,7 +318,7 @@ export class PoolProxyContract {
308
318
  const inputPrice = convertPrice(price, FLOAT_SCALAR, quoteCoin.scalar, baseCoin.scalar);
309
319
  const inputQuantity = convertQuantity(quantity, baseCoin.scalar);
310
320
  return tx.add(
311
- poolProxyMoveCalls.placeReduceOnlyLimitOrderAndRepayLoan({
321
+ this.#oracleCalls.placeReduceOnlyLimitOrderAndRepayLoan({
312
322
  package: this.#config.MARGIN_PACKAGE_ID,
313
323
  arguments: {
314
324
  registry: this.#config.MARGIN_REGISTRY_ID,
@@ -316,8 +326,8 @@ export class PoolProxyContract {
316
326
  pool: pool.address,
317
327
  baseMarginPool: baseMarginPool.address,
318
328
  quoteMarginPool: quoteMarginPool.address,
319
- baseOracle: baseCoin.priceInfoObjectId!,
320
- quoteOracle: quoteCoin.priceInfoObjectId!,
329
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
330
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
321
331
  clientOrderId: BigInt(clientOrderId),
322
332
  orderType,
323
333
  selfMatchingOption,
@@ -360,7 +370,7 @@ export class PoolProxyContract {
360
370
  const quoteMarginPool = this.#config.getMarginPool(pool.quoteCoin);
361
371
  const inputQuantity = convertQuantity(quantity, baseCoin.scalar);
362
372
  return tx.add(
363
- poolProxyMoveCalls.placeReduceOnlyMarketOrderAndRepayLoan({
373
+ this.#oracleCalls.placeReduceOnlyMarketOrderAndRepayLoan({
364
374
  package: this.#config.MARGIN_PACKAGE_ID,
365
375
  arguments: {
366
376
  registry: this.#config.MARGIN_REGISTRY_ID,
@@ -368,8 +378,8 @@ export class PoolProxyContract {
368
378
  pool: pool.address,
369
379
  baseMarginPool: baseMarginPool.address,
370
380
  quoteMarginPool: quoteMarginPool.address,
371
- baseOracle: baseCoin.priceInfoObjectId!,
372
- quoteOracle: quoteCoin.priceInfoObjectId!,
381
+ baseOracle: this.#config.getPriceInfoObjectId(pool.baseCoin),
382
+ quoteOracle: this.#config.getPriceInfoObjectId(pool.quoteCoin),
373
383
  clientOrderId: BigInt(clientOrderId),
374
384
  selfMatchingOption,
375
385
  quantity: inputQuantity,
@@ -670,20 +680,14 @@ export class PoolProxyContract {
670
680
  const pool = this.#config.getPool(poolKey);
671
681
  const baseCoin = this.#config.getCoin(pool.baseCoin);
672
682
  const quoteCoin = this.#config.getCoin(pool.quoteCoin);
673
- if (!baseCoin.priceInfoObjectId) {
674
- throw new Error(`Missing priceInfoObjectId for ${pool.baseCoin}`);
675
- }
676
- if (!quoteCoin.priceInfoObjectId) {
677
- throw new Error(`Missing priceInfoObjectId for ${pool.quoteCoin}`);
678
- }
679
683
  tx.add(
680
- poolProxyMoveCalls.updateCurrentPrice({
684
+ this.#oracleCalls.updateCurrentPrice({
681
685
  package: this.#config.MARGIN_PACKAGE_ID,
682
686
  arguments: {
683
687
  registry: this.#config.MARGIN_REGISTRY_ID,
684
688
  pool: pool.address,
685
- basePriceInfoObject: baseCoin.priceInfoObjectId,
686
- quotePriceInfoObject: quoteCoin.priceInfoObjectId,
689
+ basePriceInfoObject: this.#config.getPriceInfoObjectId(pool.baseCoin),
690
+ quotePriceInfoObject: this.#config.getPriceInfoObjectId(pool.quoteCoin),
687
691
  },
688
692
  typeArguments: [baseCoin.type, quoteCoin.type],
689
693
  }),
@@ -25,6 +25,22 @@ export interface Coin {
25
25
  priceInfoObjectId?: string;
26
26
  }
27
27
 
28
+ /** State objects identifying the Pyth deployment margin prices against. */
29
+ export interface PythConfig {
30
+ pythStateId: string;
31
+ wormholeStateId: string;
32
+ /** Hermes endpoint serving update data for this deployment. */
33
+ hermesEndpoint?: string;
34
+ /**
35
+ * Bearer token for the Hermes endpoint. The one serving Pyth's upgraded Core answers
36
+ * 401 without it, so pushing price updates needs this set.
37
+ *
38
+ * Prefer the client-level `pythAccessToken` option, which sets this without having to
39
+ * restate the state object ids. Supply the token at runtime — do not commit it.
40
+ */
41
+ accessToken?: string;
42
+ }
43
+
28
44
  export interface Pool {
29
45
  address: string;
30
46
  baseCoin: string;
@@ -287,8 +303,7 @@ export interface PoolBookParams {
287
303
  minSize: number;
288
304
  }
289
305
  export type PoolDeepPrice =
290
- | { asset_is_base: true; deep_per_base: number }
291
- | { asset_is_base: false; deep_per_quote: number };
306
+ { asset_is_base: true; deep_per_base: number } | { asset_is_base: false; deep_per_quote: number };
292
307
 
293
308
  // Quantity calculations
294
309
  export interface QuoteQuantityOut {
@@ -4,7 +4,14 @@ import type { SuiClientTypes } from '@mysten/sui/client';
4
4
  import { normalizeSuiAddress } from '@mysten/sui/utils';
5
5
 
6
6
  import { BalanceManagerContract } from '../transactions/balanceManager.js';
7
- import type { BalanceManager, MarginManager, Coin, Pool, MarginPool } from '../types/index.js';
7
+ import type {
8
+ BalanceManager,
9
+ MarginManager,
10
+ Coin,
11
+ Pool,
12
+ MarginPool,
13
+ PythConfig,
14
+ } from '../types/index.js';
8
15
  import type { CoinMap, PoolMap, MarginPoolMap, DeepbookPackageIds } from './constants.js';
9
16
  import { ResourceNotFoundError, ConfigurationError, ErrorMessages } from './errors.js';
10
17
  import {
@@ -40,10 +47,7 @@ export class DeepBookConfig {
40
47
  balanceManagers: { [key: string]: BalanceManager };
41
48
  marginManagers: { [key: string]: MarginManager };
42
49
  address: string;
43
- pyth: {
44
- pythStateId: string;
45
- wormholeStateId: string;
46
- };
50
+ pyth: PythConfig;
47
51
 
48
52
  DEEPBOOK_PACKAGE_ID: string;
49
53
  REGISTRY_ID: string;
@@ -71,6 +75,7 @@ export class DeepBookConfig {
71
75
  marginPools,
72
76
  packageIds,
73
77
  pyth,
78
+ pythAccessToken,
74
79
  }: {
75
80
  network: SuiClientTypes.Network;
76
81
  address: string;
@@ -83,7 +88,16 @@ export class DeepBookConfig {
83
88
  pools?: PoolMap;
84
89
  marginPools?: MarginPoolMap;
85
90
  packageIds?: DeepbookPackageIds;
86
- pyth?: { pythStateId: string; wormholeStateId: string };
91
+ pyth?: PythConfig;
92
+ /**
93
+ * Bearer token for the Hermes serving Pyth's upgraded Core, which answers 401
94
+ * without one. Set this rather than `pyth` when the built-in state objects are
95
+ * correct and only the credential is missing — `pyth` replaces the whole config,
96
+ * so setting a token through it means restating the state object ids.
97
+ *
98
+ * Applied after `pyth`, so if both carry a token this one wins.
99
+ */
100
+ pythAccessToken?: string;
87
101
  }) {
88
102
  this.network = network;
89
103
  this.address = normalizeSuiAddress(address);
@@ -116,7 +130,7 @@ export class DeepBookConfig {
116
130
  this.MARGIN_V1 = mainnetPackageIds.MARGIN_V1;
117
131
  this.MARGIN_REGISTRY_ID = mainnetPackageIds.MARGIN_REGISTRY_ID;
118
132
  this.LIQUIDATION_PACKAGE_ID = mainnetPackageIds.LIQUIDATION_PACKAGE_ID;
119
- this.pyth = mainnetPythConfigs;
133
+ this.pyth = pyth || mainnetPythConfigs;
120
134
  } else if (network === 'testnet') {
121
135
  this.#coins = coins || testnetCoins;
122
136
  this.#pools = pools || testnetPools;
@@ -128,24 +142,70 @@ export class DeepBookConfig {
128
142
  this.MARGIN_V1 = testnetPackageIds.MARGIN_V1;
129
143
  this.MARGIN_REGISTRY_ID = testnetPackageIds.MARGIN_REGISTRY_ID;
130
144
  this.LIQUIDATION_PACKAGE_ID = testnetPackageIds.LIQUIDATION_PACKAGE_ID;
131
- this.pyth = testnetPythConfigs;
145
+ this.pyth = pyth || testnetPythConfigs;
132
146
  } else {
133
147
  throw new Error(
134
148
  `Network '${network}' is not supported by default. Provide custom 'packageIds' for non-standard networks.`,
135
149
  );
136
150
  }
137
151
 
152
+ // Applied after the branches so a token composes with the built-in state objects
153
+ // instead of forcing the caller to restate them.
154
+ // Empty is treated as absent rather than as a credential: `PYTH_TOKEN=` exported
155
+ // blank is the common way this arrives, and a blank bearer header 401s with a
156
+ // worse message than the configuration error.
157
+ if (pythAccessToken) {
158
+ this.pyth = { ...this.pyth, accessToken: pythAccessToken };
159
+ }
160
+
138
161
  this.balanceManager = new BalanceManagerContract(this);
139
162
  }
140
163
 
141
164
  requirePyth() {
142
- if (!this.pyth.pythStateId || !this.pyth.wormholeStateId) {
165
+ const { pythStateId, wormholeStateId } = this.pyth;
166
+ if (!pythStateId || !wormholeStateId) {
143
167
  throw new ConfigurationError(
144
168
  "Pyth configuration is required for price feed operations. Provide 'pyth' when using custom packageIds.",
145
169
  );
146
170
  }
147
171
  }
148
172
 
173
+ /**
174
+ * The Pyth feed id for a coin under the active deployment.
175
+ *
176
+ * Pairs with {@link getPriceInfoObjectId}: Hermes is queried by feed id and the Move
177
+ * call takes the object, so the two must come from the same deployment or the update
178
+ * lands on an object the on-chain feed-id check then rejects.
179
+ */
180
+ getFeedId(coinKey: string): string {
181
+ const { feed } = this.getCoin(coinKey);
182
+
183
+ if (!feed) {
184
+ throw new ConfigurationError(`Coin '${coinKey}' has no Pyth feed id configured.`);
185
+ }
186
+
187
+ return feed;
188
+ }
189
+
190
+ /**
191
+ * The `PriceInfoObject` id for a coin on Pyth's upgraded Core.
192
+ *
193
+ * Throws rather than passing `undefined` into a move call: a feed may simply have no
194
+ * object on the upgraded deployment yet, and the resulting on-chain abort
195
+ * (`EPriceFeedIdMismatch`) does not say which coin was at fault.
196
+ */
197
+ getPriceInfoObjectId(coinKey: string): string {
198
+ const { priceInfoObjectId } = this.getCoin(coinKey);
199
+
200
+ if (!priceInfoObjectId) {
201
+ throw new ConfigurationError(
202
+ `Coin '${coinKey}' has no priceInfoObjectId. Pyth's upgraded Core has no price feed object for it on ${this.network}, or the id is missing from your coin config.`,
203
+ );
204
+ }
205
+
206
+ return priceInfoObjectId;
207
+ }
208
+
149
209
  // Getters
150
210
  getCoin(key: string): Coin {
151
211
  const coin = this.#coins[key];