@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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Numeric-domain guards. One place for the question "is this value inside the
|
|
3
|
+
// domain the callee can honestly compute over?", asked at the three points
|
|
4
|
+
// where garbage enters:
|
|
5
|
+
//
|
|
6
|
+
// 1. INTEGER params (`toU64` / `toU128` / `toU8` / `toU16` + the `*OrNull` /
|
|
7
|
+
// `toU64Arg` variants) on the fetch AND write (tx-build) surfaces. What the
|
|
8
|
+
// generated BCS layer does with a bad `number` depends on the width, and at
|
|
9
|
+
// no width is the answer "throw naming the parameter" (verified against
|
|
10
|
+
// `@mysten/sui`'s `bcs`):
|
|
11
|
+
// - u64 / u128 throw on negative and on fractional — but a `number` past
|
|
12
|
+
// 2^53 has already lost precision in JS BEFORE BCS sees it. `2**53 + 1`
|
|
13
|
+
// collapses to `2**53` at parse time, so BCS faithfully encodes a value
|
|
14
|
+
// the caller never wrote. (`2**53 + 2` IS exactly representable and
|
|
15
|
+
// encodes correctly — the hazard is the odd side of the f64 cliff, not
|
|
16
|
+
// BCS.) Hence the `Number.isSafeInteger` floor here.
|
|
17
|
+
// - u8 / u16 throw when the value is out of range but SILENTLY TRUNCATE a
|
|
18
|
+
// fractional one (`bcs.u8().serialize(2.7)` encodes `2`), so the
|
|
19
|
+
// fractional case is the one only a guard can catch.
|
|
20
|
+
// Every integer param funnels through these so garbage throws with the
|
|
21
|
+
// parameter's name before a transaction is built.
|
|
22
|
+
// 2. FLOAT / BIGINT domains (`assertFinite` / `assertFiniteNonNegative` /
|
|
23
|
+
// `assertUnitFraction` / `assertTokenDecimal` / `assertUnsignedBigInt`) for
|
|
24
|
+
// the money-path math in `utils/math.ts`.
|
|
25
|
+
// 3. The WHOLE-DOLLAR USD price domain (`WholeDollarUsdPrice` /
|
|
26
|
+
// `parseWholeDollarU64`) the `waterx_perp_view` read params live in.
|
|
27
|
+
//
|
|
28
|
+
// Families 2 and 3 live HERE rather than privately inside `math.ts` /
|
|
29
|
+
// `perp/fetch/positions.ts` so the whole numeric-domain vocabulary is
|
|
30
|
+
// discoverable in one file: hiding it is why `parseWholeDollarU64` once
|
|
31
|
+
// re-derived `toU64`'s entire chain (finite → integer → safe integer →
|
|
32
|
+
// non-negative → <= u64::MAX) by hand.
|
|
33
|
+
//
|
|
34
|
+
// Everything throws `RangeError` naming the offending parameter.
|
|
35
|
+
//
|
|
36
|
+
// Visibility: this module is internal EXCEPT for the whole-dollar pair, which
|
|
37
|
+
// is public and re-exported from `perp/fetch/positions.ts` (→ the `perp/fetch`
|
|
38
|
+
// barrel → `@waterx/sdk`) — that is the published import path, not this file.
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.U64_MAX = void 0;
|
|
41
|
+
exports.toU64 = toU64;
|
|
42
|
+
exports.toU128 = toU128;
|
|
43
|
+
exports.toU8 = toU8;
|
|
44
|
+
exports.toU16 = toU16;
|
|
45
|
+
exports.toU64OrNull = toU64OrNull;
|
|
46
|
+
exports.toU128OrNull = toU128OrNull;
|
|
47
|
+
exports.toU64Arg = toU64Arg;
|
|
48
|
+
exports.assertFinite = assertFinite;
|
|
49
|
+
exports.assertFiniteNonNegative = assertFiniteNonNegative;
|
|
50
|
+
exports.assertUnitFraction = assertUnitFraction;
|
|
51
|
+
exports.assertTokenDecimal = assertTokenDecimal;
|
|
52
|
+
exports.assertUnsignedBigInt = assertUnsignedBigInt;
|
|
53
|
+
exports.parseWholeDollarU64 = parseWholeDollarU64;
|
|
54
|
+
exports.U64_MAX = 18446744073709551615n; // 2^64 − 1
|
|
55
|
+
const U128_MAX = 340282366920938463463374607431768211455n; // 2^128 − 1
|
|
56
|
+
function toUint(value, label, max, width) {
|
|
57
|
+
let v;
|
|
58
|
+
if (typeof value === "bigint") {
|
|
59
|
+
v = value;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
63
|
+
throw new RangeError(`${label} must be a non-negative safe integer (< 2^53) or a bigint, got ${value}`);
|
|
64
|
+
}
|
|
65
|
+
v = BigInt(value);
|
|
66
|
+
}
|
|
67
|
+
if (v < 0n || v > max) {
|
|
68
|
+
throw new RangeError(`${label} out of ${width} range, got ${v}`);
|
|
69
|
+
}
|
|
70
|
+
return v;
|
|
71
|
+
}
|
|
72
|
+
/** Validate a u64 param (bigint passthrough with range check; number must be a safe integer >= 0). */
|
|
73
|
+
function toU64(value, label) {
|
|
74
|
+
return toUint(value, label, exports.U64_MAX, "u64");
|
|
75
|
+
}
|
|
76
|
+
/** Validate a u128 param (bigint passthrough with range check; number must be a safe integer >= 0). */
|
|
77
|
+
function toU128(value, label) {
|
|
78
|
+
return toUint(value, label, U128_MAX, "u128");
|
|
79
|
+
}
|
|
80
|
+
function toSmallUint(value, label, max, width) {
|
|
81
|
+
if (!Number.isInteger(value) || value < 0 || value > max) {
|
|
82
|
+
throw new RangeError(`${label} must be an integer in [0, ${max}] (${width}), got ${value}`);
|
|
83
|
+
}
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Validate a u8 param. Returns a `number` (not a bigint) because that is the
|
|
88
|
+
* shape the generated BCS layer takes at this width.
|
|
89
|
+
*
|
|
90
|
+
* Separate from `toU64` on purpose: at u8/u16 the BCS writer already throws on
|
|
91
|
+
* an out-of-range value, but SILENTLY TRUNCATES a fractional one — so the
|
|
92
|
+
* fractional case is what this guard exists to catch (see the header note).
|
|
93
|
+
*/
|
|
94
|
+
function toU8(value, label) {
|
|
95
|
+
return toSmallUint(value, label, 0xff, "u8");
|
|
96
|
+
}
|
|
97
|
+
/** Validate a u16 param. Same width caveat as {@link toU8}. */
|
|
98
|
+
function toU16(value, label) {
|
|
99
|
+
return toSmallUint(value, label, 0xffff, "u16");
|
|
100
|
+
}
|
|
101
|
+
/** `Option<u64>` param: `null` / `undefined` pass through as `null`, anything else is validated. */
|
|
102
|
+
function toU64OrNull(value, label) {
|
|
103
|
+
return value == null ? null : toU64(value, label);
|
|
104
|
+
}
|
|
105
|
+
/** `Option<u128>` param: `null` / `undefined` pass through as `null`, anything else is validated. */
|
|
106
|
+
function toU128OrNull(value, label) {
|
|
107
|
+
return value == null ? null : toU128(value, label);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* u64 param that may instead be a PTB result chained from an earlier command
|
|
111
|
+
* (e.g. the `lp_amount` returned by `mintWlp`). A `TransactionArgument` passes
|
|
112
|
+
* through untouched — its value only exists on chain, where Move types it.
|
|
113
|
+
*/
|
|
114
|
+
function toU64Arg(value, label) {
|
|
115
|
+
return typeof value === "bigint" || typeof value === "number" ? toU64(value, label) : value;
|
|
116
|
+
}
|
|
117
|
+
// NOTE: there is deliberately no `toU128Arg`. No write builder exposes a u128
|
|
118
|
+
// param that can take a chained `TransactionArgument` (every u128 site — size /
|
|
119
|
+
// trigger price / acceptable price — is a caller-supplied literal), so a u128
|
|
120
|
+
// half of `toU64Arg` would be an export with no consumer. Add it back the day a
|
|
121
|
+
// builder actually chains a u128 PTB result.
|
|
122
|
+
/** Reject NaN / ±Infinity for a `number` money-path input. */
|
|
123
|
+
function assertFinite(label, value) {
|
|
124
|
+
if (!Number.isFinite(value)) {
|
|
125
|
+
throw new RangeError(`${label} must be a finite number, got ${value}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** Reject NaN / ±Infinity / negative for a `number` money-path input. */
|
|
129
|
+
function assertFiniteNonNegative(label, value) {
|
|
130
|
+
assertFinite(label, value);
|
|
131
|
+
if (value < 0) {
|
|
132
|
+
throw new RangeError(`${label} must be >= 0, got ${value}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Reject anything outside `[0, 1]` for a `number` input that is a FRACTION of a
|
|
137
|
+
* whole — a maintenance-margin rate above 1 means "maintenance exceeds the
|
|
138
|
+
* entire notional", which is not a rate the caller can have meant.
|
|
139
|
+
*/
|
|
140
|
+
function assertUnitFraction(label, value) {
|
|
141
|
+
assertFinite(label, value);
|
|
142
|
+
if (value < 0 || value > 1) {
|
|
143
|
+
throw new RangeError(`${label} must be within [0, 1], got ${value}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Reject a token-decimal outside `[0, 19]` — the domain of the contract's
|
|
148
|
+
* `10u64.pow(decimal)` (`10^19 < 2^64 <= 10^20`), and the same bound the raw
|
|
149
|
+
* `POW10` table in `utils/math.ts` is built over.
|
|
150
|
+
*/
|
|
151
|
+
function assertTokenDecimal(label, value) {
|
|
152
|
+
if (!Number.isInteger(value) || value < 0 || value > 19) {
|
|
153
|
+
throw new RangeError(`${label} must be an integer in [0, 19], got ${value}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Reject a negative `bigint` where the on-chain type is unsigned. */
|
|
157
|
+
function assertUnsignedBigInt(label, value) {
|
|
158
|
+
if (value < 0n) {
|
|
159
|
+
throw new RangeError(`${label} must be >= 0, got ${value}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const PLAIN_INT_RE = /^-?\d+$/;
|
|
163
|
+
/**
|
|
164
|
+
* Parse a user/env-supplied value into a whole-dollar u64 price
|
|
165
|
+
* (`WholeDollarUsdPrice`) with NO silent rounding: throws `RangeError` on
|
|
166
|
+
* fractional, negative, non-finite, non-numeric, or `> u64::MAX` input. If
|
|
167
|
+
* rounding is ever wanted it must be explicit at the call site
|
|
168
|
+
* (e.g. `parseWholeDollarU64(Math.round(x))`) — never baked in here.
|
|
169
|
+
*
|
|
170
|
+
* The numeric domain (finite → safe integer → non-negative → `<= u64::MAX`) is
|
|
171
|
+
* `toU64`'s and is NOT restated here; this function only adds the string form,
|
|
172
|
+
* whose digits parse exactly past the 2^53 f64 cliff.
|
|
173
|
+
*/
|
|
174
|
+
function parseWholeDollarU64(value) {
|
|
175
|
+
const label = "whole-dollar USD price";
|
|
176
|
+
if (typeof value !== "string")
|
|
177
|
+
return toU64(value, label);
|
|
178
|
+
const trimmed = value.trim();
|
|
179
|
+
if (!PLAIN_INT_RE.test(trimmed)) {
|
|
180
|
+
throw new RangeError(`${label} must be a plain integer string, got "${value}"`);
|
|
181
|
+
}
|
|
182
|
+
return toU64(BigInt(trimmed), label);
|
|
183
|
+
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* or a `TransactionArgument`).
|
|
12
12
|
*/
|
|
13
13
|
import * as wxa from "../generated/waterx_account/account.js";
|
|
14
|
+
import { toU64 } from "../utils/validate.js";
|
|
14
15
|
import { makeSenderRequest } from "./account-request.js";
|
|
15
16
|
import { ACCUMULATOR_ROOT } from "./constants.js";
|
|
16
17
|
import { createAccountCall } from "./waterx-account.js";
|
|
@@ -149,7 +150,7 @@ export function requestWithdraw(client, tx, params) {
|
|
|
149
150
|
registry: tx.object(client.config.packages.waterx_account.account_registry),
|
|
150
151
|
senderRequest: req,
|
|
151
152
|
accountId: params.accountId,
|
|
152
|
-
amount: params.amount,
|
|
153
|
+
amount: toU64(params.amount, "amount"),
|
|
153
154
|
recipient: params.recipient,
|
|
154
155
|
extraData: Array.from(params.extraData ?? new Uint8Array()),
|
|
155
156
|
},
|
|
@@ -73,8 +73,9 @@ export interface WithdrawalQueuePackage {
|
|
|
73
73
|
/**
|
|
74
74
|
* Wormhole infra for the cross-chain credit bridge. `state_id` is the same
|
|
75
75
|
* shared Sui Wormhole `State` object Pyth uses (kept in sync with
|
|
76
|
-
* `
|
|
77
|
-
* `WaterXConfig.wormhole` if a deployment ever points
|
|
76
|
+
* `PYTH_CORE_INFRA[*].wormhole_state_id` in `oracle/pyth.ts`). Override
|
|
77
|
+
* per-deployment via `WaterXConfig.wormhole` if a deployment ever points
|
|
78
|
+
* elsewhere.
|
|
78
79
|
*/
|
|
79
80
|
export interface WormholeInfraConfig {
|
|
80
81
|
/** Shared Sui Wormhole `State` object. */
|
|
@@ -15,7 +15,15 @@ export interface ParkedBackingAssetBalance {
|
|
|
15
15
|
/** Sum of `listCoins` object balances — TTO'd / owned `Coin<T>` path. */
|
|
16
16
|
coinsRaw: bigint;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Rescale a u64 raw amount between token decimal precisions (truncates on
|
|
20
|
+
* downscale). `toDecimals` defaults to {@link COLLATERAL_DECIMALS} — the
|
|
21
|
+
* CREDIT/wxUSD (collateral-typed) scale, 6 on every current deployment — for
|
|
22
|
+
* the common backing-asset → CREDIT direction. When rescaling a custody
|
|
23
|
+
* backing asset, always pass its per-asset config `decimal`
|
|
24
|
+
* (`NativeCustodyAsset.decimal`) as `fromDecimals`; never assume flat 6 — a
|
|
25
|
+
* 9-dec backing asset would otherwise mis-scale by 1000×.
|
|
26
|
+
*/
|
|
19
27
|
export declare function rescaleRawAmount(raw: bigint, fromDecimals: number, toDecimals?: number): bigint;
|
|
20
28
|
/**
|
|
21
29
|
* Probe every backing asset registered on `native_custody` for non-zero balances
|
|
@@ -26,7 +34,22 @@ export declare function probeParkedBackingAssets(client: AccountClientLike, acco
|
|
|
26
34
|
/**
|
|
27
35
|
* Probe non-zero CREDIT parked at `accountId`'s Sui address. Matches the
|
|
28
36
|
* address-CREDIT legs inside {@link appendConsolidateAddressCredit}.
|
|
37
|
+
*
|
|
38
|
+
* RPC failures PROPAGATE (no swallow-to-zero): a gRPC error here used to be
|
|
39
|
+
* silently reported as an authoritative zero balance, which made
|
|
40
|
+
* `getSpendableCreditBalance` under-report spendable funds and let
|
|
41
|
+
* `appendConsolidateAddressCredit` build a tx that later aborted on-chain
|
|
42
|
+
* with a confusing insufficient-balance error. Callers that can tolerate a
|
|
43
|
+
* missing probe must catch explicitly.
|
|
29
44
|
*/
|
|
30
45
|
export declare function probeAddressCreditBalance(client: AccountClientLike, accountId: string): Promise<AddressCreditBalance>;
|
|
31
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Sum parked backing assets into CREDIT base units at the 1:1 PSM peg.
|
|
48
|
+
* Each row rescales from its own per-asset `decimals` (sourced from config
|
|
49
|
+
* `NativeCustodyAsset.decimal` by {@link probeParkedBackingAssets}), so
|
|
50
|
+
* mixed-decimal backing sets (e.g. a 9-dec asset next to 6-dec USDC) sum
|
|
51
|
+
* correctly. `creditDecimals` is the CREDIT/wxUSD **target** scale —
|
|
52
|
+
* collateral-typed, 6 on all current deployments (the config JSON carries no
|
|
53
|
+
* credit decimal).
|
|
54
|
+
*/
|
|
32
55
|
export declare function sumParkedBackingAsCreditRaw(parked: readonly ParkedBackingAssetBalance[], creditDecimals?: number): bigint;
|
|
@@ -4,7 +4,15 @@
|
|
|
4
4
|
* so display totals match what the next async tx-builder would sweep.
|
|
5
5
|
*/
|
|
6
6
|
import { COLLATERAL_DECIMALS } from "../../constants.js";
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Rescale a u64 raw amount between token decimal precisions (truncates on
|
|
9
|
+
* downscale). `toDecimals` defaults to {@link COLLATERAL_DECIMALS} — the
|
|
10
|
+
* CREDIT/wxUSD (collateral-typed) scale, 6 on every current deployment — for
|
|
11
|
+
* the common backing-asset → CREDIT direction. When rescaling a custody
|
|
12
|
+
* backing asset, always pass its per-asset config `decimal`
|
|
13
|
+
* (`NativeCustodyAsset.decimal`) as `fromDecimals`; never assume flat 6 — a
|
|
14
|
+
* 9-dec backing asset would otherwise mis-scale by 1000×.
|
|
15
|
+
*/
|
|
8
16
|
export function rescaleRawAmount(raw, fromDecimals, toDecimals = COLLATERAL_DECIMALS) {
|
|
9
17
|
if (fromDecimals === toDecimals)
|
|
10
18
|
return raw;
|
|
@@ -52,39 +60,43 @@ export async function probeParkedBackingAssets(client, accountId) {
|
|
|
52
60
|
/**
|
|
53
61
|
* Probe non-zero CREDIT parked at `accountId`'s Sui address. Matches the
|
|
54
62
|
* address-CREDIT legs inside {@link appendConsolidateAddressCredit}.
|
|
63
|
+
*
|
|
64
|
+
* RPC failures PROPAGATE (no swallow-to-zero): a gRPC error here used to be
|
|
65
|
+
* silently reported as an authoritative zero balance, which made
|
|
66
|
+
* `getSpendableCreditBalance` under-report spendable funds and let
|
|
67
|
+
* `appendConsolidateAddressCredit` build a tx that later aborted on-chain
|
|
68
|
+
* with a confusing insufficient-balance error. Callers that can tolerate a
|
|
69
|
+
* missing probe must catch explicitly.
|
|
55
70
|
*/
|
|
56
71
|
export async function probeAddressCreditBalance(client, accountId) {
|
|
57
72
|
if (!client.config.packages.waterx_credit?.credit_type) {
|
|
58
73
|
return { fundsRaw: 0n, coinsRaw: 0n };
|
|
59
74
|
}
|
|
60
75
|
const creditType = client.creditType();
|
|
61
|
-
|
|
76
|
+
const bal = (await client.getBalance({
|
|
77
|
+
owner: accountId,
|
|
78
|
+
coinType: creditType,
|
|
79
|
+
}));
|
|
80
|
+
const fundsRaw = BigInt(bal.balance?.addressBalance ?? "0");
|
|
81
|
+
const coins = (await client.listCoins({
|
|
82
|
+
owner: accountId,
|
|
83
|
+
coinType: creditType,
|
|
84
|
+
}));
|
|
62
85
|
let coinsRaw = 0n;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
owner: accountId,
|
|
66
|
-
coinType: creditType,
|
|
67
|
-
}));
|
|
68
|
-
fundsRaw = BigInt(bal.balance?.addressBalance ?? "0");
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
// ignore — treat as zero parked funds
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
const coins = (await client.listCoins({
|
|
75
|
-
owner: accountId,
|
|
76
|
-
coinType: creditType,
|
|
77
|
-
}));
|
|
78
|
-
for (const coin of coins.objects ?? []) {
|
|
79
|
-
coinsRaw += BigInt(coin.balance ?? "0");
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
// ignore — treat as zero owned coins
|
|
86
|
+
for (const coin of coins.objects ?? []) {
|
|
87
|
+
coinsRaw += BigInt(coin.balance ?? "0");
|
|
84
88
|
}
|
|
85
89
|
return { fundsRaw, coinsRaw };
|
|
86
90
|
}
|
|
87
|
-
/**
|
|
91
|
+
/**
|
|
92
|
+
* Sum parked backing assets into CREDIT base units at the 1:1 PSM peg.
|
|
93
|
+
* Each row rescales from its own per-asset `decimals` (sourced from config
|
|
94
|
+
* `NativeCustodyAsset.decimal` by {@link probeParkedBackingAssets}), so
|
|
95
|
+
* mixed-decimal backing sets (e.g. a 9-dec asset next to 6-dec USDC) sum
|
|
96
|
+
* correctly. `creditDecimals` is the CREDIT/wxUSD **target** scale —
|
|
97
|
+
* collateral-typed, 6 on all current deployments (the config JSON carries no
|
|
98
|
+
* credit decimal).
|
|
99
|
+
*/
|
|
88
100
|
export function sumParkedBackingAsCreditRaw(parked, creditDecimals = COLLATERAL_DECIMALS) {
|
|
89
101
|
let sum = 0n;
|
|
90
102
|
for (const row of parked) {
|
|
@@ -24,6 +24,7 @@ import { requestWithdraw as requestWithdrawCall } from "../../generated/waterx_a
|
|
|
24
24
|
import { consumeDepositDirect } from "../../generated/waterx_account/direct_rule.js";
|
|
25
25
|
import { enqueue as enqueueCall, executeNative as executeNativeCall, executeWormhole as executeWormholeCall, routeNative as routeNativeCall, routeWormhole as routeWormholeCall, } from "../../generated/withdrawal_queue/withdrawal_queue.js";
|
|
26
26
|
import { redeemVaa as redeemVaaCall } from "../../generated/wormhole_bridge/wormhole_bridge.js";
|
|
27
|
+
import { toU16, toU64 } from "../../utils/validate.js";
|
|
27
28
|
import { makeSenderRequest } from "../account-request.js";
|
|
28
29
|
// ============================================================================
|
|
29
30
|
// Byte helpers
|
|
@@ -126,15 +127,10 @@ export function consumeCreditDeposit(client, tx, params) {
|
|
|
126
127
|
}
|
|
127
128
|
/** Build `withdrawal_queue::route_wormhole`. Returns the `extra_data` argument. */
|
|
128
129
|
export function routeWormhole(client, tx, params) {
|
|
129
|
-
if (!Number.isInteger(params.evmDestinationChain) ||
|
|
130
|
-
params.evmDestinationChain < 0 ||
|
|
131
|
-
params.evmDestinationChain > 0xffff) {
|
|
132
|
-
throw new Error(`evmDestinationChain must be a u16 (0..65535), got ${params.evmDestinationChain}`);
|
|
133
|
-
}
|
|
134
130
|
const out = routeWormholeCall({
|
|
135
131
|
package: queuePkg(client),
|
|
136
132
|
arguments: {
|
|
137
|
-
evmDestinationChain: params.evmDestinationChain,
|
|
133
|
+
evmDestinationChain: toU16(params.evmDestinationChain, "evmDestinationChain"),
|
|
138
134
|
evmRecipient: toEvmAddressBytes(params.evmRecipient, "evmRecipient"),
|
|
139
135
|
evmToken: toEvmAddressBytes(params.evmToken, "evmToken"),
|
|
140
136
|
},
|
|
@@ -145,7 +141,7 @@ export function routeWormhole(client, tx, params) {
|
|
|
145
141
|
export function routeNative(client, tx, params) {
|
|
146
142
|
const out = routeNativeCall({
|
|
147
143
|
package: queuePkg(client),
|
|
148
|
-
arguments: { minOutput:
|
|
144
|
+
arguments: { minOutput: toU64(params.minOutput ?? 0n, "minOutput") },
|
|
149
145
|
typeArguments: [normalizeStructTag(params.assetType)],
|
|
150
146
|
})(tx);
|
|
151
147
|
return out;
|
|
@@ -163,7 +159,7 @@ export function requestCreditWithdraw(client, tx, params) {
|
|
|
163
159
|
registry: tx.object(client.config.packages.waterx_account.account_registry),
|
|
164
160
|
senderRequest: senderRequest,
|
|
165
161
|
accountId: params.accountId,
|
|
166
|
-
amount: params.amount,
|
|
162
|
+
amount: toU64(params.amount, "amount"),
|
|
167
163
|
recipient: params.recipient,
|
|
168
164
|
extraData: params.route,
|
|
169
165
|
},
|
|
@@ -194,7 +190,7 @@ export function executeWithdrawalWormhole(client, tx, params) {
|
|
|
194
190
|
package: queuePkg(client),
|
|
195
191
|
arguments: {
|
|
196
192
|
queue: tx.object(queueId(client)),
|
|
197
|
-
key: params.key,
|
|
193
|
+
key: toU64(params.key, "key"),
|
|
198
194
|
request: request,
|
|
199
195
|
bridge: tx.object(bridgeId(client)),
|
|
200
196
|
creditRegistry: tx.object(creditRegistryId(client)),
|
|
@@ -211,7 +207,7 @@ export function executeWithdrawalNative(client, tx, params) {
|
|
|
211
207
|
package: queuePkg(client),
|
|
212
208
|
arguments: {
|
|
213
209
|
queue: tx.object(queueId(client)),
|
|
214
|
-
key: params.key,
|
|
210
|
+
key: toU64(params.key, "key"),
|
|
215
211
|
request: request,
|
|
216
212
|
vault: tx.object(custodyVaultId(client)),
|
|
217
213
|
creditRegistry: tx.object(creditRegistryId(client)),
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -9,7 +9,19 @@ export declare const DOUBLE_SCALE = 1000000000000000000n;
|
|
|
9
9
|
export declare const SUI_DECIMALS = 9;
|
|
10
10
|
/** WLP LP-token decimals. */
|
|
11
11
|
export declare const WLP_DECIMALS = 6;
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Decimals for **collateral-typed** values only: the CREDIT/wxUSD internal
|
|
14
|
+
* balance and the USD-pegged trading collateral (USDC, USDSUI). All current
|
|
15
|
+
* collateral and the CREDIT coin are 6-dec, and the config JSON carries no
|
|
16
|
+
* credit decimal, so this constant is the single source for the CREDIT scale.
|
|
17
|
+
*
|
|
18
|
+
* Do NOT use it for custody **backing assets** — those carry a per-asset
|
|
19
|
+
* `decimal` in config (`NativeCustodyAsset.decimal`), threaded through
|
|
20
|
+
* `probeParkedBackingAssets` → `sumParkedBackingAsCreditRaw`. If a 9-dec
|
|
21
|
+
* backing asset ever lists, a path that assumed flat 6 for it would mis-scale
|
|
22
|
+
* its parked balance by 1000×; only a change to the CREDIT coin itself (or a
|
|
23
|
+
* non-6-dec collateral listing) would require touching this constant.
|
|
24
|
+
*/
|
|
13
25
|
export declare const COLLATERAL_DECIMALS = 6;
|
|
14
26
|
/**
|
|
15
27
|
* @deprecated Import the individual `SUI_DECIMALS` / `WLP_DECIMALS` /
|
|
@@ -23,6 +35,8 @@ export declare const TOKEN_DECIMALS: {
|
|
|
23
35
|
readonly USDSUI: 6;
|
|
24
36
|
readonly WLP: 6;
|
|
25
37
|
};
|
|
38
|
+
export declare const MS_PER_MINUTE: number;
|
|
39
|
+
export declare const MS_PER_HOUR: number;
|
|
26
40
|
export declare const MS_PER_YEAR: number;
|
|
27
41
|
/**
|
|
28
42
|
* Zero-address placeholder used as the sender in dry-run / simulate calls.
|
package/dist/src/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Shared, line-agnostic primitives (network id, scaling, decimals, time).
|
|
2
|
-
// Perp-domain enums (permissions / order tags / action codes
|
|
3
|
-
//
|
|
2
|
+
// Perp-domain enums (permissions / order tags / action codes) live in
|
|
3
|
+
// `perp/constants.ts`; prediction has its own `prediction/constants.ts`.
|
|
4
4
|
// ======== Scaling ========
|
|
5
5
|
/** Basis-point denominator (10_000). Matches BP_SCALE in the Move contracts. */
|
|
6
6
|
export const BPS_SCALE = 10000n;
|
|
@@ -13,7 +13,19 @@ export const DOUBLE_SCALE = 1000000000000000000n;
|
|
|
13
13
|
export const SUI_DECIMALS = 9;
|
|
14
14
|
/** WLP LP-token decimals. */
|
|
15
15
|
export const WLP_DECIMALS = 6;
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Decimals for **collateral-typed** values only: the CREDIT/wxUSD internal
|
|
18
|
+
* balance and the USD-pegged trading collateral (USDC, USDSUI). All current
|
|
19
|
+
* collateral and the CREDIT coin are 6-dec, and the config JSON carries no
|
|
20
|
+
* credit decimal, so this constant is the single source for the CREDIT scale.
|
|
21
|
+
*
|
|
22
|
+
* Do NOT use it for custody **backing assets** — those carry a per-asset
|
|
23
|
+
* `decimal` in config (`NativeCustodyAsset.decimal`), threaded through
|
|
24
|
+
* `probeParkedBackingAssets` → `sumParkedBackingAsCreditRaw`. If a 9-dec
|
|
25
|
+
* backing asset ever lists, a path that assumed flat 6 for it would mis-scale
|
|
26
|
+
* its parked balance by 1000×; only a change to the CREDIT coin itself (or a
|
|
27
|
+
* non-6-dec collateral listing) would require touching this constant.
|
|
28
|
+
*/
|
|
17
29
|
export const COLLATERAL_DECIMALS = 6;
|
|
18
30
|
/**
|
|
19
31
|
* @deprecated Import the individual `SUI_DECIMALS` / `WLP_DECIMALS` /
|
|
@@ -28,6 +40,8 @@ export const TOKEN_DECIMALS = {
|
|
|
28
40
|
WLP: WLP_DECIMALS,
|
|
29
41
|
};
|
|
30
42
|
// ======== Time ========
|
|
43
|
+
export const MS_PER_MINUTE = 60 * 1000;
|
|
44
|
+
export const MS_PER_HOUR = 60 * 60 * 1000;
|
|
31
45
|
export const MS_PER_YEAR = 365 * 24 * 60 * 60 * 1000;
|
|
32
46
|
// ======== Well-known addresses ========
|
|
33
47
|
/**
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**************************************************************
|
|
2
|
+
* THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
|
|
3
|
+
**************************************************************/
|
|
4
|
+
/** Module for floating points */
|
|
5
|
+
import { MoveStruct } from '../../../utils/index.ts';
|
|
6
|
+
export declare const Float: MoveStruct<{
|
|
7
|
+
value: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u128">;
|
|
8
|
+
}, "bucket_v2_framework::float::Float">;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**************************************************************
|
|
2
|
+
* THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
|
|
3
|
+
**************************************************************/
|
|
4
|
+
/** Module for floating points */
|
|
5
|
+
import { MoveStruct } from "../../../utils/index.js";
|
|
6
|
+
import { bcs } from '@mysten/sui/bcs';
|
|
7
|
+
const $moduleName = 'bucket_v2_framework::float';
|
|
8
|
+
export const Float = new MoveStruct({ name: `${$moduleName}::Float`, fields: {
|
|
9
|
+
value: bcs.u128()
|
|
10
|
+
} });
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**************************************************************
|
|
2
|
+
* THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
|
|
3
|
+
**************************************************************/
|
|
4
|
+
import { type BcsType } from '@mysten/sui/bcs';
|
|
5
|
+
import { MoveStruct } from '../../../utils/index.ts';
|
|
6
|
+
/** An entry in the map */
|
|
7
|
+
export declare function Entry<K extends BcsType<any>, V extends BcsType<any>>(...typeParameters: [
|
|
8
|
+
K,
|
|
9
|
+
V
|
|
10
|
+
]): MoveStruct<{
|
|
11
|
+
key: K;
|
|
12
|
+
value: V;
|
|
13
|
+
}, `0x2::vec_map::Entry<${K["name"]}, ${V["name"]}>`>;
|
|
14
|
+
/**
|
|
15
|
+
* A map data structure backed by a vector. The map is guaranteed not to contain
|
|
16
|
+
* duplicate keys, but entries are _not_ sorted by key--entries are included in
|
|
17
|
+
* insertion order. All operations are O(N) in the size of the map--the intention
|
|
18
|
+
* of this data structure is only to provide the convenience of programming against
|
|
19
|
+
* a map API. Large maps should use handwritten parent/child relationships instead.
|
|
20
|
+
* Maps that need sorted iteration rather than insertion order iteration should
|
|
21
|
+
* also be handwritten.
|
|
22
|
+
*/
|
|
23
|
+
export declare function VecMap<K extends BcsType<any>, V extends BcsType<any>>(...typeParameters: [
|
|
24
|
+
K,
|
|
25
|
+
V
|
|
26
|
+
]): MoveStruct<{
|
|
27
|
+
contents: BcsType<{
|
|
28
|
+
key: K extends BcsType<infer U, any, string> ? U : never;
|
|
29
|
+
value: V extends BcsType<infer U, any, string> ? U : never;
|
|
30
|
+
}[], Iterable<{
|
|
31
|
+
key: K extends BcsType<any, infer U_1, string> ? U_1 : never;
|
|
32
|
+
value: V extends BcsType<any, infer U_1, string> ? U_1 : never;
|
|
33
|
+
}> & {
|
|
34
|
+
length: number;
|
|
35
|
+
}, string>;
|
|
36
|
+
}, `0x2::vec_map::VecMap<${K["name"]}, ${V["name"]}>`>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**************************************************************
|
|
2
|
+
* THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
|
|
3
|
+
**************************************************************/
|
|
4
|
+
import { bcs } from '@mysten/sui/bcs';
|
|
5
|
+
import { MoveStruct } from "../../../utils/index.js";
|
|
6
|
+
const $moduleName = '0x2::vec_map';
|
|
7
|
+
/** An entry in the map */
|
|
8
|
+
export function Entry(...typeParameters) {
|
|
9
|
+
return new MoveStruct({ name: `${$moduleName}::Entry<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
|
|
10
|
+
key: typeParameters[0],
|
|
11
|
+
value: typeParameters[1]
|
|
12
|
+
} });
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A map data structure backed by a vector. The map is guaranteed not to contain
|
|
16
|
+
* duplicate keys, but entries are _not_ sorted by key--entries are included in
|
|
17
|
+
* insertion order. All operations are O(N) in the size of the map--the intention
|
|
18
|
+
* of this data structure is only to provide the convenience of programming against
|
|
19
|
+
* a map API. Large maps should use handwritten parent/child relationships instead.
|
|
20
|
+
* Maps that need sorted iteration rather than insertion order iteration should
|
|
21
|
+
* also be handwritten.
|
|
22
|
+
*/
|
|
23
|
+
export function VecMap(...typeParameters) {
|
|
24
|
+
return new MoveStruct({ name: `${$moduleName}::VecMap<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
|
|
25
|
+
contents: bcs.vector(Entry(typeParameters[0], typeParameters[1]))
|
|
26
|
+
} });
|
|
27
|
+
}
|