@waterx/sdk 4.0.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +37 -17
  2. package/dist/cjs/src/account/account.js +2 -1
  3. package/dist/cjs/src/account/config.d.ts +3 -2
  4. package/dist/cjs/src/account/funding/balance.d.ts +25 -2
  5. package/dist/cjs/src/account/funding/balance.js +36 -24
  6. package/dist/cjs/src/account/funding/credit.js +6 -10
  7. package/dist/cjs/src/constants.d.ts +15 -1
  8. package/dist/cjs/src/constants.js +18 -4
  9. package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
  10. package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +13 -0
  11. package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
  12. package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.js +31 -0
  13. package/dist/cjs/src/generated/waterx_rule/waterx_rule.d.ts +813 -0
  14. package/dist/cjs/src/generated/waterx_rule/waterx_rule.js +946 -0
  15. package/dist/cjs/src/oracle/aggregate.d.ts +23 -21
  16. package/dist/cjs/src/oracle/aggregate.js +133 -59
  17. package/dist/cjs/src/oracle/config.d.ts +82 -41
  18. package/dist/cjs/src/oracle/config.js +0 -42
  19. package/dist/cjs/src/oracle/host.d.ts +26 -11
  20. package/dist/cjs/src/oracle/index.d.ts +6 -2
  21. package/dist/cjs/src/oracle/index.js +36 -8
  22. package/dist/cjs/src/oracle/price-update-rule.d.ts +16 -10
  23. package/dist/cjs/src/oracle/price-update-rule.js +3 -3
  24. package/dist/cjs/src/oracle/pyth.d.ts +44 -0
  25. package/dist/cjs/src/oracle/pyth.js +48 -6
  26. package/dist/cjs/src/oracle/read-plane.d.ts +70 -0
  27. package/dist/cjs/src/oracle/read-plane.js +78 -0
  28. package/dist/cjs/src/oracle/rule-registry.d.ts +14 -11
  29. package/dist/cjs/src/oracle/rule-registry.js +16 -11
  30. package/dist/cjs/src/oracle/rules/pyth-core-rule.js +4 -4
  31. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
  32. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +29 -4
  33. package/dist/cjs/src/oracle/rules/pyth-rule.js +5 -4
  34. package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +126 -0
  35. package/dist/cjs/src/oracle/rules/waterx-rule.js +312 -0
  36. package/dist/cjs/src/perp/client.d.ts +71 -20
  37. package/dist/cjs/src/perp/client.js +35 -13
  38. package/dist/cjs/src/perp/config.d.ts +6 -7
  39. package/dist/cjs/src/perp/config.js +12 -11
  40. package/dist/cjs/src/perp/constants.d.ts +0 -6
  41. package/dist/cjs/src/perp/constants.js +11 -9
  42. package/dist/cjs/src/perp/fetch/account.js +3 -0
  43. package/dist/cjs/src/perp/fetch/bridge.js +2 -1
  44. package/dist/cjs/src/perp/fetch/market.js +2 -1
  45. package/dist/cjs/src/perp/fetch/positions.d.ts +16 -10
  46. package/dist/cjs/src/perp/fetch/positions.js +23 -20
  47. package/dist/cjs/src/perp/index.d.ts +9 -5
  48. package/dist/cjs/src/perp/index.js +16 -7
  49. package/dist/cjs/src/perp/liq-view.d.ts +64 -0
  50. package/dist/cjs/src/perp/liq-view.js +74 -0
  51. package/dist/cjs/src/perp/user/order.d.ts +13 -0
  52. package/dist/cjs/src/perp/user/order.js +30 -16
  53. package/dist/cjs/src/perp/user/staking.js +3 -2
  54. package/dist/cjs/src/perp/user/trading.js +25 -24
  55. package/dist/cjs/src/perp/user/wlp.js +6 -5
  56. package/dist/cjs/src/prediction/utils.d.ts +11 -2
  57. package/dist/cjs/src/prediction/utils.js +22 -22
  58. package/dist/cjs/src/unified-client.d.ts +41 -15
  59. package/dist/cjs/src/unified-client.js +4 -2
  60. package/dist/cjs/src/utils/format.d.ts +14 -0
  61. package/dist/cjs/src/utils/format.js +24 -0
  62. package/dist/cjs/src/utils/math.d.ts +304 -12
  63. package/dist/cjs/src/utils/math.js +397 -17
  64. package/dist/cjs/src/utils/validate.d.ts +69 -0
  65. package/dist/cjs/src/utils/validate.js +183 -0
  66. package/dist/src/account/account.js +2 -1
  67. package/dist/src/account/config.d.ts +3 -2
  68. package/dist/src/account/funding/balance.d.ts +25 -2
  69. package/dist/src/account/funding/balance.js +36 -24
  70. package/dist/src/account/funding/credit.js +6 -10
  71. package/dist/src/constants.d.ts +15 -1
  72. package/dist/src/constants.js +17 -3
  73. package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
  74. package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +10 -0
  75. package/dist/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
  76. package/dist/src/generated/waterx_rule/deps/sui/vec_map.js +27 -0
  77. package/dist/src/generated/waterx_rule/waterx_rule.d.ts +813 -0
  78. package/dist/src/generated/waterx_rule/waterx_rule.js +855 -0
  79. package/dist/src/oracle/aggregate.d.ts +23 -21
  80. package/dist/src/oracle/aggregate.js +133 -59
  81. package/dist/src/oracle/config.d.ts +82 -41
  82. package/dist/src/oracle/config.js +1 -41
  83. package/dist/src/oracle/host.d.ts +26 -11
  84. package/dist/src/oracle/index.d.ts +6 -2
  85. package/dist/src/oracle/index.js +27 -9
  86. package/dist/src/oracle/price-update-rule.d.ts +16 -10
  87. package/dist/src/oracle/price-update-rule.js +3 -3
  88. package/dist/src/oracle/pyth.d.ts +44 -0
  89. package/dist/src/oracle/pyth.js +45 -5
  90. package/dist/src/oracle/read-plane.d.ts +70 -0
  91. package/dist/src/oracle/read-plane.js +74 -0
  92. package/dist/src/oracle/rule-registry.d.ts +14 -11
  93. package/dist/src/oracle/rule-registry.js +16 -11
  94. package/dist/src/oracle/rules/pyth-core-rule.js +5 -5
  95. package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
  96. package/dist/src/oracle/rules/pyth-lazer-rule.js +28 -3
  97. package/dist/src/oracle/rules/pyth-rule.js +5 -4
  98. package/dist/src/oracle/rules/waterx-rule.d.ts +126 -0
  99. package/dist/src/oracle/rules/waterx-rule.js +305 -0
  100. package/dist/src/perp/client.d.ts +71 -20
  101. package/dist/src/perp/client.js +36 -14
  102. package/dist/src/perp/config.d.ts +6 -7
  103. package/dist/src/perp/config.js +11 -9
  104. package/dist/src/perp/constants.d.ts +0 -6
  105. package/dist/src/perp/constants.js +10 -8
  106. package/dist/src/perp/fetch/account.js +3 -0
  107. package/dist/src/perp/fetch/bridge.js +2 -1
  108. package/dist/src/perp/fetch/market.js +2 -1
  109. package/dist/src/perp/fetch/positions.d.ts +16 -10
  110. package/dist/src/perp/fetch/positions.js +28 -20
  111. package/dist/src/perp/index.d.ts +9 -5
  112. package/dist/src/perp/index.js +6 -4
  113. package/dist/src/perp/liq-view.d.ts +64 -0
  114. package/dist/src/perp/liq-view.js +71 -0
  115. package/dist/src/perp/user/order.d.ts +13 -0
  116. package/dist/src/perp/user/order.js +30 -16
  117. package/dist/src/perp/user/staking.js +3 -2
  118. package/dist/src/perp/user/trading.js +25 -24
  119. package/dist/src/perp/user/wlp.js +6 -5
  120. package/dist/src/prediction/utils.d.ts +11 -2
  121. package/dist/src/prediction/utils.js +22 -22
  122. package/dist/src/unified-client.d.ts +41 -15
  123. package/dist/src/unified-client.js +4 -2
  124. package/dist/src/utils/format.d.ts +14 -0
  125. package/dist/src/utils/format.js +21 -0
  126. package/dist/src/utils/math.d.ts +304 -12
  127. package/dist/src/utils/math.js +394 -17
  128. package/dist/src/utils/validate.d.ts +69 -0
  129. package/dist/src/utils/validate.js +167 -0
  130. package/package.json +4 -1
@@ -7,10 +7,24 @@
7
7
  *
8
8
  * Use `triggerPrice === undefined` (market form) to park an order at
9
9
  * tick 0 in the limit book; a keeper picks it up via `match_orders`.
10
+ *
11
+ * ## Trigger prices are exact order-book KEYS
12
+ *
13
+ * Every `triggerPrice` / `currentTriggerPrice` / `newTriggerPrice` below is the
14
+ * raw 1e9-scaled value the book is keyed by — off by a single 1e-9 unit and the
15
+ * lookup silently finds nothing. Build them with `rawPrice` in its EXACT mode
16
+ * (`rawPrice("95000.5")`, an `ExactDecimalUsd` string); the `number` mode
17
+ * round-trips through f64 and is exact only below ≈ $9,007,199.
18
+ *
19
+ * The params stay `bigint | number` (the RAW scaled value, not USD): both are
20
+ * legitimate raw inputs, `toU128` already rejects a non-safe-integer `number`
21
+ * before it can serialize wrong, and dropping `number` would break published
22
+ * call shapes. The mode choice belongs one level up, at `rawPrice`.
10
23
  */
11
24
  import { makeSenderRequest } from "../../account/account-request.js";
12
25
  import { newPlaceOrderArgument } from "../../generated/waterx_perp/request.js";
13
26
  import * as trading from "../../generated/waterx_perp/trading.js";
27
+ import { toU8, toU64, toU64OrNull, toU128, toU128OrNull } from "../../utils/validate.js";
14
28
  import { ORDER_TAG_WILDCARD } from "../constants.js";
15
29
  /** Build a `request::PlaceOrderArgument` Move struct in the PTB. */
16
30
  export function buildPlaceOrderArgument(client, tx, p) {
@@ -20,11 +34,11 @@ export function buildPlaceOrderArgument(client, tx, p) {
20
34
  isLong: p.isLong,
21
35
  isStopOrder: p.isStopOrder,
22
36
  reduceOnly: p.reduceOnly,
23
- size: p.size,
24
- triggerPrice: p.triggerPrice ?? null,
25
- linkedPositionId: p.linkedPositionId ?? null,
26
- acceptablePrice: p.acceptablePrice ?? null,
27
- collateralAmount: p.collateralAmount,
37
+ size: toU128(p.size, "size"),
38
+ triggerPrice: toU128OrNull(p.triggerPrice, "triggerPrice"),
39
+ linkedPositionId: toU64OrNull(p.linkedPositionId, "linkedPositionId"),
40
+ acceptablePrice: toU64OrNull(p.acceptablePrice, "acceptablePrice"),
41
+ collateralAmount: toU64(p.collateralAmount, "collateralAmount"),
28
42
  },
29
43
  })(tx);
30
44
  return arg;
@@ -66,9 +80,9 @@ export function cancelOrderRequest(client, tx, params) {
66
80
  ticker: params.ticker,
67
81
  senderRequest: req,
68
82
  accountId: params.accountId,
69
- orderId: params.orderId,
70
- triggerPrice: params.triggerPrice ?? 0n,
71
- orderTypeTag: params.orderTypeTag ?? ORDER_TAG_WILDCARD,
83
+ orderId: toU64(params.orderId, "orderId"),
84
+ triggerPrice: toU128(params.triggerPrice ?? 0n, "triggerPrice"),
85
+ orderTypeTag: toU8(params.orderTypeTag ?? ORDER_TAG_WILDCARD, "orderTypeTag"),
72
86
  },
73
87
  typeArguments: [params.collateralType, params.lpType ?? client.wlpType()],
74
88
  })(tx);
@@ -85,11 +99,11 @@ export function updateOrderRequest(client, tx, params) {
85
99
  ticker: params.ticker,
86
100
  senderRequest: req,
87
101
  accountId: params.accountId,
88
- orderId: params.orderId,
89
- currentTriggerPrice: params.currentTriggerPrice,
90
- orderTypeTag: params.orderTypeTag,
91
- newSize: params.newSize,
92
- newTriggerPrice: params.newTriggerPrice,
102
+ orderId: toU64(params.orderId, "orderId"),
103
+ currentTriggerPrice: toU128(params.currentTriggerPrice, "currentTriggerPrice"),
104
+ orderTypeTag: toU8(params.orderTypeTag, "orderTypeTag"),
105
+ newSize: toU128(params.newSize, "newSize"),
106
+ newTriggerPrice: toU128(params.newTriggerPrice, "newTriggerPrice"),
93
107
  },
94
108
  typeArguments: [params.collateralType, params.lpType ?? client.wlpType()],
95
109
  })(tx);
@@ -106,8 +120,8 @@ export function cancelPreOrderRequest(client, tx, params) {
106
120
  ticker: params.ticker,
107
121
  senderRequest: req,
108
122
  accountId: params.accountId,
109
- mainOrderId: params.mainOrderId,
110
- preOrderId: params.preOrderId,
123
+ mainOrderId: toU64(params.mainOrderId, "mainOrderId"),
124
+ preOrderId: toU64(params.preOrderId, "preOrderId"),
111
125
  },
112
126
  typeArguments: [params.collateralType, params.lpType ?? client.wlpType()],
113
127
  })(tx);
@@ -125,7 +139,7 @@ export function addPreOrderRequest(client, tx, params) {
125
139
  ticker: params.ticker,
126
140
  senderRequest: req,
127
141
  accountId: params.accountId,
128
- mainOrderId: params.mainOrderId,
142
+ mainOrderId: toU64(params.mainOrderId, "mainOrderId"),
129
143
  preOrder: preArg,
130
144
  },
131
145
  typeArguments: [params.collateralType, params.lpType ?? client.wlpType()],
@@ -17,6 +17,7 @@
17
17
  */
18
18
  import { makeSenderRequest } from "../../account/account-request.js";
19
19
  import * as staking from "../../generated/waterx_staking/waterx_staking.js";
20
+ import { toU64Arg } from "../../utils/validate.js";
20
21
  function pool(client, stakeAlias) {
21
22
  const id = client.config.packages.waterx_staking?.pools?.[stakeAlias];
22
23
  if (!id) {
@@ -41,7 +42,7 @@ export function stake(client, tx, params) {
41
42
  wxaRegistry: tx.object(client.config.packages.waterx_account.account_registry),
42
43
  accountId: params.accountId,
43
44
  accReq: req,
44
- stakeAmount: params.stakeAmount,
45
+ stakeAmount: toU64Arg(params.stakeAmount, "stakeAmount"),
45
46
  },
46
47
  typeArguments: [params.stakeType],
47
48
  })(tx);
@@ -72,7 +73,7 @@ export function unstake(client, tx, params) {
72
73
  wxaRegistry: tx.object(client.config.packages.waterx_account.account_registry),
73
74
  accountId: params.accountId,
74
75
  accReq: req,
75
- withdrawalAmount: params.withdrawalAmount,
76
+ withdrawalAmount: toU64Arg(params.withdrawalAmount, "withdrawalAmount"),
76
77
  },
77
78
  typeArguments: [params.stakeType],
78
79
  })(tx);
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import { makeSenderRequest } from "../../account/account-request.js";
14
14
  import * as trading from "../../generated/waterx_perp/trading.js";
15
+ import { toU8, toU64, toU64OrNull, toU128 } from "../../utils/validate.js";
15
16
  import { ORDER_TAG_WILDCARD } from "../constants.js";
16
17
  function typeArgs(client, t) {
17
18
  return [t.collateralType, t.lpType ?? client.wlpType()];
@@ -39,8 +40,8 @@ export function closePositionRequest(client, tx, params) {
39
40
  ticker: params.ticker,
40
41
  senderRequest: req,
41
42
  accountId: params.accountId,
42
- positionId: params.positionId,
43
- acceptablePrice: params.acceptablePrice,
43
+ positionId: toU64(params.positionId, "positionId"),
44
+ acceptablePrice: toU64(params.acceptablePrice, "acceptablePrice"),
44
45
  },
45
46
  typeArguments: typeArgs(client, params),
46
47
  })(tx);
@@ -58,11 +59,11 @@ export function increasePositionRequest(client, tx, params) {
58
59
  ticker: params.ticker,
59
60
  senderRequest: req,
60
61
  accountId: params.accountId,
61
- orderId: params.orderId ?? null,
62
- positionId: params.positionId,
63
- collateralAmount: params.collateralAmount,
64
- size: params.size,
65
- acceptablePrice: params.acceptablePrice,
62
+ orderId: toU64OrNull(params.orderId, "orderId"),
63
+ positionId: toU64(params.positionId, "positionId"),
64
+ collateralAmount: toU64(params.collateralAmount, "collateralAmount"),
65
+ size: toU128(params.size, "size"),
66
+ acceptablePrice: toU64(params.acceptablePrice, "acceptablePrice"),
66
67
  },
67
68
  typeArguments: typeArgs(client, params),
68
69
  })(tx);
@@ -80,9 +81,9 @@ export function decreasePositionRequest(client, tx, params) {
80
81
  ticker: params.ticker,
81
82
  senderRequest: req,
82
83
  accountId: params.accountId,
83
- positionId: params.positionId,
84
- size: params.size,
85
- acceptablePrice: params.acceptablePrice,
84
+ positionId: toU64(params.positionId, "positionId"),
85
+ size: toU128(params.size, "size"),
86
+ acceptablePrice: toU64(params.acceptablePrice, "acceptablePrice"),
86
87
  },
87
88
  typeArguments: typeArgs(client, params),
88
89
  })(tx);
@@ -100,8 +101,8 @@ export function depositCollateralRequest(client, tx, params) {
100
101
  ticker: params.ticker,
101
102
  senderRequest: req,
102
103
  accountId: params.accountId,
103
- positionId: params.positionId,
104
- collateralAmount: params.collateralAmount,
104
+ positionId: toU64(params.positionId, "positionId"),
105
+ collateralAmount: toU64(params.collateralAmount, "collateralAmount"),
105
106
  },
106
107
  typeArguments: typeArgs(client, params),
107
108
  })(tx);
@@ -119,8 +120,8 @@ export function withdrawCollateralRequest(client, tx, params) {
119
120
  ticker: params.ticker,
120
121
  senderRequest: req,
121
122
  accountId: params.accountId,
122
- positionId: params.positionId,
123
- amount: params.amount,
123
+ positionId: toU64(params.positionId, "positionId"),
124
+ amount: toU64(params.amount, "amount"),
124
125
  },
125
126
  typeArguments: typeArgs(client, params),
126
127
  })(tx);
@@ -154,7 +155,7 @@ export function liquidate(client, tx, params) {
154
155
  ticker: params.ticker,
155
156
  pool: tx.object(obj.wlpPool),
156
157
  senderRequest: req,
157
- positionId: params.positionId,
158
+ positionId: toU64(params.positionId, "positionId"),
158
159
  oracle: tx.object(obj.oracle),
159
160
  },
160
161
  typeArguments: typeArgs(client, params),
@@ -173,8 +174,8 @@ export function batchLiquidate(client, tx, params) {
173
174
  pool: tx.object(obj.wlpPool),
174
175
  senderRequest: req,
175
176
  oracle: tx.object(obj.oracle),
176
- pageSize: params.pageSize,
177
- pageIndex: params.pageIndex,
177
+ pageSize: toU64(params.pageSize, "pageSize"),
178
+ pageIndex: toU64(params.pageIndex, "pageIndex"),
178
179
  },
179
180
  typeArguments: typeArgs(client, params),
180
181
  })(tx);
@@ -192,9 +193,9 @@ export function matchOrders(client, tx, params) {
192
193
  pool: tx.object(obj.wlpPool),
193
194
  senderRequest: req,
194
195
  oracle: tx.object(obj.oracle),
195
- orderTypeTag: params.orderTypeTag,
196
- triggerPrice: params.triggerPrice,
197
- maxFills: params.maxFills,
196
+ orderTypeTag: toU8(params.orderTypeTag, "orderTypeTag"),
197
+ triggerPrice: toU128(params.triggerPrice, "triggerPrice"),
198
+ maxFills: toU64(params.maxFills, "maxFills"),
198
199
  },
199
200
  typeArguments: typeArgs(client, params),
200
201
  })(tx);
@@ -230,8 +231,8 @@ export function openPositionByKeeper(client, tx, params) {
230
231
  accountObjectAddress: params.accountObjectAddress,
231
232
  collateralCoin: params.collateralCoin,
232
233
  isLong: params.isLong,
233
- size: params.size,
234
- acceptablePrice: params.acceptablePrice,
234
+ size: toU128(params.size, "size"),
235
+ acceptablePrice: toU64(params.acceptablePrice, "acceptablePrice"),
235
236
  oracle: tx.object(obj.oracle),
236
237
  },
237
238
  typeArguments: typeArgs(client, params),
@@ -249,8 +250,8 @@ export function closePositionByKeeper(client, tx, params) {
249
250
  ticker: params.ticker,
250
251
  pool: tx.object(obj.wlpPool),
251
252
  keeperRequest: req,
252
- positionId: params.positionId,
253
- acceptablePrice: params.acceptablePrice,
253
+ positionId: toU64(params.positionId, "positionId"),
254
+ acceptablePrice: toU64(params.acceptablePrice, "acceptablePrice"),
254
255
  oracle: tx.object(obj.oracle),
255
256
  },
256
257
  typeArguments: typeArgs(client, params),
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import { makeSenderRequest } from "../../account/account-request.js";
13
13
  import * as lp from "../../generated/waterx_perp/lp_pool.js";
14
+ import { toU64 } from "../../utils/validate.js";
14
15
  /** Returns the minted `lp_amount` so it can be chained into e.g. `stake`. */
15
16
  export function mintWlp(client, tx, params) {
16
17
  const req = makeSenderRequest(client, tx, params.bucketAccount);
@@ -23,8 +24,8 @@ export function mintWlp(client, tx, params) {
23
24
  aum: tx.object(requireWlpAum(client)),
24
25
  senderRequest: req,
25
26
  accountId: params.accountId,
26
- depositAmount: params.depositAmount,
27
- minLpAmount: params.minLpAmount,
27
+ depositAmount: toU64(params.depositAmount, "depositAmount"),
28
+ minLpAmount: toU64(params.minLpAmount, "minLpAmount"),
28
29
  oracle: tx.object(client.config.packages.waterx_oracle.oracle),
29
30
  },
30
31
  typeArguments: [params.lpType ?? client.wlpType(), params.depositTokenType],
@@ -48,7 +49,7 @@ export function requestRedeemWlp(client, tx, params) {
48
49
  wxaRegistry: tx.object(client.config.packages.waterx_account.account_registry),
49
50
  senderRequest: req,
50
51
  accountId: params.accountId,
51
- lpAmount: params.lpAmount,
52
+ lpAmount: toU64(params.lpAmount, "lpAmount"),
52
53
  },
53
54
  typeArguments: [params.lpType ?? client.wlpType(), params.redeemTokenType],
54
55
  })(tx);
@@ -62,7 +63,7 @@ export function cancelRedeemWlp(client, tx, params) {
62
63
  globalConfig: tx.object(client.config.packages.waterx_perp.global_config),
63
64
  wxaRegistry: tx.object(client.config.packages.waterx_account.account_registry),
64
65
  senderRequest: req,
65
- requestId: params.requestId,
66
+ requestId: toU64(params.requestId, "requestId"),
66
67
  },
67
68
  typeArguments: [params.lpType ?? client.wlpType()],
68
69
  })(tx);
@@ -77,7 +78,7 @@ export function settleRedeemWlp(client, tx, params) {
77
78
  wxaRegistry: tx.object(client.config.packages.waterx_account.account_registry),
78
79
  operatorRequest: req,
79
80
  aum: tx.object(requireWlpAum(client)),
80
- requestId: params.requestId,
81
+ requestId: toU64(params.requestId, "requestId"),
81
82
  oracle: tx.object(client.config.packages.waterx_oracle.oracle),
82
83
  },
83
84
  typeArguments: [params.lpType ?? client.wlpType(), params.redeemTokenType],
@@ -10,8 +10,17 @@ export declare function resolveSettlementCoinType(client: PredictClient, coinTyp
10
10
  export declare function resolveMarketRegistry(client: PredictClient, marketRegistry?: string): string;
11
11
  export declare function resolveAccountRegistry(client: PredictClient, accountRegistry?: string): string;
12
12
  export declare function resolveGlobalConfig(client: PredictClient, globalConfig?: string): string;
13
- /** Ensures `value` is a valid unsigned 64-bit integer. */
14
- export declare function assertU64(value: bigint, name?: string): bigint;
13
+ /**
14
+ * Ensures `value` is a valid unsigned 64-bit integer.
15
+ *
16
+ * Thin alias for the shared `utils/validate.toU64` — the u64 domain rule
17
+ * (bigint range check; a `number` must be a NON-NEGATIVE SAFE integer, since
18
+ * `2^53 + 2` passes `isInteger` yet has already lost f64 precision and would
19
+ * BCS-encode a silently-wrong value) is authored ONCE there for both product
20
+ * lines. Throws `RangeError` (a subclass of `Error`) naming the parameter.
21
+ */
22
+ export declare function assertU64(value: bigint | number, name?: string): bigint;
23
+ /** Normalize a u64-ish input (bigint / number / decimal string) to a checked `bigint`. */
15
24
  export declare function toBigInt(value: bigint | number | string): bigint;
16
25
  export declare function objectArg(tx: Transaction, value: ObjectArgument): TransactionArgument;
17
26
  export declare function idArg(tx: Transaction, value: IdArgument): TransactionArgument;
@@ -1,7 +1,8 @@
1
+ import { toU64 } from "../utils/validate.js";
1
2
  import { CLOCK_OBJECT_ID } from "./constants.js";
2
3
  const SELECTIONS = ["YES", "NO"];
3
4
  const OUTCOMES = ["YES", "NO", "INVALID"];
4
- const U64_MAX = (1n << 64n) - 1n;
5
+ const DECIMAL_INT_RE = /^\d+$/;
5
6
  export function assertSelection(value) {
6
7
  if (SELECTIONS.includes(value))
7
8
  return value;
@@ -45,32 +46,31 @@ export function resolveAccountRegistry(client, accountRegistry) {
45
46
  export function resolveGlobalConfig(client, globalConfig) {
46
47
  return globalConfig === undefined || globalConfig === "" ? client.globalConfigId() : globalConfig;
47
48
  }
48
- /** Ensures `value` is a valid unsigned 64-bit integer. */
49
+ /**
50
+ * Ensures `value` is a valid unsigned 64-bit integer.
51
+ *
52
+ * Thin alias for the shared `utils/validate.toU64` — the u64 domain rule
53
+ * (bigint range check; a `number` must be a NON-NEGATIVE SAFE integer, since
54
+ * `2^53 + 2` passes `isInteger` yet has already lost f64 precision and would
55
+ * BCS-encode a silently-wrong value) is authored ONCE there for both product
56
+ * lines. Throws `RangeError` (a subclass of `Error`) naming the parameter.
57
+ */
49
58
  export function assertU64(value, name = "value") {
50
- if (value < 0n) {
51
- throw new Error(`${name} must be non-negative, got ${value}`);
52
- }
53
- if (value > U64_MAX) {
54
- throw new Error(`${name} exceeds u64 max (${U64_MAX}), got ${value}`);
55
- }
56
- return value;
59
+ return toU64(value, name);
57
60
  }
61
+ /** Normalize a u64-ish input (bigint / number / decimal string) to a checked `bigint`. */
58
62
  export function toBigInt(value) {
59
- if (typeof value === "bigint") {
63
+ if (typeof value !== "string")
60
64
  return assertU64(value);
61
- }
62
- if (typeof value === "number") {
63
- if (!Number.isInteger(value)) {
64
- throw new Error(`Invalid integer: ${value}`);
65
- }
66
- return assertU64(BigInt(value));
67
- }
65
+ // String is the one form the shared guard does not cover: digits parse exactly
66
+ // past the 2^53 f64 cliff, so the shape check lives here and the numeric
67
+ // domain still funnels through assertU64.
68
68
  const trimmed = value.trim();
69
69
  if (trimmed === "") {
70
- throw new Error("Invalid integer: empty string");
70
+ throw new RangeError("Invalid integer: empty string");
71
71
  }
72
- if (!/^\d+$/.test(trimmed)) {
73
- throw new Error(`Invalid integer: ${JSON.stringify(value)}`);
72
+ if (!DECIMAL_INT_RE.test(trimmed)) {
73
+ throw new RangeError(`Invalid integer: ${JSON.stringify(value)}`);
74
74
  }
75
75
  return assertU64(BigInt(trimmed));
76
76
  }
@@ -161,8 +161,8 @@ export function optionU64(value) {
161
161
  function formatObjectVersion(version) {
162
162
  if (typeof version === "string") {
163
163
  const trimmed = version.trim();
164
- if (trimmed === "" || !/^\d+$/.test(trimmed)) {
165
- throw new Error(`Invalid object version: ${JSON.stringify(version)}`);
164
+ if (trimmed === "" || !DECIMAL_INT_RE.test(trimmed)) {
165
+ throw new RangeError(`Invalid object version: ${JSON.stringify(version)}`);
166
166
  }
167
167
  return trimmed;
168
168
  }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Exposes three namespaces over the two product-line sub-clients:
5
5
  *
6
- * const client = await WaterXClient.create({ network: "TESTNET" });
6
+ * const client = await WaterXClient.create({ network: "TESTNET", oracleSource: "pyth_rule" });
7
7
  * client.account.createAccount(tx, { alias }); // -> shared waterx_account + funding
8
8
  * client.perp.placeOrderRequest(tx, params); // -> perp builder
9
9
  * client.predict.placeOrder(tx, params); // -> prediction builder
@@ -34,6 +34,7 @@ import * as perpReferral from "./account/referral.ts";
34
34
  import type { Network } from "./constants.ts";
35
35
  import type { PythFetchPolicy } from "./oracle/config.ts";
36
36
  import type { OracleSource } from "./oracle/price-update-rule.ts";
37
+ import type { FetchPolicy } from "./oracle/update-fetch.ts";
37
38
  import { PerpClient, type CreateClientOptions as PerpCreateOptions } from "./perp/client.ts";
38
39
  import * as perpFetch from "./perp/fetch.ts";
39
40
  import * as perpTx from "./perp/tx-builders.ts";
@@ -90,8 +91,8 @@ declare const perpOps: {
90
91
  getPosition(client: PerpClient, args: {
91
92
  ticker: string;
92
93
  positionId: bigint | number;
93
- basePriceUsd: bigint | number;
94
- collateralPriceUsd: bigint | number;
94
+ basePriceUsd: perpFetch.WholeDollarUsdPrice;
95
+ collateralPriceUsd: perpFetch.WholeDollarUsdPrice;
95
96
  lpType?: string;
96
97
  }): Promise<perpFetch.PositionDataView>;
97
98
  getOrder(client: PerpClient, args: {
@@ -99,12 +100,12 @@ declare const perpOps: {
99
100
  orderId: bigint | number;
100
101
  orderTypeTag: number;
101
102
  triggerPrice: bigint | number;
102
- basePriceUsd: bigint | number;
103
+ basePriceUsd: perpFetch.WholeDollarUsdPrice;
103
104
  lpType?: string;
104
105
  }): Promise<perpFetch.OrderDataView>;
105
106
  getMarketOrders(client: PerpClient, args: {
106
107
  ticker: string;
107
- basePriceUsd?: bigint | number;
108
+ basePriceUsd?: perpFetch.WholeDollarUsdPrice;
108
109
  lpType?: string;
109
110
  } & perpFetch.PageOpts): Promise<{
110
111
  orders: perpFetch.OrderDataView[];
@@ -112,8 +113,8 @@ declare const perpOps: {
112
113
  }>;
113
114
  getMarketPositions(client: PerpClient, args: {
114
115
  ticker: string;
115
- basePriceUsd: bigint | number;
116
- collateralPriceUsd?: bigint | number;
116
+ basePriceUsd: perpFetch.WholeDollarUsdPrice;
117
+ collateralPriceUsd?: perpFetch.WholeDollarUsdPrice;
117
118
  lpType?: string;
118
119
  } & perpFetch.PageOpts): Promise<{
119
120
  positions: perpFetch.PositionDataView[];
@@ -122,14 +123,14 @@ declare const perpOps: {
122
123
  getAccountPositions(client: PerpClient, args: {
123
124
  ticker: string;
124
125
  accountObjectAddress: string;
125
- basePriceUsd: bigint | number;
126
- collateralPriceUsd?: bigint | number;
126
+ basePriceUsd: perpFetch.WholeDollarUsdPrice;
127
+ collateralPriceUsd?: perpFetch.WholeDollarUsdPrice;
127
128
  lpType?: string;
128
129
  }): Promise<perpFetch.PositionDataView[]>;
129
130
  getAccountOrders(client: PerpClient, args: {
130
131
  ticker: string;
131
132
  accountObjectAddress: string;
132
- basePriceUsd?: bigint | number;
133
+ basePriceUsd?: perpFetch.WholeDollarUsdPrice;
133
134
  lpType?: string;
134
135
  }): Promise<perpFetch.OrderDataView[]>;
135
136
  getRedeemRequests(client: PerpClient, args?: {
@@ -138,6 +139,7 @@ declare const perpOps: {
138
139
  requests: perpFetch.RedeemRequestDataView[];
139
140
  nextCursor?: bigint;
140
141
  }>;
142
+ parseWholeDollarU64: typeof perpFetch.parseWholeDollarU64;
141
143
  getAccountsByOwner(client: PerpClient, owner: string): Promise<string[]>;
142
144
  getAccountBalance(client: PerpClient, accountId: string, coinType?: string): Promise<bigint>;
143
145
  getSpendableCreditBalance(client: PerpClient, accountId: string): Promise<perpFetch.SpendableCreditBalance>;
@@ -368,17 +370,25 @@ export interface ClientCreateOptions {
368
370
  /**
369
371
  * The perp line's oracle price-update source (perp-line only — the
370
372
  * prediction line has no oracle leg), forwarded to `PerpClient.create`.
371
- * Source-neutral by design: a future source need not be Pyth.
373
+ * REQUIRED there is NO default source: every deployment names its source
374
+ * explicitly (wire it from your own env var, e.g. `ORACLE_SOURCE`).
375
+ * Source-neutral by design: a source need not be Pyth (see `'waterx_rule'`).
372
376
  *
373
- * - `'pyth_rule'` (default) — Pyth Core updates on Core infra.
377
+ * - `'pyth_rule'` — Pyth Core updates; infra in the source's own
378
+ * `PYTH_CORE_INFRA` table.
374
379
  * - `'pyth_lazer_rule'` — Pyth Lazer signed updates (pair with `pythApiKey`
375
- * and a config carrying `packages.pyth_lazer_rule`).
380
+ * and a config carrying `packages.pyth_lazer_rule`); infra in the
381
+ * source's own `LAZER_INFRA` table.
382
+ * - `'waterx_rule'` — the first-party WaterX quote-center (Nautilus-TEE,
383
+ * ed25519 signed batches; no credential, no per-update fee); infra in the
384
+ * source's own `WATERX_INFRA` table. Pair with `waterxEndpoint` /
385
+ * `waterxFetch` when the browser needs a proxy.
376
386
  *
377
387
  * Each source is self-contained with no cross-source fallback; selecting a
378
388
  * source whose feed for a ticker is absent fails at tx-build (not at init).
379
389
  * See perp `CreateClientOptions.oracleSource` for the full note.
380
390
  */
381
- oracleSource?: OracleSource;
391
+ oracleSource: OracleSource | OracleSource[];
382
392
  /**
383
393
  * Pyth Lazer access token, forwarded to the perp line. Required under
384
394
  * `oracleSource: 'pyth_lazer_rule'`, unused by `'pyth_rule'`. A SECRET —
@@ -388,6 +398,22 @@ export interface ClientCreateOptions {
388
398
  pythApiKey?: string;
389
399
  /** Retry/timeout policy for the perp line's off-chain oracle fetches. */
390
400
  pythFetch?: PythFetchPolicy;
401
+ /**
402
+ * Quote-center base URL for `oracleSource: 'waterx_rule'`, forwarded to the
403
+ * perp line — overrides the source's own per-network `WATERX_INFRA` default.
404
+ *
405
+ * `waterx_rule` is the one source a BROWSER fetches itself, so it is bound by
406
+ * the quote-center deployment's CORS allowlist: a front end whose origin is
407
+ * not allowed points this at its own same-origin proxy. An absolute URL whose
408
+ * base PATH is preserved — `https://app.example/api/quote-center` fetches
409
+ * `…/api/quote-center/v1/quotes/update`. Unused by the Pyth sources.
410
+ */
411
+ waterxEndpoint?: string;
412
+ /**
413
+ * Retry/timeout policy — and `fetchImpl` — for the perp line's quote-center
414
+ * fetch. Falls back to the built-in defaults — never to `pythFetch`.
415
+ */
416
+ waterxFetch?: FetchPolicy;
391
417
  /** Perp-line overrides (network, grpcUrl, waterxConfigUrl, cache, …). */
392
418
  perp?: PerpLineOptions;
393
419
  /** Prediction-line overrides (network, grpcUrl, waterxConfigUrl, cache, settlement, …). */
@@ -427,6 +453,6 @@ export declare class WaterXClient {
427
453
  * `waterx-config` JSON) and returns a ready client. Each line can target a
428
454
  * different network via `opts.perp.network` / `opts.predict.network`.
429
455
  */
430
- static create(opts?: ClientCreateOptions): Promise<WaterXClient>;
456
+ static create(opts: ClientCreateOptions): Promise<WaterXClient>;
431
457
  }
432
458
  export {};
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Exposes three namespaces over the two product-line sub-clients:
5
5
  *
6
- * const client = await WaterXClient.create({ network: "TESTNET" });
6
+ * const client = await WaterXClient.create({ network: "TESTNET", oracleSource: "pyth_rule" });
7
7
  * client.account.createAccount(tx, { alias }); // -> shared waterx_account + funding
8
8
  * client.perp.placeOrderRequest(tx, params); // -> perp builder
9
9
  * client.predict.placeOrder(tx, params); // -> prediction builder
@@ -150,7 +150,7 @@ export class WaterXClient {
150
150
  * `waterx-config` JSON) and returns a ready client. Each line can target a
151
151
  * different network via `opts.perp.network` / `opts.predict.network`.
152
152
  */
153
- static async create(opts = {}) {
153
+ static async create(opts) {
154
154
  const baseNetwork = opts.network ?? "TESTNET";
155
155
  const { network: perpNetwork, ...perpRest } = opts.perp ?? {};
156
156
  const { network: predictNetwork, ...predictRest } = opts.predict ?? {};
@@ -171,6 +171,8 @@ export class WaterXClient {
171
171
  oracleSource: opts.oracleSource,
172
172
  pythApiKey: opts.pythApiKey,
173
173
  pythFetch: opts.pythFetch,
174
+ waterxEndpoint: opts.waterxEndpoint,
175
+ waterxFetch: opts.waterxFetch,
174
176
  ...perpRest,
175
177
  });
176
178
  const predictClient = await PredictClient.create(resolvedPredictNetwork, {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Funding-interval label from milliseconds: hour-based at or above one hour,
3
+ * minute-based below. Non-integer hours are kept as-is:
4
+ *
5
+ * 3_600_000 → "1H"
6
+ * 28_800_000 → "8H"
7
+ * 5_400_000 → "1.5H"
8
+ * 1_800_000 → "30M"
9
+ *
10
+ * Single source for the label the BE tickers payload emits and the FE reader
11
+ * must reproduce byte-identically (output-identical port of bucket-backend-mono
12
+ * `apps/waterx/src/core/utils/funding.ts::formatFundingInterval`).
13
+ */
14
+ export declare function formatFundingInterval(intervalMs: number): string;
@@ -0,0 +1,21 @@
1
+ // Display-label formatters that must be byte-identical wherever the same wire
2
+ // field is rendered. Hosted in the SDK so FE and BE share one implementation
3
+ // instead of hand-mirroring each other.
4
+ import { MS_PER_HOUR, MS_PER_MINUTE } from "../constants.js";
5
+ /**
6
+ * Funding-interval label from milliseconds: hour-based at or above one hour,
7
+ * minute-based below. Non-integer hours are kept as-is:
8
+ *
9
+ * 3_600_000 → "1H"
10
+ * 28_800_000 → "8H"
11
+ * 5_400_000 → "1.5H"
12
+ * 1_800_000 → "30M"
13
+ *
14
+ * Single source for the label the BE tickers payload emits and the FE reader
15
+ * must reproduce byte-identically (output-identical port of bucket-backend-mono
16
+ * `apps/waterx/src/core/utils/funding.ts::formatFundingInterval`).
17
+ */
18
+ export function formatFundingInterval(intervalMs) {
19
+ const hours = intervalMs / MS_PER_HOUR;
20
+ return hours >= 1 ? `${hours}H` : `${intervalMs / MS_PER_MINUTE}M`;
21
+ }