@mysten/deepbook-v3 2.1.4 → 2.3.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 (127) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/PREDICT.md +17 -5
  3. package/dist/account.d.mts.map +1 -1
  4. package/dist/account.mjs +3 -1
  5. package/dist/account.mjs.map +1 -1
  6. package/dist/client.d.mts +2 -2
  7. package/dist/contracts/account/account_events.d.mts +20 -20
  8. package/dist/contracts/deepbook/account.d.mts +18 -18
  9. package/dist/contracts/deepbook/balances.d.mts +4 -4
  10. package/dist/contracts/deepbook/order.d.mts +12 -12
  11. package/dist/contracts/deepbook_predict/deps/sui/vec_map.mjs +37 -0
  12. package/dist/contracts/deepbook_predict/deps/sui/vec_map.mjs.map +1 -0
  13. package/dist/contracts/deepbook_predict/expiry_cash.mjs +1 -1
  14. package/dist/contracts/deepbook_predict/expiry_cash.mjs.map +1 -1
  15. package/dist/contracts/deepbook_predict/expiry_market.mjs +15 -6
  16. package/dist/contracts/deepbook_predict/expiry_market.mjs.map +1 -1
  17. package/dist/contracts/deepbook_predict/market_manager.mjs.map +1 -1
  18. package/dist/contracts/deepbook_predict/order_events.mjs.map +1 -1
  19. package/dist/contracts/deepbook_predict/plp.mjs +53 -31
  20. package/dist/contracts/deepbook_predict/plp.mjs.map +1 -1
  21. package/dist/contracts/deepbook_predict/pool_accounting.mjs +7 -7
  22. package/dist/contracts/deepbook_predict/pool_accounting.mjs.map +1 -1
  23. package/dist/contracts/deepbook_predict/predict_account.mjs +1 -1
  24. package/dist/contracts/deepbook_predict/predict_account.mjs.map +1 -1
  25. package/dist/contracts/deepbook_predict/pricing.mjs +13 -1
  26. package/dist/contracts/deepbook_predict/pricing.mjs.map +1 -1
  27. package/dist/contracts/deepbook_predict/registry.mjs +2 -1
  28. package/dist/contracts/deepbook_predict/registry.mjs.map +1 -1
  29. package/dist/contracts/deepbook_predict/strike_exposure.mjs.map +1 -1
  30. package/dist/contracts/deepbook_predict/strike_payout_tree.mjs +13 -1
  31. package/dist/contracts/deepbook_predict/strike_payout_tree.mjs.map +1 -1
  32. package/dist/contracts/deepbook_predict/vault_events.mjs +19 -7
  33. package/dist/contracts/deepbook_predict/vault_events.mjs.map +1 -1
  34. package/dist/contracts/deepbook_sessions/session_config.d.mts +8 -8
  35. package/dist/contracts/deepbook_sessions/session_config.d.mts.map +1 -1
  36. package/dist/contracts/deepbook_sessions/sessions.d.mts +22 -22
  37. package/dist/contracts/deepbook_sessions/sessions.d.mts.map +1 -1
  38. package/dist/deployments/index.d.mts +3 -2
  39. package/dist/deployments/index.d.mts.map +1 -1
  40. package/dist/deployments/index.mjs +4 -1
  41. package/dist/deployments/index.mjs.map +1 -1
  42. package/dist/deployments/mainnet.d.mts +14 -0
  43. package/dist/deployments/mainnet.d.mts.map +1 -0
  44. package/dist/deployments/mainnet.mjs +73 -0
  45. package/dist/deployments/mainnet.mjs.map +1 -0
  46. package/dist/deployments/testnet.mjs +23 -23
  47. package/dist/deployments/testnet.mjs.map +1 -1
  48. package/dist/deployments/types.d.mts +1 -1
  49. package/dist/predict/client.d.mts +25 -4
  50. package/dist/predict/client.d.mts.map +1 -1
  51. package/dist/predict/client.mjs +4 -4
  52. package/dist/predict/client.mjs.map +1 -1
  53. package/dist/predict/config/index.d.mts +2 -0
  54. package/dist/predict/config/index.d.mts.map +1 -1
  55. package/dist/predict/config/index.mjs +4 -1
  56. package/dist/predict/config/index.mjs.map +1 -1
  57. package/dist/predict/config/mainnet.d.mts +17 -0
  58. package/dist/predict/config/mainnet.d.mts.map +1 -0
  59. package/dist/predict/config/mainnet.mjs +26 -0
  60. package/dist/predict/config/mainnet.mjs.map +1 -0
  61. package/dist/predict/config/types.d.mts +6 -0
  62. package/dist/predict/config/types.d.mts.map +1 -1
  63. package/dist/predict/index.d.mts +4 -2
  64. package/dist/predict/index.mjs +3 -1
  65. package/dist/predict/pricing.d.mts +6 -6
  66. package/dist/predict/pricing.d.mts.map +1 -1
  67. package/dist/predict/pricing.mjs +6 -6
  68. package/dist/predict/pricing.mjs.map +1 -1
  69. package/dist/predict/reads/balances.mjs.map +1 -1
  70. package/dist/predict/reads/markets.mjs +1 -1
  71. package/dist/predict/reads/markets.mjs.map +1 -1
  72. package/dist/predict/reads/pricing.d.mts +2 -1
  73. package/dist/predict/reads/pricing.d.mts.map +1 -1
  74. package/dist/predict/reads/pricing.mjs.map +1 -1
  75. package/dist/sessions.d.mts.map +1 -1
  76. package/dist/sessions.mjs +3 -1
  77. package/dist/sessions.mjs.map +1 -1
  78. package/dist/transactions/balanceManager.d.mts +12 -12
  79. package/dist/transactions/balanceManager.d.mts.map +1 -1
  80. package/dist/transactions/deepbook.d.mts +20 -20
  81. package/dist/transactions/deepbook.d.mts.map +1 -1
  82. package/dist/transactions/deepbookAdmin.d.mts +4 -4
  83. package/dist/transactions/deepbookAdmin.d.mts.map +1 -1
  84. package/dist/transactions/marginAdmin.d.mts +7 -7
  85. package/dist/transactions/marginLiquidations.d.mts +3 -3
  86. package/dist/transactions/marginMaintainer.d.mts +5 -5
  87. package/dist/transactions/marginManager.d.mts +32 -32
  88. package/dist/transactions/marginPool.d.mts +18 -18
  89. package/dist/transactions/marginPool.d.mts.map +1 -1
  90. package/dist/transactions/marginRegistry.d.mts +16 -16
  91. package/dist/transactions/marginTPSL.d.mts +10 -10
  92. package/dist/transactions/poolProxy.d.mts +8 -8
  93. package/package.json +3 -3
  94. package/src/account.ts +3 -1
  95. package/src/contracts/deepbook_predict/builder_code.ts +3 -3
  96. package/src/contracts/deepbook_predict/config_events.ts +9 -2
  97. package/src/contracts/deepbook_predict/deps/sui/vec_map.ts +33 -0
  98. package/src/contracts/deepbook_predict/expiry_cash.ts +1 -1
  99. package/src/contracts/deepbook_predict/expiry_market.ts +70 -11
  100. package/src/contracts/deepbook_predict/market_lifecycle_cap.ts +3 -10
  101. package/src/contracts/deepbook_predict/market_manager.ts +2 -2
  102. package/src/contracts/deepbook_predict/order_events.ts +6 -6
  103. package/src/contracts/deepbook_predict/plp.ts +263 -81
  104. package/src/contracts/deepbook_predict/pool_accounting.ts +14 -14
  105. package/src/contracts/deepbook_predict/pool_valuation_cap.ts +69 -0
  106. package/src/contracts/deepbook_predict/predict_account.ts +1 -1
  107. package/src/contracts/deepbook_predict/pricing.ts +16 -4
  108. package/src/contracts/deepbook_predict/protocol_config.ts +202 -7
  109. package/src/contracts/deepbook_predict/registry.ts +91 -17
  110. package/src/contracts/deepbook_predict/strike_exposure.ts +1 -1
  111. package/src/contracts/deepbook_predict/strike_payout_tree.ts +27 -0
  112. package/src/contracts/deepbook_predict/vault_events.ts +45 -14
  113. package/src/contracts/propbook/block_scholes_store.ts +8 -42
  114. package/src/deployments/index.ts +13 -3
  115. package/src/deployments/mainnet.ts +107 -0
  116. package/src/deployments/testnet.ts +25 -25
  117. package/src/deployments/types.ts +1 -1
  118. package/src/predict/client.ts +45 -15
  119. package/src/predict/config/index.ts +7 -2
  120. package/src/predict/config/mainnet.ts +27 -0
  121. package/src/predict/config/types.ts +7 -1
  122. package/src/predict/index.ts +5 -0
  123. package/src/predict/pricing.ts +11 -9
  124. package/src/predict/reads/balances.ts +1 -1
  125. package/src/predict/reads/markets.ts +1 -1
  126. package/src/predict/reads/pricing.ts +2 -1
  127. package/src/sessions.ts +4 -1
@@ -1,6 +1,8 @@
1
+ import { MAINNET_DEPLOYMENT, MAINNET_UNITS } from "../deployments/mainnet.mjs";
1
2
  import { TESTNET_DEPLOYMENT, TESTNET_UNITS } from "../deployments/testnet.mjs";
2
3
  import { getDeployment, getUnits } from "../deployments/index.mjs";
3
4
  import { PredictConfig, PredictPackages, UnderlyingConfig } from "./config/types.mjs";
5
+ import { MAINNET_CONFIG } from "./config/mainnet.mjs";
4
6
  import { TESTNET_CONFIG } from "./config/testnet.mjs";
5
7
  import { getConfig } from "./config/index.mjs";
6
8
  import { BalanceChangeReceipt, BuilderCodeReceipt, ClaimReceipt, CreateManagerReceipt, DecodableEvent, DecodableTransactionResult, MintReceipt, PlpCancelReceipt, PlpRequestReceipt, RedeemReceipt } from "./decode.mjs";
@@ -11,8 +13,8 @@ import { MarketFeeds, loadLivePricer } from "./tx/trade.mjs";
11
13
  import { ReadClient } from "./reads/inspect.mjs";
12
14
  import { PricerSnapshot } from "./reads/pricing.mjs";
13
15
  import { POS_INF_TICK, Side, binaryRangeTicks } from "./ticks.mjs";
14
- import { ActiveMarket, CloseOptions, MarketDescriptor, MarketSummary, MintAmountOptions, MintOptions, MintQuote, POSITION_LOT_SIZE, PoolSummary, PredictClient, PredictCompatibleClient, RedeemQuote, predict } from "./client.mjs";
16
+ import { ActiveMarket, CloseOptions, MarketDescriptor, MarketSummary, MintAmountOptions, MintOptions, MintQuote, POSITION_LOT_SIZE, PlpSupplyOptions, PlpWithdrawOptions, PoolSummary, PredictClient, PredictCompatibleClient, RedeemQuote, predict } from "./client.mjs";
15
17
  import { deriveAccountWrapperId, generateAuth } from "./tx/common.mjs";
16
18
  import { U64_MAX, priceToRaw, probabilityToRaw, rawToPrice, rawToProbability, rawToUsdc, usdcToRaw } from "./units.mjs";
17
19
  import { MoveAbortError, PredictInputError, PredictMoveError, decodeMoveAbort } from "./errors.mjs";
18
- export { type ActiveMarket, type BalanceChangeReceipt, type BuilderCodeReceipt, type ClaimReceipt, type CloseOptions, type CreateManagerReceipt, type DecodableEvent, type DecodableTransactionResult, type GeneratedConfig, type MarketDescriptor, type MarketFeeds, type MarketSummary, type MintAmountOptions, type MintOptions, type MintQuote, type MintReceipt, type MoveAbortError, type OpenPosition, POSITION_LOT_SIZE, POS_INF_TICK, type PlpCancelReceipt, type PlpRequestReceipt, type PoolSummary, PredictClient, type PredictCompatibleClient, type PredictConfig, PredictInputError, PredictMoveError, type PredictPackages, type PricerSnapshot, type ReadClient, type RedeemQuote, type RedeemReceipt, type Side, TESTNET_CONFIG, TESTNET_DEPLOYMENT, TESTNET_UNITS, U64_MAX, type UnderlyingConfig, binaryRangeTicks, decodeMoveAbort, deriveAccountWrapperId, generateAuth, getConfig, getDeployment, getUnits, loadLivePricer, predict, priceToRaw, pricing_d_exports as pricing, probabilityToRaw, rawToPrice, rawToProbability, rawToUsdc, toGeneratedConfig, usdcToRaw };
20
+ export { type ActiveMarket, type BalanceChangeReceipt, type BuilderCodeReceipt, type ClaimReceipt, type CloseOptions, type CreateManagerReceipt, type DecodableEvent, type DecodableTransactionResult, type GeneratedConfig, MAINNET_CONFIG, MAINNET_DEPLOYMENT, MAINNET_UNITS, type MarketDescriptor, type MarketFeeds, type MarketSummary, type MintAmountOptions, type MintOptions, type MintQuote, type MintReceipt, type MoveAbortError, type OpenPosition, POSITION_LOT_SIZE, POS_INF_TICK, type PlpCancelReceipt, type PlpRequestReceipt, type PlpSupplyOptions, type PlpWithdrawOptions, type PoolSummary, PredictClient, type PredictCompatibleClient, type PredictConfig, PredictInputError, PredictMoveError, type PredictPackages, type PricerSnapshot, type ReadClient, type RedeemQuote, type RedeemReceipt, type Side, TESTNET_CONFIG, TESTNET_DEPLOYMENT, TESTNET_UNITS, U64_MAX, type UnderlyingConfig, binaryRangeTicks, decodeMoveAbort, deriveAccountWrapperId, generateAuth, getConfig, getDeployment, getUnits, loadLivePricer, predict, priceToRaw, pricing_d_exports as pricing, probabilityToRaw, rawToPrice, rawToProbability, rawToUsdc, toGeneratedConfig, usdcToRaw };
@@ -1,5 +1,7 @@
1
+ import { MAINNET_DEPLOYMENT, MAINNET_UNITS } from "../deployments/mainnet.mjs";
1
2
  import { TESTNET_DEPLOYMENT, TESTNET_UNITS } from "../deployments/testnet.mjs";
2
3
  import { getDeployment, getUnits } from "../deployments/index.mjs";
4
+ import { MAINNET_CONFIG } from "./config/mainnet.mjs";
3
5
  import { TESTNET_CONFIG } from "./config/testnet.mjs";
4
6
  import { getConfig } from "./config/index.mjs";
5
7
  import { toGeneratedConfig } from "./config/generated.mjs";
@@ -11,4 +13,4 @@ import { loadLivePricer } from "./tx/trade.mjs";
11
13
  import { pricing_exports } from "./pricing.mjs";
12
14
  import { POSITION_LOT_SIZE, PredictClient, predict } from "./client.mjs";
13
15
 
14
- export { POSITION_LOT_SIZE, POS_INF_TICK, PredictClient, PredictInputError, PredictMoveError, TESTNET_CONFIG, TESTNET_DEPLOYMENT, TESTNET_UNITS, U64_MAX, binaryRangeTicks, decodeMoveAbort, deriveAccountWrapperId, generateAuth, getConfig, getDeployment, getUnits, loadLivePricer, predict, priceToRaw, pricing_exports as pricing, probabilityToRaw, rawToPrice, rawToProbability, rawToUsdc, toGeneratedConfig, usdcToRaw };
16
+ export { MAINNET_CONFIG, MAINNET_DEPLOYMENT, MAINNET_UNITS, POSITION_LOT_SIZE, POS_INF_TICK, PredictClient, PredictInputError, PredictMoveError, TESTNET_CONFIG, TESTNET_DEPLOYMENT, TESTNET_UNITS, U64_MAX, binaryRangeTicks, decodeMoveAbort, deriveAccountWrapperId, generateAuth, getConfig, getDeployment, getUnits, loadLivePricer, predict, priceToRaw, pricing_exports as pricing, probabilityToRaw, rawToPrice, rawToProbability, rawToUsdc, toGeneratedConfig, usdcToRaw };
@@ -36,12 +36,12 @@ declare function probability(inputs: PricerInputs, strike: number, side: 'up' |
36
36
  declare function strikeAtProbability(inputs: PricerInputs, p: number): number | null;
37
37
  /** Roll `a` and `b` down by the fraction of anchored time remaining, matching the chain's
38
38
  * `roll_down_svi` (variance decays toward expiry). `remainingMs` = expiry − now;
39
- * `anchorTteMs` = expiry − the SVI observation's **batch envelope time** — the same clock the
40
- * freshness gate uses, and what the chain anchors on. It is NOT the provider's calibration
41
- * (model) time, which stays on the stored observation: using that rolls by the wrong
42
- * fraction. `read.pricer` avoids the question entirely (the chain has already rolled).
43
- * `rho`, `m`, `sigma` are unchanged. Feed an UNrolled provider surface; the result is what {@link upProbability}
44
- * expects. */
39
+ * `anchorTteMs` = expiry − the SVI observation's **provider `svi_timestamp`** (its per-update
40
+ * source timestamp) — the same clock the freshness gate accepts, and what the chain anchors on
41
+ * (`pricing.move`: "One clock serves every job"). Anchoring on the batch's ingestion time
42
+ * instead rolls by the wrong fraction. `read.pricer` avoids the question entirely (the chain
43
+ * has already rolled). `rho`, `m`, `sigma` are unchanged. Feed an UNrolled provider surface;
44
+ * the result is what {@link upProbability} expects. */
45
45
  declare function rollDown(svi: Svi, remainingMs: number, anchorTteMs: number): Svi;
46
46
  /** The forward the contract prices against: Pyth spot re-anchored by the Block-Scholes
47
47
  * basis (`spot · forward/bsSpot`), falling back to the Block-Scholes forward when Pyth is
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.d.mts","names":[],"sources":["../../src/predict/pricing.ts"],"mappings":";;;;;;UA6BiB,GAAA;EAChB,CAAA;EACA,CAAA;EACA,GAAA;EACA,CAAA;EACA,KAAA;AAAA;;;;UAMgB,YAAA;;EAEhB,OAAA;EACA,GAAA,EAAK,GAAA;AAAA;;;;iBAiCU,aAAA,CAAc,MAAA,EAAQ,YAAA,EAAc,MAAA;;;iBAwBpC,eAAA,CAAgB,MAAA,EAAQ,YAAA,EAAc,MAAA;;;iBAMtC,gBAAA,CAAiB,MAAA,EAAQ,YAAA,EAAc,KAAA,UAAe,MAAA;;iBAStD,WAAA,CAAY,MAAA,EAAQ,YAAA,EAAc,MAAA,UAAgB,IAAA;;;iBAOlD,mBAAA,CAAoB,MAAA,EAAQ,YAAA,EAAc,CAAA;;;;AA9C1D;;;;;iBA8EgB,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,WAAA,UAAqB,WAAA,WAAsB,GAAA;;;;AAtD9E;;;;iBAkEgB,OAAA,CAAQ,QAAA,UAAkB,MAAA,UAAgB,SAAA;;;;UAQzC,WAAA,SAAoB,YAAA;EApErB;EAsEf,EAAA,CAAG,MAAA;;EAEH,IAAA,CAAK,MAAA;EAxEmC;EA0ExC,WAAA,CAAY,MAAA,UAAgB,IAAA;EA1E0B;EA4EtD,KAAA,CAAM,KAAA,UAAe,MAAA;EA5E8D;EA8EnF,mBAAA,CAAoB,CAAA;AAAA;;iBAIL,WAAA,CAAY,MAAA,EAAQ,YAAA,GAAe,WAAA"}
1
+ {"version":3,"file":"pricing.d.mts","names":[],"sources":["../../src/predict/pricing.ts"],"mappings":";;;;;;UA+BiB,GAAA;EAChB,CAAA;EACA,CAAA;EACA,GAAA;EACA,CAAA;EACA,KAAA;AAAA;;;;UAMgB,YAAA;;EAEhB,OAAA;EACA,GAAA,EAAK,GAAA;AAAA;;;;iBAiCU,aAAA,CAAc,MAAA,EAAQ,YAAA,EAAc,MAAA;;;iBAwBpC,eAAA,CAAgB,MAAA,EAAQ,YAAA,EAAc,MAAA;;;iBAMtC,gBAAA,CAAiB,MAAA,EAAQ,YAAA,EAAc,KAAA,UAAe,MAAA;;iBAStD,WAAA,CAAY,MAAA,EAAQ,YAAA,EAAc,MAAA,UAAgB,IAAA;;;iBAOlD,mBAAA,CAAoB,MAAA,EAAQ,YAAA,EAAc,CAAA;;;;AA9C1D;;;;;iBA8EgB,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,WAAA,UAAqB,WAAA,WAAsB,GAAA;;;;AAtD9E;;;;iBAkEgB,OAAA,CAAQ,QAAA,UAAkB,MAAA,UAAgB,SAAA;;;;UAQzC,WAAA,SAAoB,YAAA;EApErB;EAsEf,EAAA,CAAG,MAAA;;EAEH,IAAA,CAAK,MAAA;EAxEmC;EA0ExC,WAAA,CAAY,MAAA,UAAgB,IAAA;EA1E0B;EA4EtD,KAAA,CAAM,KAAA,UAAe,MAAA;EA5E8D;EA8EnF,mBAAA,CAAoB,CAAA;AAAA;;iBAIL,WAAA,CAAY,MAAA,EAAQ,YAAA,GAAe,WAAA"}
@@ -86,12 +86,12 @@ function strikeAtProbability(inputs, p) {
86
86
  }
87
87
  /** Roll `a` and `b` down by the fraction of anchored time remaining, matching the chain's
88
88
  * `roll_down_svi` (variance decays toward expiry). `remainingMs` = expiry − now;
89
- * `anchorTteMs` = expiry − the SVI observation's **batch envelope time** — the same clock the
90
- * freshness gate uses, and what the chain anchors on. It is NOT the provider's calibration
91
- * (model) time, which stays on the stored observation: using that rolls by the wrong
92
- * fraction. `read.pricer` avoids the question entirely (the chain has already rolled).
93
- * `rho`, `m`, `sigma` are unchanged. Feed an UNrolled provider surface; the result is what {@link upProbability}
94
- * expects. */
89
+ * `anchorTteMs` = expiry − the SVI observation's **provider `svi_timestamp`** (its per-update
90
+ * source timestamp) — the same clock the freshness gate accepts, and what the chain anchors on
91
+ * (`pricing.move`: "One clock serves every job"). Anchoring on the batch's ingestion time
92
+ * instead rolls by the wrong fraction. `read.pricer` avoids the question entirely (the chain
93
+ * has already rolled). `rho`, `m`, `sigma` are unchanged. Feed an UNrolled provider surface;
94
+ * the result is what {@link upProbability} expects. */
95
95
  function rollDown(svi, remainingMs, anchorTteMs) {
96
96
  const frac = anchorTteMs > 0 ? remainingMs / anchorTteMs : 0;
97
97
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.mjs","names":["forward"],"sources":["../../src/predict/pricing.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n// Faithful float port of the deployed `deepbook_predict::pricing::compute_nd2`\n// (testnet `predict-testnet-8-21`, sourceCommit 1f79fe87) — the SVI-adjusted digital\n// probability, WITH the skew-correction term. It operates on the pricer's\n// ALREADY-RESOLVED forward and ALREADY-ROLLED-DOWN SVI, exactly as `load_live_pricer`\n// returns them (decoded by `reads/pricing.ts`). So the two on-chain steps that pick the\n// forward (Pyth-spot vs Block-Scholes, admin flag + freshness) and roll `a`/`b` down by\n// remaining/anchored time already happened on-chain — this module never re-derives them,\n// which is what keeps it faithful.\n//\n// This is the fast client-side board pricer: read one `Pricer` snapshot, then price every\n// strike locally with no further chain calls. `read.price` / `read.quoteMint` (a chain\n// dry-run) stay the authoritative quote at trade time. Divergence vs the chain is up to\n// ~1e-4 in probability, dominated by the chain's fixed-point truncation near ATM when sigma\n// sits at its floor (float64 here is the more precise side, not the less); negligible for\n// display. `tests/testnet/pricing.test.ts` bounds it live against the deployment.\n//\n// The on-chain formula (pricing.move `compute_nd2`, 1f79fe87):\n// k = ln(strike / forward)\n// x = k - m\n// w = a + b·(ρ·x + √(x² + σ²)) // a, b already rolled down\n// d2 = −(k + w/2) / √w // clamped to ±8\n// w′ = b·(ρ + x/√(x² + σ²)) // SVI slope\n// price = N(d2) − φ(d2)·w′ / (2·√w) // the skew correction, clamped [0,1]\n\n/** Rolled-down SVI parameters for one expiry, in decimal (NOT the chain's 1e9/1e18 integer\n * scaling) — the surface AFTER Predict's remaining-time roll-down, as carried by the\n * on-chain `Pricer`. `a`, `rho`, `m` are signed; `b`, `sigma` are non-negative. */\nexport interface Svi {\n\ta: number;\n\tb: number;\n\trho: number;\n\tm: number;\n\tsigma: number;\n}\n\n/** A resolved pricer snapshot: the forward the contract prices against and its rolled SVI\n * surface, both in decimal. Produced by `read.pricer(market)`; consume via {@link boardPricer}\n * or the pure functions below. */\nexport interface PricerInputs {\n\t/** Forward price the digital settles against, in decimal (same units as `strike`). */\n\tforward: number;\n\tsvi: Svi;\n}\n\n/** Standard normal CDF via erf (Abramowitz–Stegun 7.1.26, |err| < 1.5e-7). */\nfunction normalCdf(x: number): number {\n\treturn 0.5 * (1 + erf(x / Math.SQRT2));\n}\n\n/** Standard normal PDF. */\nfunction normalPdf(x: number): number {\n\treturn Math.exp(-0.5 * x * x) / Math.sqrt(2 * Math.PI);\n}\n\nfunction erf(x: number): number {\n\tconst sign = x >= 0 ? 1 : -1;\n\tconst ax = Math.abs(x);\n\tconst t = 1 / (1 + 0.3275911 * ax);\n\tconst y =\n\t\t1 -\n\t\t((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - 0.284496736) * t + 0.254829592) *\n\t\t\tt *\n\t\t\tMath.exp(-ax * ax);\n\treturn sign * y;\n}\n\n// Clamp |d2| at 8, matching the chain (`normal_cdf`/`normal_pdf` saturate beyond that).\nfunction clampD2(d2: number): number {\n\treturn d2 > 8 ? 8 : d2 < -8 ? -8 : d2;\n}\n\n/** P(settle > strike) — the UP digital, with the SVI skew correction. `inputs.svi` is the\n * already-rolled surface (no roll-down applied here). `forward` and `strike` share units.\n * Returns a probability in [0, 1]. */\nexport function upProbability(inputs: PricerInputs, strike: number): number {\n\tconst { forward, svi } = inputs;\n\tif (!(forward > 0)) return 0;\n\tif (strike <= 0) return 1; // neg-inf limit\n\tconst { a, b, rho, m, sigma } = svi;\n\tconst k = Math.log(strike / forward);\n\tconst km = k - m;\n\tconst root = Math.sqrt(km * km + sigma * sigma);\n\tconst inner = rho * km + root; // >= 0 for |rho| <= 1\n\tconst w = a + b * inner; // total variance\n\t// The chain guarantees w > 0 at every strike (assert_min_total_variance_positive at\n\t// load time), so this branch is unreachable in practice; return the variance→0 tail\n\t// limit rather than throw, so a UI never crashes on a degenerate snapshot.\n\tif (w <= 0) return k < 0 ? 1 : 0;\n\tconst sq = Math.sqrt(w);\n\tconst d2 = clampD2(-((k + w / 2) / sq));\n\tconst nd2 = normalCdf(d2);\n\tconst wPrime = b * (rho + km / root); // SVI slope × b\n\tconst price = nd2 - (normalPdf(d2) * wPrime) / (2 * sq); // skew correction\n\treturn price < 0 ? 0 : price > 1 ? 1 : price;\n}\n\n/** P(settle < strike) — the DOWN digital. Exactly `1 − up`, matching the chain's\n * `range_price(-inf, strike] = up(-inf) − up(strike) = 1 − up(strike)`. */\nexport function downProbability(inputs: PricerInputs, strike: number): number {\n\treturn 1 - upProbability(inputs, strike);\n}\n\n/** Probability mass in `(lower, higher]`, floored at 0 (matches `compute_range_price`'s\n * saturating subtraction). Use `lower <= 0` for the −∞ bound and `higher = Infinity` for +∞. */\nexport function rangeProbability(inputs: PricerInputs, lower: number, higher: number): number {\n\t// up(lower) − up(higher), where up(+inf) = 0 and up(<= 0) = 1.\n\tconst upLower = lower <= 0 ? 1 : upProbability(inputs, lower);\n\tconst upHigher = higher === Infinity ? 0 : upProbability(inputs, higher);\n\tconst d = upLower - upHigher;\n\treturn d < 0 ? 0 : d;\n}\n\n/** Binary probability at `strike` for the given side (`up` = P(>strike), `down` = 1 − up). */\nexport function probability(inputs: PricerInputs, strike: number, side: 'up' | 'down'): number {\n\tconst up = upProbability(inputs, strike);\n\treturn side === 'up' ? up : 1 - up;\n}\n\n/** Strike where P(settle > strike) = `p`, by bisection (UP is monotone-decreasing in\n * strike). Null when no crossing exists within ±64% of forward. */\nexport function strikeAtProbability(inputs: PricerInputs, p: number): number | null {\n\tconst { forward } = inputs;\n\tif (!(forward > 0) || !(p > 0 && p < 1)) return null;\n\tconst up = (strike: number) => upProbability(inputs, strike);\n\tlet r = 0.01;\n\twhile (up(forward * (1 - r)) < p || up(forward * (1 + r)) > p) {\n\t\tr *= 2;\n\t\tif (r > 0.64) return null;\n\t}\n\tlet lo = forward * (1 - r);\n\tlet hi = forward * (1 + r);\n\tfor (let i = 0; i < 64; i++) {\n\t\tconst mid = (lo + hi) / 2;\n\t\tif (up(mid) > p) lo = mid;\n\t\telse hi = mid;\n\t}\n\treturn (lo + hi) / 2;\n}\n\n// --- Resolving raw feed data client-side (for consumers that hold their own live oracle\n// feed and want to price with NO chain call, e.g. deepbook-app). The turnkey path is\n// `read.pricer(market)`, which reads these already resolved from the chain's `Pricer`;\n// these two helpers reproduce the on-chain resolution when you'd rather not read the chain.\n\n/** Roll `a` and `b` down by the fraction of anchored time remaining, matching the chain's\n * `roll_down_svi` (variance decays toward expiry). `remainingMs` = expiry − now;\n * `anchorTteMs` = expiry − the SVI observation's **batch envelope time** — the same clock the\n * freshness gate uses, and what the chain anchors on. It is NOT the provider's calibration\n * (model) time, which stays on the stored observation: using that rolls by the wrong\n * fraction. `read.pricer` avoids the question entirely (the chain has already rolled).\n * `rho`, `m`, `sigma` are unchanged. Feed an UNrolled provider surface; the result is what {@link upProbability}\n * expects. */\nexport function rollDown(svi: Svi, remainingMs: number, anchorTteMs: number): Svi {\n\tconst frac = anchorTteMs > 0 ? remainingMs / anchorTteMs : 0;\n\treturn { ...svi, a: svi.a * frac, b: svi.b * frac };\n}\n\n/** The forward the contract prices against: Pyth spot re-anchored by the Block-Scholes\n * basis (`spot · forward/bsSpot`), falling back to the Block-Scholes forward when Pyth is\n * absent. Pass `pythSpot <= 0` to force the fallback. NOTE: on-chain this branch is also\n * gated by the admin flag `use_pyth_spot_for_forward` (default on) and a Pyth freshness\n * window — when the flag is off or the Pyth spot is stale, the chain uses `bsForward`. If\n * you track that config/freshness, apply it before calling (or use `read.pricer`, which\n * gets the resolved forward from the chain). */\nexport function forward(pythSpot: number, bsSpot: number, bsForward: number): number {\n\tif (pythSpot > 0 && bsSpot > 0) return pythSpot * (bsForward / bsSpot);\n\treturn bsForward;\n}\n\n/** A pricer bound to one resolved snapshot: price a whole board of strikes locally, no\n * chain calls. Returned by `read.pricer(market)`; also constructable directly from inputs\n * you already hold (e.g. from a `Pricer` snapshot decoded elsewhere). */\nexport interface BoardPricer extends PricerInputs {\n\t/** P(settle > strike). */\n\tup(strike: number): number;\n\t/** P(settle < strike) = 1 − up. */\n\tdown(strike: number): number;\n\t/** P(side wins at strike). */\n\tprobability(strike: number, side: 'up' | 'down'): number;\n\t/** Probability mass in `(lower, higher]` (use `lower<=0`/`higher=Infinity` for the tails). */\n\trange(lower: number, higher: number): number;\n\t/** Strike where P(> strike) = `p`, or null if outside ±64% of forward. */\n\tstrikeAtProbability(p: number): number | null;\n}\n\n/** Build a {@link BoardPricer} from a resolved snapshot (decimal forward + rolled SVI). Pure. */\nexport function boardPricer(inputs: PricerInputs): BoardPricer {\n\treturn {\n\t\tforward: inputs.forward,\n\t\tsvi: inputs.svi,\n\t\tup: (strike) => upProbability(inputs, strike),\n\t\tdown: (strike) => downProbability(inputs, strike),\n\t\tprobability: (strike, side) => probability(inputs, strike, side),\n\t\trange: (lower, higher) => rangeProbability(inputs, lower, higher),\n\t\tstrikeAtProbability: (p) => strikeAtProbability(inputs, p),\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pricing.mjs","names":["forward"],"sources":["../../src/predict/pricing.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n// Faithful float port of `deepbook_predict::pricing::compute_nd2` as of the anchor the\n// generated bindings are pinned to (`sui-codegen.config.ts`: the `deepbook-predict-testnet`\n// deployment). `pricing.move` is untouched across the anchors this SDK has used, so the\n// formula is unchanged from earlier deployments — the SVI-adjusted digital\n// probability, WITH the skew-correction term. It operates on the pricer's\n// ALREADY-RESOLVED forward and ALREADY-ROLLED-DOWN SVI, exactly as `load_live_pricer`\n// returns them (decoded by `reads/pricing.ts`). So the two on-chain steps that pick the\n// forward (Pyth-spot vs Block-Scholes, admin flag + freshness) and roll `a`/`b` down by\n// remaining/anchored time already happened on-chain — this module never re-derives them,\n// which is what keeps it faithful.\n//\n// This is the fast client-side board pricer: read one `Pricer` snapshot, then price every\n// strike locally with no further chain calls. `read.price` / `read.quoteMint` (a chain\n// dry-run) stay the authoritative quote at trade time. Divergence vs the chain is up to\n// ~1e-4 in probability, dominated by the chain's fixed-point truncation near ATM when sigma\n// sits at its floor (float64 here is the more precise side, not the less); negligible for\n// display. `tests/testnet/pricing.test.ts` bounds it live against the deployment.\n//\n// The on-chain formula (pricing/pricing.move `compute_nd2`):\n// k = ln(strike / forward)\n// x = k - m\n// w = a + b·(ρ·x + √(x² + σ²)) // a, b already rolled down\n// d2 = −(k + w/2) / √w // clamped to ±8\n// w′ = b·(ρ + x/√(x² + σ²)) // SVI slope\n// price = N(d2) − φ(d2)·w′ / (2·√w) // the skew correction, clamped [0,1]\n\n/** Rolled-down SVI parameters for one expiry, in decimal (NOT the chain's 1e9/1e18 integer\n * scaling) — the surface AFTER Predict's remaining-time roll-down, as carried by the\n * on-chain `Pricer`. `a`, `rho`, `m` are signed; `b`, `sigma` are non-negative. */\nexport interface Svi {\n\ta: number;\n\tb: number;\n\trho: number;\n\tm: number;\n\tsigma: number;\n}\n\n/** A resolved pricer snapshot: the forward the contract prices against and its rolled SVI\n * surface, both in decimal. Produced by `read.pricer(market)`; consume via {@link boardPricer}\n * or the pure functions below. */\nexport interface PricerInputs {\n\t/** Forward price the digital settles against, in decimal (same units as `strike`). */\n\tforward: number;\n\tsvi: Svi;\n}\n\n/** Standard normal CDF via erf (Abramowitz–Stegun 7.1.26, |err| < 1.5e-7). */\nfunction normalCdf(x: number): number {\n\treturn 0.5 * (1 + erf(x / Math.SQRT2));\n}\n\n/** Standard normal PDF. */\nfunction normalPdf(x: number): number {\n\treturn Math.exp(-0.5 * x * x) / Math.sqrt(2 * Math.PI);\n}\n\nfunction erf(x: number): number {\n\tconst sign = x >= 0 ? 1 : -1;\n\tconst ax = Math.abs(x);\n\tconst t = 1 / (1 + 0.3275911 * ax);\n\tconst y =\n\t\t1 -\n\t\t((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - 0.284496736) * t + 0.254829592) *\n\t\t\tt *\n\t\t\tMath.exp(-ax * ax);\n\treturn sign * y;\n}\n\n// Clamp |d2| at 8, matching the chain (`normal_cdf`/`normal_pdf` saturate beyond that).\nfunction clampD2(d2: number): number {\n\treturn d2 > 8 ? 8 : d2 < -8 ? -8 : d2;\n}\n\n/** P(settle > strike) — the UP digital, with the SVI skew correction. `inputs.svi` is the\n * already-rolled surface (no roll-down applied here). `forward` and `strike` share units.\n * Returns a probability in [0, 1]. */\nexport function upProbability(inputs: PricerInputs, strike: number): number {\n\tconst { forward, svi } = inputs;\n\tif (!(forward > 0)) return 0;\n\tif (strike <= 0) return 1; // neg-inf limit\n\tconst { a, b, rho, m, sigma } = svi;\n\tconst k = Math.log(strike / forward);\n\tconst km = k - m;\n\tconst root = Math.sqrt(km * km + sigma * sigma);\n\tconst inner = rho * km + root; // >= 0 for |rho| <= 1\n\tconst w = a + b * inner; // total variance\n\t// The chain guarantees w > 0 at every strike (assert_min_total_variance_positive at\n\t// load time), so this branch is unreachable in practice; return the variance→0 tail\n\t// limit rather than throw, so a UI never crashes on a degenerate snapshot.\n\tif (w <= 0) return k < 0 ? 1 : 0;\n\tconst sq = Math.sqrt(w);\n\tconst d2 = clampD2(-((k + w / 2) / sq));\n\tconst nd2 = normalCdf(d2);\n\tconst wPrime = b * (rho + km / root); // SVI slope × b\n\tconst price = nd2 - (normalPdf(d2) * wPrime) / (2 * sq); // skew correction\n\treturn price < 0 ? 0 : price > 1 ? 1 : price;\n}\n\n/** P(settle < strike) — the DOWN digital. Exactly `1 − up`, matching the chain's\n * `range_price(-inf, strike] = up(-inf) − up(strike) = 1 − up(strike)`. */\nexport function downProbability(inputs: PricerInputs, strike: number): number {\n\treturn 1 - upProbability(inputs, strike);\n}\n\n/** Probability mass in `(lower, higher]`, floored at 0 (matches `compute_range_price`'s\n * saturating subtraction). Use `lower <= 0` for the −∞ bound and `higher = Infinity` for +∞. */\nexport function rangeProbability(inputs: PricerInputs, lower: number, higher: number): number {\n\t// up(lower) − up(higher), where up(+inf) = 0 and up(<= 0) = 1.\n\tconst upLower = lower <= 0 ? 1 : upProbability(inputs, lower);\n\tconst upHigher = higher === Infinity ? 0 : upProbability(inputs, higher);\n\tconst d = upLower - upHigher;\n\treturn d < 0 ? 0 : d;\n}\n\n/** Binary probability at `strike` for the given side (`up` = P(>strike), `down` = 1 − up). */\nexport function probability(inputs: PricerInputs, strike: number, side: 'up' | 'down'): number {\n\tconst up = upProbability(inputs, strike);\n\treturn side === 'up' ? up : 1 - up;\n}\n\n/** Strike where P(settle > strike) = `p`, by bisection (UP is monotone-decreasing in\n * strike). Null when no crossing exists within ±64% of forward. */\nexport function strikeAtProbability(inputs: PricerInputs, p: number): number | null {\n\tconst { forward } = inputs;\n\tif (!(forward > 0) || !(p > 0 && p < 1)) return null;\n\tconst up = (strike: number) => upProbability(inputs, strike);\n\tlet r = 0.01;\n\twhile (up(forward * (1 - r)) < p || up(forward * (1 + r)) > p) {\n\t\tr *= 2;\n\t\tif (r > 0.64) return null;\n\t}\n\tlet lo = forward * (1 - r);\n\tlet hi = forward * (1 + r);\n\tfor (let i = 0; i < 64; i++) {\n\t\tconst mid = (lo + hi) / 2;\n\t\tif (up(mid) > p) lo = mid;\n\t\telse hi = mid;\n\t}\n\treturn (lo + hi) / 2;\n}\n\n// --- Resolving raw feed data client-side (for consumers that hold their own live oracle\n// feed and want to price with NO chain call, e.g. deepbook-app). The turnkey path is\n// `read.pricer(market)`, which reads these already resolved from the chain's `Pricer`;\n// these two helpers reproduce the on-chain resolution when you'd rather not read the chain.\n\n/** Roll `a` and `b` down by the fraction of anchored time remaining, matching the chain's\n * `roll_down_svi` (variance decays toward expiry). `remainingMs` = expiry − now;\n * `anchorTteMs` = expiry − the SVI observation's **provider `svi_timestamp`** (its per-update\n * source timestamp) — the same clock the freshness gate accepts, and what the chain anchors on\n * (`pricing.move`: \"One clock serves every job\"). Anchoring on the batch's ingestion time\n * instead rolls by the wrong fraction. `read.pricer` avoids the question entirely (the chain\n * has already rolled). `rho`, `m`, `sigma` are unchanged. Feed an UNrolled provider surface;\n * the result is what {@link upProbability} expects. */\nexport function rollDown(svi: Svi, remainingMs: number, anchorTteMs: number): Svi {\n\tconst frac = anchorTteMs > 0 ? remainingMs / anchorTteMs : 0;\n\treturn { ...svi, a: svi.a * frac, b: svi.b * frac };\n}\n\n/** The forward the contract prices against: Pyth spot re-anchored by the Block-Scholes\n * basis (`spot · forward/bsSpot`), falling back to the Block-Scholes forward when Pyth is\n * absent. Pass `pythSpot <= 0` to force the fallback. NOTE: on-chain this branch is also\n * gated by the admin flag `use_pyth_spot_for_forward` (default on) and a Pyth freshness\n * window — when the flag is off or the Pyth spot is stale, the chain uses `bsForward`. If\n * you track that config/freshness, apply it before calling (or use `read.pricer`, which\n * gets the resolved forward from the chain). */\nexport function forward(pythSpot: number, bsSpot: number, bsForward: number): number {\n\tif (pythSpot > 0 && bsSpot > 0) return pythSpot * (bsForward / bsSpot);\n\treturn bsForward;\n}\n\n/** A pricer bound to one resolved snapshot: price a whole board of strikes locally, no\n * chain calls. Returned by `read.pricer(market)`; also constructable directly from inputs\n * you already hold (e.g. from a `Pricer` snapshot decoded elsewhere). */\nexport interface BoardPricer extends PricerInputs {\n\t/** P(settle > strike). */\n\tup(strike: number): number;\n\t/** P(settle < strike) = 1 − up. */\n\tdown(strike: number): number;\n\t/** P(side wins at strike). */\n\tprobability(strike: number, side: 'up' | 'down'): number;\n\t/** Probability mass in `(lower, higher]` (use `lower<=0`/`higher=Infinity` for the tails). */\n\trange(lower: number, higher: number): number;\n\t/** Strike where P(> strike) = `p`, or null if outside ±64% of forward. */\n\tstrikeAtProbability(p: number): number | null;\n}\n\n/** Build a {@link BoardPricer} from a resolved snapshot (decimal forward + rolled SVI). Pure. */\nexport function boardPricer(inputs: PricerInputs): BoardPricer {\n\treturn {\n\t\tforward: inputs.forward,\n\t\tsvi: inputs.svi,\n\t\tup: (strike) => upProbability(inputs, strike),\n\t\tdown: (strike) => downProbability(inputs, strike),\n\t\tprobability: (strike, side) => probability(inputs, strike, side),\n\t\trange: (lower, higher) => rangeProbability(inputs, lower, higher),\n\t\tstrikeAtProbability: (p) => strikeAtProbability(inputs, p),\n\t};\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"balances.mjs","names":["account.loadAccount","account.balance","predictAccount.hasPosition"],"sources":["../../../src/predict/reads/balances.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { Transaction } from '@mysten/sui/transactions';\nimport type { GeneratedConfig } from '../config/generated.js';\nimport { deriveAccountWrapperIdFrom } from '../tx/common.js';\nimport { accountMoveCalls as account } from '../../account.js';\nimport * as predictAccount from '../../contracts/deepbook_predict/predict_account.js';\nimport { inspectReturns, type ReadClient } from './inspect.js';\nimport { parseU64LE } from './parse.js';\n\n// An owner's stored account balance for `coinType` (the deployment's quote coin,\n// DUSDC on testnet, unless the caller asks for another). Chains `account::load_account(wrapper)` →\n// `account::balance<T>(account, root, clock)`; the u64 is command 1's return —\n// see packages/account/sources/account.move:{80,86}. The clock is auto-injected by\n// the generated `balance` wrapper; the wrapper id is derived off-chain (no read).\nexport async function accountBalance(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\towner: string,\n\tcoinType: string,\n): Promise<bigint> {\n\tconst tx = new Transaction();\n\tconst acct = tx.add(\n\t\taccount.loadAccount({ config, arguments: { self: deriveAccountWrapperIdFrom(config, owner) } }),\n\t);\n\ttx.add(account.balance({ config, typeArguments: [coinType], arguments: { self: acct } }));\n\tconst cmds = await inspectReturns(client, tx);\n\treturn parseU64LE(cmds[1][0]);\n}\n\n// Whether the owner's account still holds `orderId` on `marketId`. The cheap\n// on-chain validator for app-stored order ids (stale after a full close or a\n// partial-close replacement — see RedeemReceipt.replacementOrderId). Chains\n// `account::load_account(wrapper)` → `predict_account::has_position(account,\n// market_id, order_id)` — see packages/predict/sources/predict_account.move:85.\nexport async function hasPosition(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\towner: string,\n\tmarketId: string,\n\torderId: bigint,\n): Promise<boolean> {\n\tconst tx = new Transaction();\n\tconst acct = tx.add(\n\t\taccount.loadAccount({ config, arguments: { self: deriveAccountWrapperIdFrom(config, owner) } }),\n\t);\n\ttx.add(\n\t\tpredictAccount.hasPosition({\n\t\t\tconfig,\n\t\t\targuments: { account: acct, expiryMarketId: marketId, orderId },\n\t\t}),\n\t);\n\tconst cmds = await inspectReturns(client, tx);\n\treturn (cmds[1][0][0] ?? 0) !== 0; // BCS bool: 1 byte\n}\n"],"mappings":";;;;;;;;AAeA,eAAsB,eACrB,QACA,QACA,OACA,UACkB;CAClB,MAAM,KAAK,IAAI,aAAa;CAC5B,MAAM,OAAO,GAAG,IACfA,YAAoB;EAAE;EAAQ,WAAW,EAAE,MAAM,2BAA2B,QAAQ,MAAM,EAAE;EAAE,CAAC,CAC/F;AACD,IAAG,IAAIC,QAAgB;EAAE;EAAQ,eAAe,CAAC,SAAS;EAAE,WAAW,EAAE,MAAM,MAAM;EAAE,CAAC,CAAC;AAEzF,QAAO,YADM,MAAM,eAAe,QAAQ,GAAG,EACtB,GAAG,GAAG;;AAQ9B,eAAsB,YACrB,QACA,QACA,OACA,UACA,SACmB;CACnB,MAAM,KAAK,IAAI,aAAa;CAC5B,MAAM,OAAO,GAAG,IACfD,YAAoB;EAAE;EAAQ,WAAW,EAAE,MAAM,2BAA2B,QAAQ,MAAM,EAAE;EAAE,CAAC,CAC/F;AACD,IAAG,IACFE,cAA2B;EAC1B;EACA,WAAW;GAAE,SAAS;GAAM,gBAAgB;GAAU;GAAS;EAC/D,CAAC,CACF;AAED,UADa,MAAM,eAAe,QAAQ,GAAG,EAChC,GAAG,GAAG,MAAM,OAAO"}
1
+ {"version":3,"file":"balances.mjs","names":["account.loadAccount","account.balance","predictAccount.hasPosition"],"sources":["../../../src/predict/reads/balances.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { Transaction } from '@mysten/sui/transactions';\nimport type { GeneratedConfig } from '../config/generated.js';\nimport { deriveAccountWrapperIdFrom } from '../tx/common.js';\nimport { accountMoveCalls as account } from '../../account.js';\nimport * as predictAccount from '../../contracts/deepbook_predict/predict_account.js';\nimport { inspectReturns, type ReadClient } from './inspect.js';\nimport { parseU64LE } from './parse.js';\n\n// An owner's stored account balance for `coinType` (the deployment's quote coin,\n// USDC on testnet, unless the caller asks for another). Chains `account::load_account(wrapper)` →\n// `account::balance<T>(account, root, clock)`; the u64 is command 1's return —\n// see packages/account/sources/account.move:{80,86}. The clock is auto-injected by\n// the generated `balance` wrapper; the wrapper id is derived off-chain (no read).\nexport async function accountBalance(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\towner: string,\n\tcoinType: string,\n): Promise<bigint> {\n\tconst tx = new Transaction();\n\tconst acct = tx.add(\n\t\taccount.loadAccount({ config, arguments: { self: deriveAccountWrapperIdFrom(config, owner) } }),\n\t);\n\ttx.add(account.balance({ config, typeArguments: [coinType], arguments: { self: acct } }));\n\tconst cmds = await inspectReturns(client, tx);\n\treturn parseU64LE(cmds[1][0]);\n}\n\n// Whether the owner's account still holds `orderId` on `marketId`. The cheap\n// on-chain validator for app-stored order ids (stale after a full close or a\n// partial-close replacement — see RedeemReceipt.replacementOrderId). Chains\n// `account::load_account(wrapper)` → `predict_account::has_position(account,\n// market_id, order_id)` — see packages/predict/sources/predict_account.move:85.\nexport async function hasPosition(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\towner: string,\n\tmarketId: string,\n\torderId: bigint,\n): Promise<boolean> {\n\tconst tx = new Transaction();\n\tconst acct = tx.add(\n\t\taccount.loadAccount({ config, arguments: { self: deriveAccountWrapperIdFrom(config, owner) } }),\n\t);\n\ttx.add(\n\t\tpredictAccount.hasPosition({\n\t\t\tconfig,\n\t\t\targuments: { account: acct, expiryMarketId: marketId, orderId },\n\t\t}),\n\t);\n\tconst cmds = await inspectReturns(client, tx);\n\treturn (cmds[1][0][0] ?? 0) !== 0; // BCS bool: 1 byte\n}\n"],"mappings":";;;;;;;;AAeA,eAAsB,eACrB,QACA,QACA,OACA,UACkB;CAClB,MAAM,KAAK,IAAI,aAAa;CAC5B,MAAM,OAAO,GAAG,IACfA,YAAoB;EAAE;EAAQ,WAAW,EAAE,MAAM,2BAA2B,QAAQ,MAAM,EAAE;EAAE,CAAC,CAC/F;AACD,IAAG,IAAIC,QAAgB;EAAE;EAAQ,eAAe,CAAC,SAAS;EAAE,WAAW,EAAE,MAAM,MAAM;EAAE,CAAC,CAAC;AAEzF,QAAO,YADM,MAAM,eAAe,QAAQ,GAAG,EACtB,GAAG,GAAG;;AAQ9B,eAAsB,YACrB,QACA,QACA,OACA,UACA,SACmB;CACnB,MAAM,KAAK,IAAI,aAAa;CAC5B,MAAM,OAAO,GAAG,IACfD,YAAoB;EAAE;EAAQ,WAAW,EAAE,MAAM,2BAA2B,QAAQ,MAAM,EAAE;EAAE,CAAC,CAC/F;AACD,IAAG,IACFE,cAA2B;EAC1B;EACA,WAAW;GAAE,SAAS;GAAM,gBAAgB;GAAU;GAAS;EAC/D,CAAC,CACF;AAED,UADa,MAAM,eAAe,QAAQ,GAAG,EAChC,GAAG,GAAG,MAAM,OAAO"}
@@ -3,8 +3,8 @@ import { parseOptionalId, parseOptionalU64, parseU64LE, parseVectorOfIds } from
3
3
  import { POS_INF_TICK } from "../ticks.mjs";
4
4
  import { admissionTickSize, currentNav as currentNav$1, expiry, mintPaused, referenceTick as referenceTick$1, tickSize } from "../../contracts/deepbook_predict/expiry_market.mjs";
5
5
  import { loadLivePricer } from "../tx/trade.mjs";
6
- import { activeExpiryMarkets } from "../../contracts/deepbook_predict/plp.mjs";
7
6
  import { rangePrice } from "../../contracts/deepbook_predict/pricing.mjs";
7
+ import { activeExpiryMarkets } from "../../contracts/deepbook_predict/plp.mjs";
8
8
  import { strikeFromTick } from "../../contracts/deepbook_predict/range_codec.mjs";
9
9
  import { expiryMarketId as expiryMarketId$1 } from "../../contracts/deepbook_predict/registry.mjs";
10
10
  import { Transaction } from "@mysten/sui/transactions";
@@ -1 +1 @@
1
- {"version":3,"file":"markets.mjs","names":["plp.activeExpiryMarkets","registry.expiryMarketId","expiryMarket.expiry","expiryMarket.tickSize","expiryMarket.admissionTickSize","expiryMarket.mintPaused","expiryMarket.referenceTick","rangeCodec.strikeFromTick","pricing.rangePrice","expiryMarket.currentNav"],"sources":["../../../src/predict/reads/markets.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { Transaction } from '@mysten/sui/transactions';\nimport { type GeneratedConfig } from '../config/generated.js';\nimport { type UnderlyingConfig } from '../config/index.js';\nimport { PredictMoveError } from '../errors.js';\nimport { POS_INF_TICK } from '../ticks.js';\nimport { loadLivePricer, type MarketFeeds } from '../tx/trade.js';\nimport * as expiryMarket from '../../contracts/deepbook_predict/expiry_market.js';\nimport * as plp from '../../contracts/deepbook_predict/plp.js';\nimport * as pricing from '../../contracts/deepbook_predict/pricing.js';\nimport * as rangeCodec from '../../contracts/deepbook_predict/range_codec.js';\nimport * as registry from '../../contracts/deepbook_predict/registry.js';\nimport { inspectReturns, type ReadClient } from './inspect.js';\nimport { parseOptionalId, parseOptionalU64, parseU64LE, parseVectorOfIds } from './parse.js';\n\n// On-chain ids of the pool's active (live, not-yet-settled) expiry markets.\n// `plp::active_expiry_markets(vault)` — see packages/predict/sources/plp/plp.move:179.\nexport async function activeMarketIds(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n): Promise<string[]> {\n\tconst tx = new Transaction();\n\ttx.add(plp.activeExpiryMarkets({ config }));\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn parseVectorOfIds(cmd0[0]);\n}\n\n// The expiry market id for one underlying at one expiry, or null if none exists.\n// `registry::expiry_market_id(registry, propbook_underlying_id: u32, expiry: u64):\n// Option<ID>` — see packages/predict/sources/registry/registry.move:53.\nexport async function expiryMarketId(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tunderlying: UnderlyingConfig,\n\texpiryMs: bigint,\n): Promise<string | null> {\n\tconst tx = new Transaction();\n\ttx.add(\n\t\tregistry.expiryMarketId({\n\t\t\tconfig,\n\t\t\targuments: { propbookUnderlyingId: underlying.propbookUnderlyingId, expiry: expiryMs },\n\t\t}),\n\t);\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn parseOptionalId(cmd0[0]);\n}\n\nexport interface MarketState {\n\texpiryMs: bigint;\n\ttickSizeRaw: bigint;\n\t/**\n\t * The COARSER raw-price step new finite mint boundaries must align to\n\t * (`expiry_market::admission_tick_size`). A numeric strike must be a whole\n\t * multiple of this — the fine `tickSizeRaw` grid alone is not sufficient — or\n\t * the chain aborts `EInvalidAdmissionTick`. The market's reference tick is the\n\t * one finite boundary allowed to bypass it.\n\t */\n\tadmissionTickSizeRaw: bigint;\n\tmintPaused: boolean;\n\t/**\n\t * The reference fine-grid tick (Polymarket-style anchor strike: derived\n\t * on-chain from the exact previous-window oracle observation), or null while\n\t * the keeper has not seeded it. Reference PRICE raw = tick * tickSizeRaw.\n\t */\n\treferenceTickRaw: bigint | null;\n}\n\n// The per-market state getters, in fixed order. `expiry_market::{expiry,\n// tick_size, mint_paused, reference_tick}` — see\n// packages/predict/sources/expiry_market.move:{101,177,259,187}. reference_tick\n// returns Option (no abort risk). settlement is read separately via\n// `settlementPrice` (its own non-batched getter below).\nconst STATE_FNS = [\n\texpiryMarket.expiry,\n\texpiryMarket.tickSize,\n\texpiryMarket.admissionTickSize,\n\texpiryMarket.mintPaused,\n\texpiryMarket.referenceTick,\n] as const;\n\nfunction parseStateAt(cmds: Uint8Array[][], base: number): MarketState {\n\treturn {\n\t\texpiryMs: parseU64LE(cmds[base][0]),\n\t\ttickSizeRaw: parseU64LE(cmds[base + 1][0]),\n\t\tadmissionTickSizeRaw: parseU64LE(cmds[base + 2][0]),\n\t\tmintPaused: (cmds[base + 3][0][0] ?? 0) !== 0, // BCS bool: 1 byte\n\t\treferenceTickRaw: parseOptionalU64(cmds[base + 4][0]),\n\t};\n}\n\nexport async function marketState(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n): Promise<MarketState> {\n\tconst [state] = await marketStates(client, config, [marketId]);\n\treturn state;\n}\n\n// Batched marketState for N markets in ONE PTB (STATE_FNS.length commands per\n// market, same order). Returns states aligned with `marketIds`.\nexport async function marketStates(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketIds: readonly string[],\n): Promise<MarketState[]> {\n\tif (marketIds.length === 0) return [];\n\tconst tx = new Transaction();\n\tfor (const id of marketIds) {\n\t\tfor (const fn of STATE_FNS) {\n\t\t\ttx.add(fn({ config, arguments: { market: id } }));\n\t\t}\n\t}\n\tconst cmds = await inspectReturns(client, tx);\n\treturn marketIds.map((_, i) => parseStateAt(cmds, STATE_FNS.length * i));\n}\n\n// Anonymous both-sides pricing for one strike: the chain's own probability for\n// (strike, +inf] and (-inf, strike]. Deployed `pricing::range_price` takes typed\n// `range_codec::Strike`s (NOT raw u64) — each boundary is built via\n// `range_codec::strike_from_tick(tick, tick_size)`, which maps tick 0 → -inf,\n// POS_INF_TICK → +inf, and any finite tick → tick*tick_size. `range_price` is a\n// public fun on the deployed package. Both sides read the SAME pricer in one PTB, so\n// `down` is the chain's number, not 1 − up.\nexport async function rangePrices(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n\tfeeds: MarketFeeds,\n\tstrikeRaw: bigint,\n\ttickSizeRaw: bigint,\n): Promise<{ upRaw: bigint; downRaw: bigint }> {\n\tconst tx = new Transaction();\n\tconst pricer = tx.add(loadLivePricer(config, { expiryMarketId: marketId, ...feeds }));\n\t// strikeRaw is a whole tick multiple (the caller validates divisibility), so the\n\t// finite boundary is `strike_from_tick(strikeRaw / tickSize, tickSize)`.\n\tconst strikeTick = strikeRaw / tickSizeRaw;\n\tconst mkStrike = (tick: bigint) =>\n\t\ttx.add(rangeCodec.strikeFromTick({ config, arguments: { tick, tickSize: tickSizeRaw } }));\n\tconst strike = mkStrike(strikeTick);\n\tconst posInf = mkStrike(POS_INF_TICK);\n\tconst negInf = mkStrike(0n);\n\t// UP: (strike, +inf], then DOWN: (-inf, strike] — the last two commands.\n\ttx.add(pricing.rangePrice({ config, arguments: { pricer, lower: strike, higher: posInf } }));\n\ttx.add(pricing.rangePrice({ config, arguments: { pricer, lower: negInf, higher: strike } }));\n\tconst cmds = await inspectReturns(client, tx);\n\treturn {\n\t\tupRaw: parseU64LE(cmds[cmds.length - 2][0]),\n\t\tdownRaw: parseU64LE(cmds[cmds.length - 1][0]),\n\t};\n}\n\n// Fresh single read of the reference tick — used by mint-at-reference, which\n// must not trust a cached state (the reference is unset early in a window\n// until the keeper seeds it).\nexport async function referenceTick(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n): Promise<bigint | null> {\n\tconst tx = new Transaction();\n\ttx.add(expiryMarket.referenceTick({ config, arguments: { market: marketId } }));\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn parseOptionalU64(cmd0[0]);\n}\n\n// The recorded settlement price, or null while the market is unsettled.\n//\n// On the deployed package `expiry_market::settlement_price` is public and\n// `destroy_some`s the stored Option — callable here only because simulate runs with\n// checksEnabled:false, and it aborts in std::option (EOPTION_NOT_SET) when the\n// market has not settled; we map exactly that abort (and the public\n// EMarketNotSettled variant, should a future package guard it directly) to null.\n// (A non-aborting `try_settlement_price` also exists on-chain if this ever wants to\n// drop the abort-catch.)\nexport async function settlementPrice(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n): Promise<bigint | null> {\n\tconst tx = new Transaction();\n\ttx.add(expiryMarket.settlementPrice({ config, arguments: { market: marketId } }));\n\ttry {\n\t\tconst [cmd0] = await inspectReturns(client, tx);\n\t\treturn parseU64LE(cmd0[0]);\n\t} catch (e) {\n\t\tif (\n\t\t\te instanceof PredictMoveError &&\n\t\t\t(e.module === 'option' ||\n\t\t\t\t(e.module === 'expiry_market' && e.abortName === 'EMarketNotSettled'))\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow e;\n\t}\n}\n\n// A market's current NAV mark (the per-expiry recoverable value the flush prices\n// against). Loads a fresh live pricer, then reads `current_nav(market, &pricer)` —\n// see packages/predict/sources/expiry_market.move:236. `Pricer` has copy+drop, so\n// the unconsumed borrow is fine in a read-only inspect.\nexport async function currentNav(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n\tunderlying: UnderlyingConfig,\n): Promise<bigint> {\n\tconst tx = new Transaction();\n\tconst pricer = tx.add(\n\t\tloadLivePricer(config, {\n\t\t\texpiryMarketId: marketId,\n\t\t\tpythFeed: underlying.pythFeed,\n\t\t\tblockScholesValueStore: underlying.blockScholesValueStore,\n\t\t\tblockScholesSviStore: underlying.blockScholesSviStore,\n\t\t}),\n\t);\n\ttx.add(expiryMarket.currentNav({ config, arguments: { market: marketId, pricer } }));\n\tconst cmds = await inspectReturns(client, tx);\n\t// current_nav is the last command; load_live_pricer precedes it.\n\treturn parseU64LE(cmds[cmds.length - 1][0]);\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,eAAsB,gBACrB,QACA,QACoB;CACpB,MAAM,KAAK,IAAI,aAAa;AAC5B,IAAG,IAAIA,oBAAwB,EAAE,QAAQ,CAAC,CAAC;CAC3C,MAAM,CAAC,QAAQ,MAAM,eAAe,QAAQ,GAAG;AAC/C,QAAO,iBAAiB,KAAK,GAAG;;AAMjC,eAAsB,eACrB,QACA,QACA,YACA,UACyB;CACzB,MAAM,KAAK,IAAI,aAAa;AAC5B,IAAG,IACFC,iBAAwB;EACvB;EACA,WAAW;GAAE,sBAAsB,WAAW;GAAsB,QAAQ;GAAU;EACtF,CAAC,CACF;CACD,MAAM,CAAC,QAAQ,MAAM,eAAe,QAAQ,GAAG;AAC/C,QAAO,gBAAgB,KAAK,GAAG;;AA4BhC,MAAM,YAAY;CACjBC;CACAC;CACAC;CACAC;CACAC;CACA;AAED,SAAS,aAAa,MAAsB,MAA2B;AACtE,QAAO;EACN,UAAU,WAAW,KAAK,MAAM,GAAG;EACnC,aAAa,WAAW,KAAK,OAAO,GAAG,GAAG;EAC1C,sBAAsB,WAAW,KAAK,OAAO,GAAG,GAAG;EACnD,aAAa,KAAK,OAAO,GAAG,GAAG,MAAM,OAAO;EAC5C,kBAAkB,iBAAiB,KAAK,OAAO,GAAG,GAAG;EACrD;;AAGF,eAAsB,YACrB,QACA,QACA,UACuB;CACvB,MAAM,CAAC,SAAS,MAAM,aAAa,QAAQ,QAAQ,CAAC,SAAS,CAAC;AAC9D,QAAO;;AAKR,eAAsB,aACrB,QACA,QACA,WACyB;AACzB,KAAI,UAAU,WAAW,EAAG,QAAO,EAAE;CACrC,MAAM,KAAK,IAAI,aAAa;AAC5B,MAAK,MAAM,MAAM,UAChB,MAAK,MAAM,MAAM,UAChB,IAAG,IAAI,GAAG;EAAE;EAAQ,WAAW,EAAE,QAAQ,IAAI;EAAE,CAAC,CAAC;CAGnD,MAAM,OAAO,MAAM,eAAe,QAAQ,GAAG;AAC7C,QAAO,UAAU,KAAK,GAAG,MAAM,aAAa,MAAM,UAAU,SAAS,EAAE,CAAC;;AAUzE,eAAsB,YACrB,QACA,QACA,UACA,OACA,WACA,aAC8C;CAC9C,MAAM,KAAK,IAAI,aAAa;CAC5B,MAAM,SAAS,GAAG,IAAI,eAAe,QAAQ;EAAE,gBAAgB;EAAU,GAAG;EAAO,CAAC,CAAC;CAGrF,MAAM,aAAa,YAAY;CAC/B,MAAM,YAAY,SACjB,GAAG,IAAIC,eAA0B;EAAE;EAAQ,WAAW;GAAE;GAAM,UAAU;GAAa;EAAE,CAAC,CAAC;CAC1F,MAAM,SAAS,SAAS,WAAW;CACnC,MAAM,SAAS,SAAS,aAAa;CACrC,MAAM,SAAS,SAAS,GAAG;AAE3B,IAAG,IAAIC,WAAmB;EAAE;EAAQ,WAAW;GAAE;GAAQ,OAAO;GAAQ,QAAQ;GAAQ;EAAE,CAAC,CAAC;AAC5F,IAAG,IAAIA,WAAmB;EAAE;EAAQ,WAAW;GAAE;GAAQ,OAAO;GAAQ,QAAQ;GAAQ;EAAE,CAAC,CAAC;CAC5F,MAAM,OAAO,MAAM,eAAe,QAAQ,GAAG;AAC7C,QAAO;EACN,OAAO,WAAW,KAAK,KAAK,SAAS,GAAG,GAAG;EAC3C,SAAS,WAAW,KAAK,KAAK,SAAS,GAAG,GAAG;EAC7C;;AAMF,eAAsB,cACrB,QACA,QACA,UACyB;CACzB,MAAM,KAAK,IAAI,aAAa;AAC5B,IAAG,IAAIF,gBAA2B;EAAE;EAAQ,WAAW,EAAE,QAAQ,UAAU;EAAE,CAAC,CAAC;CAC/E,MAAM,CAAC,QAAQ,MAAM,eAAe,QAAQ,GAAG;AAC/C,QAAO,iBAAiB,KAAK,GAAG;;AAsCjC,eAAsB,WACrB,QACA,QACA,UACA,YACkB;CAClB,MAAM,KAAK,IAAI,aAAa;CAC5B,MAAM,SAAS,GAAG,IACjB,eAAe,QAAQ;EACtB,gBAAgB;EAChB,UAAU,WAAW;EACrB,wBAAwB,WAAW;EACnC,sBAAsB,WAAW;EACjC,CAAC,CACF;AACD,IAAG,IAAIG,aAAwB;EAAE;EAAQ,WAAW;GAAE,QAAQ;GAAU;GAAQ;EAAE,CAAC,CAAC;CACpF,MAAM,OAAO,MAAM,eAAe,QAAQ,GAAG;AAE7C,QAAO,WAAW,KAAK,KAAK,SAAS,GAAG,GAAG"}
1
+ {"version":3,"file":"markets.mjs","names":["plp.activeExpiryMarkets","registry.expiryMarketId","expiryMarket.expiry","expiryMarket.tickSize","expiryMarket.admissionTickSize","expiryMarket.mintPaused","expiryMarket.referenceTick","rangeCodec.strikeFromTick","pricing.rangePrice","expiryMarket.currentNav"],"sources":["../../../src/predict/reads/markets.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { Transaction } from '@mysten/sui/transactions';\nimport { type GeneratedConfig } from '../config/generated.js';\nimport { type UnderlyingConfig } from '../config/index.js';\nimport { PredictMoveError } from '../errors.js';\nimport { POS_INF_TICK } from '../ticks.js';\nimport { loadLivePricer, type MarketFeeds } from '../tx/trade.js';\nimport * as expiryMarket from '../../contracts/deepbook_predict/expiry_market.js';\nimport * as plp from '../../contracts/deepbook_predict/plp.js';\nimport * as pricing from '../../contracts/deepbook_predict/pricing.js';\nimport * as rangeCodec from '../../contracts/deepbook_predict/range_codec.js';\nimport * as registry from '../../contracts/deepbook_predict/registry.js';\nimport { inspectReturns, type ReadClient } from './inspect.js';\nimport { parseOptionalId, parseOptionalU64, parseU64LE, parseVectorOfIds } from './parse.js';\n\n// On-chain ids of the pool's active (live, not-yet-settled) expiry markets.\n// `plp::active_expiry_markets(vault)` — see packages/predict/sources/plp/plp.move:179.\nexport async function activeMarketIds(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n): Promise<string[]> {\n\tconst tx = new Transaction();\n\ttx.add(plp.activeExpiryMarkets({ config }));\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn parseVectorOfIds(cmd0[0]);\n}\n\n// The expiry market id for one underlying at one expiry, or null if none exists.\n// `registry::expiry_market_id(registry, propbook_underlying_id: u32, expiry: u64):\n// Option<ID>` — see packages/predict/sources/registry/registry.move:58.\nexport async function expiryMarketId(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tunderlying: UnderlyingConfig,\n\texpiryMs: bigint,\n): Promise<string | null> {\n\tconst tx = new Transaction();\n\ttx.add(\n\t\tregistry.expiryMarketId({\n\t\t\tconfig,\n\t\t\targuments: { propbookUnderlyingId: underlying.propbookUnderlyingId, expiry: expiryMs },\n\t\t}),\n\t);\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn parseOptionalId(cmd0[0]);\n}\n\nexport interface MarketState {\n\texpiryMs: bigint;\n\ttickSizeRaw: bigint;\n\t/**\n\t * The COARSER raw-price step new finite mint boundaries must align to\n\t * (`expiry_market::admission_tick_size`). A numeric strike must be a whole\n\t * multiple of this — the fine `tickSizeRaw` grid alone is not sufficient — or\n\t * the chain aborts `EInvalidAdmissionTick`. The market's reference tick is the\n\t * one finite boundary allowed to bypass it.\n\t */\n\tadmissionTickSizeRaw: bigint;\n\tmintPaused: boolean;\n\t/**\n\t * The reference fine-grid tick (Polymarket-style anchor strike: derived\n\t * on-chain from the exact previous-window oracle observation), or null while\n\t * the keeper has not seeded it. Reference PRICE raw = tick * tickSizeRaw.\n\t */\n\treferenceTickRaw: bigint | null;\n}\n\n// The per-market state getters, in fixed order. `expiry_market::{expiry,\n// tick_size, mint_paused, reference_tick}` — see\n// packages/predict/sources/expiry_market.move:{101,177,259,187}. reference_tick\n// returns Option (no abort risk). settlement is read separately via\n// `settlementPrice` (its own non-batched getter below).\nconst STATE_FNS = [\n\texpiryMarket.expiry,\n\texpiryMarket.tickSize,\n\texpiryMarket.admissionTickSize,\n\texpiryMarket.mintPaused,\n\texpiryMarket.referenceTick,\n] as const;\n\nfunction parseStateAt(cmds: Uint8Array[][], base: number): MarketState {\n\treturn {\n\t\texpiryMs: parseU64LE(cmds[base][0]),\n\t\ttickSizeRaw: parseU64LE(cmds[base + 1][0]),\n\t\tadmissionTickSizeRaw: parseU64LE(cmds[base + 2][0]),\n\t\tmintPaused: (cmds[base + 3][0][0] ?? 0) !== 0, // BCS bool: 1 byte\n\t\treferenceTickRaw: parseOptionalU64(cmds[base + 4][0]),\n\t};\n}\n\nexport async function marketState(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n): Promise<MarketState> {\n\tconst [state] = await marketStates(client, config, [marketId]);\n\treturn state;\n}\n\n// Batched marketState for N markets in ONE PTB (STATE_FNS.length commands per\n// market, same order). Returns states aligned with `marketIds`.\nexport async function marketStates(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketIds: readonly string[],\n): Promise<MarketState[]> {\n\tif (marketIds.length === 0) return [];\n\tconst tx = new Transaction();\n\tfor (const id of marketIds) {\n\t\tfor (const fn of STATE_FNS) {\n\t\t\ttx.add(fn({ config, arguments: { market: id } }));\n\t\t}\n\t}\n\tconst cmds = await inspectReturns(client, tx);\n\treturn marketIds.map((_, i) => parseStateAt(cmds, STATE_FNS.length * i));\n}\n\n// Anonymous both-sides pricing for one strike: the chain's own probability for\n// (strike, +inf] and (-inf, strike]. Deployed `pricing::range_price` takes typed\n// `range_codec::Strike`s (NOT raw u64) — each boundary is built via\n// `range_codec::strike_from_tick(tick, tick_size)`, which maps tick 0 → -inf,\n// POS_INF_TICK → +inf, and any finite tick → tick*tick_size. `range_price` is a\n// public fun on the deployed package. Both sides read the SAME pricer in one PTB, so\n// `down` is the chain's number, not 1 − up.\nexport async function rangePrices(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n\tfeeds: MarketFeeds,\n\tstrikeRaw: bigint,\n\ttickSizeRaw: bigint,\n): Promise<{ upRaw: bigint; downRaw: bigint }> {\n\tconst tx = new Transaction();\n\tconst pricer = tx.add(loadLivePricer(config, { expiryMarketId: marketId, ...feeds }));\n\t// strikeRaw is a whole tick multiple (the caller validates divisibility), so the\n\t// finite boundary is `strike_from_tick(strikeRaw / tickSize, tickSize)`.\n\tconst strikeTick = strikeRaw / tickSizeRaw;\n\tconst mkStrike = (tick: bigint) =>\n\t\ttx.add(rangeCodec.strikeFromTick({ config, arguments: { tick, tickSize: tickSizeRaw } }));\n\tconst strike = mkStrike(strikeTick);\n\tconst posInf = mkStrike(POS_INF_TICK);\n\tconst negInf = mkStrike(0n);\n\t// UP: (strike, +inf], then DOWN: (-inf, strike] — the last two commands.\n\ttx.add(pricing.rangePrice({ config, arguments: { pricer, lower: strike, higher: posInf } }));\n\ttx.add(pricing.rangePrice({ config, arguments: { pricer, lower: negInf, higher: strike } }));\n\tconst cmds = await inspectReturns(client, tx);\n\treturn {\n\t\tupRaw: parseU64LE(cmds[cmds.length - 2][0]),\n\t\tdownRaw: parseU64LE(cmds[cmds.length - 1][0]),\n\t};\n}\n\n// Fresh single read of the reference tick — used by mint-at-reference, which\n// must not trust a cached state (the reference is unset early in a window\n// until the keeper seeds it).\nexport async function referenceTick(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n): Promise<bigint | null> {\n\tconst tx = new Transaction();\n\ttx.add(expiryMarket.referenceTick({ config, arguments: { market: marketId } }));\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn parseOptionalU64(cmd0[0]);\n}\n\n// The recorded settlement price, or null while the market is unsettled.\n//\n// On the deployed package `expiry_market::settlement_price` is public and\n// `destroy_some`s the stored Option — callable here only because simulate runs with\n// checksEnabled:false, and it aborts in std::option (EOPTION_NOT_SET) when the\n// market has not settled; we map exactly that abort (and the public\n// EMarketNotSettled variant, should a future package guard it directly) to null.\n// (A non-aborting `try_settlement_price` also exists on-chain if this ever wants to\n// drop the abort-catch.)\nexport async function settlementPrice(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n): Promise<bigint | null> {\n\tconst tx = new Transaction();\n\ttx.add(expiryMarket.settlementPrice({ config, arguments: { market: marketId } }));\n\ttry {\n\t\tconst [cmd0] = await inspectReturns(client, tx);\n\t\treturn parseU64LE(cmd0[0]);\n\t} catch (e) {\n\t\tif (\n\t\t\te instanceof PredictMoveError &&\n\t\t\t(e.module === 'option' ||\n\t\t\t\t(e.module === 'expiry_market' && e.abortName === 'EMarketNotSettled'))\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow e;\n\t}\n}\n\n// A market's current NAV mark (the per-expiry recoverable value the flush prices\n// against). Loads a fresh live pricer, then reads `current_nav(market, &pricer)` —\n// see packages/predict/sources/expiry_market.move:236. `Pricer` has copy+drop, so\n// the unconsumed borrow is fine in a read-only inspect.\nexport async function currentNav(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n\tunderlying: UnderlyingConfig,\n): Promise<bigint> {\n\tconst tx = new Transaction();\n\tconst pricer = tx.add(\n\t\tloadLivePricer(config, {\n\t\t\texpiryMarketId: marketId,\n\t\t\tpythFeed: underlying.pythFeed,\n\t\t\tblockScholesValueStore: underlying.blockScholesValueStore,\n\t\t\tblockScholesSviStore: underlying.blockScholesSviStore,\n\t\t}),\n\t);\n\ttx.add(expiryMarket.currentNav({ config, arguments: { market: marketId, pricer } }));\n\tconst cmds = await inspectReturns(client, tx);\n\t// current_nav is the last command; load_live_pricer precedes it.\n\treturn parseU64LE(cmds[cmds.length - 1][0]);\n}\n"],"mappings":"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"}
@@ -6,7 +6,8 @@ import "../tx/trade.mjs";
6
6
  /** A resolved pricer snapshot read from the chain: the decimal forward + rolled SVI the
7
7
  * client-side math consumes, plus the oracle source timestamps behind it (ms; for
8
8
  * staleness display — Pyth is 0 when no usable spot existed). The Block-Scholes entries are
9
- * batch ENVELOPE times (what freshness and the SVI roll-down anchor on), not model times. */
9
+ * the provider's PER-UPDATE source timestamps (`value_timestamp` for spot/forward,
10
+ * `svi_timestamp` for SVI) — the clocks freshness and the SVI roll-down anchor on. */
10
11
  interface PricerSnapshot extends PricerInputs {
11
12
  sources: {
12
13
  pythSpotMs: number;
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.d.mts","names":[],"sources":["../../../src/predict/reads/pricing.ts"],"mappings":";;;;;;AA0BA;;;UAAiB,cAAA,SAAuB,YAAA;EACvC,OAAA;IACC,UAAA;IACA,kBAAA;IACA,qBAAA;IACA,iBAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"pricing.d.mts","names":[],"sources":["../../../src/predict/reads/pricing.ts"],"mappings":";;;;;;AA2BA;;;;UAAiB,cAAA,SAAuB,YAAA;EACvC,OAAA;IACC,UAAA;IACA,kBAAA;IACA,qBAAA;IACA,iBAAA;EAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.mjs","names":[],"sources":["../../../src/predict/reads/pricing.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { Transaction } from '@mysten/sui/transactions';\nimport { type GeneratedConfig } from '../config/generated.js';\nimport { Pricer } from '../../contracts/deepbook_predict/pricing.js';\nimport type { PricerInputs, Svi } from '../pricing.js';\nimport { loadLivePricer, type MarketFeeds } from '../tx/trade.js';\nimport { inspectReturns, type ReadClient } from './inspect.js';\n\n// The chain's fixed-point scales for the rolled `PricingSVI` (see the generated\n// `Pricer`/`PricingSVI` struct): forward and rho/m/sigma at 1e9; the rolled `a`/`b` land\n// at 1e18 (roll_down multiplies the 1e9 raw by an extra 1e9). Converting to `number`\n// (float) is deliberate — this is a display pricer; a is a variance ~O(1e-2), so f64's\n// ~15 significant digits are ample and, per pricing.ts, more precise than the chain's\n// fixed point on the short-dated surfaces this prices.\nconst FORWARD_SCALE = 1e9;\nconst AB_SCALE = 1e18;\nconst RMS_SCALE = 1e9; // rho, m, sigma\n\nconst i64 = (v: { magnitude: string | number | bigint; is_negative: boolean }): number =>\n\t(v.is_negative ? -1 : 1) * Number(v.magnitude);\n\n/** A resolved pricer snapshot read from the chain: the decimal forward + rolled SVI the\n * client-side math consumes, plus the oracle source timestamps behind it (ms; for\n * staleness display — Pyth is 0 when no usable spot existed). The Block-Scholes entries are\n * batch ENVELOPE times (what freshness and the SVI roll-down anchor on), not model times. */\nexport interface PricerSnapshot extends PricerInputs {\n\tsources: {\n\t\tpythSpotMs: number;\n\t\tblockScholesSpotMs: number;\n\t\tblockScholesForwardMs: number;\n\t\tblockScholesSviMs: number;\n\t};\n}\n\n// Decode a `Pricer` (already forward-resolved + roll-down-applied on-chain) into decimal\n// `PricerInputs`. Signed fields (`a`, `rho`, `m`) carry the magnitude/flag pair the chain\n// uses; `b`/`sigma` are non-negative.\nfunction decodePricer(pricer: ReturnType<typeof Pricer.parse>): PricerSnapshot {\n\tconst s = pricer.svi;\n\tconst svi: Svi = {\n\t\ta: ((s.a_is_negative ? -1 : 1) * Number(s.a_magnitude)) / AB_SCALE,\n\t\tb: Number(s.b) / AB_SCALE,\n\t\trho: i64(s.rho) / RMS_SCALE,\n\t\tm: i64(s.m) / RMS_SCALE,\n\t\tsigma: Number(s.sigma) / RMS_SCALE,\n\t};\n\treturn {\n\t\tforward: Number(pricer.forward) / FORWARD_SCALE,\n\t\tsvi,\n\t\tsources: {\n\t\t\tpythSpotMs: Number(pricer.pyth_spot_source_timestamp_ms),\n\t\t\tblockScholesSpotMs: Number(pricer.block_scholes_spot_source_timestamp_ms),\n\t\t\tblockScholesForwardMs: Number(pricer.block_scholes_forward_source_timestamp_ms),\n\t\t\tblockScholesSviMs: Number(pricer.block_scholes_svi_source_timestamp_ms),\n\t\t},\n\t};\n}\n\n// Read one live pricer snapshot for `marketId`: a single simulate of\n// `load_live_pricer` — the chain reads the oracle feeds, picks the forward\n// (Pyth-vs-Block-Scholes admin policy + freshness), and rolls the SVI down to now, then\n// returns the whole `Pricer` by value (copy+drop), whose BCS we decode. One round trip;\n// then a `boardPricer` prices every strike locally.\n//\n// `load_live_pricer` ABORTS (a typed PredictMoveError) when the market is expired, a feed\n// is stale, or the surface fails the pricing-safe envelope — i.e. exactly when the chain\n// itself cannot quote. Callers surface that the same way `read.price` does.\nexport async function readPricerSnapshot(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n\tfeeds: MarketFeeds,\n): Promise<PricerSnapshot> {\n\tconst tx = new Transaction();\n\ttx.add(loadLivePricer(config, { expiryMarketId: marketId, ...feeds }));\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn decodePricer(Pricer.parse(cmd0[0]));\n}\n"],"mappings":";;;;;;AAeA,MAAM,gBAAgB;AACtB,MAAM,WAAW;AACjB,MAAM,YAAY;AAElB,MAAM,OAAO,OACX,EAAE,cAAc,KAAK,KAAK,OAAO,EAAE,UAAU;AAkB/C,SAAS,aAAa,QAAyD;CAC9E,MAAM,IAAI,OAAO;CACjB,MAAM,MAAW;EAChB,IAAK,EAAE,gBAAgB,KAAK,KAAK,OAAO,EAAE,YAAY,GAAI;EAC1D,GAAG,OAAO,EAAE,EAAE,GAAG;EACjB,KAAK,IAAI,EAAE,IAAI,GAAG;EAClB,GAAG,IAAI,EAAE,EAAE,GAAG;EACd,OAAO,OAAO,EAAE,MAAM,GAAG;EACzB;AACD,QAAO;EACN,SAAS,OAAO,OAAO,QAAQ,GAAG;EAClC;EACA,SAAS;GACR,YAAY,OAAO,OAAO,8BAA8B;GACxD,oBAAoB,OAAO,OAAO,uCAAuC;GACzE,uBAAuB,OAAO,OAAO,0CAA0C;GAC/E,mBAAmB,OAAO,OAAO,sCAAsC;GACvE;EACD;;AAYF,eAAsB,mBACrB,QACA,QACA,UACA,OAC0B;CAC1B,MAAM,KAAK,IAAI,aAAa;AAC5B,IAAG,IAAI,eAAe,QAAQ;EAAE,gBAAgB;EAAU,GAAG;EAAO,CAAC,CAAC;CACtE,MAAM,CAAC,QAAQ,MAAM,eAAe,QAAQ,GAAG;AAC/C,QAAO,aAAa,OAAO,MAAM,KAAK,GAAG,CAAC"}
1
+ {"version":3,"file":"pricing.mjs","names":[],"sources":["../../../src/predict/reads/pricing.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { Transaction } from '@mysten/sui/transactions';\nimport { type GeneratedConfig } from '../config/generated.js';\nimport { Pricer } from '../../contracts/deepbook_predict/pricing.js';\nimport type { PricerInputs, Svi } from '../pricing.js';\nimport { loadLivePricer, type MarketFeeds } from '../tx/trade.js';\nimport { inspectReturns, type ReadClient } from './inspect.js';\n\n// The chain's fixed-point scales for the rolled `PricingSVI` (see the generated\n// `Pricer`/`PricingSVI` struct): forward and rho/m/sigma at 1e9; the rolled `a`/`b` land\n// at 1e18 (roll_down multiplies the 1e9 raw by an extra 1e9). Converting to `number`\n// (float) is deliberate — this is a display pricer; a is a variance ~O(1e-2), so f64's\n// ~15 significant digits are ample and, per pricing.ts, more precise than the chain's\n// fixed point on the short-dated surfaces this prices.\nconst FORWARD_SCALE = 1e9;\nconst AB_SCALE = 1e18;\nconst RMS_SCALE = 1e9; // rho, m, sigma\n\nconst i64 = (v: { magnitude: string | number | bigint; is_negative: boolean }): number =>\n\t(v.is_negative ? -1 : 1) * Number(v.magnitude);\n\n/** A resolved pricer snapshot read from the chain: the decimal forward + rolled SVI the\n * client-side math consumes, plus the oracle source timestamps behind it (ms; for\n * staleness display — Pyth is 0 when no usable spot existed). The Block-Scholes entries are\n * the provider's PER-UPDATE source timestamps (`value_timestamp` for spot/forward,\n * `svi_timestamp` for SVI) — the clocks freshness and the SVI roll-down anchor on. */\nexport interface PricerSnapshot extends PricerInputs {\n\tsources: {\n\t\tpythSpotMs: number;\n\t\tblockScholesSpotMs: number;\n\t\tblockScholesForwardMs: number;\n\t\tblockScholesSviMs: number;\n\t};\n}\n\n// Decode a `Pricer` (already forward-resolved + roll-down-applied on-chain) into decimal\n// `PricerInputs`. Signed fields (`a`, `rho`, `m`) carry the magnitude/flag pair the chain\n// uses; `b`/`sigma` are non-negative.\nfunction decodePricer(pricer: ReturnType<typeof Pricer.parse>): PricerSnapshot {\n\tconst s = pricer.svi;\n\tconst svi: Svi = {\n\t\ta: ((s.a_is_negative ? -1 : 1) * Number(s.a_magnitude)) / AB_SCALE,\n\t\tb: Number(s.b) / AB_SCALE,\n\t\trho: i64(s.rho) / RMS_SCALE,\n\t\tm: i64(s.m) / RMS_SCALE,\n\t\tsigma: Number(s.sigma) / RMS_SCALE,\n\t};\n\treturn {\n\t\tforward: Number(pricer.forward) / FORWARD_SCALE,\n\t\tsvi,\n\t\tsources: {\n\t\t\tpythSpotMs: Number(pricer.pyth_spot_source_timestamp_ms),\n\t\t\tblockScholesSpotMs: Number(pricer.block_scholes_spot_source_timestamp_ms),\n\t\t\tblockScholesForwardMs: Number(pricer.block_scholes_forward_source_timestamp_ms),\n\t\t\tblockScholesSviMs: Number(pricer.block_scholes_svi_source_timestamp_ms),\n\t\t},\n\t};\n}\n\n// Read one live pricer snapshot for `marketId`: a single simulate of\n// `load_live_pricer` — the chain reads the oracle feeds, picks the forward\n// (Pyth-vs-Block-Scholes admin policy + freshness), and rolls the SVI down to now, then\n// returns the whole `Pricer` by value (copy+drop), whose BCS we decode. One round trip;\n// then a `boardPricer` prices every strike locally.\n//\n// `load_live_pricer` ABORTS (a typed PredictMoveError) when the market is expired, a feed\n// is stale, or the surface fails the pricing-safe envelope — i.e. exactly when the chain\n// itself cannot quote. Callers surface that the same way `read.price` does.\nexport async function readPricerSnapshot(\n\tclient: ReadClient,\n\tconfig: GeneratedConfig,\n\tmarketId: string,\n\tfeeds: MarketFeeds,\n): Promise<PricerSnapshot> {\n\tconst tx = new Transaction();\n\ttx.add(loadLivePricer(config, { expiryMarketId: marketId, ...feeds }));\n\tconst [cmd0] = await inspectReturns(client, tx);\n\treturn decodePricer(Pricer.parse(cmd0[0]));\n}\n"],"mappings":";;;;;;AAeA,MAAM,gBAAgB;AACtB,MAAM,WAAW;AACjB,MAAM,YAAY;AAElB,MAAM,OAAO,OACX,EAAE,cAAc,KAAK,KAAK,OAAO,EAAE,UAAU;AAmB/C,SAAS,aAAa,QAAyD;CAC9E,MAAM,IAAI,OAAO;CACjB,MAAM,MAAW;EAChB,IAAK,EAAE,gBAAgB,KAAK,KAAK,OAAO,EAAE,YAAY,GAAI;EAC1D,GAAG,OAAO,EAAE,EAAE,GAAG;EACjB,KAAK,IAAI,EAAE,IAAI,GAAG;EAClB,GAAG,IAAI,EAAE,EAAE,GAAG;EACd,OAAO,OAAO,EAAE,MAAM,GAAG;EACzB;AACD,QAAO;EACN,SAAS,OAAO,OAAO,QAAQ,GAAG;EAClC;EACA,SAAS;GACR,YAAY,OAAO,OAAO,8BAA8B;GACxD,oBAAoB,OAAO,OAAO,uCAAuC;GACzE,uBAAuB,OAAO,OAAO,0CAA0C;GAC/E,mBAAmB,OAAO,OAAO,sCAAsC;GACvE;EACD;;AAYF,eAAsB,mBACrB,QACA,QACA,UACA,OAC0B;CAC1B,MAAM,KAAK,IAAI,aAAa;AAC5B,IAAG,IAAI,eAAe,QAAQ;EAAE,gBAAgB;EAAU,GAAG;EAAO,CAAC,CAAC;CACtE,MAAM,CAAC,QAAQ,MAAM,eAAe,QAAQ,GAAG;AAC/C,QAAO,aAAa,OAAO,MAAM,KAAK,GAAG,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.d.mts","names":[],"sources":["../src/sessions.ts"],"mappings":";;;;;;;;;;;AA0BA;;;;UAAiB,cAAA,SAAuB,sBAAA;EAEvC;EAAA,iBAAA;EAIA;EAFA,cAAA;EAIe;EAFf,gBAAA;EAUgB;EARhB,eAAA;AAAA;;;AAgBD;;;UARiB,eAAA;EAUF;EARd,gBAAA;EAqBgC;EAnBhC,4BAAA;AAAA;;UAIgB,kBAAA;EAiBqB;EAfrC,cAAA;AAAA;;;;;;;;AA2BD;;;iBAdgB,iBAAA,CACf,OAAA,EAAS,UAAA,GACP,cAAA,GAAiB,eAAA,GAAkB,kBAAA;;cAYzB,uBAAA;;cAGA,wBAAA;;UAkBI,YAAA;EAAA;EAEhB,OAAA;;EAEA,WAAA;AAAA;AAsCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,cAAa,gBAAA;EAAA;cAGA,MAAA,EAAQ,cAAA;EAgE0B;;;;EA9C9C,sBAAA,CAAuB,KAAA;EAqEvB;;;;;EAzDA,eAAA,CAAgB,KAAA;EAyEhB;;;;;EA5DA,qBAAA,CAAsB,KAAA;EA6DK;;;;;;;;EAxC3B,gBAAA,CAAiB,MAAA;IAAU,SAAA;IAAmB,OAAA;IAAiB,UAAA;EAAA,KACtD,EAAA,EAAI,WAAA;EA2EA;;;;;;;;EArDb,aAAA,CAAc,MAAA;IAAU,SAAA;IAAmB,OAAA;EAAA,KAClC,EAAA,EAAI,WAAA;EAqFZ;;;;;EAtED,mBAAA,CAAoB,MAAA;IAAU,SAAA;IAAmB,OAAA;EAAA,KACxC,EAAA,EAAI,WAAA,KAAc,iBAAA;EAwG1B;;;;;;;EA/ED,iBAAA,CAAkB,MAAA;IACjB,cAAA;IACA,SAAA;IACA,cAAA;IACA,MAAA,EAAQ,mBAAA;IACR,SAAA;IACA,UAAA;IACA,QAAA;IACA,OAAA;IACA,cAAA;EAAA,KAEQ,EAAA,EAAI,WAAA,KAAc,iBAAA;EAyGlB;;;;;EAhFT,eAAA,CAAgB,MAAA;IACf,cAAA;IACA,SAAA;IACA,cAAA;IACA,MAAA,EAAQ,mBAAA;IACR,SAAA;IACA,UAAA;IACA,UAAA;IACA,WAAA;IACA,OAAA;EAAA,KAEQ,EAAA,EAAI,WAAA,KAAc,iBAAA;EAoIkE;;;;;;;;;EAvG7F,UAAA,CAAW,MAAA;IACV,cAAA;IACA,SAAA;IACA,cAAA;IACA,MAAA,EAAQ,mBAAA;IACR,OAAA;IACA,aAAA;IACA,cAAA;IACA,WAAA;EAAA,KAEQ,EAAA,EAAI,WAAA,KAAc,iBAAA;;;;;;EAwB3B,aAAA,CAAc,MAAA;IACb,cAAA;IACA,SAAA;IACA,cAAA;IACA,OAAA;EAAA,KAEQ,EAAA,EAAI,WAAA;;;;;;;;;;;;;;;SA8BN,cAAA,CAAe,QAAA,EAAU,UAAA,GAAa,YAAA;;SAqBtC,cAAA,CAAe,MAAA,WAAiB,YAAA,IAAgB,KAAA,oBAAyB,YAAA;;;;;;;SAYzE,eAAA,CAAgB,MAAA,WAAiB,YAAA,IAAgB,KAAA,oBAAyB,YAAA;AAAA"}
1
+ {"version":3,"file":"sessions.d.mts","names":[],"sources":["../src/sessions.ts"],"mappings":";;;;;;;;;;;AA2BA;;;;UAAiB,cAAA,SAAuB,sBAAA;EAEvC;EAAA,iBAAA;EAIA;EAFA,cAAA;EAIe;EAFf,gBAAA;EAUgB;EARhB,eAAA;AAAA;;;AAgBD;;;UARiB,eAAA;EAUF;EARd,gBAAA;EAqBgC;EAnBhC,4BAAA;AAAA;;UAIgB,kBAAA;EAiBqB;EAfrC,cAAA;AAAA;;;;;;;;AA6BD;;;iBAhBgB,iBAAA,CACf,OAAA,EAAS,UAAA,GACP,cAAA,GAAiB,eAAA,GAAkB,kBAAA;;cAczB,uBAAA;;cAGA,wBAAA;;UAkBI,YAAA;EAAA;EAEhB,OAAA;;EAEA,WAAA;AAAA;AAsCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,cAAa,gBAAA;EAAA;cAGA,MAAA,EAAQ,cAAA;EAgE0B;;;;EA9C9C,sBAAA,CAAuB,KAAA;EAqEvB;;;;;EAzDA,eAAA,CAAgB,KAAA;EAyEhB;;;;;EA5DA,qBAAA,CAAsB,KAAA;EA6DK;;;;;;;;EAxC3B,gBAAA,CAAiB,MAAA;IAAU,SAAA;IAAmB,OAAA;IAAiB,UAAA;EAAA,KACtD,EAAA,EAAI,WAAA;EA2EA;;;;;;;;EArDb,aAAA,CAAc,MAAA;IAAU,SAAA;IAAmB,OAAA;EAAA,KAClC,EAAA,EAAI,WAAA;EAqFZ;;;;;EAtED,mBAAA,CAAoB,MAAA;IAAU,SAAA;IAAmB,OAAA;EAAA,KACxC,EAAA,EAAI,WAAA,KAAc,iBAAA;EAwG1B;;;;;;;EA/ED,iBAAA,CAAkB,MAAA;IACjB,cAAA;IACA,SAAA;IACA,cAAA;IACA,MAAA,EAAQ,mBAAA;IACR,SAAA;IACA,UAAA;IACA,QAAA;IACA,OAAA;IACA,cAAA;EAAA,KAEQ,EAAA,EAAI,WAAA,KAAc,iBAAA;EAyGlB;;;;;EAhFT,eAAA,CAAgB,MAAA;IACf,cAAA;IACA,SAAA;IACA,cAAA;IACA,MAAA,EAAQ,mBAAA;IACR,SAAA;IACA,UAAA;IACA,UAAA;IACA,WAAA;IACA,OAAA;EAAA,KAEQ,EAAA,EAAI,WAAA,KAAc,iBAAA;EAoIkE;;;;;;;;;EAvG7F,UAAA,CAAW,MAAA;IACV,cAAA;IACA,SAAA;IACA,cAAA;IACA,MAAA,EAAQ,mBAAA;IACR,OAAA;IACA,aAAA;IACA,cAAA;IACA,WAAA;EAAA,KAEQ,EAAA,EAAI,WAAA,KAAc,iBAAA;;;;;;EAwB3B,aAAA,CAAc,MAAA;IACb,cAAA;IACA,SAAA;IACA,cAAA;IACA,OAAA;EAAA,KAEQ,EAAA,EAAI,WAAA;;;;;;;;;;;;;;;SA8BN,cAAA,CAAe,QAAA,EAAU,UAAA,GAAa,YAAA;;SAqBtC,cAAA,CAAe,MAAA,WAAiB,YAAA,IAAgB,KAAA,oBAAyB,YAAA;;;;;;;SAYzE,eAAA,CAAgB,MAAA,WAAiB,YAAA,IAAgB,KAAA,oBAAyB,YAAA;AAAA"}
package/dist/sessions.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { MAINNET_SESSIONS } from "./deployments/mainnet.mjs";
1
2
  import { TESTNET_DEPLOYMENT, TESTNET_SESSIONS, TESTNET_UNITS } from "./deployments/testnet.mjs";
2
3
  import { getDeployment, getUnits } from "./deployments/index.mjs";
3
4
  import { AccountContract } from "./account.mjs";
@@ -19,7 +20,8 @@ import { deriveDynamicFieldID, deriveObjectID } from "@mysten/sui/utils";
19
20
  */
20
21
  function getSessionsConfig(network) {
21
22
  if (network === "testnet") return TESTNET_SESSIONS;
22
- throw new Error(`@mysten/deepbook-v3/sessions: no sessions deployment recorded for network '${network}'. Sessions is testnet-only today; for your own deployment construct a \`SessionsConfig\` and pass it to SessionsContract directly.`);
23
+ if (network === "mainnet") return MAINNET_SESSIONS;
24
+ throw new Error(`@mysten/deepbook-v3/sessions: no sessions deployment recorded for network '${network}'. Sessions is recorded for testnet and mainnet; for your own deployment construct a \`SessionsConfig\` and pass it to SessionsContract directly.`);
23
25
  }
24
26
  /** The maximum session duration the contract accepts: 30 days, in milliseconds. */
25
27
  const MAX_SESSION_DURATION_MS = 720 * 60 * 60 * 1e3;
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.mjs","names":["#config","#generatedConfig","sessions.authorizeSession","sessions.revokeSession","sessions.sessionExpirationMs","sessions.mintExactQuantity","sessions.mintExactAmount","sessions.redeemLive","sessions.redeemSettled"],"sources":["../src/sessions.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { bcs } from '@mysten/sui/bcs';\nimport type { Transaction, TransactionArgument, TransactionResult } from '@mysten/sui/transactions';\nimport { deriveDynamicFieldID, deriveObjectID } from '@mysten/sui/utils';\n\nimport { TESTNET_SESSIONS } from './deployments/testnet.js';\nimport type { NetworkArg } from './deployments/index.js';\n\n// Provenance and scale constants, so a sessions-only consumer can answer \"which deployment\n// is this pinned to?\" and format a custody balance without importing another subpath.\nexport { getDeployment, getUnits, TESTNET_DEPLOYMENT, TESTNET_UNITS } from './deployments/index.js';\nexport type { DeployedNetwork, NetworkArg } from './deployments/index.js';\n\nimport { AccountContract } from './account.js';\nimport type { DeepbookSessionsConfig } from './contracts/deepbook_sessions/config-arguments.js';\nimport * as sessions from './contracts/deepbook_sessions/sessions.js';\nimport { SessionsData } from './contracts/deepbook_sessions/sessions.js';\n\n/**\n * Deployed ids the sessions builders address.\n *\n * `accountPackageId` / `accountRegistry` are the same shared-account ids\n * {@link AccountContract} takes — sessions is an Account app, so it addresses the same\n * registry. `sessionsPackageId` and `sessionsConfig` come from the sessions deployment.\n */\nexport interface SessionsConfig extends DeepbookSessionsConfig {\n\t/** The `deepbook_sessions` Move package id. */\n\tsessionsPackageId: string;\n\t/** The shared `SessionsConfig` object id. */\n\tsessionsConfig: string;\n\t/** The shared `account` Move package id. */\n\taccountPackageId: string;\n\t/** The shared `AccountRegistry` object id. */\n\taccountRegistry: string;\n}\n\n/**\n * Ids the DeepBook **spot** session wrappers need on top of {@link SessionsConfig}. The\n * Predict wrappers never take these, so they are kept off the main config rather than made\n * optional there.\n */\nexport interface SessionsSpotIds {\n\t/** DeepBook's shared `Registry` — `deepbook_registry` on the spot entrypoints. */\n\tdeepbookRegistry: string;\n\t/** The `deepbook_core_account` Move package id. */\n\tdeepbookCoreAccountPackageId: string;\n}\n\n/** Ids the Predict session wrappers need beyond {@link SessionsConfig}. */\nexport interface SessionsPredictIds {\n\t/** Every Predict wrapper takes `config: &ProtocolConfig`. */\n\tprotocolConfig: string;\n}\n\n/**\n * @description The deployed sessions ids for `network`, so a caller does not transcribe\n * them. Generated from the deploy manifest — see `src/deployments/`. The returned object\n * also carries {@link SessionsSpotIds} for the generated spot wrappers.\n * @throws if the network has no recorded deployment, rather than returning placeholder ids.\n *\n * ```ts\n * const sessions = new SessionsContract(getSessionsConfig('testnet'));\n * ```\n */\nexport function getSessionsConfig(\n\tnetwork: NetworkArg,\n): SessionsConfig & SessionsSpotIds & SessionsPredictIds {\n\t// The frozen record itself, matching `/account` — returning a spread here would have\n\t// quietly exempted this subpath from the immutability the others guarantee.\n\tif (network === 'testnet') return TESTNET_SESSIONS;\n\tthrow new Error(\n\t\t`@mysten/deepbook-v3/sessions: no sessions deployment recorded for network '${network}'. ` +\n\t\t\t'Sessions is testnet-only today; for your own deployment construct a `SessionsConfig` ' +\n\t\t\t'and pass it to SessionsContract directly.',\n\t);\n}\n\n/** The maximum session duration the contract accepts: 30 days, in milliseconds. */\nexport const MAX_SESSION_DURATION_MS = 30 * 24 * 60 * 60 * 1000;\n\n/** The maximum number of distinct session addresses one Account may store. */\nexport const MAX_SESSIONS_PER_ACCOUNT = 20;\n\n// `sui::dynamic_field::Field<DataKey<SessionsApp>, SessionsData>` — what a core `getObject`\n// on the grant field actually returns. `DataKey` is source-empty, but Move inserts a\n// hidden `dummy_field: bool` into empty structs, so the name occupies ONE zero byte\n// between the id and the value. Decoding the value alone would read the field id's first\n// byte as the VecMap length: garbage grants, or a silent empty list.\nconst SessionsDataField = bcs.struct('Field<DataKey,SessionsData>', {\n\tid: bcs.Address,\n\tname: bcs.bool(), // DataKey's hidden dummy_field\n\tvalue: SessionsData,\n});\n\n// `AccountKey(owner)` — the canonical ACCOUNT identity, a different derived object from\n// the wrapper. Grant data hangs off this one.\nconst AccountKey = bcs.struct('AccountKey', { pos0: bcs.Address });\n\n/** One stored session grant. */\nexport interface SessionGrant {\n\t/** The authorized ephemeral address. */\n\tsession: string;\n\t/** Absolute expiry, ms since epoch. The grant is dead AT this timestamp (strict `<`). */\n\texpiresAtMs: bigint;\n}\n\n/**\n * SessionsContract — time-limited trading sessions over a canonical Account.\n *\n * An Account owner authorizes an ephemeral address to submit a bounded set of\n * transactions on the Account's behalf until a fixed expiry. The session key never\n * receives a reusable `Auth`: each wrapper mints app authorization internally and\n * consumes it in the same call.\n *\n * WHAT A SESSION KEY CAN DO. It cannot withdraw to an address, cannot grant or revoke\n * sessions, and cannot outlive its expiry — those all require owner auth. It CAN trade\n * the Account's full balance: the spot wrappers take a caller-chosen `Pool` and, through\n * `deepbook_core_account`, pull the account's entire Base, Quote and DEEP balance\n * (stored plus unsettled) into the embedded manager for the duration of the call, with\n * `price_limit` supplied by the caller. Nothing caps notional, restricts which pools are\n * reachable, or bounds loss to adverse pricing. Treat a session key as authority over\n * everything the Account holds, and fund an ephemeral-session Account accordingly.\n *\n * Operational precondition: an admin must have authorized `SessionsApp` on the account\n * registry. Until then — or after a `deauthorize_app` — the TRADING wrappers abort with\n * `EAppNotAuthorized`; `authorizeSession`, `revokeSession` and `sessionExpirationMs` use\n * owner auth or no auth and keep working. Note that `deauthorize_app` does not clear\n * `SessionsData`, so re-authorizing makes every still-unexpired grant live again at once\n * — it is a pause, not a kill switch. Revoking, and reading expirations, also keep\n * working if the sessions package is later version-gated.\n *\n * This class wraps the session lifecycle and the **Predict** entrypoints. The DeepBook\n * spot session wrappers are generated (see `sessionsMoveCalls`) but are not wrapped here\n * — note `placeLimitOrder` and `placeMarketOrder` put `accountRegistry` at index 2 and\n * `sessionsConfig` at 4, because `deepbookRegistry` sits between them; the other three\n * (`cancelLiveOrder`, `cancelLiveOrders`, `withdrawSettledAmounts`) take no\n * `deepbookRegistry` and so keep 1 and 3 like the Predict wrappers:\n * the surrounding spot-over-Account workflow — discovering the embedded balance manager,\n * reading resting orders and locked balances — is not modelled yet, so a wrapped builder\n * would be hard to use well. They are reachable from the generated bindings meanwhile.\n */\nexport class SessionsContract {\n\t#config: SessionsConfig;\n\n\tconstructor(config: SessionsConfig) {\n\t\tthis.#config = config;\n\t}\n\n\t// The generated thunks resolve the package address and auto-inject the shared\n\t// `SessionsConfig` from this object. `accountRegistry` stays an explicit argument —\n\t// it belongs to the account package, which is a separate codegen entry.\n\tget #generatedConfig() {\n\t\treturn {\n\t\t\tsessionsPackageId: this.#config.sessionsPackageId,\n\t\t\tsessionsConfig: this.#config.sessionsConfig,\n\t\t};\n\t}\n\n\t/**\n\t * @description The owner's canonical `AccountWrapper` id — derived off-chain, no read.\n\t * Every builder here takes that id.\n\t */\n\tderiveAccountWrapperId(owner: string): string {\n\t\treturn new AccountContract({\n\t\t\taccountPackageId: this.#config.accountPackageId,\n\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t}).deriveAccountWrapperId(owner);\n\t}\n\n\t/**\n\t * @description The owner's canonical ACCOUNT id — a different derived object from the\n\t * wrapper. The session grants hang off this one, so this is what\n\t * {@link deriveSessionsFieldId} and {@link decodeSessions} work from.\n\t */\n\tderiveAccountId(owner: string): string {\n\t\treturn deriveObjectID(\n\t\t\tthis.#config.accountRegistry,\n\t\t\t`${this.#config.accountPackageId}::account_registry::AccountKey`,\n\t\t\tAccountKey.serialize({ pos0: owner }).toBytes(),\n\t\t);\n\t}\n\n\t/**\n\t * @description The object id of the owner's `DataKey<SessionsApp>` dynamic field —\n\t * fetch this object and pass its BCS contents to {@link decodeSessions}. There is no\n\t * bulk on-chain read, so this is the route to enumerating grants.\n\t */\n\tderiveSessionsFieldId(owner: string): string {\n\t\t// A PLAIN dynamic field, not a derived object: `account::attach` writes it with\n\t\t// `df::add` (`use fun df::add as UID.add`), whereas the account and wrapper ids are\n\t\t// claimed through `derived_object::claim`. `deriveObjectID` would wrap the tag in\n\t\t// `0x2::derived_object::DerivedObjectKey<..>` and yield an id that points at nothing.\n\t\treturn deriveDynamicFieldID(\n\t\t\tthis.deriveAccountId(owner),\n\t\t\t`${this.#config.accountPackageId}::account::DataKey<${this.#config.sessionsPackageId}::sessions::SessionsApp>`,\n\t\t\t// DataKey is source-empty; Move's hidden `dummy_field: bool` is the key's one byte.\n\t\t\tnew Uint8Array([0]),\n\t\t);\n\t}\n\n\t/**\n\t * @description Grant `session` authority over the Account until `now + durationMs`.\n\t * Authority is derived from the transaction SENDER, so the owner must sign this.\n\t * `durationMs` must be > 0 and <= {@link MAX_SESSION_DURATION_MS}; an Account holds at\n\t * most {@link MAX_SESSIONS_PER_ACCOUNT} distinct addresses. Re-authorizing an address\n\t * replaces its expiry in place and consumes no additional slot.\n\t * @returns A function that takes a Transaction object\n\t */\n\tauthorizeSession(params: { wrapperId: string; session: string; durationMs: number | bigint }) {\n\t\treturn (tx: Transaction): void => {\n\t\t\ttx.add(\n\t\t\t\tsessions.authorizeSession({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tsession: params.session,\n\t\t\t\t\t\tdurationMs: params.durationMs,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\t}\n\n\t/**\n\t * @description Remove `session`'s grant. Owner-signed, like `authorizeSession`.\n\t * Deliberately takes no `SessionsConfig`: revocation is not version-gated, so it keeps\n\t * working after the package is retired. Revoking an address that holds no grant is a\n\t * silent no-op — it neither aborts nor emits, so read before and after if you need to\n\t * distinguish \"revoked\" from \"was never granted\".\n\t * @returns A function that takes a Transaction object\n\t */\n\trevokeSession(params: { wrapperId: string; session: string }) {\n\t\treturn (tx: Transaction): void => {\n\t\t\ttx.add(\n\t\t\t\tsessions.revokeSession({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: { wrapper: params.wrapperId, session: params.session },\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\t}\n\n\t/**\n\t * @description Read one session's absolute expiry as `Option<u64>`. Compose in a\n\t * dev-inspect/simulate PTB and decode the returned BCS. Not version-gated.\n\t * @returns A function that takes a Transaction object\n\t */\n\tsessionExpirationMs(params: { wrapperId: string; session: string }) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.sessionExpirationMs({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: { wrapper: params.wrapperId, session: params.session },\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t// === Predict wrappers ===\n\t//\n\t// Each mirrors the Predict entrypoint of the same name, with two differences: the\n\t// caller supplies NO `Auth` (the wrapper mints and consumes app authorization\n\t// internally), and `accountRegistry` + `sessionsConfig` are threaded in. `pricer` is a\n\t// PTB RESULT, not an object — it comes from a preceding `expiry_market::load_live_pricer`\n\t// command in the same transaction. Everything else matches Predict exactly, and Predict\n\t// still performs all parameter validation.\n\n\t/**\n\t * @description Mint a position of an exact payout quantity, as `session`. Pass\n\t * `u64::MAX` for `maxCost` / `maxProbability` to leave either slippage cap\n\t * effectively unbounded — the chain asserts `value <= cap`, so the max value can never\n\t * trip. Both are required; there is no default.\n\t * @returns A function that takes a Transaction object and returns the new order id (u256)\n\t */\n\tmintExactQuantity(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\tpricer: TransactionArgument;\n\t\tlowerTick: number | bigint;\n\t\thigherTick: number | bigint;\n\t\tquantity: number | bigint;\n\t\tmaxCost: number | bigint;\n\t\tmaxProbability: number | bigint;\n\t}) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.mintExactQuantity({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\tpricer: params.pricer,\n\t\t\t\t\t\tlowerTick: params.lowerTick,\n\t\t\t\t\t\thigherTick: params.higherTick,\n\t\t\t\t\t\tquantity: params.quantity,\n\t\t\t\t\t\tmaxCost: params.maxCost,\n\t\t\t\t\t\tmaxProbability: params.maxProbability,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t/**\n\t * @description Mint by spending up to a premium budget, flooring the quantity received.\n\t * The chain requires `maxCost > 0`.\n\t * @returns A function that takes a Transaction object and returns the new order id (u256)\n\t */\n\tmintExactAmount(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\tpricer: TransactionArgument;\n\t\tlowerTick: number | bigint;\n\t\thigherTick: number | bigint;\n\t\tmaxPremium: number | bigint;\n\t\tminQuantity: number | bigint;\n\t\tmaxCost: number | bigint;\n\t}) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.mintExactAmount({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\tpricer: params.pricer,\n\t\t\t\t\t\tlowerTick: params.lowerTick,\n\t\t\t\t\t\thigherTick: params.higherTick,\n\t\t\t\t\t\tmaxPremium: params.maxPremium,\n\t\t\t\t\t\tminQuantity: params.minQuantity,\n\t\t\t\t\t\tmaxCost: params.maxCost,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t/**\n\t * @description Close part or all of a live position at the pricer's mark, as `session`.\n\t * `minProbability` / `minProceeds` are close-side slippage floors; `0` disables either,\n\t * and OMITTING them is `0` — unlike the mint caps, which are required. On a delegated\n\t * key this is the direction that closes a position at any price, so pass real floors\n\t * unless you mean to accept whatever the mark gives you.\n\t * @returns A function that takes a Transaction object and returns `Option<u256>` — the\n\t * replacement order id when a partial close leaves quantity open\n\t */\n\tredeemLive(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\tpricer: TransactionArgument;\n\t\torderId: bigint;\n\t\tcloseQuantity: number | bigint;\n\t\tminProbability?: number | bigint;\n\t\tminProceeds?: number | bigint;\n\t}) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.redeemLive({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\tpricer: params.pricer,\n\t\t\t\t\t\torderId: params.orderId,\n\t\t\t\t\t\tcloseQuantity: params.closeQuantity,\n\t\t\t\t\t\tminProbability: params.minProbability ?? 0,\n\t\t\t\t\t\tminProceeds: params.minProceeds ?? 0,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t/**\n\t * @description Claim a settled position in full, as `session`. Takes no pricer — the\n\t * settlement price is fixed — and no quantity: a settled claim is all-or-nothing.\n\t * @returns A function that takes a Transaction object\n\t */\n\tredeemSettled(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\torderId: bigint;\n\t}) {\n\t\treturn (tx: Transaction): void => {\n\t\t\ttx.add(\n\t\t\t\tsessions.redeemSettled({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\torderId: params.orderId,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\t}\n\n\t/**\n\t * @description Decode an Account's stored grants from the raw BCS content of its\n\t * `DataKey<SessionsApp>` dynamic FIELD object — the whole\n\t * `Field<DataKey<SessionsApp>, SessionsData>`, as the core API returns it, not the\n\t * inner `SessionsData`. Get the id from {@link deriveSessionsFieldId}.\n\t *\n\t * There is no bulk on-chain read — `sessionExpirationMs` answers one address at a time —\n\t * so listing grants means fetching that field and decoding it here. Note the field hangs\n\t * off the DERIVED ACCOUNT address, not the wrapper address; they are different objects.\n\t *\n\t * Expired grants are never pruned automatically and keep occupying slots, so callers\n\t * managing the {@link MAX_SESSIONS_PER_ACCOUNT} cap should list, drop anything already\n\t * expired, and revoke before granting again.\n\t */\n\tstatic decodeSessions(contents: Uint8Array): SessionGrant[] {\n\t\t// Assert full consumption. `@mysten/bcs`'s ULEB reader indexes the underlying\n\t\t// ArrayBuffer rather than the view, so a truncated SUBARRAY — which is exactly what a\n\t\t// gRPC `content` field is — can read past its bound and decode to `[]` with no error.\n\t\t// Re-serializing and comparing lengths turns both truncation and trailing junk into a\n\t\t// throw, so \"no grants\" can only ever mean no grants.\n\t\tconst field = SessionsDataField.parse(contents);\n\t\tconst reencoded = SessionsDataField.serialize(field).toBytes();\n\t\tif (reencoded.length !== contents.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`sessions field is ${contents.length} bytes but its contents encode to ${reencoded.length}; ` +\n\t\t\t\t\t'the bytes are truncated or carry trailing data',\n\t\t\t);\n\t\t}\n\t\treturn field.value.sessions.contents.map((entry) => ({\n\t\t\tsession: entry.key,\n\t\t\texpiresAtMs: BigInt(entry.value),\n\t\t}));\n\t}\n\n\t/** Grants from {@link decodeSessions} that are still live at `nowMs`. */\n\tstatic activeSessions(grants: readonly SessionGrant[], nowMs: number | bigint): SessionGrant[] {\n\t\tconst now = BigInt(nowMs);\n\t\t// The chain asserts `now < expiresAtMs`, so a grant is dead AT its expiry.\n\t\treturn grants.filter((g) => now < g.expiresAtMs);\n\t}\n\n\t/**\n\t * @description Grants that are already dead at `nowMs` — the complement of\n\t * {@link activeSessions}, and the list to revoke when reclaiming slots. Use this rather\n\t * than filtering by hand: `nowMs > expiresAtMs` looks equivalent but leaves the grant\n\t * expiring exactly at `nowMs` occupying a slot forever.\n\t */\n\tstatic expiredSessions(grants: readonly SessionGrant[], nowMs: number | bigint): SessionGrant[] {\n\t\tconst now = BigInt(nowMs);\n\t\treturn grants.filter((g) => now >= g.expiresAtMs);\n\t}\n}\n\n// === Generated bindings ===\n// NOTE: this namespace carries the DeepBook spot session calls too\n// (`placeLimitOrder`, `placeMarketOrder`, `cancelLiveOrder(s)`, `withdrawSettledAmounts`).\n// They are generated and callable; they are simply not wrapped on `SessionsContract`.\nexport * as sessionsMoveCalls from './contracts/deepbook_sessions/sessions.js';\nexport * as sessionConfigMoveCalls from './contracts/deepbook_sessions/session_config.js';\nexport {\n\tSessionsApp,\n\tSessionsData,\n\tSessionAuthorized,\n\tSessionRevoked,\n} from './contracts/deepbook_sessions/sessions.js';\n"],"mappings":"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"}
1
+ {"version":3,"file":"sessions.mjs","names":["#config","#generatedConfig","sessions.authorizeSession","sessions.revokeSession","sessions.sessionExpirationMs","sessions.mintExactQuantity","sessions.mintExactAmount","sessions.redeemLive","sessions.redeemSettled"],"sources":["../src/sessions.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { bcs } from '@mysten/sui/bcs';\nimport type { Transaction, TransactionArgument, TransactionResult } from '@mysten/sui/transactions';\nimport { deriveDynamicFieldID, deriveObjectID } from '@mysten/sui/utils';\n\nimport { MAINNET_SESSIONS } from './deployments/mainnet.js';\nimport { TESTNET_SESSIONS } from './deployments/testnet.js';\nimport type { NetworkArg } from './deployments/index.js';\n\n// Provenance and scale constants, so a sessions-only consumer can answer \"which deployment\n// is this pinned to?\" and format a custody balance without importing another subpath.\nexport { getDeployment, getUnits, TESTNET_DEPLOYMENT, TESTNET_UNITS } from './deployments/index.js';\nexport type { DeployedNetwork, NetworkArg } from './deployments/index.js';\n\nimport { AccountContract } from './account.js';\nimport type { DeepbookSessionsConfig } from './contracts/deepbook_sessions/config-arguments.js';\nimport * as sessions from './contracts/deepbook_sessions/sessions.js';\nimport { SessionsData } from './contracts/deepbook_sessions/sessions.js';\n\n/**\n * Deployed ids the sessions builders address.\n *\n * `accountPackageId` / `accountRegistry` are the same shared-account ids\n * {@link AccountContract} takes — sessions is an Account app, so it addresses the same\n * registry. `sessionsPackageId` and `sessionsConfig` come from the sessions deployment.\n */\nexport interface SessionsConfig extends DeepbookSessionsConfig {\n\t/** The `deepbook_sessions` Move package id. */\n\tsessionsPackageId: string;\n\t/** The shared `SessionsConfig` object id. */\n\tsessionsConfig: string;\n\t/** The shared `account` Move package id. */\n\taccountPackageId: string;\n\t/** The shared `AccountRegistry` object id. */\n\taccountRegistry: string;\n}\n\n/**\n * Ids the DeepBook **spot** session wrappers need on top of {@link SessionsConfig}. The\n * Predict wrappers never take these, so they are kept off the main config rather than made\n * optional there.\n */\nexport interface SessionsSpotIds {\n\t/** DeepBook's shared `Registry` — `deepbook_registry` on the spot entrypoints. */\n\tdeepbookRegistry: string;\n\t/** The `deepbook_core_account` Move package id. */\n\tdeepbookCoreAccountPackageId: string;\n}\n\n/** Ids the Predict session wrappers need beyond {@link SessionsConfig}. */\nexport interface SessionsPredictIds {\n\t/** Every Predict wrapper takes `config: &ProtocolConfig`. */\n\tprotocolConfig: string;\n}\n\n/**\n * @description The deployed sessions ids for `network`, so a caller does not transcribe\n * them. Generated from the deploy manifest — see `src/deployments/`. The returned object\n * also carries {@link SessionsSpotIds} for the generated spot wrappers.\n * @throws if the network has no recorded deployment, rather than returning placeholder ids.\n *\n * ```ts\n * const sessions = new SessionsContract(getSessionsConfig('testnet'));\n * ```\n */\nexport function getSessionsConfig(\n\tnetwork: NetworkArg,\n): SessionsConfig & SessionsSpotIds & SessionsPredictIds {\n\t// The frozen record itself, matching `/account` — returning a spread here would have\n\t// quietly exempted this subpath from the immutability the others guarantee.\n\tif (network === 'testnet') return TESTNET_SESSIONS;\n\tif (network === 'mainnet') return MAINNET_SESSIONS;\n\tthrow new Error(\n\t\t`@mysten/deepbook-v3/sessions: no sessions deployment recorded for network '${network}'. ` +\n\t\t\t'Sessions is recorded for testnet and mainnet; for your own deployment construct a ' +\n\t\t\t'`SessionsConfig` ' +\n\t\t\t'and pass it to SessionsContract directly.',\n\t);\n}\n\n/** The maximum session duration the contract accepts: 30 days, in milliseconds. */\nexport const MAX_SESSION_DURATION_MS = 30 * 24 * 60 * 60 * 1000;\n\n/** The maximum number of distinct session addresses one Account may store. */\nexport const MAX_SESSIONS_PER_ACCOUNT = 20;\n\n// `sui::dynamic_field::Field<DataKey<SessionsApp>, SessionsData>` — what a core `getObject`\n// on the grant field actually returns. `DataKey` is source-empty, but Move inserts a\n// hidden `dummy_field: bool` into empty structs, so the name occupies ONE zero byte\n// between the id and the value. Decoding the value alone would read the field id's first\n// byte as the VecMap length: garbage grants, or a silent empty list.\nconst SessionsDataField = bcs.struct('Field<DataKey,SessionsData>', {\n\tid: bcs.Address,\n\tname: bcs.bool(), // DataKey's hidden dummy_field\n\tvalue: SessionsData,\n});\n\n// `AccountKey(owner)` — the canonical ACCOUNT identity, a different derived object from\n// the wrapper. Grant data hangs off this one.\nconst AccountKey = bcs.struct('AccountKey', { pos0: bcs.Address });\n\n/** One stored session grant. */\nexport interface SessionGrant {\n\t/** The authorized ephemeral address. */\n\tsession: string;\n\t/** Absolute expiry, ms since epoch. The grant is dead AT this timestamp (strict `<`). */\n\texpiresAtMs: bigint;\n}\n\n/**\n * SessionsContract — time-limited trading sessions over a canonical Account.\n *\n * An Account owner authorizes an ephemeral address to submit a bounded set of\n * transactions on the Account's behalf until a fixed expiry. The session key never\n * receives a reusable `Auth`: each wrapper mints app authorization internally and\n * consumes it in the same call.\n *\n * WHAT A SESSION KEY CAN DO. It cannot withdraw to an address, cannot grant or revoke\n * sessions, and cannot outlive its expiry — those all require owner auth. It CAN trade\n * the Account's full balance: the spot wrappers take a caller-chosen `Pool` and, through\n * `deepbook_core_account`, pull the account's entire Base, Quote and DEEP balance\n * (stored plus unsettled) into the embedded manager for the duration of the call, with\n * `price_limit` supplied by the caller. Nothing caps notional, restricts which pools are\n * reachable, or bounds loss to adverse pricing. Treat a session key as authority over\n * everything the Account holds, and fund an ephemeral-session Account accordingly.\n *\n * Operational precondition: an admin must have authorized `SessionsApp` on the account\n * registry. Until then — or after a `deauthorize_app` — the TRADING wrappers abort with\n * `EAppNotAuthorized`; `authorizeSession`, `revokeSession` and `sessionExpirationMs` use\n * owner auth or no auth and keep working. Note that `deauthorize_app` does not clear\n * `SessionsData`, so re-authorizing makes every still-unexpired grant live again at once\n * — it is a pause, not a kill switch. Revoking, and reading expirations, also keep\n * working if the sessions package is later version-gated.\n *\n * This class wraps the session lifecycle and the **Predict** entrypoints. The DeepBook\n * spot session wrappers are generated (see `sessionsMoveCalls`) but are not wrapped here\n * — note `placeLimitOrder` and `placeMarketOrder` put `accountRegistry` at index 2 and\n * `sessionsConfig` at 4, because `deepbookRegistry` sits between them; the other three\n * (`cancelLiveOrder`, `cancelLiveOrders`, `withdrawSettledAmounts`) take no\n * `deepbookRegistry` and so keep 1 and 3 like the Predict wrappers:\n * the surrounding spot-over-Account workflow — discovering the embedded balance manager,\n * reading resting orders and locked balances — is not modelled yet, so a wrapped builder\n * would be hard to use well. They are reachable from the generated bindings meanwhile.\n */\nexport class SessionsContract {\n\t#config: SessionsConfig;\n\n\tconstructor(config: SessionsConfig) {\n\t\tthis.#config = config;\n\t}\n\n\t// The generated thunks resolve the package address and auto-inject the shared\n\t// `SessionsConfig` from this object. `accountRegistry` stays an explicit argument —\n\t// it belongs to the account package, which is a separate codegen entry.\n\tget #generatedConfig() {\n\t\treturn {\n\t\t\tsessionsPackageId: this.#config.sessionsPackageId,\n\t\t\tsessionsConfig: this.#config.sessionsConfig,\n\t\t};\n\t}\n\n\t/**\n\t * @description The owner's canonical `AccountWrapper` id — derived off-chain, no read.\n\t * Every builder here takes that id.\n\t */\n\tderiveAccountWrapperId(owner: string): string {\n\t\treturn new AccountContract({\n\t\t\taccountPackageId: this.#config.accountPackageId,\n\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t}).deriveAccountWrapperId(owner);\n\t}\n\n\t/**\n\t * @description The owner's canonical ACCOUNT id — a different derived object from the\n\t * wrapper. The session grants hang off this one, so this is what\n\t * {@link deriveSessionsFieldId} and {@link decodeSessions} work from.\n\t */\n\tderiveAccountId(owner: string): string {\n\t\treturn deriveObjectID(\n\t\t\tthis.#config.accountRegistry,\n\t\t\t`${this.#config.accountPackageId}::account_registry::AccountKey`,\n\t\t\tAccountKey.serialize({ pos0: owner }).toBytes(),\n\t\t);\n\t}\n\n\t/**\n\t * @description The object id of the owner's `DataKey<SessionsApp>` dynamic field —\n\t * fetch this object and pass its BCS contents to {@link decodeSessions}. There is no\n\t * bulk on-chain read, so this is the route to enumerating grants.\n\t */\n\tderiveSessionsFieldId(owner: string): string {\n\t\t// A PLAIN dynamic field, not a derived object: `account::attach` writes it with\n\t\t// `df::add` (`use fun df::add as UID.add`), whereas the account and wrapper ids are\n\t\t// claimed through `derived_object::claim`. `deriveObjectID` would wrap the tag in\n\t\t// `0x2::derived_object::DerivedObjectKey<..>` and yield an id that points at nothing.\n\t\treturn deriveDynamicFieldID(\n\t\t\tthis.deriveAccountId(owner),\n\t\t\t`${this.#config.accountPackageId}::account::DataKey<${this.#config.sessionsPackageId}::sessions::SessionsApp>`,\n\t\t\t// DataKey is source-empty; Move's hidden `dummy_field: bool` is the key's one byte.\n\t\t\tnew Uint8Array([0]),\n\t\t);\n\t}\n\n\t/**\n\t * @description Grant `session` authority over the Account until `now + durationMs`.\n\t * Authority is derived from the transaction SENDER, so the owner must sign this.\n\t * `durationMs` must be > 0 and <= {@link MAX_SESSION_DURATION_MS}; an Account holds at\n\t * most {@link MAX_SESSIONS_PER_ACCOUNT} distinct addresses. Re-authorizing an address\n\t * replaces its expiry in place and consumes no additional slot.\n\t * @returns A function that takes a Transaction object\n\t */\n\tauthorizeSession(params: { wrapperId: string; session: string; durationMs: number | bigint }) {\n\t\treturn (tx: Transaction): void => {\n\t\t\ttx.add(\n\t\t\t\tsessions.authorizeSession({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tsession: params.session,\n\t\t\t\t\t\tdurationMs: params.durationMs,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\t}\n\n\t/**\n\t * @description Remove `session`'s grant. Owner-signed, like `authorizeSession`.\n\t * Deliberately takes no `SessionsConfig`: revocation is not version-gated, so it keeps\n\t * working after the package is retired. Revoking an address that holds no grant is a\n\t * silent no-op — it neither aborts nor emits, so read before and after if you need to\n\t * distinguish \"revoked\" from \"was never granted\".\n\t * @returns A function that takes a Transaction object\n\t */\n\trevokeSession(params: { wrapperId: string; session: string }) {\n\t\treturn (tx: Transaction): void => {\n\t\t\ttx.add(\n\t\t\t\tsessions.revokeSession({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: { wrapper: params.wrapperId, session: params.session },\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\t}\n\n\t/**\n\t * @description Read one session's absolute expiry as `Option<u64>`. Compose in a\n\t * dev-inspect/simulate PTB and decode the returned BCS. Not version-gated.\n\t * @returns A function that takes a Transaction object\n\t */\n\tsessionExpirationMs(params: { wrapperId: string; session: string }) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.sessionExpirationMs({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: { wrapper: params.wrapperId, session: params.session },\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t// === Predict wrappers ===\n\t//\n\t// Each mirrors the Predict entrypoint of the same name, with two differences: the\n\t// caller supplies NO `Auth` (the wrapper mints and consumes app authorization\n\t// internally), and `accountRegistry` + `sessionsConfig` are threaded in. `pricer` is a\n\t// PTB RESULT, not an object — it comes from a preceding `expiry_market::load_live_pricer`\n\t// command in the same transaction. Everything else matches Predict exactly, and Predict\n\t// still performs all parameter validation.\n\n\t/**\n\t * @description Mint a position of an exact payout quantity, as `session`. Pass\n\t * `u64::MAX` for `maxCost` / `maxProbability` to leave either slippage cap\n\t * effectively unbounded — the chain asserts `value <= cap`, so the max value can never\n\t * trip. Both are required; there is no default.\n\t * @returns A function that takes a Transaction object and returns the new order id (u256)\n\t */\n\tmintExactQuantity(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\tpricer: TransactionArgument;\n\t\tlowerTick: number | bigint;\n\t\thigherTick: number | bigint;\n\t\tquantity: number | bigint;\n\t\tmaxCost: number | bigint;\n\t\tmaxProbability: number | bigint;\n\t}) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.mintExactQuantity({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\tpricer: params.pricer,\n\t\t\t\t\t\tlowerTick: params.lowerTick,\n\t\t\t\t\t\thigherTick: params.higherTick,\n\t\t\t\t\t\tquantity: params.quantity,\n\t\t\t\t\t\tmaxCost: params.maxCost,\n\t\t\t\t\t\tmaxProbability: params.maxProbability,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t/**\n\t * @description Mint by spending up to a premium budget, flooring the quantity received.\n\t * The chain requires `maxCost > 0`.\n\t * @returns A function that takes a Transaction object and returns the new order id (u256)\n\t */\n\tmintExactAmount(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\tpricer: TransactionArgument;\n\t\tlowerTick: number | bigint;\n\t\thigherTick: number | bigint;\n\t\tmaxPremium: number | bigint;\n\t\tminQuantity: number | bigint;\n\t\tmaxCost: number | bigint;\n\t}) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.mintExactAmount({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\tpricer: params.pricer,\n\t\t\t\t\t\tlowerTick: params.lowerTick,\n\t\t\t\t\t\thigherTick: params.higherTick,\n\t\t\t\t\t\tmaxPremium: params.maxPremium,\n\t\t\t\t\t\tminQuantity: params.minQuantity,\n\t\t\t\t\t\tmaxCost: params.maxCost,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t/**\n\t * @description Close part or all of a live position at the pricer's mark, as `session`.\n\t * `minProbability` / `minProceeds` are close-side slippage floors; `0` disables either,\n\t * and OMITTING them is `0` — unlike the mint caps, which are required. On a delegated\n\t * key this is the direction that closes a position at any price, so pass real floors\n\t * unless you mean to accept whatever the mark gives you.\n\t * @returns A function that takes a Transaction object and returns `Option<u256>` — the\n\t * replacement order id when a partial close leaves quantity open\n\t */\n\tredeemLive(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\tpricer: TransactionArgument;\n\t\torderId: bigint;\n\t\tcloseQuantity: number | bigint;\n\t\tminProbability?: number | bigint;\n\t\tminProceeds?: number | bigint;\n\t}) {\n\t\treturn (tx: Transaction): TransactionResult =>\n\t\t\ttx.add(\n\t\t\t\tsessions.redeemLive({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\tpricer: params.pricer,\n\t\t\t\t\t\torderId: params.orderId,\n\t\t\t\t\t\tcloseQuantity: params.closeQuantity,\n\t\t\t\t\t\tminProbability: params.minProbability ?? 0,\n\t\t\t\t\t\tminProceeds: params.minProceeds ?? 0,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\t/**\n\t * @description Claim a settled position in full, as `session`. Takes no pricer — the\n\t * settlement price is fixed — and no quantity: a settled claim is all-or-nothing.\n\t * @returns A function that takes a Transaction object\n\t */\n\tredeemSettled(params: {\n\t\texpiryMarketId: string;\n\t\twrapperId: string;\n\t\tprotocolConfig: string;\n\t\torderId: bigint;\n\t}) {\n\t\treturn (tx: Transaction): void => {\n\t\t\ttx.add(\n\t\t\t\tsessions.redeemSettled({\n\t\t\t\t\tconfig: this.#generatedConfig,\n\t\t\t\t\targuments: {\n\t\t\t\t\t\tmarket: params.expiryMarketId,\n\t\t\t\t\t\taccountRegistry: this.#config.accountRegistry,\n\t\t\t\t\t\twrapper: params.wrapperId,\n\t\t\t\t\t\tconfig: params.protocolConfig,\n\t\t\t\t\t\torderId: params.orderId,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\t}\n\n\t/**\n\t * @description Decode an Account's stored grants from the raw BCS content of its\n\t * `DataKey<SessionsApp>` dynamic FIELD object — the whole\n\t * `Field<DataKey<SessionsApp>, SessionsData>`, as the core API returns it, not the\n\t * inner `SessionsData`. Get the id from {@link deriveSessionsFieldId}.\n\t *\n\t * There is no bulk on-chain read — `sessionExpirationMs` answers one address at a time —\n\t * so listing grants means fetching that field and decoding it here. Note the field hangs\n\t * off the DERIVED ACCOUNT address, not the wrapper address; they are different objects.\n\t *\n\t * Expired grants are never pruned automatically and keep occupying slots, so callers\n\t * managing the {@link MAX_SESSIONS_PER_ACCOUNT} cap should list, drop anything already\n\t * expired, and revoke before granting again.\n\t */\n\tstatic decodeSessions(contents: Uint8Array): SessionGrant[] {\n\t\t// Assert full consumption. `@mysten/bcs`'s ULEB reader indexes the underlying\n\t\t// ArrayBuffer rather than the view, so a truncated SUBARRAY — which is exactly what a\n\t\t// gRPC `content` field is — can read past its bound and decode to `[]` with no error.\n\t\t// Re-serializing and comparing lengths turns both truncation and trailing junk into a\n\t\t// throw, so \"no grants\" can only ever mean no grants.\n\t\tconst field = SessionsDataField.parse(contents);\n\t\tconst reencoded = SessionsDataField.serialize(field).toBytes();\n\t\tif (reencoded.length !== contents.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`sessions field is ${contents.length} bytes but its contents encode to ${reencoded.length}; ` +\n\t\t\t\t\t'the bytes are truncated or carry trailing data',\n\t\t\t);\n\t\t}\n\t\treturn field.value.sessions.contents.map((entry) => ({\n\t\t\tsession: entry.key,\n\t\t\texpiresAtMs: BigInt(entry.value),\n\t\t}));\n\t}\n\n\t/** Grants from {@link decodeSessions} that are still live at `nowMs`. */\n\tstatic activeSessions(grants: readonly SessionGrant[], nowMs: number | bigint): SessionGrant[] {\n\t\tconst now = BigInt(nowMs);\n\t\t// The chain asserts `now < expiresAtMs`, so a grant is dead AT its expiry.\n\t\treturn grants.filter((g) => now < g.expiresAtMs);\n\t}\n\n\t/**\n\t * @description Grants that are already dead at `nowMs` — the complement of\n\t * {@link activeSessions}, and the list to revoke when reclaiming slots. Use this rather\n\t * than filtering by hand: `nowMs > expiresAtMs` looks equivalent but leaves the grant\n\t * expiring exactly at `nowMs` occupying a slot forever.\n\t */\n\tstatic expiredSessions(grants: readonly SessionGrant[], nowMs: number | bigint): SessionGrant[] {\n\t\tconst now = BigInt(nowMs);\n\t\treturn grants.filter((g) => now >= g.expiresAtMs);\n\t}\n}\n\n// === Generated bindings ===\n// NOTE: this namespace carries the DeepBook spot session calls too\n// (`placeLimitOrder`, `placeMarketOrder`, `cancelLiveOrder(s)`, `withdrawSettledAmounts`).\n// They are generated and callable; they are simply not wrapped on `SessionsContract`.\nexport * as sessionsMoveCalls from './contracts/deepbook_sessions/sessions.js';\nexport * as sessionConfigMoveCalls from './contracts/deepbook_sessions/session_config.js';\nexport {\n\tSessionsApp,\n\tSessionsData,\n\tSessionAuthorized,\n\tSessionRevoked,\n} from './contracts/deepbook_sessions/sessions.js';\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { DeepBookConfig } from "../utils/config.mjs";
2
- import * as _mysten_sui_transactions141 from "@mysten/sui/transactions";
2
+ import * as _mysten_sui_transactions48 from "@mysten/sui/transactions";
3
3
  import { Transaction, TransactionArgument } from "@mysten/sui/transactions";
4
4
 
5
5
  //#region src/transactions/balanceManager.d.ts
@@ -21,7 +21,7 @@ declare class BalanceManagerContract {
21
21
  * @description Create a new BalanceManager, manually set the owner. Returns the manager.
22
22
  * @returns A function that takes a Transaction object
23
23
  */
24
- createBalanceManagerWithOwner: (ownerAddress: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
24
+ createBalanceManagerWithOwner: (ownerAddress: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
25
25
  /**
26
26
  * @description Share the BalanceManager
27
27
  * @param {TransactionArgument} manager The BalanceManager to share
@@ -65,38 +65,38 @@ declare class BalanceManagerContract {
65
65
  * @param {string} managerKey The key of the BalanceManager
66
66
  * @returns A function that takes a Transaction object
67
67
  */
68
- generateProof: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
68
+ generateProof: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
69
69
  /**
70
70
  * @description Generate a trade proof as the owner
71
71
  * @param {string} managerId The ID of the BalanceManager
72
72
  * @returns A function that takes a Transaction object
73
73
  */
74
- generateProofAsOwner: (managerId: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
74
+ generateProofAsOwner: (managerId: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
75
75
  /**
76
76
  * @description Generate a trade proof as a trader
77
77
  * @param {string} managerId The ID of the BalanceManager
78
78
  * @param {string} tradeCapId The ID of the tradeCap
79
79
  * @returns A function that takes a Transaction object
80
80
  */
81
- generateProofAsTrader: (managerId: string, tradeCapId: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
81
+ generateProofAsTrader: (managerId: string, tradeCapId: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
82
82
  /**
83
83
  * @description Mint a TradeCap
84
84
  * @param {string} managerKey The name of the BalanceManager
85
85
  * @returns A function that takes a Transaction object
86
86
  */
87
- mintTradeCap: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
87
+ mintTradeCap: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
88
88
  /**
89
89
  * @description Mint a DepositCap
90
90
  * @param {string} managerKey The name of the BalanceManager
91
91
  * @returns A function that takes a Transaction object
92
92
  */
93
- mintDepositCap: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
93
+ mintDepositCap: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
94
94
  /**
95
95
  * @description Mint a WithdrawalCap
96
96
  * @param {string} managerKey The name of the BalanceManager
97
97
  * @returns A function that takes a Transaction object
98
98
  */
99
- mintWithdrawalCap: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
99
+ mintWithdrawalCap: (managerKey: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
100
100
  /**
101
101
  * @description Deposit using the DepositCap
102
102
  * @param {string} managerKey The name of the BalanceManager
@@ -112,7 +112,7 @@ declare class BalanceManagerContract {
112
112
  * @param {number} amountToWithdraw The amount to withdraw
113
113
  * @returns A function that takes a Transaction object
114
114
  */
115
- withdrawWithCap: (managerKey: string, coinKey: string, amountToWithdraw: number) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
115
+ withdrawWithCap: (managerKey: string, coinKey: string, amountToWithdraw: number) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
116
116
  /**
117
117
  * @description Set the referral for the BalanceManager for a specific pool
118
118
  * @param {string} managerKey The name of the BalanceManager
@@ -147,20 +147,20 @@ declare class BalanceManagerContract {
147
147
  * @param {string} referralId The ID of the referral to get the owner of
148
148
  * @returns A function that takes a Transaction object
149
149
  */
150
- balanceManagerReferralOwner: (referralId: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
150
+ balanceManagerReferralOwner: (referralId: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
151
151
  /**
152
152
  * @description Get the pool ID associated with a referral (DeepBookPoolReferral)
153
153
  * @param {string} referralId The ID of the referral to get the pool ID of
154
154
  * @returns A function that takes a Transaction object
155
155
  */
156
- balanceManagerReferralPoolId: (referralId: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
156
+ balanceManagerReferralPoolId: (referralId: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
157
157
  /**
158
158
  * @description Get the referral ID from the balance manager for a specific pool
159
159
  * @param {string} managerKey The name of the BalanceManager
160
160
  * @param {string} poolKey Key of the pool to get the referral for
161
161
  * @returns A function that takes a Transaction object
162
162
  */
163
- getBalanceManagerReferralId: (managerKey: string, poolKey: string) => (tx: Transaction) => _mysten_sui_transactions141.TransactionResult;
163
+ getBalanceManagerReferralId: (managerKey: string, poolKey: string) => (tx: Transaction) => _mysten_sui_transactions48.TransactionResult;
164
164
  /**
165
165
  * @description Revoke a TradeCap. This also revokes the associated DepositCap and WithdrawCap.
166
166
  * @param {string} managerKey The name of the BalanceManager
@@ -1 +1 @@
1
- {"version":3,"file":"balanceManager.d.mts","names":[],"sources":["../../src/transactions/balanceManager.ts"],"mappings":";;;;;;;;cAYa,sBAAA;EAAA;;;;cAMA,MAAA,EAAQ,cAAA;EA6BsD;;;;EArB1E,4BAAA,SAAsC,EAAA,EAAI,WAAA;EAyGwB;;;;EApFlE,6BAAA,GAAiC,YAAA,cAA0B,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EAuIZ;;;;;EAzH9D,mBAAA,GAAuB,OAAA,EAAS,mBAAA,MAAyB,EAAA,EAAI,WAAA;EAsKJ;;;;;;;EArJzD,kBAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,eAAA,cAA6B,EAAA,EAAI,WAAA;EAmQvB;;;;;;;;EAxOjD,mBAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,gBAAA,UAA0B,SAAA,cAC/D,EAAA,EAAI,WAAA;EA2TsE;;;;;;;EArS5E,sBAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,SAAA,cAAuB,EAAA,EAAI,WAAA;EAjHtD;;;;;;EAqIZ,mBAAA,GAAuB,UAAA,UAAoB,OAAA,cAAqB,EAAA,EAAI,WAAA;EAxGT;;;;;EAyH3D,aAAA,GAAiB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EA3GC;;;;;EAyHzD,oBAAA,GAAwB,SAAA,cAAuB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EAvGM;;;;;;EAsHpE,qBAAA,GAAyB,SAAA,UAAmB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EAzFjF;;;;;EAuGF,YAAA,GAAgB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EAhFO;;;;;EAgG9D,cAAA,GAAkB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EA3DzD;;;;;EA2EA,iBAAA,GAAqB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EA7DpC;;;;;;;EA+ExB,cAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,eAAA,cAA6B,EAAA,EAAI,WAAA;EAjEJ;;;;;;;EA+FpE,eAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,gBAAA,cAA8B,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EAlElE;;;;;;;EA4FlB,yBAAA,GACE,UAAA,UAAoB,QAAA,UAAkB,QAAA,EAAU,mBAAA,MAAyB,EAAA,EAAI,WAAA;EA7EnB;;;;;;;EA8F5D,2BAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,QAAA,EAAU,mBAAA,MAAyB,EAAA,EAAI,WAAA;EAW9E,sBAAA,GAA0B,UAAA,cAAwB,EAAA,EAAI,WAAA;EAxDhC;;;;;EAuEtB,KAAA,GAAS,UAAA,cAAwB,EAAA,EAAI,WAAA;EA5CnC;;;;;EA2DF,EAAA,GAAM,UAAA,cAAwB,EAAA,EAAI,WAAA;EA1ClC;;;;;EAyDA,2BAAA,GAA+B,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EAxDI;;;;;EAsE1E,4BAAA,GAAgC,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EA5C9D;;;;;;EA2DT,2BAAA,GAA+B,UAAA,UAAoB,OAAA,cAAqB,EAAA,EAAI,WAAA,KAAW,2BAAA,CAAA,iBAAA;EA7BvF;;;;;;EA8CA,cAAA,GAAkB,UAAA,UAAoB,UAAA,cAAwB,EAAA,EAAI,WAAA;AAAA"}
1
+ {"version":3,"file":"balanceManager.d.mts","names":[],"sources":["../../src/transactions/balanceManager.ts"],"mappings":";;;;;;;;cAYa,sBAAA;EAAA;;;;cAMA,MAAA,EAAQ,cAAA;EA6BsD;;;;EArB1E,4BAAA,SAAsC,EAAA,EAAI,WAAA;EAyGwB;;;;EApFlE,6BAAA,GAAiC,YAAA,cAA0B,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EAuIZ;;;;;EAzH9D,mBAAA,GAAuB,OAAA,EAAS,mBAAA,MAAyB,EAAA,EAAI,WAAA;EAsKJ;;;;;;;EArJzD,kBAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,eAAA,cAA6B,EAAA,EAAI,WAAA;EAmQvB;;;;;;;;EAxOjD,mBAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,gBAAA,UAA0B,SAAA,cAC/D,EAAA,EAAI,WAAA;EA2TsE;;;;;;;EArS5E,sBAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,SAAA,cAAuB,EAAA,EAAI,WAAA;EAjHtD;;;;;;EAqIZ,mBAAA,GAAuB,UAAA,UAAoB,OAAA,cAAqB,EAAA,EAAI,WAAA;EAxGT;;;;;EAyH3D,aAAA,GAAiB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EA3GC;;;;;EAyHzD,oBAAA,GAAwB,SAAA,cAAuB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EAvGM;;;;;;EAsHpE,qBAAA,GAAyB,SAAA,UAAmB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EAzFjF;;;;;EAuGF,YAAA,GAAgB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EAhFO;;;;;EAgG9D,cAAA,GAAkB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EA3DzD;;;;;EA2EA,iBAAA,GAAqB,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EA7DpC;;;;;;;EA+ExB,cAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,eAAA,cAA6B,EAAA,EAAI,WAAA;EAjEJ;;;;;;;EA+FpE,eAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,gBAAA,cAA8B,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EAlElE;;;;;;;EA4FlB,yBAAA,GACE,UAAA,UAAoB,QAAA,UAAkB,QAAA,EAAU,mBAAA,MAAyB,EAAA,EAAI,WAAA;EA7EnB;;;;;;;EA8F5D,2BAAA,GACE,UAAA,UAAoB,OAAA,UAAiB,QAAA,EAAU,mBAAA,MAAyB,EAAA,EAAI,WAAA;EAW9E,sBAAA,GAA0B,UAAA,cAAwB,EAAA,EAAI,WAAA;EAxDhC;;;;;EAuEtB,KAAA,GAAS,UAAA,cAAwB,EAAA,EAAI,WAAA;EA5CnC;;;;;EA2DF,EAAA,GAAM,UAAA,cAAwB,EAAA,EAAI,WAAA;EA1ClC;;;;;EAyDA,2BAAA,GAA+B,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EAxDI;;;;;EAsE1E,4BAAA,GAAgC,UAAA,cAAwB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EA5C9D;;;;;;EA2DT,2BAAA,GAA+B,UAAA,UAAoB,OAAA,cAAqB,EAAA,EAAI,WAAA,KAAW,0BAAA,CAAA,iBAAA;EA7BvF;;;;;;EA8CA,cAAA,GAAkB,UAAA,UAAoB,UAAA,cAAwB,EAAA,EAAI,WAAA;AAAA"}