@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.
- package/README.md +37 -17
- package/dist/cjs/src/account/account.js +2 -1
- package/dist/cjs/src/account/config.d.ts +3 -2
- package/dist/cjs/src/account/funding/balance.d.ts +25 -2
- package/dist/cjs/src/account/funding/balance.js +36 -24
- package/dist/cjs/src/account/funding/credit.js +6 -10
- package/dist/cjs/src/constants.d.ts +15 -1
- package/dist/cjs/src/constants.js +18 -4
- package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
- package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +13 -0
- package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
- package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.js +31 -0
- package/dist/cjs/src/generated/waterx_rule/waterx_rule.d.ts +813 -0
- package/dist/cjs/src/generated/waterx_rule/waterx_rule.js +946 -0
- package/dist/cjs/src/oracle/aggregate.d.ts +23 -21
- package/dist/cjs/src/oracle/aggregate.js +133 -59
- package/dist/cjs/src/oracle/config.d.ts +82 -41
- package/dist/cjs/src/oracle/config.js +0 -42
- package/dist/cjs/src/oracle/host.d.ts +26 -11
- package/dist/cjs/src/oracle/index.d.ts +6 -2
- package/dist/cjs/src/oracle/index.js +36 -8
- package/dist/cjs/src/oracle/price-update-rule.d.ts +16 -10
- package/dist/cjs/src/oracle/price-update-rule.js +3 -3
- package/dist/cjs/src/oracle/pyth.d.ts +44 -0
- package/dist/cjs/src/oracle/pyth.js +48 -6
- package/dist/cjs/src/oracle/read-plane.d.ts +70 -0
- package/dist/cjs/src/oracle/read-plane.js +78 -0
- package/dist/cjs/src/oracle/rule-registry.d.ts +14 -11
- package/dist/cjs/src/oracle/rule-registry.js +16 -11
- package/dist/cjs/src/oracle/rules/pyth-core-rule.js +4 -4
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +29 -4
- package/dist/cjs/src/oracle/rules/pyth-rule.js +5 -4
- package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +126 -0
- package/dist/cjs/src/oracle/rules/waterx-rule.js +312 -0
- package/dist/cjs/src/perp/client.d.ts +71 -20
- package/dist/cjs/src/perp/client.js +35 -13
- package/dist/cjs/src/perp/config.d.ts +6 -7
- package/dist/cjs/src/perp/config.js +12 -11
- package/dist/cjs/src/perp/constants.d.ts +0 -6
- package/dist/cjs/src/perp/constants.js +11 -9
- package/dist/cjs/src/perp/fetch/account.js +3 -0
- package/dist/cjs/src/perp/fetch/bridge.js +2 -1
- package/dist/cjs/src/perp/fetch/market.js +2 -1
- package/dist/cjs/src/perp/fetch/positions.d.ts +16 -10
- package/dist/cjs/src/perp/fetch/positions.js +23 -20
- package/dist/cjs/src/perp/index.d.ts +9 -5
- package/dist/cjs/src/perp/index.js +16 -7
- package/dist/cjs/src/perp/liq-view.d.ts +64 -0
- package/dist/cjs/src/perp/liq-view.js +74 -0
- package/dist/cjs/src/perp/user/order.d.ts +13 -0
- package/dist/cjs/src/perp/user/order.js +30 -16
- package/dist/cjs/src/perp/user/staking.js +3 -2
- package/dist/cjs/src/perp/user/trading.js +25 -24
- package/dist/cjs/src/perp/user/wlp.js +6 -5
- package/dist/cjs/src/prediction/utils.d.ts +11 -2
- package/dist/cjs/src/prediction/utils.js +22 -22
- package/dist/cjs/src/unified-client.d.ts +41 -15
- package/dist/cjs/src/unified-client.js +4 -2
- package/dist/cjs/src/utils/format.d.ts +14 -0
- package/dist/cjs/src/utils/format.js +24 -0
- package/dist/cjs/src/utils/math.d.ts +304 -12
- package/dist/cjs/src/utils/math.js +397 -17
- package/dist/cjs/src/utils/validate.d.ts +69 -0
- package/dist/cjs/src/utils/validate.js +183 -0
- package/dist/src/account/account.js +2 -1
- package/dist/src/account/config.d.ts +3 -2
- package/dist/src/account/funding/balance.d.ts +25 -2
- package/dist/src/account/funding/balance.js +36 -24
- package/dist/src/account/funding/credit.js +6 -10
- package/dist/src/constants.d.ts +15 -1
- package/dist/src/constants.js +17 -3
- package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
- package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +10 -0
- package/dist/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
- package/dist/src/generated/waterx_rule/deps/sui/vec_map.js +27 -0
- package/dist/src/generated/waterx_rule/waterx_rule.d.ts +813 -0
- package/dist/src/generated/waterx_rule/waterx_rule.js +855 -0
- package/dist/src/oracle/aggregate.d.ts +23 -21
- package/dist/src/oracle/aggregate.js +133 -59
- package/dist/src/oracle/config.d.ts +82 -41
- package/dist/src/oracle/config.js +1 -41
- package/dist/src/oracle/host.d.ts +26 -11
- package/dist/src/oracle/index.d.ts +6 -2
- package/dist/src/oracle/index.js +27 -9
- package/dist/src/oracle/price-update-rule.d.ts +16 -10
- package/dist/src/oracle/price-update-rule.js +3 -3
- package/dist/src/oracle/pyth.d.ts +44 -0
- package/dist/src/oracle/pyth.js +45 -5
- package/dist/src/oracle/read-plane.d.ts +70 -0
- package/dist/src/oracle/read-plane.js +74 -0
- package/dist/src/oracle/rule-registry.d.ts +14 -11
- package/dist/src/oracle/rule-registry.js +16 -11
- package/dist/src/oracle/rules/pyth-core-rule.js +5 -5
- package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
- package/dist/src/oracle/rules/pyth-lazer-rule.js +28 -3
- package/dist/src/oracle/rules/pyth-rule.js +5 -4
- package/dist/src/oracle/rules/waterx-rule.d.ts +126 -0
- package/dist/src/oracle/rules/waterx-rule.js +305 -0
- package/dist/src/perp/client.d.ts +71 -20
- package/dist/src/perp/client.js +36 -14
- package/dist/src/perp/config.d.ts +6 -7
- package/dist/src/perp/config.js +11 -9
- package/dist/src/perp/constants.d.ts +0 -6
- package/dist/src/perp/constants.js +10 -8
- package/dist/src/perp/fetch/account.js +3 -0
- package/dist/src/perp/fetch/bridge.js +2 -1
- package/dist/src/perp/fetch/market.js +2 -1
- package/dist/src/perp/fetch/positions.d.ts +16 -10
- package/dist/src/perp/fetch/positions.js +28 -20
- package/dist/src/perp/index.d.ts +9 -5
- package/dist/src/perp/index.js +6 -4
- package/dist/src/perp/liq-view.d.ts +64 -0
- package/dist/src/perp/liq-view.js +71 -0
- package/dist/src/perp/user/order.d.ts +13 -0
- package/dist/src/perp/user/order.js +30 -16
- package/dist/src/perp/user/staking.js +3 -2
- package/dist/src/perp/user/trading.js +25 -24
- package/dist/src/perp/user/wlp.js +6 -5
- package/dist/src/prediction/utils.d.ts +11 -2
- package/dist/src/prediction/utils.js +22 -22
- package/dist/src/unified-client.d.ts +41 -15
- package/dist/src/unified-client.js +4 -2
- package/dist/src/utils/format.d.ts +14 -0
- package/dist/src/utils/format.js +21 -0
- package/dist/src/utils/math.d.ts +304 -12
- package/dist/src/utils/math.js +394 -17
- package/dist/src/utils/validate.d.ts +69 -0
- package/dist/src/utils/validate.js +167 -0
- 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
|
|
25
|
-
linkedPositionId: p.linkedPositionId
|
|
26
|
-
acceptablePrice: p.acceptablePrice
|
|
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
|
|
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
|
-
/**
|
|
14
|
-
|
|
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
|
|
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
|
-
/**
|
|
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
|
-
|
|
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
|
|
63
|
+
if (typeof value !== "string")
|
|
60
64
|
return assertU64(value);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
|
70
|
+
throw new RangeError("Invalid integer: empty string");
|
|
71
71
|
}
|
|
72
|
-
if (
|
|
73
|
-
throw new
|
|
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 === "" ||
|
|
165
|
-
throw new
|
|
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:
|
|
94
|
-
collateralPriceUsd:
|
|
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:
|
|
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?:
|
|
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:
|
|
116
|
-
collateralPriceUsd?:
|
|
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:
|
|
126
|
-
collateralPriceUsd?:
|
|
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?:
|
|
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
|
-
*
|
|
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'`
|
|
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
|
|
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
|
|
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
|
+
}
|