@mysten/deepbook-v3 2.0.1 → 2.1.3

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 (272) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/PREDICT.md +256 -0
  3. package/README.md +116 -0
  4. package/dist/account.d.mts +139 -0
  5. package/dist/account.d.mts.map +1 -0
  6. package/dist/account.mjs +181 -0
  7. package/dist/account.mjs.map +1 -0
  8. package/dist/bcs/integers.mjs +23 -0
  9. package/dist/bcs/integers.mjs.map +1 -0
  10. package/dist/contracts/account/account.d.mts +382 -0
  11. package/dist/contracts/account/account.d.mts.map +1 -0
  12. package/dist/contracts/account/account.mjs +443 -0
  13. package/dist/contracts/account/account.mjs.map +1 -0
  14. package/dist/contracts/account/account_events.d.mts +41 -0
  15. package/dist/contracts/account/account_events.d.mts.map +1 -0
  16. package/dist/contracts/account/account_events.mjs +72 -0
  17. package/dist/contracts/account/account_events.mjs.map +1 -0
  18. package/dist/contracts/account/account_registry.d.mts +210 -0
  19. package/dist/contracts/account/account_registry.d.mts.map +1 -0
  20. package/dist/contracts/account/account_registry.mjs +263 -0
  21. package/dist/contracts/account/account_registry.mjs.map +1 -0
  22. package/dist/contracts/account/config-arguments.d.mts +10 -0
  23. package/dist/contracts/account/config-arguments.d.mts.map +1 -0
  24. package/dist/contracts/account/deps/sui/bag.mjs +44 -0
  25. package/dist/contracts/account/deps/sui/bag.mjs.map +1 -0
  26. package/dist/contracts/deepbook/account.d.mts +18 -18
  27. package/dist/contracts/deepbook/balances.d.mts +4 -4
  28. package/dist/contracts/deepbook/deep_price.d.mts +3 -3
  29. package/dist/contracts/deepbook/deep_price.d.mts.map +1 -1
  30. package/dist/contracts/deepbook/order.d.mts +12 -12
  31. package/dist/contracts/deepbook_predict/builder_code_events.mjs +38 -0
  32. package/dist/contracts/deepbook_predict/builder_code_events.mjs.map +1 -0
  33. package/dist/contracts/deepbook_predict/config-arguments.d.mts +13 -0
  34. package/dist/contracts/deepbook_predict/config-arguments.d.mts.map +1 -0
  35. package/dist/contracts/deepbook_predict/deps/fixed_math/i64.mjs +25 -0
  36. package/dist/contracts/deepbook_predict/deps/fixed_math/i64.mjs.map +1 -0
  37. package/dist/contracts/deepbook_predict/deps/sui/balance.mjs +25 -0
  38. package/dist/contracts/deepbook_predict/deps/sui/balance.mjs.map +1 -0
  39. package/dist/contracts/deepbook_predict/deps/sui/coin.mjs +24 -0
  40. package/dist/contracts/deepbook_predict/deps/sui/coin.mjs.map +1 -0
  41. package/dist/contracts/deepbook_predict/deps/sui/table.mjs +39 -0
  42. package/dist/contracts/deepbook_predict/deps/sui/table.mjs.map +1 -0
  43. package/dist/contracts/deepbook_predict/deps/sui/vec_set.mjs +26 -0
  44. package/dist/contracts/deepbook_predict/deps/sui/vec_set.mjs.map +1 -0
  45. package/dist/contracts/deepbook_predict/ewma.mjs +29 -0
  46. package/dist/contracts/deepbook_predict/ewma.mjs.map +1 -0
  47. package/dist/contracts/deepbook_predict/expiry_cash.mjs +27 -0
  48. package/dist/contracts/deepbook_predict/expiry_cash.mjs.map +1 -0
  49. package/dist/contracts/deepbook_predict/expiry_market.mjs +367 -0
  50. package/dist/contracts/deepbook_predict/expiry_market.mjs.map +1 -0
  51. package/dist/contracts/deepbook_predict/lp_book.mjs +92 -0
  52. package/dist/contracts/deepbook_predict/lp_book.mjs.map +1 -0
  53. package/dist/contracts/deepbook_predict/market_manager.mjs +59 -0
  54. package/dist/contracts/deepbook_predict/market_manager.mjs.map +1 -0
  55. package/dist/contracts/deepbook_predict/order.mjs +26 -0
  56. package/dist/contracts/deepbook_predict/order.mjs.map +1 -0
  57. package/dist/contracts/deepbook_predict/order_events.mjs +84 -0
  58. package/dist/contracts/deepbook_predict/order_events.mjs.map +1 -0
  59. package/dist/contracts/deepbook_predict/plp.mjs +284 -0
  60. package/dist/contracts/deepbook_predict/plp.mjs.map +1 -0
  61. package/dist/contracts/deepbook_predict/pool_accounting.mjs +58 -0
  62. package/dist/contracts/deepbook_predict/pool_accounting.mjs.map +1 -0
  63. package/dist/contracts/deepbook_predict/predict_account.mjs +106 -0
  64. package/dist/contracts/deepbook_predict/predict_account.mjs.map +1 -0
  65. package/dist/contracts/deepbook_predict/pricing.mjs +80 -0
  66. package/dist/contracts/deepbook_predict/pricing.mjs.map +1 -0
  67. package/dist/contracts/deepbook_predict/range_codec.mjs +41 -0
  68. package/dist/contracts/deepbook_predict/range_codec.mjs.map +1 -0
  69. package/dist/contracts/deepbook_predict/registry.mjs +55 -0
  70. package/dist/contracts/deepbook_predict/registry.mjs.map +1 -0
  71. package/dist/contracts/deepbook_predict/strike_exposure.mjs +65 -0
  72. package/dist/contracts/deepbook_predict/strike_exposure.mjs.map +1 -0
  73. package/dist/contracts/deepbook_predict/strike_exposure_config.mjs +33 -0
  74. package/dist/contracts/deepbook_predict/strike_exposure_config.mjs.map +1 -0
  75. package/dist/contracts/deepbook_predict/strike_payout_tree.mjs +72 -0
  76. package/dist/contracts/deepbook_predict/strike_payout_tree.mjs.map +1 -0
  77. package/dist/contracts/deepbook_predict/vault_events.mjs +184 -0
  78. package/dist/contracts/deepbook_predict/vault_events.mjs.map +1 -0
  79. package/dist/contracts/deepbook_sessions/config-arguments.d.mts +10 -0
  80. package/dist/contracts/deepbook_sessions/config-arguments.d.mts.map +1 -0
  81. package/dist/contracts/deepbook_sessions/deps/sui/vec_map.mjs +37 -0
  82. package/dist/contracts/deepbook_sessions/deps/sui/vec_map.mjs.map +1 -0
  83. package/dist/contracts/deepbook_sessions/session_config.d.mts +63 -0
  84. package/dist/contracts/deepbook_sessions/session_config.d.mts.map +1 -0
  85. package/dist/contracts/deepbook_sessions/session_config.mjs +82 -0
  86. package/dist/contracts/deepbook_sessions/session_config.mjs.map +1 -0
  87. package/dist/contracts/deepbook_sessions/sessions.d.mts +275 -0
  88. package/dist/contracts/deepbook_sessions/sessions.d.mts.map +1 -0
  89. package/dist/contracts/deepbook_sessions/sessions.mjs +443 -0
  90. package/dist/contracts/deepbook_sessions/sessions.mjs.map +1 -0
  91. package/dist/contracts/utils/index.d.mts +18 -1
  92. package/dist/contracts/utils/index.d.mts.map +1 -1
  93. package/dist/deployments/index.d.mts +31 -0
  94. package/dist/deployments/index.d.mts.map +1 -0
  95. package/dist/deployments/index.mjs +30 -0
  96. package/dist/deployments/index.mjs.map +1 -0
  97. package/dist/deployments/testnet.d.mts +14 -0
  98. package/dist/deployments/testnet.d.mts.map +1 -0
  99. package/dist/deployments/testnet.mjs +73 -0
  100. package/dist/deployments/testnet.mjs.map +1 -0
  101. package/dist/deployments/types.d.mts +36 -0
  102. package/dist/deployments/types.d.mts.map +1 -0
  103. package/dist/index.mjs +0 -1
  104. package/dist/predict/client.d.mts +255 -0
  105. package/dist/predict/client.d.mts.map +1 -0
  106. package/dist/predict/client.mjs +436 -0
  107. package/dist/predict/client.mjs.map +1 -0
  108. package/dist/predict/config/generated.d.mts +29 -0
  109. package/dist/predict/config/generated.d.mts.map +1 -0
  110. package/dist/predict/config/generated.mjs +16 -0
  111. package/dist/predict/config/generated.mjs.map +1 -0
  112. package/dist/predict/config/index.d.mts +10 -0
  113. package/dist/predict/config/index.d.mts.map +1 -0
  114. package/dist/predict/config/index.mjs +13 -0
  115. package/dist/predict/config/index.mjs.map +1 -0
  116. package/dist/predict/config/testnet.d.mts +17 -0
  117. package/dist/predict/config/testnet.d.mts.map +1 -0
  118. package/dist/predict/config/testnet.mjs +26 -0
  119. package/dist/predict/config/testnet.mjs.map +1 -0
  120. package/dist/predict/config/types.d.mts +55 -0
  121. package/dist/predict/config/types.d.mts.map +1 -0
  122. package/dist/predict/decode.d.mts +162 -0
  123. package/dist/predict/decode.d.mts.map +1 -0
  124. package/dist/predict/decode.mjs +175 -0
  125. package/dist/predict/decode.mjs.map +1 -0
  126. package/dist/predict/errors.d.mts +42 -0
  127. package/dist/predict/errors.d.mts.map +1 -0
  128. package/dist/predict/errors.mjs +37 -0
  129. package/dist/predict/errors.mjs.map +1 -0
  130. package/dist/predict/index.d.mts +18 -0
  131. package/dist/predict/index.mjs +14 -0
  132. package/dist/predict/pricing.d.mts +73 -0
  133. package/dist/predict/pricing.d.mts.map +1 -0
  134. package/dist/predict/pricing.mjs +129 -0
  135. package/dist/predict/pricing.mjs.map +1 -0
  136. package/dist/predict/reads/balances.mjs +41 -0
  137. package/dist/predict/reads/balances.mjs.map +1 -0
  138. package/dist/predict/reads/inspect.d.mts +8 -0
  139. package/dist/predict/reads/inspect.d.mts.map +1 -0
  140. package/dist/predict/reads/inspect.mjs +37 -0
  141. package/dist/predict/reads/inspect.mjs.map +1 -0
  142. package/dist/predict/reads/markets.mjs +130 -0
  143. package/dist/predict/reads/markets.mjs.map +1 -0
  144. package/dist/predict/reads/parse.mjs +20 -0
  145. package/dist/predict/reads/parse.mjs.map +1 -0
  146. package/dist/predict/reads/pool.mjs +26 -0
  147. package/dist/predict/reads/pool.mjs.map +1 -0
  148. package/dist/predict/reads/positions.d.mts +12 -0
  149. package/dist/predict/reads/positions.d.mts.map +1 -0
  150. package/dist/predict/reads/positions.mjs +77 -0
  151. package/dist/predict/reads/positions.mjs.map +1 -0
  152. package/dist/predict/reads/pricing.d.mts +20 -0
  153. package/dist/predict/reads/pricing.d.mts.map +1 -0
  154. package/dist/predict/reads/pricing.mjs +43 -0
  155. package/dist/predict/reads/pricing.mjs.map +1 -0
  156. package/dist/predict/ticks.d.mts +11 -0
  157. package/dist/predict/ticks.d.mts.map +1 -0
  158. package/dist/predict/ticks.mjs +21 -0
  159. package/dist/predict/ticks.mjs.map +1 -0
  160. package/dist/predict/tx/authed.mjs +18 -0
  161. package/dist/predict/tx/authed.mjs.map +1 -0
  162. package/dist/predict/tx/common.d.mts +18 -0
  163. package/dist/predict/tx/common.d.mts.map +1 -0
  164. package/dist/predict/tx/common.mjs +52 -0
  165. package/dist/predict/tx/common.mjs.map +1 -0
  166. package/dist/predict/tx/trade.d.mts +15 -0
  167. package/dist/predict/tx/trade.d.mts.map +1 -0
  168. package/dist/predict/tx/trade.mjs +86 -0
  169. package/dist/predict/tx/trade.mjs.map +1 -0
  170. package/dist/predict/units.d.mts +11 -0
  171. package/dist/predict/units.d.mts.map +1 -0
  172. package/dist/predict/units.mjs +44 -0
  173. package/dist/predict/units.mjs.map +1 -0
  174. package/dist/queries/accountQueries.mjs +0 -1
  175. package/dist/queries/accountQueries.mjs.map +1 -1
  176. package/dist/queries/orderQueries.mjs +0 -1
  177. package/dist/queries/orderQueries.mjs.map +1 -1
  178. package/dist/queries/registryQueries.mjs +0 -1
  179. package/dist/queries/registryQueries.mjs.map +1 -1
  180. package/dist/sessions.d.mts +244 -0
  181. package/dist/sessions.d.mts.map +1 -0
  182. package/dist/sessions.mjs +291 -0
  183. package/dist/sessions.mjs.map +1 -0
  184. package/dist/transactions/balanceManager.d.mts +12 -12
  185. package/dist/transactions/balanceManager.d.mts.map +1 -1
  186. package/dist/transactions/deepbook.d.mts +20 -20
  187. package/dist/transactions/deepbook.d.mts.map +1 -1
  188. package/dist/transactions/deepbookAdmin.d.mts +4 -4
  189. package/dist/transactions/marginAdmin.d.mts +7 -7
  190. package/dist/transactions/marginLiquidations.d.mts +3 -3
  191. package/dist/transactions/marginMaintainer.d.mts +5 -5
  192. package/dist/transactions/marginManager.d.mts +32 -32
  193. package/dist/transactions/marginPool.d.mts +18 -18
  194. package/dist/transactions/marginRegistry.d.mts +16 -16
  195. package/dist/transactions/marginTPSL.d.mts +10 -10
  196. package/dist/transactions/poolProxy.d.mts +8 -8
  197. package/package.json +25 -4
  198. package/src/account.ts +239 -0
  199. package/src/bcs/integers.ts +35 -0
  200. package/src/contracts/account/account.ts +706 -0
  201. package/src/contracts/account/account_events.ts +64 -0
  202. package/src/contracts/account/account_registry.ts +468 -0
  203. package/src/contracts/account/config-arguments.ts +8 -0
  204. package/src/contracts/account/deps/sui/bag.ts +42 -0
  205. package/src/contracts/deepbook_predict/admin.ts +44 -0
  206. package/src/contracts/deepbook_predict/builder_code.ts +155 -0
  207. package/src/contracts/deepbook_predict/builder_code_events.ts +34 -0
  208. package/src/contracts/deepbook_predict/config-arguments.ts +11 -0
  209. package/src/contracts/deepbook_predict/config_events.ts +140 -0
  210. package/src/contracts/deepbook_predict/deps/fixed_math/i64.ts +21 -0
  211. package/src/contracts/deepbook_predict/deps/sui/balance.ts +25 -0
  212. package/src/contracts/deepbook_predict/deps/sui/coin.ts +20 -0
  213. package/src/contracts/deepbook_predict/deps/sui/table.ts +37 -0
  214. package/src/contracts/deepbook_predict/deps/sui/vec_set.ts +22 -0
  215. package/src/contracts/deepbook_predict/ewma.ts +26 -0
  216. package/src/contracts/deepbook_predict/ewma_config.ts +28 -0
  217. package/src/contracts/deepbook_predict/expiry_cash.ts +24 -0
  218. package/src/contracts/deepbook_predict/expiry_market.ts +1549 -0
  219. package/src/contracts/deepbook_predict/lp_book.ts +105 -0
  220. package/src/contracts/deepbook_predict/market_lifecycle_cap.ts +75 -0
  221. package/src/contracts/deepbook_predict/market_manager.ts +218 -0
  222. package/src/contracts/deepbook_predict/order.ts +24 -0
  223. package/src/contracts/deepbook_predict/order_events.ts +129 -0
  224. package/src/contracts/deepbook_predict/pause_cap.ts +68 -0
  225. package/src/contracts/deepbook_predict/plp.ts +987 -0
  226. package/src/contracts/deepbook_predict/pool_accounting.ts +79 -0
  227. package/src/contracts/deepbook_predict/predict_account.ts +180 -0
  228. package/src/contracts/deepbook_predict/pricing.ts +124 -0
  229. package/src/contracts/deepbook_predict/pricing_config.ts +41 -0
  230. package/src/contracts/deepbook_predict/protocol_config.ts +1066 -0
  231. package/src/contracts/deepbook_predict/range_codec.ts +53 -0
  232. package/src/contracts/deepbook_predict/registry.ts +694 -0
  233. package/src/contracts/deepbook_predict/strike_exposure.ts +77 -0
  234. package/src/contracts/deepbook_predict/strike_exposure_config.ts +46 -0
  235. package/src/contracts/deepbook_predict/strike_payout_tree.ts +89 -0
  236. package/src/contracts/deepbook_predict/vault_events.ts +222 -0
  237. package/src/contracts/deepbook_sessions/config-arguments.ts +8 -0
  238. package/src/contracts/deepbook_sessions/deps/sui/vec_map.ts +33 -0
  239. package/src/contracts/deepbook_sessions/session_config.ts +130 -0
  240. package/src/contracts/deepbook_sessions/sessions.ts +663 -0
  241. package/src/contracts/propbook/block_scholes_store.ts +842 -0
  242. package/src/contracts/propbook/deps/sui/table.ts +37 -0
  243. package/src/contracts/propbook/oracle_lane.ts +170 -0
  244. package/src/contracts/propbook/pyth_feed.ts +414 -0
  245. package/src/contracts/propbook/registry.ts +596 -0
  246. package/src/deployments/index.ts +73 -0
  247. package/src/deployments/testnet.ts +107 -0
  248. package/src/deployments/types.ts +81 -0
  249. package/src/index.ts +5 -0
  250. package/src/predict/client.ts +941 -0
  251. package/src/predict/config/generated.ts +39 -0
  252. package/src/predict/config/index.ts +25 -0
  253. package/src/predict/config/testnet.ts +27 -0
  254. package/src/predict/config/types.ts +52 -0
  255. package/src/predict/decode.ts +476 -0
  256. package/src/predict/errors.ts +83 -0
  257. package/src/predict/index.ts +94 -0
  258. package/src/predict/pricing.ts +199 -0
  259. package/src/predict/reads/balances.ts +55 -0
  260. package/src/predict/reads/inspect.ts +78 -0
  261. package/src/predict/reads/markets.ts +222 -0
  262. package/src/predict/reads/parse.ts +30 -0
  263. package/src/predict/reads/pool.ts +37 -0
  264. package/src/predict/reads/positions.ts +144 -0
  265. package/src/predict/reads/pricing.ts +79 -0
  266. package/src/predict/ticks.ts +42 -0
  267. package/src/predict/tx/authed.ts +20 -0
  268. package/src/predict/tx/common.ts +92 -0
  269. package/src/predict/tx/trade.ts +183 -0
  270. package/src/predict/units.ts +49 -0
  271. package/src/sessions.ts +471 -0
  272. package/dist/types/bcs.mjs +0 -7
@@ -0,0 +1,73 @@
1
+ declare namespace pricing_d_exports {
2
+ export { BoardPricer, PricerInputs, Svi, boardPricer, downProbability, forward, probability, rangeProbability, rollDown, strikeAtProbability, upProbability };
3
+ }
4
+ /** Rolled-down SVI parameters for one expiry, in decimal (NOT the chain's 1e9/1e18 integer
5
+ * scaling) — the surface AFTER Predict's remaining-time roll-down, as carried by the
6
+ * on-chain `Pricer`. `a`, `rho`, `m` are signed; `b`, `sigma` are non-negative. */
7
+ interface Svi {
8
+ a: number;
9
+ b: number;
10
+ rho: number;
11
+ m: number;
12
+ sigma: number;
13
+ }
14
+ /** A resolved pricer snapshot: the forward the contract prices against and its rolled SVI
15
+ * surface, both in decimal. Produced by `read.pricer(market)`; consume via {@link boardPricer}
16
+ * or the pure functions below. */
17
+ interface PricerInputs {
18
+ /** Forward price the digital settles against, in decimal (same units as `strike`). */
19
+ forward: number;
20
+ svi: Svi;
21
+ }
22
+ /** P(settle > strike) — the UP digital, with the SVI skew correction. `inputs.svi` is the
23
+ * already-rolled surface (no roll-down applied here). `forward` and `strike` share units.
24
+ * Returns a probability in [0, 1]. */
25
+ declare function upProbability(inputs: PricerInputs, strike: number): number;
26
+ /** P(settle < strike) — the DOWN digital. Exactly `1 − up`, matching the chain's
27
+ * `range_price(-inf, strike] = up(-inf) − up(strike) = 1 − up(strike)`. */
28
+ declare function downProbability(inputs: PricerInputs, strike: number): number;
29
+ /** Probability mass in `(lower, higher]`, floored at 0 (matches `compute_range_price`'s
30
+ * saturating subtraction). Use `lower <= 0` for the −∞ bound and `higher = Infinity` for +∞. */
31
+ declare function rangeProbability(inputs: PricerInputs, lower: number, higher: number): number;
32
+ /** Binary probability at `strike` for the given side (`up` = P(>strike), `down` = 1 − up). */
33
+ declare function probability(inputs: PricerInputs, strike: number, side: 'up' | 'down'): number;
34
+ /** Strike where P(settle > strike) = `p`, by bisection (UP is monotone-decreasing in
35
+ * strike). Null when no crossing exists within ±64% of forward. */
36
+ declare function strikeAtProbability(inputs: PricerInputs, p: number): number | null;
37
+ /** Roll `a` and `b` down by the fraction of anchored time remaining, matching the chain's
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. */
45
+ declare function rollDown(svi: Svi, remainingMs: number, anchorTteMs: number): Svi;
46
+ /** The forward the contract prices against: Pyth spot re-anchored by the Block-Scholes
47
+ * basis (`spot · forward/bsSpot`), falling back to the Block-Scholes forward when Pyth is
48
+ * absent. Pass `pythSpot <= 0` to force the fallback. NOTE: on-chain this branch is also
49
+ * gated by the admin flag `use_pyth_spot_for_forward` (default on) and a Pyth freshness
50
+ * window — when the flag is off or the Pyth spot is stale, the chain uses `bsForward`. If
51
+ * you track that config/freshness, apply it before calling (or use `read.pricer`, which
52
+ * gets the resolved forward from the chain). */
53
+ declare function forward(pythSpot: number, bsSpot: number, bsForward: number): number;
54
+ /** A pricer bound to one resolved snapshot: price a whole board of strikes locally, no
55
+ * chain calls. Returned by `read.pricer(market)`; also constructable directly from inputs
56
+ * you already hold (e.g. from a `Pricer` snapshot decoded elsewhere). */
57
+ interface BoardPricer extends PricerInputs {
58
+ /** P(settle > strike). */
59
+ up(strike: number): number;
60
+ /** P(settle < strike) = 1 − up. */
61
+ down(strike: number): number;
62
+ /** P(side wins at strike). */
63
+ probability(strike: number, side: 'up' | 'down'): number;
64
+ /** Probability mass in `(lower, higher]` (use `lower<=0`/`higher=Infinity` for the tails). */
65
+ range(lower: number, higher: number): number;
66
+ /** Strike where P(> strike) = `p`, or null if outside ±64% of forward. */
67
+ strikeAtProbability(p: number): number | null;
68
+ }
69
+ /** Build a {@link BoardPricer} from a resolved snapshot (decimal forward + rolled SVI). Pure. */
70
+ declare function boardPricer(inputs: PricerInputs): BoardPricer;
71
+ //#endregion
72
+ export { BoardPricer, PricerInputs, pricing_d_exports };
73
+ //# sourceMappingURL=pricing.d.mts.map
@@ -0,0 +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"}
@@ -0,0 +1,129 @@
1
+ import { __exportAll } from "../_virtual/rolldown_runtime.mjs";
2
+
3
+ //#region src/predict/pricing.ts
4
+ var pricing_exports = /* @__PURE__ */ __exportAll({
5
+ boardPricer: () => boardPricer,
6
+ downProbability: () => downProbability,
7
+ forward: () => forward,
8
+ probability: () => probability,
9
+ rangeProbability: () => rangeProbability,
10
+ rollDown: () => rollDown,
11
+ strikeAtProbability: () => strikeAtProbability,
12
+ upProbability: () => upProbability
13
+ });
14
+ /** Standard normal CDF via erf (Abramowitz–Stegun 7.1.26, |err| < 1.5e-7). */
15
+ function normalCdf(x) {
16
+ return .5 * (1 + erf(x / Math.SQRT2));
17
+ }
18
+ /** Standard normal PDF. */
19
+ function normalPdf(x) {
20
+ return Math.exp(-.5 * x * x) / Math.sqrt(2 * Math.PI);
21
+ }
22
+ function erf(x) {
23
+ const sign = x >= 0 ? 1 : -1;
24
+ const ax = Math.abs(x);
25
+ const t = 1 / (1 + .3275911 * ax);
26
+ return sign * (1 - ((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - .284496736) * t + .254829592) * t * Math.exp(-ax * ax));
27
+ }
28
+ function clampD2(d2) {
29
+ return d2 > 8 ? 8 : d2 < -8 ? -8 : d2;
30
+ }
31
+ /** P(settle > strike) — the UP digital, with the SVI skew correction. `inputs.svi` is the
32
+ * already-rolled surface (no roll-down applied here). `forward` and `strike` share units.
33
+ * Returns a probability in [0, 1]. */
34
+ function upProbability(inputs, strike) {
35
+ const { forward: forward$1, svi } = inputs;
36
+ if (!(forward$1 > 0)) return 0;
37
+ if (strike <= 0) return 1;
38
+ const { a, b, rho, m, sigma } = svi;
39
+ const k = Math.log(strike / forward$1);
40
+ const km = k - m;
41
+ const root = Math.sqrt(km * km + sigma * sigma);
42
+ const w = a + b * (rho * km + root);
43
+ if (w <= 0) return k < 0 ? 1 : 0;
44
+ const sq = Math.sqrt(w);
45
+ const d2 = clampD2(-((k + w / 2) / sq));
46
+ const nd2 = normalCdf(d2);
47
+ const wPrime = b * (rho + km / root);
48
+ const price = nd2 - normalPdf(d2) * wPrime / (2 * sq);
49
+ return price < 0 ? 0 : price > 1 ? 1 : price;
50
+ }
51
+ /** P(settle < strike) — the DOWN digital. Exactly `1 − up`, matching the chain's
52
+ * `range_price(-inf, strike] = up(-inf) − up(strike) = 1 − up(strike)`. */
53
+ function downProbability(inputs, strike) {
54
+ return 1 - upProbability(inputs, strike);
55
+ }
56
+ /** Probability mass in `(lower, higher]`, floored at 0 (matches `compute_range_price`'s
57
+ * saturating subtraction). Use `lower <= 0` for the −∞ bound and `higher = Infinity` for +∞. */
58
+ function rangeProbability(inputs, lower, higher) {
59
+ const d = (lower <= 0 ? 1 : upProbability(inputs, lower)) - (higher === Infinity ? 0 : upProbability(inputs, higher));
60
+ return d < 0 ? 0 : d;
61
+ }
62
+ /** Binary probability at `strike` for the given side (`up` = P(>strike), `down` = 1 − up). */
63
+ function probability(inputs, strike, side) {
64
+ const up = upProbability(inputs, strike);
65
+ return side === "up" ? up : 1 - up;
66
+ }
67
+ /** Strike where P(settle > strike) = `p`, by bisection (UP is monotone-decreasing in
68
+ * strike). Null when no crossing exists within ±64% of forward. */
69
+ function strikeAtProbability(inputs, p) {
70
+ const { forward: forward$1 } = inputs;
71
+ if (!(forward$1 > 0) || !(p > 0 && p < 1)) return null;
72
+ const up = (strike) => upProbability(inputs, strike);
73
+ let r = .01;
74
+ while (up(forward$1 * (1 - r)) < p || up(forward$1 * (1 + r)) > p) {
75
+ r *= 2;
76
+ if (r > .64) return null;
77
+ }
78
+ let lo = forward$1 * (1 - r);
79
+ let hi = forward$1 * (1 + r);
80
+ for (let i = 0; i < 64; i++) {
81
+ const mid = (lo + hi) / 2;
82
+ if (up(mid) > p) lo = mid;
83
+ else hi = mid;
84
+ }
85
+ return (lo + hi) / 2;
86
+ }
87
+ /** Roll `a` and `b` down by the fraction of anchored time remaining, matching the chain's
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. */
95
+ function rollDown(svi, remainingMs, anchorTteMs) {
96
+ const frac = anchorTteMs > 0 ? remainingMs / anchorTteMs : 0;
97
+ return {
98
+ ...svi,
99
+ a: svi.a * frac,
100
+ b: svi.b * frac
101
+ };
102
+ }
103
+ /** The forward the contract prices against: Pyth spot re-anchored by the Block-Scholes
104
+ * basis (`spot · forward/bsSpot`), falling back to the Block-Scholes forward when Pyth is
105
+ * absent. Pass `pythSpot <= 0` to force the fallback. NOTE: on-chain this branch is also
106
+ * gated by the admin flag `use_pyth_spot_for_forward` (default on) and a Pyth freshness
107
+ * window — when the flag is off or the Pyth spot is stale, the chain uses `bsForward`. If
108
+ * you track that config/freshness, apply it before calling (or use `read.pricer`, which
109
+ * gets the resolved forward from the chain). */
110
+ function forward(pythSpot, bsSpot, bsForward) {
111
+ if (pythSpot > 0 && bsSpot > 0) return pythSpot * (bsForward / bsSpot);
112
+ return bsForward;
113
+ }
114
+ /** Build a {@link BoardPricer} from a resolved snapshot (decimal forward + rolled SVI). Pure. */
115
+ function boardPricer(inputs) {
116
+ return {
117
+ forward: inputs.forward,
118
+ svi: inputs.svi,
119
+ up: (strike) => upProbability(inputs, strike),
120
+ down: (strike) => downProbability(inputs, strike),
121
+ probability: (strike, side) => probability(inputs, strike, side),
122
+ range: (lower, higher) => rangeProbability(inputs, lower, higher),
123
+ strikeAtProbability: (p) => strikeAtProbability(inputs, p)
124
+ };
125
+ }
126
+
127
+ //#endregion
128
+ export { boardPricer, pricing_exports };
129
+ //# sourceMappingURL=pricing.mjs.map
@@ -0,0 +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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"}
@@ -0,0 +1,41 @@
1
+ import { balance, loadAccount } from "../../contracts/account/account.mjs";
2
+ import { inspectReturns } from "./inspect.mjs";
3
+ import { deriveAccountWrapperIdFrom } from "../tx/common.mjs";
4
+ import { hasPosition as hasPosition$1 } from "../../contracts/deepbook_predict/predict_account.mjs";
5
+ import { parseU64LE } from "./parse.mjs";
6
+ import { Transaction } from "@mysten/sui/transactions";
7
+
8
+ //#region src/predict/reads/balances.ts
9
+ async function accountBalance(client, config, owner, coinType) {
10
+ const tx = new Transaction();
11
+ const acct = tx.add(loadAccount({
12
+ config,
13
+ arguments: { self: deriveAccountWrapperIdFrom(config, owner) }
14
+ }));
15
+ tx.add(balance({
16
+ config,
17
+ typeArguments: [coinType],
18
+ arguments: { self: acct }
19
+ }));
20
+ return parseU64LE((await inspectReturns(client, tx))[1][0]);
21
+ }
22
+ async function hasPosition(client, config, owner, marketId, orderId) {
23
+ const tx = new Transaction();
24
+ const acct = tx.add(loadAccount({
25
+ config,
26
+ arguments: { self: deriveAccountWrapperIdFrom(config, owner) }
27
+ }));
28
+ tx.add(hasPosition$1({
29
+ config,
30
+ arguments: {
31
+ account: acct,
32
+ expiryMarketId: marketId,
33
+ orderId
34
+ }
35
+ }));
36
+ return ((await inspectReturns(client, tx))[1][0][0] ?? 0) !== 0;
37
+ }
38
+
39
+ //#endregion
40
+ export { accountBalance, hasPosition };
41
+ //# sourceMappingURL=balances.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,8 @@
1
+ import { Transaction } from "@mysten/sui/transactions";
2
+ import { ClientWithCoreApi } from "@mysten/sui/client";
3
+
4
+ //#region src/predict/reads/inspect.d.ts
5
+ type ReadClient = ClientWithCoreApi;
6
+ //#endregion
7
+ export { ReadClient };
8
+ //# sourceMappingURL=inspect.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.mts","names":[],"sources":["../../../src/predict/reads/inspect.ts"],"mappings":";;;;KAUY,UAAA,GAAa,iBAAA"}
@@ -0,0 +1,37 @@
1
+ import { decodeMoveAbort } from "../errors.mjs";
2
+ import { normalizeSuiAddress } from "@mysten/sui/utils";
3
+
4
+ //#region src/predict/reads/inspect.ts
5
+ function throwSimFailure(failed) {
6
+ const status = failed?.status;
7
+ const error = status && status.success === false ? status.error : void 0;
8
+ const decoded = error ? decodeMoveAbort(error) : null;
9
+ if (decoded) throw decoded;
10
+ throw new Error(error?.message ?? "simulateTransaction aborted (FailedTransaction)");
11
+ }
12
+ async function simulateWithEvents(client, tx, sender) {
13
+ tx.setSender(sender);
14
+ const result = await client.core.simulateTransaction({
15
+ transaction: tx,
16
+ checksEnabled: false,
17
+ include: { events: true }
18
+ });
19
+ if (result.$kind === "FailedTransaction") throwSimFailure(result.FailedTransaction);
20
+ return result.Transaction?.events ?? [];
21
+ }
22
+ async function inspectReturns(client, tx, sender = normalizeSuiAddress("0x0")) {
23
+ tx.setSender(sender);
24
+ const result = await client.core.simulateTransaction({
25
+ transaction: tx,
26
+ checksEnabled: false,
27
+ include: { commandResults: true }
28
+ });
29
+ if (result.$kind === "FailedTransaction") throwSimFailure(result.FailedTransaction);
30
+ const commands = result.commandResults;
31
+ if (!commands) throw new Error("simulateTransaction returned no commandResults");
32
+ return commands.map((c) => c.returnValues.map((rv) => rv.bcs));
33
+ }
34
+
35
+ //#endregion
36
+ export { inspectReturns, simulateWithEvents };
37
+ //# sourceMappingURL=inspect.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.mjs","names":[],"sources":["../../../src/predict/reads/inspect.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport type { Transaction } from '@mysten/sui/transactions';\nimport { normalizeSuiAddress } from '@mysten/sui/utils';\nimport { decodeMoveAbort, type MoveAbortError } from '../errors.js';\n\n// The one network seam every read sits on: any client exposing the core API\n// (`client.core.simulateTransaction`, plus the object reads positions.ts needs).\n// Callers pass a real SuiGrpcClient/SuiJsonRpcClient; tests inject a structural mock.\nexport type ReadClient = ClientWithCoreApi;\n\n// The abort payload a failed simulate result carries: the structured gRPC `MoveAbort`\n// arm (`{ abortCode, location: { module }, cleverError: { constantName } }`) plus an\n// optional display `message`. Read structurally so mocks and API-shape drift satisfy it.\ntype SimAbortError = MoveAbortError & { message?: string };\n\n// Run a read-only PTB through the gRPC `simulateTransaction` (the devInspect\n// replacement) and return each command's BCS return values, indexed\n// [commandIndex][returnValueIndex].\n//\n// `checksEnabled: false` disables validation so we may inspect non-entry public\n// funs — see SimulateTransactionOptions.checksEnabled in\n// node_modules/@mysten/sui/dist/client/types.d.mts:385-396. Per-command outputs\n// live under `commandResults[i].returnValues[j].bcs` — see\n// SimulateTransactionResult / CommandResult / CommandOutput in that same file at\n// lines 309-348. `commandResults` is only populated when `include.commandResults`\n// is set, so we request it explicitly.\n//\n// A sender is required to simulate; callers rarely have one for a pure read, so we\n// default to the zero address. On abort the result's `$kind` is `FailedTransaction`;\n// we decode the carried abort into a typed PredictMoveError, falling back to a plain\n// Error with the failure message when it isn't a decodable Move abort.\n// Shared failure handling: decode the abort carried by a FailedTransaction\n// into a typed PredictMoveError, else throw a plain Error.\nfunction throwSimFailure(failed: unknown): never {\n\tconst status = (failed as { status?: { success: boolean; error?: SimAbortError } })?.status;\n\tconst error = status && status.success === false ? status.error : undefined;\n\tconst decoded = error ? decodeMoveAbort(error) : null;\n\tif (decoded) throw decoded;\n\tthrow new Error(error?.message ?? 'simulateTransaction aborted (FailedTransaction)');\n}\n\n// Simulate a full transaction (typically one built by a tx.* builder) and return\n// the events it would emit — the quote path: dry-run the real action, decode the\n// receipt. Sender must be the acting owner so account auth resolves. Throws the\n// same typed errors the real execution would surface.\nexport async function simulateWithEvents(\n\tclient: ReadClient,\n\ttx: Transaction,\n\tsender: string,\n): Promise<{ eventType?: string; bcs?: Uint8Array | string }[]> {\n\ttx.setSender(sender);\n\tconst result = await client.core.simulateTransaction({\n\t\ttransaction: tx,\n\t\tchecksEnabled: false,\n\t\tinclude: { events: true },\n\t});\n\tif (result.$kind === 'FailedTransaction') throwSimFailure(result.FailedTransaction);\n\treturn (result.Transaction?.events ?? []) as { eventType?: string; bcs?: Uint8Array }[];\n}\n\nexport async function inspectReturns(\n\tclient: ReadClient,\n\ttx: Transaction,\n\tsender: string = normalizeSuiAddress('0x0'),\n): Promise<Uint8Array[][]> {\n\ttx.setSender(sender);\n\tconst result = await client.core.simulateTransaction({\n\t\ttransaction: tx,\n\t\tchecksEnabled: false,\n\t\tinclude: { commandResults: true },\n\t});\n\tif (result.$kind === 'FailedTransaction') throwSimFailure(result.FailedTransaction);\n\tconst commands = result.commandResults;\n\tif (!commands) throw new Error('simulateTransaction returned no commandResults');\n\treturn commands.map((c) => c.returnValues.map((rv) => rv.bcs));\n}\n"],"mappings":";;;;AAmCA,SAAS,gBAAgB,QAAwB;CAChD,MAAM,SAAU,QAAqE;CACrF,MAAM,QAAQ,UAAU,OAAO,YAAY,QAAQ,OAAO,QAAQ;CAClE,MAAM,UAAU,QAAQ,gBAAgB,MAAM,GAAG;AACjD,KAAI,QAAS,OAAM;AACnB,OAAM,IAAI,MAAM,OAAO,WAAW,kDAAkD;;AAOrF,eAAsB,mBACrB,QACA,IACA,QAC+D;AAC/D,IAAG,UAAU,OAAO;CACpB,MAAM,SAAS,MAAM,OAAO,KAAK,oBAAoB;EACpD,aAAa;EACb,eAAe;EACf,SAAS,EAAE,QAAQ,MAAM;EACzB,CAAC;AACF,KAAI,OAAO,UAAU,oBAAqB,iBAAgB,OAAO,kBAAkB;AACnF,QAAQ,OAAO,aAAa,UAAU,EAAE;;AAGzC,eAAsB,eACrB,QACA,IACA,SAAiB,oBAAoB,MAAM,EACjB;AAC1B,IAAG,UAAU,OAAO;CACpB,MAAM,SAAS,MAAM,OAAO,KAAK,oBAAoB;EACpD,aAAa;EACb,eAAe;EACf,SAAS,EAAE,gBAAgB,MAAM;EACjC,CAAC;AACF,KAAI,OAAO,UAAU,oBAAqB,iBAAgB,OAAO,kBAAkB;CACnF,MAAM,WAAW,OAAO;AACxB,KAAI,CAAC,SAAU,OAAM,IAAI,MAAM,iDAAiD;AAChF,QAAO,SAAS,KAAK,MAAM,EAAE,aAAa,KAAK,OAAO,GAAG,IAAI,CAAC"}
@@ -0,0 +1,130 @@
1
+ import { inspectReturns } from "./inspect.mjs";
2
+ import { parseOptionalId, parseOptionalU64, parseU64LE, parseVectorOfIds } from "./parse.mjs";
3
+ import { POS_INF_TICK } from "../ticks.mjs";
4
+ import { admissionTickSize, currentNav as currentNav$1, expiry, mintPaused, referenceTick as referenceTick$1, tickSize } from "../../contracts/deepbook_predict/expiry_market.mjs";
5
+ import { loadLivePricer } from "../tx/trade.mjs";
6
+ import { activeExpiryMarkets } from "../../contracts/deepbook_predict/plp.mjs";
7
+ import { rangePrice } from "../../contracts/deepbook_predict/pricing.mjs";
8
+ import { strikeFromTick } from "../../contracts/deepbook_predict/range_codec.mjs";
9
+ import { expiryMarketId as expiryMarketId$1 } from "../../contracts/deepbook_predict/registry.mjs";
10
+ import { Transaction } from "@mysten/sui/transactions";
11
+
12
+ //#region src/predict/reads/markets.ts
13
+ async function activeMarketIds(client, config) {
14
+ const tx = new Transaction();
15
+ tx.add(activeExpiryMarkets({ config }));
16
+ const [cmd0] = await inspectReturns(client, tx);
17
+ return parseVectorOfIds(cmd0[0]);
18
+ }
19
+ async function expiryMarketId(client, config, underlying, expiryMs) {
20
+ const tx = new Transaction();
21
+ tx.add(expiryMarketId$1({
22
+ config,
23
+ arguments: {
24
+ propbookUnderlyingId: underlying.propbookUnderlyingId,
25
+ expiry: expiryMs
26
+ }
27
+ }));
28
+ const [cmd0] = await inspectReturns(client, tx);
29
+ return parseOptionalId(cmd0[0]);
30
+ }
31
+ const STATE_FNS = [
32
+ expiry,
33
+ tickSize,
34
+ admissionTickSize,
35
+ mintPaused,
36
+ referenceTick$1
37
+ ];
38
+ function parseStateAt(cmds, base) {
39
+ return {
40
+ expiryMs: parseU64LE(cmds[base][0]),
41
+ tickSizeRaw: parseU64LE(cmds[base + 1][0]),
42
+ admissionTickSizeRaw: parseU64LE(cmds[base + 2][0]),
43
+ mintPaused: (cmds[base + 3][0][0] ?? 0) !== 0,
44
+ referenceTickRaw: parseOptionalU64(cmds[base + 4][0])
45
+ };
46
+ }
47
+ async function marketState(client, config, marketId) {
48
+ const [state] = await marketStates(client, config, [marketId]);
49
+ return state;
50
+ }
51
+ async function marketStates(client, config, marketIds) {
52
+ if (marketIds.length === 0) return [];
53
+ const tx = new Transaction();
54
+ for (const id of marketIds) for (const fn of STATE_FNS) tx.add(fn({
55
+ config,
56
+ arguments: { market: id }
57
+ }));
58
+ const cmds = await inspectReturns(client, tx);
59
+ return marketIds.map((_, i) => parseStateAt(cmds, STATE_FNS.length * i));
60
+ }
61
+ async function rangePrices(client, config, marketId, feeds, strikeRaw, tickSizeRaw) {
62
+ const tx = new Transaction();
63
+ const pricer = tx.add(loadLivePricer(config, {
64
+ expiryMarketId: marketId,
65
+ ...feeds
66
+ }));
67
+ const strikeTick = strikeRaw / tickSizeRaw;
68
+ const mkStrike = (tick) => tx.add(strikeFromTick({
69
+ config,
70
+ arguments: {
71
+ tick,
72
+ tickSize: tickSizeRaw
73
+ }
74
+ }));
75
+ const strike = mkStrike(strikeTick);
76
+ const posInf = mkStrike(POS_INF_TICK);
77
+ const negInf = mkStrike(0n);
78
+ tx.add(rangePrice({
79
+ config,
80
+ arguments: {
81
+ pricer,
82
+ lower: strike,
83
+ higher: posInf
84
+ }
85
+ }));
86
+ tx.add(rangePrice({
87
+ config,
88
+ arguments: {
89
+ pricer,
90
+ lower: negInf,
91
+ higher: strike
92
+ }
93
+ }));
94
+ const cmds = await inspectReturns(client, tx);
95
+ return {
96
+ upRaw: parseU64LE(cmds[cmds.length - 2][0]),
97
+ downRaw: parseU64LE(cmds[cmds.length - 1][0])
98
+ };
99
+ }
100
+ async function referenceTick(client, config, marketId) {
101
+ const tx = new Transaction();
102
+ tx.add(referenceTick$1({
103
+ config,
104
+ arguments: { market: marketId }
105
+ }));
106
+ const [cmd0] = await inspectReturns(client, tx);
107
+ return parseOptionalU64(cmd0[0]);
108
+ }
109
+ async function currentNav(client, config, marketId, underlying) {
110
+ const tx = new Transaction();
111
+ const pricer = tx.add(loadLivePricer(config, {
112
+ expiryMarketId: marketId,
113
+ pythFeed: underlying.pythFeed,
114
+ blockScholesValueStore: underlying.blockScholesValueStore,
115
+ blockScholesSviStore: underlying.blockScholesSviStore
116
+ }));
117
+ tx.add(currentNav$1({
118
+ config,
119
+ arguments: {
120
+ market: marketId,
121
+ pricer
122
+ }
123
+ }));
124
+ const cmds = await inspectReturns(client, tx);
125
+ return parseU64LE(cmds[cmds.length - 1][0]);
126
+ }
127
+
128
+ //#endregion
129
+ export { activeMarketIds, currentNav, expiryMarketId, marketState, marketStates, rangePrices, referenceTick };
130
+ //# sourceMappingURL=markets.mjs.map
@@ -0,0 +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":"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"}
@@ -0,0 +1,20 @@
1
+ import { bcs } from "@mysten/sui/bcs";
2
+
3
+ //#region src/predict/reads/parse.ts
4
+ function parseU64LE(bytes) {
5
+ return BigInt(bcs.u64().parse(bytes));
6
+ }
7
+ function parseVectorOfIds(bytes) {
8
+ return bcs.vector(bcs.Address).parse(bytes);
9
+ }
10
+ function parseOptionalU64(bytes) {
11
+ const v = bcs.option(bcs.u64()).parse(bytes);
12
+ return v == null ? null : BigInt(v);
13
+ }
14
+ function parseOptionalId(bytes) {
15
+ return bcs.option(bcs.Address).parse(bytes);
16
+ }
17
+
18
+ //#endregion
19
+ export { parseOptionalId, parseOptionalU64, parseU64LE, parseVectorOfIds };
20
+ //# sourceMappingURL=parse.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.mjs","names":[],"sources":["../../../src/predict/reads/parse.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n// BCS decoders for the return values of on-chain reads, built on the\n// `@mysten/sui/bcs` codec so the read layer decodes exactly the on-chain Move ABI\n// (u64 LE, vector<ID>, Option) with no hand-rolled byte walking. Round-tripped\n// against `@mysten/sui/bcs` in tests/reads.test.ts.\n\nimport { bcs } from '@mysten/sui/bcs';\n\n// BCS u64 → bigint. `bcs.u64()` parses to a decimal string.\nexport function parseU64LE(bytes: Uint8Array): bigint {\n\treturn BigInt(bcs.u64().parse(bytes));\n}\n\n// BCS vector<ID> / vector<address> → full-length 0x lowercase ids\n// (`bcs.Address` already yields normalized ids).\nexport function parseVectorOfIds(bytes: Uint8Array): string[] {\n\treturn bcs.vector(bcs.Address).parse(bytes);\n}\n\n// BCS Option<u64>: None → null, Some(x) → x.\nexport function parseOptionalU64(bytes: Uint8Array): bigint | null {\n\tconst v = bcs.option(bcs.u64()).parse(bytes);\n\treturn v == null ? null : BigInt(v);\n}\n\n// BCS Option<ID>: None → null, Some(id) → normalized 0x id.\nexport function parseOptionalId(bytes: Uint8Array): string | null {\n\treturn bcs.option(bcs.Address).parse(bytes);\n}\n"],"mappings":";;;AAUA,SAAgB,WAAW,OAA2B;AACrD,QAAO,OAAO,IAAI,KAAK,CAAC,MAAM,MAAM,CAAC;;AAKtC,SAAgB,iBAAiB,OAA6B;AAC7D,QAAO,IAAI,OAAO,IAAI,QAAQ,CAAC,MAAM,MAAM;;AAI5C,SAAgB,iBAAiB,OAAkC;CAClE,MAAM,IAAI,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,MAAM,MAAM;AAC5C,QAAO,KAAK,OAAO,OAAO,OAAO,EAAE;;AAIpC,SAAgB,gBAAgB,OAAkC;AACjE,QAAO,IAAI,OAAO,IAAI,QAAQ,CAAC,MAAM,MAAM"}
@@ -0,0 +1,26 @@
1
+ import { inspectReturns } from "./inspect.mjs";
2
+ import { parseU64LE } from "./parse.mjs";
3
+ import { idleBalance, plpTotalSupply, supplyRequestsPending, withdrawRequestsPending } from "../../contracts/deepbook_predict/plp.mjs";
4
+ import { Transaction } from "@mysten/sui/transactions";
5
+
6
+ //#region src/predict/reads/pool.ts
7
+ async function poolStats(client, config) {
8
+ const tx = new Transaction();
9
+ for (const fn of [
10
+ plpTotalSupply,
11
+ idleBalance,
12
+ supplyRequestsPending,
13
+ withdrawRequestsPending
14
+ ]) tx.add(fn({ config }));
15
+ const cmds = await inspectReturns(client, tx);
16
+ return {
17
+ plpTotalSupply: parseU64LE(cmds[0][0]),
18
+ idleBalance: parseU64LE(cmds[1][0]),
19
+ supplyRequestsPending: parseU64LE(cmds[2][0]),
20
+ withdrawRequestsPending: parseU64LE(cmds[3][0])
21
+ };
22
+ }
23
+
24
+ //#endregion
25
+ export { poolStats };
26
+ //# sourceMappingURL=pool.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.mjs","names":["plp.plpTotalSupply","plp.idleBalance","plp.supplyRequestsPending","plp.withdrawRequestsPending"],"sources":["../../../src/predict/reads/pool.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 * as plp from '../../contracts/deepbook_predict/plp.js';\nimport { inspectReturns, type ReadClient } from './inspect.js';\nimport { parseU64LE } from './parse.js';\n\nexport interface PoolStats {\n\tplpTotalSupply: bigint;\n\tidleBalance: bigint;\n\tsupplyRequestsPending: bigint;\n\twithdrawRequestsPending: bigint;\n}\n\n// The pool's four u64 vault stats batched into one PTB (command order fixed below).\n// `plp::{plp_total_supply, idle_balance, supply_requests_pending,\n// withdraw_requests_pending}(vault)` — see\n// packages/predict/sources/plp/plp.move:{164,149,169,174}.\nexport async function poolStats(client: ReadClient, config: GeneratedConfig): Promise<PoolStats> {\n\tconst tx = new Transaction();\n\tfor (const fn of [\n\t\tplp.plpTotalSupply,\n\t\tplp.idleBalance,\n\t\tplp.supplyRequestsPending,\n\t\tplp.withdrawRequestsPending,\n\t]) {\n\t\ttx.add(fn({ config }));\n\t}\n\tconst cmds = await inspectReturns(client, tx);\n\treturn {\n\t\tplpTotalSupply: parseU64LE(cmds[0][0]),\n\t\tidleBalance: parseU64LE(cmds[1][0]),\n\t\tsupplyRequestsPending: parseU64LE(cmds[2][0]),\n\t\twithdrawRequestsPending: parseU64LE(cmds[3][0]),\n\t};\n}\n"],"mappings":";;;;;;AAmBA,eAAsB,UAAU,QAAoB,QAA6C;CAChG,MAAM,KAAK,IAAI,aAAa;AAC5B,MAAK,MAAM,MAAM;EAChBA;EACAC;EACAC;EACAC;EACA,CACA,IAAG,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC;CAEvB,MAAM,OAAO,MAAM,eAAe,QAAQ,GAAG;AAC7C,QAAO;EACN,gBAAgB,WAAW,KAAK,GAAG,GAAG;EACtC,aAAa,WAAW,KAAK,GAAG,GAAG;EACnC,uBAAuB,WAAW,KAAK,GAAG,GAAG;EAC7C,yBAAyB,WAAW,KAAK,GAAG,GAAG;EAC/C"}
@@ -0,0 +1,12 @@
1
+ import "../config/generated.mjs";
2
+ import { ClientWithCoreApi } from "@mysten/sui/client";
3
+
4
+ //#region src/predict/reads/positions.d.ts
5
+ /** One open position — the coordinates redeem/claim/hasPosition take. */
6
+ interface OpenPosition {
7
+ marketId: string;
8
+ orderId: bigint;
9
+ }
10
+ //#endregion
11
+ export { OpenPosition };
12
+ //# sourceMappingURL=positions.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"positions.d.mts","names":[],"sources":["../../../src/predict/reads/positions.ts"],"mappings":";;;;;UAyCiB,YAAA;EAChB,QAAA;EACA,OAAA;AAAA"}