@mysten/deepbook-v3 2.6.4 → 2.8.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 (250) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/PREDICT.md +389 -61
  3. package/dist/contracts/account/account.d.mts +23 -23
  4. package/dist/contracts/account/account.d.mts.map +1 -1
  5. package/dist/contracts/account/account_registry.d.mts +13 -13
  6. package/dist/contracts/deepbook/account.d.mts +18 -18
  7. package/dist/contracts/deepbook/balances.d.mts +4 -4
  8. package/dist/contracts/deepbook/deep_price.d.mts +3 -3
  9. package/dist/contracts/deepbook/order.d.mts +12 -12
  10. package/dist/contracts/deepbook_predict/admin.d.mts +4 -4
  11. package/dist/contracts/deepbook_predict/builder_code.d.mts +11 -11
  12. package/dist/contracts/deepbook_predict/builder_code_events.d.mts +10 -10
  13. package/dist/contracts/deepbook_predict/config_events.d.mts +93 -68
  14. package/dist/contracts/deepbook_predict/config_events.d.mts.map +1 -1
  15. package/dist/contracts/deepbook_predict/config_events.mjs +45 -1
  16. package/dist/contracts/deepbook_predict/config_events.mjs.map +1 -1
  17. package/dist/contracts/deepbook_predict/deps/std/type_name.mjs +17 -0
  18. package/dist/contracts/deepbook_predict/deps/std/type_name.mjs.map +1 -0
  19. package/dist/contracts/deepbook_predict/expiry_market.d.mts +652 -235
  20. package/dist/contracts/deepbook_predict/expiry_market.d.mts.map +1 -1
  21. package/dist/contracts/deepbook_predict/expiry_market.mjs +652 -186
  22. package/dist/contracts/deepbook_predict/expiry_market.mjs.map +1 -1
  23. package/dist/contracts/deepbook_predict/lp_book.mjs +1 -1
  24. package/dist/contracts/deepbook_predict/market_lifecycle_cap.d.mts +5 -5
  25. package/dist/contracts/deepbook_predict/market_manager.d.mts +27 -27
  26. package/dist/contracts/deepbook_predict/order_events.d.mts +50 -50
  27. package/dist/contracts/deepbook_predict/order_events.d.mts.map +1 -1
  28. package/dist/contracts/deepbook_predict/order_events.mjs +3 -1
  29. package/dist/contracts/deepbook_predict/order_events.mjs.map +1 -1
  30. package/dist/contracts/deepbook_predict/pause_cap.d.mts +5 -5
  31. package/dist/contracts/deepbook_predict/plp.d.mts +184 -82
  32. package/dist/contracts/deepbook_predict/plp.d.mts.map +1 -1
  33. package/dist/contracts/deepbook_predict/plp.mjs +126 -7
  34. package/dist/contracts/deepbook_predict/plp.mjs.map +1 -1
  35. package/dist/contracts/deepbook_predict/pool_accounting.mjs +1 -1
  36. package/dist/contracts/deepbook_predict/pool_valuation_cap.d.mts +5 -5
  37. package/dist/contracts/deepbook_predict/predict_account.d.mts +14 -14
  38. package/dist/contracts/deepbook_predict/pricing.d.mts +91 -58
  39. package/dist/contracts/deepbook_predict/pricing.d.mts.map +1 -1
  40. package/dist/contracts/deepbook_predict/pricing.mjs +30 -3
  41. package/dist/contracts/deepbook_predict/pricing.mjs.map +1 -1
  42. package/dist/contracts/deepbook_predict/pricing_config.mjs.map +1 -1
  43. package/dist/contracts/deepbook_predict/protocol_config.d.mts +400 -92
  44. package/dist/contracts/deepbook_predict/protocol_config.d.mts.map +1 -1
  45. package/dist/contracts/deepbook_predict/protocol_config.mjs +451 -61
  46. package/dist/contracts/deepbook_predict/protocol_config.mjs.map +1 -1
  47. package/dist/contracts/deepbook_predict/range_codec.d.mts +2 -2
  48. package/dist/contracts/deepbook_predict/registry.d.mts +28 -28
  49. package/dist/contracts/deepbook_predict/strike_exposure.mjs +1 -1
  50. package/dist/contracts/deepbook_predict/strike_payout_tree.mjs +17 -12
  51. package/dist/contracts/deepbook_predict/strike_payout_tree.mjs.map +1 -1
  52. package/dist/contracts/deepbook_predict/vault_events.d.mts +154 -106
  53. package/dist/contracts/deepbook_predict/vault_events.d.mts.map +1 -1
  54. package/dist/contracts/deepbook_predict/vault_events.mjs +57 -1
  55. package/dist/contracts/deepbook_predict/vault_events.mjs.map +1 -1
  56. package/dist/contracts/deepbook_predict_math/config-arguments.d.mts +10 -0
  57. package/dist/contracts/deepbook_predict_math/config-arguments.d.mts.map +1 -0
  58. package/dist/contracts/deepbook_predict_math/lazer_price.d.mts +106 -0
  59. package/dist/contracts/deepbook_predict_math/lazer_price.d.mts.map +1 -0
  60. package/dist/contracts/deepbook_predict_math/lazer_price.mjs +125 -0
  61. package/dist/contracts/deepbook_predict_math/lazer_price.mjs.map +1 -0
  62. package/dist/contracts/deepbook_predict_math/math.d.mts +284 -0
  63. package/dist/contracts/deepbook_predict_math/math.d.mts.map +1 -0
  64. package/dist/contracts/deepbook_predict_math/math.mjs +364 -0
  65. package/dist/contracts/deepbook_predict_math/math.mjs.map +1 -0
  66. package/dist/contracts/deepbook_predict_orders/config-arguments.d.mts +13 -0
  67. package/dist/contracts/deepbook_predict_orders/config-arguments.d.mts.map +1 -0
  68. package/dist/contracts/deepbook_predict_orders/delayed_execution_config.d.mts +215 -0
  69. package/dist/contracts/deepbook_predict_orders/delayed_execution_config.d.mts.map +1 -0
  70. package/dist/contracts/deepbook_predict_orders/delayed_execution_config.mjs +215 -0
  71. package/dist/contracts/deepbook_predict_orders/delayed_execution_config.mjs.map +1 -0
  72. package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/expiry_market.mjs +87 -0
  73. package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/expiry_market.mjs.map +1 -0
  74. package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/pricing.mjs +52 -0
  75. package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/pricing.mjs.map +1 -0
  76. package/dist/contracts/deepbook_predict_orders/deps/fixed_math/i64.mjs +25 -0
  77. package/dist/contracts/deepbook_predict_orders/deps/fixed_math/i64.mjs.map +1 -0
  78. package/dist/contracts/deepbook_predict_orders/deps/sui/balance.mjs +21 -0
  79. package/dist/contracts/deepbook_predict_orders/deps/sui/balance.mjs.map +1 -0
  80. package/dist/contracts/deepbook_predict_orders/deps/sui/table.mjs +39 -0
  81. package/dist/contracts/deepbook_predict_orders/deps/sui/table.mjs.map +1 -0
  82. package/dist/contracts/deepbook_predict_orders/desk.d.mts +187 -0
  83. package/dist/contracts/deepbook_predict_orders/desk.d.mts.map +1 -0
  84. package/dist/contracts/deepbook_predict_orders/desk.mjs +261 -0
  85. package/dist/contracts/deepbook_predict_orders/desk.mjs.map +1 -0
  86. package/dist/contracts/deepbook_predict_orders/order_queue.d.mts +1042 -0
  87. package/dist/contracts/deepbook_predict_orders/order_queue.d.mts.map +1 -0
  88. package/dist/contracts/deepbook_predict_orders/order_queue.mjs +849 -0
  89. package/dist/contracts/deepbook_predict_orders/order_queue.mjs.map +1 -0
  90. package/dist/contracts/deepbook_predict_orders/queue.d.mts +683 -0
  91. package/dist/contracts/deepbook_predict_orders/queue.d.mts.map +1 -0
  92. package/dist/contracts/deepbook_predict_orders/queue.mjs +912 -0
  93. package/dist/contracts/deepbook_predict_orders/queue.mjs.map +1 -0
  94. package/dist/contracts/deepbook_predict_orders/queue_events.d.mts +195 -0
  95. package/dist/contracts/deepbook_predict_orders/queue_events.d.mts.map +1 -0
  96. package/dist/contracts/deepbook_predict_orders/queue_events.mjs +187 -0
  97. package/dist/contracts/deepbook_predict_orders/queue_events.mjs.map +1 -0
  98. package/dist/contracts/deepbook_sessions/session_config.d.mts +8 -8
  99. package/dist/contracts/deepbook_sessions/sessions.d.mts +163 -28
  100. package/dist/contracts/deepbook_sessions/sessions.d.mts.map +1 -1
  101. package/dist/contracts/deepbook_sessions/sessions.mjs +234 -5
  102. package/dist/contracts/deepbook_sessions/sessions.mjs.map +1 -1
  103. package/dist/deployments/mainnet.mjs +7 -4
  104. package/dist/deployments/mainnet.mjs.map +1 -1
  105. package/dist/deployments/testnet.mjs +7 -4
  106. package/dist/deployments/testnet.mjs.map +1 -1
  107. package/dist/predict/bindings/expiry-market.d.mts +77 -0
  108. package/dist/predict/bindings/expiry-market.d.mts.map +1 -0
  109. package/dist/predict/bindings/expiry-market.mjs +139 -0
  110. package/dist/predict/bindings/expiry-market.mjs.map +1 -0
  111. package/dist/predict/bindings/protocol-config.d.mts +39 -0
  112. package/dist/predict/bindings/protocol-config.d.mts.map +1 -0
  113. package/dist/predict/bindings/protocol-config.mjs +90 -0
  114. package/dist/predict/bindings/protocol-config.mjs.map +1 -0
  115. package/dist/predict/bindings/rename.mjs +9 -0
  116. package/dist/predict/bindings/rename.mjs.map +1 -0
  117. package/dist/predict/client.d.mts +595 -16
  118. package/dist/predict/client.d.mts.map +1 -1
  119. package/dist/predict/client.mjs +986 -10
  120. package/dist/predict/client.mjs.map +1 -1
  121. package/dist/predict/config/generated.d.mts +22 -1
  122. package/dist/predict/config/generated.d.mts.map +1 -1
  123. package/dist/predict/config/generated.mjs +30 -1
  124. package/dist/predict/config/generated.mjs.map +1 -1
  125. package/dist/predict/config/mainnet.mjs +11 -3
  126. package/dist/predict/config/mainnet.mjs.map +1 -1
  127. package/dist/predict/config/testnet.mjs +11 -3
  128. package/dist/predict/config/testnet.mjs.map +1 -1
  129. package/dist/predict/config/types.d.mts +50 -1
  130. package/dist/predict/config/types.d.mts.map +1 -1
  131. package/dist/predict/cost.d.mts +38 -11
  132. package/dist/predict/cost.d.mts.map +1 -1
  133. package/dist/predict/cost.mjs +37 -11
  134. package/dist/predict/cost.mjs.map +1 -1
  135. package/dist/predict/decode.d.mts +251 -1
  136. package/dist/predict/decode.d.mts.map +1 -1
  137. package/dist/predict/decode.mjs +342 -4
  138. package/dist/predict/decode.mjs.map +1 -1
  139. package/dist/predict/errors.d.mts +69 -6
  140. package/dist/predict/errors.d.mts.map +1 -1
  141. package/dist/predict/errors.mjs +277 -4
  142. package/dist/predict/errors.mjs.map +1 -1
  143. package/dist/predict/index.d.mts +21 -10
  144. package/dist/predict/index.mjs +24 -12
  145. package/dist/predict/queue-id.d.mts +13 -0
  146. package/dist/predict/queue-id.d.mts.map +1 -0
  147. package/dist/predict/queue-id.mjs +19 -0
  148. package/dist/predict/queue-id.mjs.map +1 -0
  149. package/dist/predict/queue.d.mts +505 -0
  150. package/dist/predict/queue.d.mts.map +1 -0
  151. package/dist/predict/queue.mjs +774 -0
  152. package/dist/predict/queue.mjs.map +1 -0
  153. package/dist/predict/reads/balances.mjs +1 -1
  154. package/dist/predict/reads/markets.mjs +46 -5
  155. package/dist/predict/reads/markets.mjs.map +1 -1
  156. package/dist/predict/reads/pool.mjs +1 -1
  157. package/dist/predict/reads/pricing.d.mts +1 -1
  158. package/dist/predict/reads/queue.d.mts +105 -0
  159. package/dist/predict/reads/queue.d.mts.map +1 -0
  160. package/dist/predict/reads/queue.mjs +445 -0
  161. package/dist/predict/reads/queue.mjs.map +1 -0
  162. package/dist/predict/ticks.d.mts +9 -1
  163. package/dist/predict/ticks.d.mts.map +1 -1
  164. package/dist/predict/ticks.mjs +18 -1
  165. package/dist/predict/ticks.mjs.map +1 -1
  166. package/dist/predict/tx/authed.mjs +1 -1
  167. package/dist/predict/tx/common.d.mts.map +1 -1
  168. package/dist/predict/tx/common.mjs +12 -1
  169. package/dist/predict/tx/common.mjs.map +1 -1
  170. package/dist/predict/tx/queue.d.mts +220 -0
  171. package/dist/predict/tx/queue.d.mts.map +1 -0
  172. package/dist/predict/tx/queue.mjs +399 -0
  173. package/dist/predict/tx/queue.mjs.map +1 -0
  174. package/dist/predict/tx/trade.d.mts.map +1 -1
  175. package/dist/predict/tx/trade.mjs +61 -43
  176. package/dist/predict/tx/trade.mjs.map +1 -1
  177. package/dist/sessions.d.mts +90 -2
  178. package/dist/sessions.d.mts.map +1 -1
  179. package/dist/sessions.mjs +107 -2
  180. package/dist/sessions.mjs.map +1 -1
  181. package/dist/transactions/balanceManager.d.mts +12 -12
  182. package/dist/transactions/balanceManager.d.mts.map +1 -1
  183. package/dist/transactions/deepbook.d.mts +20 -20
  184. package/dist/transactions/deepbook.d.mts.map +1 -1
  185. package/dist/transactions/deepbookAdmin.d.mts +4 -4
  186. package/dist/transactions/deepbookAdmin.d.mts.map +1 -1
  187. package/dist/transactions/marginAdmin.d.mts +7 -7
  188. package/dist/transactions/marginAdmin.d.mts.map +1 -1
  189. package/dist/transactions/marginLiquidations.d.mts +3 -3
  190. package/dist/transactions/marginMaintainer.d.mts +5 -5
  191. package/dist/transactions/marginMaintainer.d.mts.map +1 -1
  192. package/dist/transactions/marginManager.d.mts +32 -32
  193. package/dist/transactions/marginManager.d.mts.map +1 -1
  194. package/dist/transactions/marginPool.d.mts +18 -18
  195. package/dist/transactions/marginRegistry.d.mts +16 -16
  196. package/dist/transactions/marginTPSL.d.mts +10 -10
  197. package/dist/transactions/marginTPSL.d.mts.map +1 -1
  198. package/dist/transactions/poolProxy.d.mts +8 -8
  199. package/dist/transactions/poolProxy.d.mts.map +1 -1
  200. package/package.json +4 -4
  201. package/src/contracts/deepbook_predict/config_events.ts +39 -0
  202. package/src/contracts/deepbook_predict/deps/std/type_name.ts +24 -0
  203. package/src/contracts/deepbook_predict/expiry_market.ts +960 -169
  204. package/src/contracts/deepbook_predict/order_events.ts +3 -1
  205. package/src/contracts/deepbook_predict/plp.ts +150 -9
  206. package/src/contracts/deepbook_predict/pricing.ts +46 -7
  207. package/src/contracts/deepbook_predict/pricing_config.ts +3 -1
  208. package/src/contracts/deepbook_predict/protocol_config.ts +648 -33
  209. package/src/contracts/deepbook_predict/strike_payout_tree.ts +25 -21
  210. package/src/contracts/deepbook_predict/vault_events.ts +65 -0
  211. package/src/contracts/deepbook_predict_math/config-arguments.ts +6 -0
  212. package/src/contracts/deepbook_predict_math/lazer_price.ts +196 -0
  213. package/src/contracts/deepbook_predict_math/math.ts +553 -0
  214. package/src/contracts/deepbook_predict_orders/config-arguments.ts +11 -0
  215. package/src/contracts/deepbook_predict_orders/delayed_execution_config.ts +430 -0
  216. package/src/contracts/deepbook_predict_orders/deps/deepbook_predict/expiry_market.ts +108 -0
  217. package/src/contracts/deepbook_predict_orders/deps/deepbook_predict/pricing.ts +58 -0
  218. package/src/contracts/deepbook_predict_orders/deps/fixed_math/i64.ts +21 -0
  219. package/src/contracts/deepbook_predict_orders/deps/sui/balance.ts +19 -0
  220. package/src/contracts/deepbook_predict_orders/deps/sui/table.ts +37 -0
  221. package/src/contracts/deepbook_predict_orders/desk.ts +419 -0
  222. package/src/contracts/deepbook_predict_orders/order_flow.ts +19 -0
  223. package/src/contracts/deepbook_predict_orders/order_queue.ts +1670 -0
  224. package/src/contracts/deepbook_predict_orders/queue.ts +1394 -0
  225. package/src/contracts/deepbook_predict_orders/queue_events.ts +189 -0
  226. package/src/contracts/deepbook_sessions/sessions.ts +355 -4
  227. package/src/deployments/mainnet.ts +7 -2
  228. package/src/deployments/testnet.ts +7 -2
  229. package/src/deployments/types.ts +14 -1
  230. package/src/predict/bindings/expiry-market.ts +127 -0
  231. package/src/predict/bindings/protocol-config.ts +59 -0
  232. package/src/predict/bindings/rename.ts +14 -0
  233. package/src/predict/client.ts +2076 -13
  234. package/src/predict/config/generated.ts +50 -0
  235. package/src/predict/config/mainnet.ts +16 -2
  236. package/src/predict/config/testnet.ts +16 -2
  237. package/src/predict/config/types.ts +51 -1
  238. package/src/predict/cost.ts +62 -14
  239. package/src/predict/decode.ts +691 -2
  240. package/src/predict/errors.ts +391 -14
  241. package/src/predict/index.ts +87 -6
  242. package/src/predict/queue-id.ts +22 -0
  243. package/src/predict/queue.ts +1231 -0
  244. package/src/predict/reads/markets.ts +30 -0
  245. package/src/predict/reads/queue.ts +606 -0
  246. package/src/predict/ticks.ts +35 -0
  247. package/src/predict/tx/common.ts +25 -1
  248. package/src/predict/tx/queue.ts +525 -0
  249. package/src/predict/tx/trade.ts +80 -49
  250. package/src/sessions.ts +206 -1
@@ -1,22 +1,27 @@
1
1
  import { TESTNET_PREDICT } from "../deployments/testnet.mjs";
2
+ import { deriveQueueId } from "./queue-id.mjs";
2
3
  import { getConfig } from "./config/index.mjs";
3
- import { toGeneratedConfig } from "./config/generated.mjs";
4
- import { PredictInputError } from "./errors.mjs";
4
+ import { PredictInputError, PredictMoveError, PredictPreflightError } from "./errors.mjs";
5
+ import { toGeneratedConfig, toOrdersConfig } from "./config/generated.mjs";
6
+ import { boardPricer } from "./pricing.mjs";
7
+ import { POS_INF_TICK, binaryRangeTicks } from "./ticks.mjs";
5
8
  import { fromRaw, priceToRaw, probabilityToRaw, rawToProbability, rawToUsdc, usdcToRaw } from "./units.mjs";
6
- import { decodeAccountsCreated, decodeBuilderCodeSets, decodeClaims, decodeDeposits, decodeMints, decodePlpCancels, decodePlpRequests, decodeRedeems, decodeWithdrawals, exactlyOne } from "./decode.mjs";
9
+ import { MIN_PREMIUM, decodeOrderRange } from "./cost.mjs";
10
+ import { ORDER_FLOW_PACKAGE_VERSION, ORDER_KIND, ORDER_STATUS, budgetMintLimits, cashNeedSell, channelTickMs, exactMintLimits, feeCovered, maxMintNow, mintBudget, mintCashNeed, orderKindName, orderView, previewTiming, sellLimits, slippageBand } from "./queue.mjs";
11
+ import { decodeAccountsCreated, decodeBuilderCodeSets, decodeClaims, decodeCohortCommits, decodeDeposits, decodeEnqueues, decodeExpiryPnlRealized, decodeMarketPayoutsCompleted, decodeMints, decodeOpenRecordPayouts, decodePlpCancels, decodePlpRequests, decodePolicyUpdates, decodeQueueEvents, decodeQueueOps, decodeQueuedFills, decodeQueuedRefunds, decodeRecordFunds, decodeRedeems, decodeWithdrawals, exactlyOne } from "./decode.mjs";
7
12
  import { simulateWithEvents } from "./reads/inspect.mjs";
8
13
  import { accountContract, deriveAccountWrapperIdFrom } from "./tx/common.mjs";
14
+ import { assertOrderFeeAtMost, claimParked, enqueueExactAmount, enqueueExactCost, enqueueExactQuantity, enqueueRedeemOpen, fill, payOpen, rebalanceExpiryCash, refund } from "./tx/queue.mjs";
15
+ import { mintExactAmount, mintExactCost, mintExactQuantity, redeemLive, redeemSettled } from "./tx/trade.mjs";
16
+ import { executionModeFor, lazerPackages, marketQueueState, orderFeeAndBalance, pendingFunds, queuedOrders, quoteMintAnonymous, quoteMintForAccount, quoteRedeemOpen, versionWatermark } from "./reads/queue.mjs";
9
17
  import { positionsFromTable, resolvePositionsTable } from "./reads/positions.mjs";
10
18
  import { accountBalance, hasPosition } from "./reads/balances.mjs";
11
- import { POS_INF_TICK, binaryRangeTicks } from "./ticks.mjs";
12
- import { mintExactAmount, mintExactCost, mintExactQuantity, redeemLive, redeemSettled } from "./tx/trade.mjs";
13
- import { activeMarketIds, currentNav, expiryMarketId, marketState, marketStates, rangePrices, referenceTick } from "./reads/markets.mjs";
19
+ import { activeMarketIds, currentNav, expiryMarketId, marketFeePolicy, marketState, marketStates, rangePrices, referenceTick, settlementPrice } from "./reads/markets.mjs";
14
20
  import { poolStats } from "./reads/pool.mjs";
15
21
  import { readPricerSnapshot } from "./reads/pricing.mjs";
16
- import { boardPricer } from "./pricing.mjs";
17
22
  import { cancelSupplyRequest, cancelWithdrawRequest, depositFunds, requestSupply, requestWithdraw, setBuilderCode, unsetBuilderCode, withdrawFunds } from "./tx/authed.mjs";
18
23
  import { Transaction, coinWithBalance } from "@mysten/sui/transactions";
19
- import { isValidSuiObjectId } from "@mysten/sui/utils";
24
+ import { isValidSuiObjectId, normalizeSuiAddress } from "@mysten/sui/utils";
20
25
 
21
26
  //#region src/predict/client.ts
22
27
  /**
@@ -24,6 +29,7 @@ import { isValidSuiObjectId } from "@mysten/sui/utils";
24
29
  * size of the config actually in play; this is the convenience constant for testnet callers.
25
30
  */
26
31
  const POSITION_LOT_SIZE = BigInt(TESTNET_PREDICT.units.positionLotSize);
32
+ const NEAR_DOLLAR_PER_CONTRACT = 950000000n;
27
33
  function txOf(command) {
28
34
  const tx = new Transaction();
29
35
  tx.add(command);
@@ -51,6 +57,12 @@ function predict({ name = "predict", network, config }) {
51
57
  * returns a finished `Transaction`; callers composing their own PTBs use the generated
52
58
  * move-call bindings this subpath exports (`plpMoveCalls`, `expiryMarketMoveCalls`, …).
53
59
  */
60
+ function isOrderFailsLimits(error) {
61
+ return error instanceof PredictMoveError && error.abortName === "EOrderFailsLimits";
62
+ }
63
+ function isPastExpiry(error) {
64
+ return error instanceof PredictMoveError && error.abortName === "ELivePricingExpired";
65
+ }
54
66
  var PredictClient = class PredictClient {
55
67
  get #config() {
56
68
  return toGeneratedConfig(this.cfg);
@@ -58,6 +70,7 @@ var PredictClient = class PredictClient {
58
70
  #client;
59
71
  #marketCache = /* @__PURE__ */ new Map();
60
72
  #positionsCache = /* @__PURE__ */ new Map();
73
+ #knownQueues = /* @__PURE__ */ new Set();
61
74
  constructor(opts) {
62
75
  this.tx = {
63
76
  createManager: () => txOf(accountContract(this.cfg).createAccount()),
@@ -128,6 +141,118 @@ var PredictClient = class PredictClient {
128
141
  orderId: opts$1.orderId
129
142
  }));
130
143
  },
144
+ enqueueMint: async (owner, m, opts$1) => {
145
+ const quantityRaw = usdcToRaw(opts$1.quantity);
146
+ this.#assertLot(quantityRaw);
147
+ const maxCostRaw = usdcToRaw(opts$1.maxCost);
148
+ const maxProbabilityRaw = probabilityToRaw(opts$1.maxProbability);
149
+ return this.#planMint(owner, m, {
150
+ kind: ORDER_KIND.EXACT_QUANTITY,
151
+ maxCostRaw,
152
+ quantityRaw
153
+ }, (orders, target) => enqueueExactQuantity(orders, {
154
+ ...target,
155
+ quantityRaw,
156
+ maxCostRaw,
157
+ maxProbabilityRaw
158
+ }));
159
+ },
160
+ enqueueMintAmount: async (owner, m, opts$1) => {
161
+ const maxPremiumRaw = usdcToRaw(opts$1.spend);
162
+ const minQuantityRaw = usdcToRaw(opts$1.minQuantity);
163
+ const maxCostRaw = usdcToRaw(opts$1.maxCost);
164
+ if (maxPremiumRaw < MIN_PREMIUM) throw new PredictPreflightError("min-premium", `spend ${rawToUsdc(maxPremiumRaw)} is below the ${rawToUsdc(MIN_PREMIUM)} minimum premium`);
165
+ return this.#planMint(owner, m, {
166
+ kind: ORDER_KIND.EXACT_AMOUNT,
167
+ maxCostRaw,
168
+ maxPremiumRaw
169
+ }, (orders, target) => enqueueExactAmount(orders, {
170
+ ...target,
171
+ maxPremiumRaw,
172
+ minQuantityRaw,
173
+ maxCostRaw
174
+ }));
175
+ },
176
+ enqueueMintCost: async (owner, m, opts$1) => {
177
+ const maxCostRaw = usdcToRaw(opts$1.spend);
178
+ const minQuantityRaw = usdcToRaw(opts$1.minQuantity);
179
+ return this.#planMint(owner, m, {
180
+ kind: ORDER_KIND.EXACT_COST,
181
+ maxCostRaw
182
+ }, (orders, target) => enqueueExactCost(orders, {
183
+ ...target,
184
+ maxCostRaw,
185
+ minQuantityRaw
186
+ }));
187
+ },
188
+ enqueueSell: (owner, m, opts$1) => this.#planSell(owner, m, opts$1),
189
+ enqueuePlan: async (owner, m, plan) => {
190
+ if (plan.refusal != null) throw new PredictPreflightError(plan.refusal, `the plan was refused (${plan.refusal})`);
191
+ const target = plan.target;
192
+ const { id, state: marketState$1 } = await this.#resolveMarket(m);
193
+ if (normalizeSuiAddress(owner) !== normalizeSuiAddress(target.owner)) throw new PredictInputError(`the plan was made for owner ${target.owner}, not ${owner}`);
194
+ if (normalizeSuiAddress(id) !== normalizeSuiAddress(target.expiryMarketId)) throw new PredictInputError(`the plan was made for market ${target.expiryMarketId}, not ${id}`);
195
+ const order = plan.order;
196
+ const descriptor = "side" in m ? m : null;
197
+ let placed;
198
+ if (order.builder === "enqueueSell") {
199
+ if (order.options.recordId !== target.recordId) throw new PredictInputError(`the plan was made for record ${target.recordId}, not ${order.options.recordId}`);
200
+ placed = await this.tx.enqueueSell(owner, m, order.options);
201
+ } else {
202
+ if (descriptor == null) throw new PredictInputError("a mint plan needs the market descriptor it was planned with (its strike and side)");
203
+ const { lowerTick, higherTick } = await this.#strikeTicks(descriptor, id, marketState$1);
204
+ if (lowerTick !== target.lowerTick || higherTick !== target.higherTick) throw new PredictInputError("the market descriptor names a different strike or side than the plan, or its reference strike moved: plan again");
205
+ placed = order.builder === "enqueueMintCost" ? await this.tx.enqueueMintCost(owner, descriptor, order.options) : await this.tx.enqueueMint(owner, descriptor, order.options);
206
+ }
207
+ if (placed.preview.raw.orderFee > plan.raw.orderFee) throw new PredictInputError(`the order fee rose from ${rawToUsdc(plan.raw.orderFee)} to ${placed.preview.orderFee} since the plan: plan again`);
208
+ if (order.builder === "enqueueSell") return placed;
209
+ const planned = plan.raw.budget;
210
+ if (placed.preview.raw.budget < planned) throw new PredictPreflightError("fee", `the balance now escrows ${placed.preview.budget}, below the plan's ${rawToUsdc(planned)}`);
211
+ return placed;
212
+ },
213
+ refund: async (m, opts$1 = {}) => {
214
+ const orders = this.#requireDelayedExecution();
215
+ const { id } = await this.#resolveMarket(m);
216
+ return txOf(refund(orders, {
217
+ expiryMarketId: id,
218
+ queueId: await this.#existingQueueId(orders, id),
219
+ maxOrders: BigInt(opts$1.maxOrders ?? 100)
220
+ }));
221
+ },
222
+ claimParked: async (m, recordId) => {
223
+ const orders = this.#requireDelayedExecution();
224
+ const { id } = await this.#resolveMarket(m);
225
+ return txOf(claimParked(orders, {
226
+ expiryMarketId: id,
227
+ queueId: await this.#existingQueueId(orders, id),
228
+ recordId
229
+ }));
230
+ },
231
+ payOpen: async (m, recordId) => {
232
+ const orders = this.#requireDelayedExecution();
233
+ const { id } = await this.#resolveMarket(m);
234
+ return txOf(payOpen(orders, {
235
+ expiryMarketId: id,
236
+ queueId: await this.#existingQueueId(orders, id),
237
+ recordId
238
+ }));
239
+ },
240
+ fill: async (m, opts$1) => {
241
+ const orders = this.#requireDelayedExecution();
242
+ const stateId = opts$1.lazerStateId ?? this.cfg.oracle?.pythLazerState;
243
+ if (!stateId) throw new PredictInputError("fill needs the Pyth Lazer State: pass `lazerStateId`");
244
+ const { id } = await this.#resolveMarket(m);
245
+ const queueId = await this.#existingQueueId(orders, id);
246
+ const lazer = await lazerPackages(this.#client, stateId);
247
+ return txOf(fill(orders, {
248
+ expiryMarketId: id,
249
+ queueId,
250
+ payloads: opts$1.payloads,
251
+ lazer,
252
+ maxOrders: BigInt(opts$1.maxOrders ?? 15),
253
+ refundOverdue: opts$1.refundOverdue
254
+ }));
255
+ },
131
256
  supplyPlp: (owner, amountUsdc, options = {}) => txOf(requestSupply({
132
257
  config: this.#config,
133
258
  arguments: {
@@ -215,10 +340,480 @@ var PredictClient = class PredictClient {
215
340
  };
216
341
  },
217
342
  quoteMint: async (owner, m, opts$1) => {
343
+ if (this.cfg.packages.predictDelayedExecution) {
344
+ const orders = this.#requireDelayedExecution();
345
+ const feeds = this.#feeds(m.underlying);
346
+ const { id, state } = await this.#resolveMarket(m);
347
+ const quantityRaw = usdcToRaw(opts$1.quantity);
348
+ this.#assertLot(quantityRaw);
349
+ const { lowerTick, higherTick } = await this.#strikeTicks(m, id, state);
350
+ const { quote, policy } = await quoteMintForAccount(this.#client, this.#config, {
351
+ expiryMarketId: id,
352
+ wrapperId: this.wrapperIdFor(owner),
353
+ lowerTick,
354
+ higherTick,
355
+ request: {
356
+ shape: "exact-quantity",
357
+ quantityRaw
358
+ },
359
+ ordersConfig: orders,
360
+ ...feeds
361
+ });
362
+ return PredictClient.#queuedMintQuote(quote, policy);
363
+ }
218
364
  const tx = await this.#buildMint(owner, m, opts$1);
219
365
  return this.#quoteMintTransaction(owner, tx);
220
366
  },
221
- quoteMintCost: async (owner, m, opts$1) => this.#quoteMintTransaction(owner, await this.#buildMintCost(owner, m, opts$1)),
367
+ quoteMintCost: async (owner, m, opts$1) => {
368
+ if (this.cfg.packages.predictDelayedExecution) {
369
+ const orders = this.#requireDelayedExecution();
370
+ const feeds = this.#feeds(m.underlying);
371
+ const { id, state } = await this.#resolveMarket(m);
372
+ const { lowerTick, higherTick } = await this.#strikeTicks(m, id, state);
373
+ const { policy, availableRaw } = await orderFeeAndBalance(this.#client, orders, owner, this.cfg.quoteCoinType);
374
+ const fee = policy.orderFee;
375
+ const spendRaw = usdcToRaw(opts$1.spend);
376
+ const escrowable = availableRaw > fee ? availableRaw - fee : 0n;
377
+ const { quote } = await quoteMintForAccount(this.#client, this.#config, {
378
+ expiryMarketId: id,
379
+ wrapperId: this.wrapperIdFor(owner),
380
+ lowerTick,
381
+ higherTick,
382
+ request: {
383
+ shape: "exact-cost",
384
+ maxCostRaw: spendRaw < escrowable ? spendRaw : escrowable,
385
+ minQuantityRaw: usdcToRaw(opts$1.minQuantity)
386
+ },
387
+ ...feeds
388
+ });
389
+ return PredictClient.#queuedMintQuote(quote, policy);
390
+ }
391
+ return this.#quoteMintTransaction(owner, await this.#buildMintCost(owner, m, opts$1));
392
+ },
393
+ quoteSell: async (owner, m, opts$1) => {
394
+ const orders = this.#requireDelayedExecution();
395
+ const feeds = this.#feeds(m.underlying);
396
+ const { id } = await this.#resolveMarket(m);
397
+ const closeQuantityRaw = usdcToRaw(opts$1.quantity);
398
+ this.#assertLot(closeQuantityRaw);
399
+ const queueId = await this.#existingQueueId(orders, id);
400
+ const { quote, policy } = await quoteRedeemOpen(this.#client, orders, {
401
+ expiryMarketId: id,
402
+ queueId,
403
+ wrapperId: this.wrapperIdFor(owner),
404
+ recordId: opts$1.recordId,
405
+ closeQuantityRaw,
406
+ ...feeds
407
+ });
408
+ const orderFee = policy.orderFee;
409
+ return {
410
+ probability: rawToProbability(quote.probability),
411
+ proceeds: rawToUsdc(quote.proceeds),
412
+ net: rawToUsdc(quote.proceeds - orderFee),
413
+ fees: {
414
+ trading: rawToUsdc(quote.tradingFee),
415
+ builder: rawToUsdc(quote.builderFee),
416
+ inventoryImpactRebate: rawToUsdc(quote.inventoryImpactRebate),
417
+ order: rawToUsdc(orderFee)
418
+ },
419
+ quantityClosed: rawToUsdc(quote.closeQuantity),
420
+ raw: {
421
+ probability: quote.probability,
422
+ proceeds: quote.proceeds,
423
+ orderFee,
424
+ quantityClosed: quote.closeQuantity
425
+ }
426
+ };
427
+ },
428
+ executionMode: async () => executionModeFor(await versionWatermark(this.#client, this.cfg.objects.protocolConfig), this.#recordsDelayedExecution(), this.cfg.packages.predictDelayedExecution != null),
429
+ queue: async (m, owner) => {
430
+ const orders = this.#requireDelayedExecution();
431
+ const { id } = await this.#resolveMarket(m);
432
+ const state = await this.#queueState(orders, id, { owner });
433
+ const nowMs = BigInt(Date.now());
434
+ const policy = state.desk.policy;
435
+ const mode = executionModeFor(state.protocol.versionWatermark, true);
436
+ const timing = previewTiming({
437
+ nowMs,
438
+ policy,
439
+ heads: state.heads,
440
+ expiryMs: state.expiryMs,
441
+ noTradeWindowMs: state.protocol.noTradeWindowMs
442
+ });
443
+ const refusalFor = (side) => {
444
+ try {
445
+ this.#assertQueueOpen(state, side, nowMs);
446
+ return null;
447
+ } catch (e) {
448
+ if (e instanceof PredictPreflightError) return e.code;
449
+ throw e;
450
+ }
451
+ };
452
+ const refusal = {
453
+ mint: refusalFor("mint"),
454
+ sell: refusalFor("sell")
455
+ };
456
+ return {
457
+ ...state,
458
+ mode,
459
+ timing,
460
+ acceptingMints: refusal.mint == null,
461
+ acceptingSells: refusal.sell == null,
462
+ refusal,
463
+ maxMint: {
464
+ exactQuantity: maxMintNow({
465
+ shape: "exact-quantity",
466
+ spareCashRaw: state.spareCash,
467
+ minEntryProbability: state.minEntryProbability,
468
+ lotSize: BigInt(this.cfg.units.positionLotSize),
469
+ asOfMs: nowMs
470
+ }),
471
+ budget: maxMintNow({
472
+ shape: "budget",
473
+ spareCashRaw: state.spareCash,
474
+ minEntryProbability: state.minEntryProbability,
475
+ availableRaw: state.account?.availableRaw,
476
+ orderFeeRaw: policy.orderFee,
477
+ asOfMs: nowMs
478
+ })
479
+ }
480
+ };
481
+ },
482
+ planMint: async (owner, m, opts$1) => {
483
+ const orders = this.#requireDelayedExecution();
484
+ const feeds = this.#feeds(m.underlying);
485
+ const { id, state: market } = await this.#resolveMarket(m);
486
+ const { lowerTick, higherTick } = await this.#strikeTicks(m, id, market);
487
+ const hasAccount = await this.#hasAccount(owner);
488
+ const state = await this.#queueState(orders, id, hasAccount ? { owner } : {});
489
+ const nowMs = BigInt(Date.now());
490
+ const policy = state.desk.policy;
491
+ const fee = policy.orderFee;
492
+ const availableRaw = state.account?.availableRaw ?? null;
493
+ const lot = BigInt(this.cfg.units.positionLotSize);
494
+ const ticks = {
495
+ expiryMarketId: id,
496
+ lowerTick,
497
+ higherTick,
498
+ ...feeds
499
+ };
500
+ const forAccount = (request) => quoteMintForAccount(this.#client, this.#config, {
501
+ ...ticks,
502
+ wrapperId: this.wrapperIdFor(owner),
503
+ request
504
+ }).then((r) => r.quote);
505
+ let quote;
506
+ let quoteForAccount;
507
+ let budgetRequested = null;
508
+ if ("amount" in opts$1) {
509
+ const amountRaw = usdcToRaw(opts$1.amount);
510
+ budgetRequested = (opts$1.orderFee ?? "inclusive") === "inclusive" ? amountRaw > fee ? amountRaw - fee : 0n : amountRaw;
511
+ if (budgetRequested === 0n) throw new PredictPreflightError("min-premium", `${opts$1.amount} doesn't cover the ${rawToUsdc(fee)} order fee, so it buys no premium`);
512
+ if (budgetRequested < MIN_PREMIUM) throw new PredictPreflightError("min-premium", `a budget of ${rawToUsdc(budgetRequested)} is below the minimum premium (a mint's premium must be at least ${rawToUsdc(MIN_PREMIUM)} USDC)`);
513
+ quoteForAccount = availableRaw != null && availableRaw > fee && availableRaw - fee >= budgetRequested;
514
+ const budget = budgetRequested;
515
+ const search = () => this.#searchBudgetQuote(ticks, budget, lot).catch(async (error) => {
516
+ if (error instanceof PredictPreflightError && error.code === "min-premium") throw await this.#entryBandRefusal(m) ?? error;
517
+ throw await this.#quoteRefusal(error, { m });
518
+ });
519
+ if (quoteForAccount) try {
520
+ quote = await forAccount({
521
+ shape: "exact-cost",
522
+ maxCostRaw: budget,
523
+ minQuantityRaw: 0n
524
+ });
525
+ } catch (error) {
526
+ if (!isOrderFailsLimits(error)) throw await this.#quoteRefusal(error);
527
+ await search();
528
+ throw error;
529
+ }
530
+ else quote = await search();
531
+ } else {
532
+ const quantityRaw = usdcToRaw(opts$1.quantity);
533
+ this.#assertLot(quantityRaw);
534
+ quoteForAccount = hasAccount;
535
+ try {
536
+ quote = hasAccount ? await forAccount({
537
+ shape: "exact-quantity",
538
+ quantityRaw
539
+ }) : (await quoteMintAnonymous(this.#client, this.#config, {
540
+ ...ticks,
541
+ request: {
542
+ shape: "exact-quantity",
543
+ quantityRaw
544
+ }
545
+ })).quote;
546
+ } catch (error) {
547
+ throw await this.#quoteRefusal(error, {
548
+ m,
549
+ quantityRaw
550
+ });
551
+ }
552
+ }
553
+ const costRaw = quote.allInCost - quote.penaltyFee;
554
+ const slippage = PredictClient.#appliedSlippage(opts$1, quote.entryProbability, state, nowMs);
555
+ const limitsIn = {
556
+ quoteCostRaw: costRaw,
557
+ quoteQuantityRaw: quote.quantity,
558
+ entryProbabilityRaw: quote.entryProbability,
559
+ slippageRaw: slippage.raw,
560
+ feeIncentiveSubsidyRaw: quote.feeIncentiveSubsidy,
561
+ lotSize: lot
562
+ };
563
+ let budgetRaw;
564
+ let minQuantityRaw;
565
+ let admitted = null;
566
+ let maxCostRaw = null;
567
+ let maxProbabilityRaw = null;
568
+ let price;
569
+ let order;
570
+ if (budgetRequested != null) {
571
+ const limits = budgetMintLimits({
572
+ ...limitsIn,
573
+ budgetRaw: budgetRequested
574
+ });
575
+ budgetRaw = budgetRequested;
576
+ const unsubsidizedCost = costRaw + quote.feeIncentiveSubsidy;
577
+ const start = unsubsidizedCost === 0n ? quote.quantity : budgetRaw * quote.quantity / unsubsidizedCost / lot * lot;
578
+ admitted = await this.#admittedFloor((quantityRaw) => quoteForAccount ? forAccount({
579
+ shape: "exact-quantity",
580
+ quantityRaw
581
+ }) : quoteMintAnonymous(this.#client, this.#config, {
582
+ ...ticks,
583
+ request: {
584
+ shape: "exact-quantity",
585
+ quantityRaw
586
+ }
587
+ }).then((r) => r.quote), budgetRaw, start < quote.quantity ? start : quote.quantity, lot, quote.entryProbability, quote.quantity === 0n ? 0n : unsubsidizedCost * 1000000000n / quote.quantity);
588
+ const ceiling = "quantity" in admitted ? admitted.quantity : 0n;
589
+ minQuantityRaw = limits.minQuantityRaw < ceiling ? limits.minQuantityRaw : ceiling;
590
+ price = limits.pricePerContract;
591
+ order = {
592
+ builder: "enqueueMintCost",
593
+ options: {
594
+ spend: rawToUsdc(budgetRaw),
595
+ minQuantity: rawToUsdc(minQuantityRaw)
596
+ }
597
+ };
598
+ } else {
599
+ const limits = exactMintLimits(limitsIn);
600
+ maxCostRaw = limits.maxCostRaw;
601
+ maxProbabilityRaw = limits.maxProbabilityRaw;
602
+ budgetRaw = maxCostRaw < quote.quantity ? maxCostRaw : quote.quantity;
603
+ minQuantityRaw = quote.quantity;
604
+ price = limits.pricePerContract;
605
+ order = {
606
+ builder: "enqueueMint",
607
+ options: {
608
+ quantity: rawToUsdc(quote.quantity),
609
+ maxCost: rawToUsdc(maxCostRaw),
610
+ maxProbability: rawToProbability(maxProbabilityRaw)
611
+ }
612
+ };
613
+ }
614
+ const totalDebitRaw = budgetRaw + fee;
615
+ const expectedDebitRaw = costRaw + fee;
616
+ const inclusive = "amount" in opts$1 && (opts$1.orderFee ?? "inclusive") === "inclusive";
617
+ const refusal = PredictClient.#refusal(() => {
618
+ this.#assertQueueOpen(state, "mint", nowMs);
619
+ if (availableRaw == null || availableRaw < totalDebitRaw) throw new PredictPreflightError("fee", `the balance doesn't cover the plan's ${rawToUsdc(totalDebitRaw)} debit`);
620
+ PredictClient.#assertMintOrder(state, policy, budgetRequested != null ? {
621
+ kind: ORDER_KIND.EXACT_COST,
622
+ maxCostRaw: budgetRaw
623
+ } : {
624
+ kind: ORDER_KIND.EXACT_QUANTITY,
625
+ maxCostRaw: maxCostRaw ?? budgetRaw,
626
+ quantityRaw: quote.quantity
627
+ });
628
+ if (costRaw + quote.feeIncentiveSubsidy > quote.quantity) throw new PredictPreflightError("cost-above-payout", "the all-in cost without the fee subsidy is above the payout");
629
+ if (admitted != null && "refusal" in admitted) throw new PredictPreflightError(admitted.refusal, admitted.refusal === "min-premium" ? `without the fee subsidy, ${rawToUsdc(budgetRaw)} buys no fill that clears the ${rawToUsdc(MIN_PREMIUM)} minimum premium` : admitted.refusal === "entry-band" ? "the entry probability left the market's entry band while the order was sized: plan again, or pick a strike nearer the money" : `without the fee subsidy, ${rawToUsdc(budgetRaw)} buys a fill near $1 a contract, whose admission sizing can't be previewed`);
630
+ });
631
+ let max = maxMintNow(budgetRequested != null ? {
632
+ shape: "budget",
633
+ spareCashRaw: state.spareCash,
634
+ minEntryProbability: state.minEntryProbability,
635
+ availableRaw: availableRaw ?? void 0,
636
+ orderFeeRaw: fee,
637
+ asOfMs: nowMs
638
+ } : {
639
+ shape: "exact-quantity",
640
+ spareCashRaw: state.spareCash,
641
+ minEntryProbability: state.minEntryProbability,
642
+ lotSize: lot,
643
+ asOfMs: nowMs
644
+ }).maxRaw;
645
+ if (budgetRequested == null && availableRaw != null && price.worstRaw > 0n) {
646
+ const spendable = availableRaw > fee ? availableRaw - fee : 0n;
647
+ const perContract = price.worstRaw < 1000000000n ? price.worstRaw : 1000000000n;
648
+ const byBalance = spendable * 1000000000n / perContract / lot * lot;
649
+ if (max == null || byBalance < max) max = byBalance;
650
+ }
651
+ return {
652
+ shape: budgetRequested != null ? "budget" : "exact-quantity",
653
+ target: {
654
+ owner: normalizeSuiAddress(owner),
655
+ expiryMarketId: id,
656
+ lowerTick,
657
+ higherTick
658
+ },
659
+ quote: PredictClient.#queuedMintQuote(quote, policy),
660
+ quoteForAccount,
661
+ slippage: slippage.applied,
662
+ potentialPayout: rawToUsdc(quote.quantity),
663
+ minPayout: rawToUsdc(minQuantityRaw),
664
+ payoutMultiple: Number(quote.quantity) / Number(expectedDebitRaw),
665
+ minPayoutMultiple: Number(minQuantityRaw) / Number(totalDebitRaw),
666
+ pricePerContract: rawToProbability(price.nowRaw),
667
+ worstPricePerContract: rawToProbability(price.worstRaw),
668
+ orderFee: rawToUsdc(fee),
669
+ budget: rawToUsdc(budgetRaw),
670
+ totalDebit: rawToUsdc(totalDebitRaw),
671
+ expectedDebit: rawToUsdc(expectedDebitRaw),
672
+ balance: {
673
+ hasAccount,
674
+ available: availableRaw == null ? null : rawToUsdc(availableRaw),
675
+ covers: availableRaw == null ? null : availableRaw >= totalDebitRaw
676
+ },
677
+ maxNow: max == null ? null : rawToUsdc(inclusive ? max + fee : max),
678
+ timing: previewTiming({
679
+ nowMs,
680
+ policy,
681
+ heads: state.heads,
682
+ expiryMs: state.expiryMs,
683
+ noTradeWindowMs: state.protocol.noTradeWindowMs
684
+ }),
685
+ accepting: refusal == null,
686
+ refusal,
687
+ order,
688
+ raw: {
689
+ budget: budgetRaw,
690
+ orderFee: fee,
691
+ totalDebit: totalDebitRaw,
692
+ slippage: slippage.raw,
693
+ minQuantity: minQuantityRaw,
694
+ maxCost: maxCostRaw,
695
+ maxProbability: maxProbabilityRaw,
696
+ pricePerContract: price.nowRaw,
697
+ worstPricePerContract: price.worstRaw
698
+ }
699
+ };
700
+ },
701
+ planSell: async (owner, m, opts$1) => {
702
+ const orders = this.#requireDelayedExecution();
703
+ const { id } = await this.#resolveMarket(m);
704
+ const state = await this.#queueState(orders, id, {
705
+ owner,
706
+ recordIds: [opts$1.recordId]
707
+ });
708
+ const record = PredictClient.#assertRecordOpen(state, opts$1.recordId);
709
+ this.#assertSellQuantity(record, usdcToRaw(opts$1.quantity));
710
+ const quote = await this.read.quoteSell(owner, m, {
711
+ recordId: opts$1.recordId,
712
+ quantity: opts$1.quantity
713
+ }).catch(async (error) => {
714
+ throw await this.#quoteRefusal(error);
715
+ });
716
+ const nowMs = BigInt(Date.now());
717
+ const slippage = PredictClient.#appliedSlippage(opts$1, quote.raw.probability, state, nowMs);
718
+ const limits = sellLimits({
719
+ proceedsRaw: quote.raw.proceeds,
720
+ closeQuantityRaw: quote.raw.quantityClosed,
721
+ probabilityRaw: quote.raw.probability,
722
+ slippageRaw: slippage.raw
723
+ });
724
+ const fee = quote.raw.orderFee;
725
+ const refusal = PredictClient.#refusal(() => {
726
+ const { policy } = this.#assertQueueOpen(state, "sell", nowMs);
727
+ this.#assertSellOrder(state, policy, opts$1.recordId, usdcToRaw(opts$1.quantity));
728
+ });
729
+ return {
730
+ target: {
731
+ owner: normalizeSuiAddress(owner),
732
+ expiryMarketId: id,
733
+ recordId: opts$1.recordId
734
+ },
735
+ quote,
736
+ slippage: slippage.applied,
737
+ proceeds: quote.proceeds,
738
+ net: quote.net,
739
+ minProceeds: rawToUsdc(limits.minProceedsRaw),
740
+ minNet: rawToUsdc(limits.minProceedsRaw - fee),
741
+ orderFee: rawToUsdc(fee),
742
+ timing: previewTiming({
743
+ nowMs,
744
+ policy: state.desk.policy,
745
+ heads: state.heads,
746
+ expiryMs: state.expiryMs,
747
+ noTradeWindowMs: state.protocol.noTradeWindowMs
748
+ }),
749
+ accepting: refusal == null,
750
+ refusal,
751
+ order: {
752
+ builder: "enqueueSell",
753
+ options: {
754
+ recordId: opts$1.recordId,
755
+ quantity: opts$1.quantity,
756
+ minProbability: rawToProbability(limits.minProbabilityRaw),
757
+ minProceeds: rawToUsdc(limits.minProceedsRaw)
758
+ }
759
+ },
760
+ raw: {
761
+ slippage: slippage.raw,
762
+ minProceeds: limits.minProceedsRaw,
763
+ minProbability: limits.minProbabilityRaw,
764
+ orderFee: fee
765
+ }
766
+ };
767
+ },
768
+ order: async (m, recordId) => (await this.read.orders(m, [recordId]))[0],
769
+ orders: async (m, recordIds) => {
770
+ const orders = this.#requireDelayedExecution();
771
+ const { id } = await this.#resolveMarket(m);
772
+ const queueId = await this.#existingQueueId(orders, id);
773
+ const records = await queuedOrders(this.#client, orders, {
774
+ expiryMarketId: id,
775
+ queueId
776
+ }, recordIds);
777
+ const nowMs = BigInt(Date.now());
778
+ return records.map((record, i) => record ? {
779
+ recordId: recordIds[i],
780
+ record,
781
+ view: orderView(record, nowMs, { lotSize: BigInt(this.cfg.units.positionLotSize) })
782
+ } : null);
783
+ },
784
+ waitForOutcome: async (m, recordId, opts$1 = {}) => {
785
+ const pollMs = opts$1.pollMs ?? 250;
786
+ const deadline = Date.now() + (opts$1.timeoutMs ?? 3e4);
787
+ let seen = false;
788
+ for (;;) {
789
+ const order = await this.read.order(m, recordId);
790
+ const timedOut = Date.now() + pollMs > deadline;
791
+ if (!order) {
792
+ if (seen || timedOut) return {
793
+ outcome: "gone",
794
+ order: null
795
+ };
796
+ } else {
797
+ seen = true;
798
+ const state = order.view.state;
799
+ if (state === "filled" || state === "refunded" || state === "closed") return {
800
+ outcome: state,
801
+ order
802
+ };
803
+ if (timedOut) return {
804
+ outcome: "timeout",
805
+ order
806
+ };
807
+ }
808
+ await sleep(pollMs, opts$1.signal);
809
+ }
810
+ },
811
+ pendingFunds: async (owner) => rawToUsdc(await pendingFunds(this.#client, this.wrapperIdFor(owner), this.cfg.quoteCoinType)),
812
+ lazerPackages: (stateId) => {
813
+ const id = stateId ?? this.cfg.oracle?.pythLazerState;
814
+ if (!id) throw new PredictInputError("pass the Pyth Lazer State id");
815
+ return lazerPackages(this.#client, id);
816
+ },
222
817
  quoteRedeem: async (owner, m, opts$1) => {
223
818
  const tx = await this.#buildRedeem(owner, m, opts$1);
224
819
  const events = await simulateWithEvents(this.#client, tx, owner);
@@ -258,6 +853,19 @@ var PredictClient = class PredictClient {
258
853
  referencePrice: PredictClient.#referencePriceOf(state)
259
854
  };
260
855
  },
856
+ settlement: async (m) => {
857
+ const { id, state } = await this.#resolveMarket(m);
858
+ const raw = await settlementPrice(this.#client, this.#config, id);
859
+ return {
860
+ marketId: id,
861
+ expiryMs: state.expiryMs,
862
+ settled: raw != null,
863
+ settlementPrice: raw == null ? null : fromRaw(raw, 9),
864
+ settlementPriceRaw: raw,
865
+ tickSizeRaw: state.tickSizeRaw
866
+ };
867
+ },
868
+ feePolicy: async (m) => marketFeePolicy(this.#client, (await this.#resolveMarket(m)).id),
261
869
  balance: async (owner) => rawToUsdc(await accountBalance(this.#client, this.#config, owner, this.cfg.quoteCoinType)),
262
870
  plpBalance: (owner) => accountBalance(this.#client, this.#config, owner, this.cfg.coinTypes.plp),
263
871
  pool: async () => {
@@ -282,7 +890,19 @@ var PredictClient = class PredictClient {
282
890
  withdraw: (r) => exactlyOne(decodeWithdrawals(this.cfg, r), "Withdrawn"),
283
891
  plpRequest: (r) => exactlyOne(decodePlpRequests(this.cfg, r), "supply/withdraw-requested"),
284
892
  plpCancel: (r) => exactlyOne(decodePlpCancels(this.cfg, r), "RequestCancelled"),
285
- builderCode: (r) => exactlyOne(decodeBuilderCodeSets(this.cfg, r), "BuilderCodeSet")
893
+ builderCode: (r) => exactlyOne(decodeBuilderCodeSets(this.cfg, r), "BuilderCodeSet"),
894
+ enqueue: (r) => exactlyOne(decodeEnqueues(this.cfg, r), "OrderEnqueued"),
895
+ enqueues: (r) => decodeEnqueues(this.cfg, r),
896
+ queueEvents: (r) => decodeQueueEvents(this.cfg, r),
897
+ cohortCommits: (r) => decodeCohortCommits(this.cfg, r),
898
+ queuedFills: (r) => decodeQueuedFills(this.cfg, r),
899
+ queuedRefunds: (r) => decodeQueuedRefunds(this.cfg, r),
900
+ openRecordPayouts: (r) => decodeOpenRecordPayouts(this.cfg, r),
901
+ marketPayoutsCompleted: (r) => decodeMarketPayoutsCompleted(this.cfg, r),
902
+ queueOps: (r) => decodeQueueOps(this.cfg, r),
903
+ recordFunds: (r) => decodeRecordFunds(this.cfg, r),
904
+ policyUpdates: (r) => decodePolicyUpdates(this.cfg, r),
905
+ expiryPnlRealized: (r) => decodeExpiryPnlRealized(this.cfg, r)
286
906
  };
287
907
  this.cfg = opts.config ?? getConfig(opts.network);
288
908
  this.#client = opts.client;
@@ -291,6 +911,14 @@ var PredictClient = class PredictClient {
291
911
  wrapperIdFor(owner) {
292
912
  return deriveAccountWrapperIdFrom(this.#config, owner);
293
913
  }
914
+ /**
915
+ * The deterministic id of a market's `MarketQueue` under the config's queue registry, whether
916
+ * or not it exists yet — no chain read. Throws `PredictInputError` while the config doesn't
917
+ * record delayed execution.
918
+ */
919
+ queueIdFor(marketId) {
920
+ return deriveQueueId(this.#requireDelayedExecution().queueRegistry, marketId);
921
+ }
294
922
  #underlying(underlying) {
295
923
  const u = this.cfg.underlyings[underlying];
296
924
  if (!u) throw new PredictInputError(`unknown underlying: ${underlying}`);
@@ -380,6 +1008,134 @@ var PredictClient = class PredictClient {
380
1008
  const lot = BigInt(this.cfg.units.positionLotSize);
381
1009
  if (quantityRaw % lot !== 0n) throw new PredictInputError(`quantity ${quantityRaw} raw is not a whole ${lot}-unit lot (position_lot_size)`);
382
1010
  }
1011
+ async #hasAccount(owner) {
1012
+ const { objects: [wrapper] } = await this.#client.core.getObjects({ objectIds: [this.wrapperIdFor(owner)] });
1013
+ return !(wrapper instanceof Error);
1014
+ }
1015
+ static #appliedSlippage(opts, probabilityRaw, state, nowMs) {
1016
+ const cents = opts.slippageCents ?? "auto";
1017
+ if (cents !== "auto") {
1018
+ if (!(Number.isFinite(cents) && cents >= 0 && cents <= 100)) throw new PredictInputError(`slippageCents must be in [0, 100] cents per contract, got ${cents}`);
1019
+ const raw$1 = BigInt(Math.round(cents * 1e7));
1020
+ return {
1021
+ raw: raw$1,
1022
+ applied: {
1023
+ cents: Number(raw$1) / 1e7,
1024
+ source: "input",
1025
+ band: null
1026
+ }
1027
+ };
1028
+ }
1029
+ const policy = state.desk.policy;
1030
+ const band = slippageBand({
1031
+ probability: Math.min(Math.max(rawToProbability(probabilityRaw), 1e-6), .999999),
1032
+ timeToExpiryMs: Number(state.expiryMs > nowMs ? state.expiryMs - nowMs : 0n),
1033
+ delayMs: Number(policy.delayMs),
1034
+ tickMs: Number(channelTickMs(policy.pythChannel)),
1035
+ k: opts.k
1036
+ });
1037
+ const raw = BigInt(Math.ceil(band.deltaProbability * 1e9));
1038
+ return {
1039
+ raw,
1040
+ applied: {
1041
+ cents: Number(raw) / 1e7,
1042
+ source: "auto",
1043
+ band
1044
+ }
1045
+ };
1046
+ }
1047
+ async #quoteRefusal(error, mint) {
1048
+ if (isPastExpiry(error)) return new PredictPreflightError("past-cutoff", "the market reached its expiry, so it has no live price and takes no orders");
1049
+ if (mint != null && isOrderFailsLimits(error)) return await this.#entryBandRefusal(mint.m, mint.quantityRaw) ?? error;
1050
+ return error;
1051
+ }
1052
+ async #entryBandRefusal(m, quantityRaw) {
1053
+ if (m.side === "range") return null;
1054
+ const read = await Promise.all([this.read.price(m), this.read.feePolicy(m)]).catch(() => null);
1055
+ if (read == null) return null;
1056
+ const [prices, policy] = read;
1057
+ const probability = probabilityToRaw(m.side === "up" ? prices.up : prices.down);
1058
+ if (probability < policy.minEntryProbability || probability > policy.maxEntryProbability) return new PredictPreflightError("entry-band", `the ${m.side} probability ${rawToProbability(probability)} is outside the market's entry band [${rawToProbability(policy.minEntryProbability)}, ${rawToProbability(policy.maxEntryProbability)}]: pick a strike nearer the money`);
1059
+ if (quantityRaw != null && quantityRaw * probability / 1000000000n < MIN_PREMIUM) return new PredictPreflightError("min-premium", `${rawToUsdc(quantityRaw)} contracts cost a premium below the ${rawToUsdc(MIN_PREMIUM)} USDC minimum`);
1060
+ return null;
1061
+ }
1062
+ async #admittedFloor(quoteAt, budgetRaw, startRaw, lot, entryProbabilityRaw, unsubsidizedPricePerContractRaw) {
1063
+ const ceilLot = (x) => (x + lot - 1n) / lot * lot;
1064
+ const minPremiumQuantity = entryProbabilityRaw === 0n ? 0n : ceilLot((MIN_PREMIUM * 1000000000n + entryProbabilityRaw - 1n) / entryProbabilityRaw);
1065
+ let quantity = startRaw;
1066
+ let raised = false;
1067
+ for (let probe = 0; probe < 5 && quantity > 0n; probe++) {
1068
+ let quote;
1069
+ try {
1070
+ quote = await quoteAt(quantity);
1071
+ } catch (e) {
1072
+ if (!isOrderFailsLimits(e)) throw e;
1073
+ if (!raised && quantity < minPremiumQuantity) {
1074
+ raised = true;
1075
+ quantity = minPremiumQuantity;
1076
+ continue;
1077
+ }
1078
+ if (raised || quantity < minPremiumQuantity) return { refusal: "min-premium" };
1079
+ return { refusal: unsubsidizedPricePerContractRaw < NEAR_DOLLAR_PER_CONTRACT ? "entry-band" : "cost-above-payout" };
1080
+ }
1081
+ const unsubsidized = quote.allInCost - quote.penaltyFee + quote.feeIncentiveSubsidy;
1082
+ if (unsubsidized <= budgetRaw) return quantity >= budgetRaw ? { quantity } : { refusal: "cost-above-payout" };
1083
+ if (raised) return { refusal: "min-premium" };
1084
+ const next = quantity * budgetRaw / unsubsidized / lot * lot;
1085
+ quantity = next < quantity ? next : quantity - lot;
1086
+ }
1087
+ return { refusal: "min-premium" };
1088
+ }
1089
+ async #searchBudgetQuote(ticks, budgetRaw, lot) {
1090
+ const floorLot = (x) => x / lot * lot;
1091
+ let refusal = null;
1092
+ let priced = false;
1093
+ const probeQuote = async (request) => {
1094
+ try {
1095
+ const { quote: quote$1 } = await quoteMintAnonymous(this.#client, this.#config, {
1096
+ ...ticks,
1097
+ request
1098
+ });
1099
+ priced = true;
1100
+ return quote$1;
1101
+ } catch (e) {
1102
+ if (!isOrderFailsLimits(e)) throw e;
1103
+ refusal ??= e;
1104
+ return null;
1105
+ }
1106
+ };
1107
+ let best = null;
1108
+ let quote = await probeQuote({
1109
+ shape: "exact-amount",
1110
+ maxPremiumRaw: budgetRaw,
1111
+ minQuantityRaw: lot
1112
+ });
1113
+ for (let probe = 1; quote != null; probe++) {
1114
+ const cost = quote.allInCost - quote.penaltyFee;
1115
+ if (cost <= budgetRaw && (best == null || quote.quantity > best.quantity)) best = quote;
1116
+ if (probe === 4) break;
1117
+ const next = cost === 0n ? quote.quantity : floorLot(budgetRaw * quote.quantity / cost);
1118
+ if (next === 0n || next === quote.quantity) break;
1119
+ quote = await probeQuote({
1120
+ shape: "exact-quantity",
1121
+ quantityRaw: next
1122
+ });
1123
+ }
1124
+ if (best == null) {
1125
+ if (!priced && refusal != null && budgetRaw >= MIN_PREMIUM + lot) throw refusal;
1126
+ throw new PredictPreflightError("min-premium", `a budget of ${rawToUsdc(budgetRaw)} buys no payout at the current price (a mint's premium must be at least ${rawToUsdc(MIN_PREMIUM)} USDC)`);
1127
+ }
1128
+ return best;
1129
+ }
1130
+ static #refusal(check) {
1131
+ try {
1132
+ check();
1133
+ return null;
1134
+ } catch (e) {
1135
+ if (e instanceof PredictPreflightError) return e.code;
1136
+ throw e;
1137
+ }
1138
+ }
383
1139
  async #buildMint(owner, m, opts) {
384
1140
  const feeds = this.#feeds(m.underlying);
385
1141
  const { id, state } = await this.#resolveMarket(m);
@@ -451,7 +1207,227 @@ var PredictClient = class PredictClient {
451
1207
  if (tick == null) throw new PredictInputError(`reference price not set yet for ${m.underlying} @ ${m.expiryMs} — retry shortly or pass a numeric strike`);
452
1208
  return tick * state.tickSizeRaw;
453
1209
  }
1210
+ #requireDelayedExecution() {
1211
+ return toOrdersConfig(this.cfg);
1212
+ }
1213
+ #recordsDelayedExecution() {
1214
+ const { predictDelayedExecution, predictOrders } = this.cfg.packages;
1215
+ const { orderDesk, queueRegistry } = this.cfg.objects;
1216
+ return Boolean(predictDelayedExecution && predictOrders && orderDesk && queueRegistry);
1217
+ }
1218
+ async #existingQueueId(orders, marketId) {
1219
+ const queueId = deriveQueueId(orders.queueRegistry, marketId);
1220
+ if (this.#knownQueues.has(queueId)) return queueId;
1221
+ const { objects: [queue] } = await this.#client.core.getObjects({ objectIds: [queueId] });
1222
+ if (queue instanceof Error) throw new PredictPreflightError("no-queue", `market ${marketId} has no order queue yet (\`queue::create_and_share\` hasn't run for it)`);
1223
+ this.#knownQueues.add(queueId);
1224
+ return queueId;
1225
+ }
1226
+ async #queueState(orders, marketId, opts = {}) {
1227
+ const queueId = await this.#existingQueueId(orders, marketId);
1228
+ return marketQueueState(this.#client, orders, marketId, {
1229
+ owner: opts.owner,
1230
+ quoteCoinType: this.cfg.quoteCoinType,
1231
+ recordIds: opts.recordIds,
1232
+ queueId
1233
+ });
1234
+ }
1235
+ #assertQueueOpen(state, side, nowMs) {
1236
+ const policy = state.desk.policy;
1237
+ if (!state.protocol.orderFlowEnabled) throw new PredictPreflightError("not-live", "queued orders aren't live yet: the protocol hasn't enabled the order-flow package");
1238
+ const mode = executionModeFor(state.protocol.versionWatermark, true);
1239
+ if (mode === "retired") throw new PredictPreflightError("retired", "the Predict package version this SDK calls is retired: update the SDK");
1240
+ if (mode !== "delayed") throw new PredictPreflightError("not-live", "queued orders aren't live yet: the protocol's version watermark hasn't been raised");
1241
+ if (state.desk.versionWatermark > ORDER_FLOW_PACKAGE_VERSION) throw new PredictPreflightError("retired", "the order-flow package version this SDK calls is retired: update the SDK");
1242
+ if (state.protocol.frozen) throw new PredictPreflightError("paused", "the protocol is frozen");
1243
+ if (side === "mint" && (state.protocol.tradingPaused || state.mintPaused)) throw new PredictPreflightError("paused", "minting is paused on this market");
1244
+ if (state.stuck) throw new PredictPreflightError("stuck", "pricing is delayed for this market, try again shortly");
1245
+ const [pending, capacity] = side === "mint" ? [state.pending.mints, policy.mintCapacity] : [state.pending.sells, policy.sellCapacity];
1246
+ if (pending >= capacity) throw new PredictPreflightError("queue-full", `the market has ${pending} waiting ${side}s, its maximum`);
1247
+ if (state.account && state.account.waitingOrders >= policy.perAccountCap) throw new PredictPreflightError("account-cap", `the account already has ${state.account.waitingOrders} waiting orders in this market, its maximum`);
1248
+ const timing = previewTiming({
1249
+ nowMs,
1250
+ policy,
1251
+ heads: state.heads,
1252
+ expiryMs: state.expiryMs,
1253
+ noTradeWindowMs: state.protocol.noTradeWindowMs
1254
+ });
1255
+ if (!timing.beforeCutoff) throw new PredictPreflightError("past-cutoff", "this market no longer takes orders before its expiry");
1256
+ return {
1257
+ policy,
1258
+ timing
1259
+ };
1260
+ }
1261
+ #preview(marketId, kind, timing, policy, budget, cashNeedRaw, spareCashRaw, funding) {
1262
+ const totalDebit = budget + policy.orderFee;
1263
+ return {
1264
+ marketId,
1265
+ kind,
1266
+ kindName: orderKindName(kind),
1267
+ timing,
1268
+ orderFee: rawToUsdc(policy.orderFee),
1269
+ budget: rawToUsdc(budget),
1270
+ totalDebit: rawToUsdc(totalDebit),
1271
+ cashNeedRaw,
1272
+ spareCashRaw,
1273
+ ...funding,
1274
+ raw: {
1275
+ orderFee: policy.orderFee,
1276
+ budget,
1277
+ totalDebit
1278
+ }
1279
+ };
1280
+ }
1281
+ async #planMint(owner, m, order, build) {
1282
+ const orders = this.#requireDelayedExecution();
1283
+ const feeds = this.#feeds(m.underlying);
1284
+ const { id, state: market } = await this.#resolveMarket(m);
1285
+ const { lowerTick, higherTick } = await this.#strikeTicks(m, id, market);
1286
+ const thunk = build(orders, {
1287
+ expiryMarketId: id,
1288
+ wrapperId: this.wrapperIdFor(owner),
1289
+ lowerTick,
1290
+ higherTick,
1291
+ ...feeds
1292
+ });
1293
+ const state = await this.#queueState(orders, id, { owner });
1294
+ const { policy, timing } = this.#assertQueueOpen(state, "mint", BigInt(Date.now()));
1295
+ const { budget, cashNeed } = PredictClient.#assertMintOrder(state, policy, order);
1296
+ const tx = new Transaction();
1297
+ tx.add(assertOrderFeeAtMost(orders, policy.orderFee));
1298
+ tx.add(thunk);
1299
+ return {
1300
+ transaction: tx,
1301
+ preview: this.#preview(id, order.kind, timing, policy, budget, cashNeed, state.spareCash, {
1302
+ needsFunding: false,
1303
+ fundedInTransaction: false
1304
+ })
1305
+ };
1306
+ }
1307
+ static #assertMintOrder(state, policy, order) {
1308
+ const available = state.account?.availableRaw ?? 0n;
1309
+ const budget = mintBudget({
1310
+ kind: order.kind,
1311
+ maxCostRaw: order.maxCostRaw,
1312
+ availableRaw: available,
1313
+ orderFeeRaw: policy.orderFee,
1314
+ quantityRaw: order.quantityRaw
1315
+ });
1316
+ if (budget == null) throw new PredictPreflightError("fee", `the balance (${rawToUsdc(available)}) doesn't cover the ${rawToUsdc(policy.orderFee)} order fee`);
1317
+ if (budget < MIN_PREMIUM) throw new PredictPreflightError("min-premium", `the escrowed budget ${rawToUsdc(budget)} is below the ${rawToUsdc(MIN_PREMIUM)} minimum premium`);
1318
+ if (order.kind !== ORDER_KIND.EXACT_QUANTITY && state.minEntryProbability === 0n) throw new PredictPreflightError("market-cash", "this market takes no budget mints");
1319
+ const cashNeed = mintCashNeed({
1320
+ kind: order.kind,
1321
+ budgetRaw: budget,
1322
+ minEntryProbability: state.minEntryProbability,
1323
+ quantityRaw: order.quantityRaw,
1324
+ maxPremiumRaw: order.maxPremiumRaw
1325
+ });
1326
+ if (cashNeed > state.spareCash) throw new PredictPreflightError("market-cash", "this market can't take an order this size right now");
1327
+ return {
1328
+ budget,
1329
+ cashNeed
1330
+ };
1331
+ }
1332
+ static #assertRecordOpen(state, recordId) {
1333
+ const record = state.records[0];
1334
+ if (!record || record.status !== ORDER_STATUS.OPEN || record.position.order_id === 0n) throw new PredictPreflightError("record-not-open", `record ${recordId} isn't an Open position`);
1335
+ return record;
1336
+ }
1337
+ #assertSellQuantity(record, closeQuantityRaw) {
1338
+ const held = decodeOrderRange(record.position.order_id, BigInt(this.cfg.units.positionLotSize)).quantity;
1339
+ if (closeQuantityRaw > held) throw new PredictInputError(`quantity ${rawToUsdc(closeQuantityRaw)} is above the record's ${rawToUsdc(held)}`);
1340
+ return held;
1341
+ }
1342
+ #assertSellOrder(state, policy, recordId, closeQuantityRaw) {
1343
+ const record = PredictClient.#assertRecordOpen(state, recordId);
1344
+ if (!state.account || normalizeSuiAddress(record.account_id) !== normalizeSuiAddress(state.account.accountId)) throw new PredictPreflightError("not-record-owner", `record ${recordId} belongs to another account`);
1345
+ if (!feeCovered("sell", state.account.availableRaw, policy.orderFee)) throw new PredictPreflightError("fee", `the balance doesn't cover the ${rawToUsdc(policy.orderFee)} order fee`);
1346
+ const held = this.#assertSellQuantity(record, closeQuantityRaw);
1347
+ const min = policy.minSellQuantity;
1348
+ if (closeQuantityRaw < min || closeQuantityRaw < held && held - closeQuantityRaw < min) throw new PredictPreflightError("below-min-sell", `a sell must close at least ${rawToUsdc(min)} and leave either nothing or at least that much`);
1349
+ }
1350
+ async #planSell(owner, m, opts) {
1351
+ const orders = this.#requireDelayedExecution();
1352
+ const feeds = this.#feeds(m.underlying);
1353
+ const { id } = await this.#resolveMarket(m);
1354
+ const closeQuantityRaw = usdcToRaw(opts.quantity);
1355
+ this.#assertLot(closeQuantityRaw);
1356
+ const thunk = enqueueRedeemOpen(orders, {
1357
+ expiryMarketId: id,
1358
+ wrapperId: this.wrapperIdFor(owner),
1359
+ recordId: opts.recordId,
1360
+ closeQuantityRaw,
1361
+ minProbabilityRaw: probabilityToRaw(opts.minProbability),
1362
+ minProceedsRaw: usdcToRaw(opts.minProceeds),
1363
+ ...feeds
1364
+ });
1365
+ const state = await this.#queueState(orders, id, {
1366
+ owner,
1367
+ recordIds: [opts.recordId]
1368
+ });
1369
+ const { policy, timing } = this.#assertQueueOpen(state, "sell", BigInt(Date.now()));
1370
+ this.#assertSellOrder(state, policy, opts.recordId, closeQuantityRaw);
1371
+ const cashNeed = cashNeedSell(closeQuantityRaw, state.backingBufferLambda);
1372
+ const needsFunding = cashNeed > state.spareCash;
1373
+ const fund = opts.fundMarket ?? "auto";
1374
+ const funded = fund === "always" || fund === "auto" && needsFunding;
1375
+ const tx = new Transaction();
1376
+ tx.add(assertOrderFeeAtMost(orders, policy.orderFee));
1377
+ tx.add(thunk);
1378
+ if (funded) tx.add(rebalanceExpiryCash(this.#config, { expiryMarketId: id }));
1379
+ return {
1380
+ transaction: tx,
1381
+ preview: this.#preview(id, ORDER_KIND.REDEEM_OPEN, timing, policy, 0n, cashNeed, state.spareCash, {
1382
+ needsFunding,
1383
+ fundedInTransaction: funded
1384
+ })
1385
+ };
1386
+ }
1387
+ static #queuedMintQuote(q, policy) {
1388
+ const costRaw = q.allInCost - q.penaltyFee;
1389
+ return {
1390
+ entryProbability: rawToProbability(q.entryProbability),
1391
+ premium: rawToUsdc(q.premium),
1392
+ fees: {
1393
+ trading: rawToUsdc(q.tradingFee),
1394
+ subsidy: rawToUsdc(q.feeIncentiveSubsidy),
1395
+ builder: rawToUsdc(q.builderFee),
1396
+ penalty: 0,
1397
+ referral: 0,
1398
+ inventoryImpact: rawToUsdc(q.inventoryImpactCharge)
1399
+ },
1400
+ cost: rawToUsdc(costRaw),
1401
+ quantity: rawToUsdc(q.quantity),
1402
+ raw: {
1403
+ premium: q.premium,
1404
+ cost: costRaw,
1405
+ quantity: q.quantity,
1406
+ entryProbability: q.entryProbability
1407
+ },
1408
+ feesExact: true,
1409
+ queued: true,
1410
+ orderFee: policy ? rawToUsdc(policy.orderFee) : void 0
1411
+ };
1412
+ }
454
1413
  };
1414
+ function sleep(ms, signal) {
1415
+ return new Promise((resolve, reject) => {
1416
+ if (signal?.aborted) {
1417
+ reject(signal.reason);
1418
+ return;
1419
+ }
1420
+ const onAbort = () => {
1421
+ clearTimeout(timer);
1422
+ reject(signal?.reason);
1423
+ };
1424
+ const timer = setTimeout(() => {
1425
+ signal?.removeEventListener("abort", onAbort);
1426
+ resolve();
1427
+ }, ms);
1428
+ signal?.addEventListener("abort", onAbort, { once: true });
1429
+ });
1430
+ }
455
1431
 
456
1432
  //#endregion
457
1433
  export { POSITION_LOT_SIZE, PredictClient, predict };