@waterx/sdk 2.1.0 → 2.4.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 +75 -169
- package/dist/src/client.d.ts +40 -2
- package/dist/src/client.js +55 -6
- package/dist/src/config.d.ts +66 -3
- package/dist/src/config.js +10 -4
- package/dist/src/constants.d.ts +6 -0
- package/dist/src/constants.js +6 -0
- package/dist/src/core/waterx-account.d.ts +31 -0
- package/dist/src/core/waterx-account.js +26 -0
- package/dist/src/fetch.d.ts +110 -0
- package/dist/src/fetch.js +149 -4
- package/dist/src/generated/bucket_v2_framework/account.d.ts +5 -5
- package/dist/src/generated/bucket_v2_framework/double.d.ts +77 -77
- package/dist/src/generated/bucket_v2_framework/float.d.ts +73 -73
- package/dist/src/generated/bucket_v2_framework/liability.d.ts +33 -33
- package/dist/src/generated/bucket_v2_framework/linked_table.d.ts +5 -5
- package/dist/src/generated/bucket_v2_framework/linked_table.js +2 -2
- package/dist/src/generated/bucket_v2_framework/sheet.d.ts +57 -57
- package/dist/src/generated/bucket_v2_framework/sheet.js +5 -11
- package/dist/src/generated/native_custody/custody_vault.d.ts +46 -32
- package/dist/src/generated/native_custody/custody_vault.js +19 -10
- package/dist/src/generated/native_custody/deps/bucket_v2_framework/sheet.js +1 -3
- package/dist/src/generated/native_custody/events.js +1 -2
- package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +7 -7
- package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +1 -2
- package/dist/src/generated/utils/index.d.ts +7 -7
- package/dist/src/generated/utils/index.js +9 -6
- package/dist/src/generated/waterx_account/account.d.ts +124 -71
- package/dist/src/generated/waterx_account/account.js +64 -29
- package/dist/src/generated/waterx_account/deps/bucket_v2_framework/sheet.js +1 -3
- package/dist/src/generated/waterx_account/direct_rule.d.ts +5 -5
- package/dist/src/generated/waterx_account/events.d.ts +10 -0
- package/dist/src/generated/waterx_account/events.js +31 -50
- package/dist/src/generated/waterx_constant_rule/constant_rule.d.ts +68 -0
- package/dist/src/generated/waterx_constant_rule/constant_rule.js +59 -0
- package/dist/src/generated/waterx_constant_rule/deps/bucket_v2_framework/float.d.ts +8 -0
- package/dist/src/generated/waterx_constant_rule/deps/bucket_v2_framework/float.js +10 -0
- package/dist/src/generated/waterx_constant_rule/deps/sui/vec_map.d.ts +36 -0
- package/dist/src/generated/waterx_constant_rule/deps/sui/vec_map.js +27 -0
- package/dist/src/generated/waterx_credit/credit_registry.d.ts +9 -9
- package/dist/src/generated/waterx_credit/credit_registry.js +1 -2
- package/dist/src/generated/waterx_credit/limited_supply.d.ts +17 -17
- package/dist/src/generated/waterx_oracle/aggregator.js +1 -2
- package/dist/src/generated/waterx_oracle/collector.d.ts +17 -17
- package/dist/src/generated/waterx_oracle/collector.js +1 -1
- package/dist/src/generated/waterx_oracle/oracle.d.ts +5 -5
- package/dist/src/generated/waterx_perp/account_data.d.ts +5 -5
- package/dist/src/generated/waterx_perp/account_data.js +1 -2
- package/dist/src/generated/waterx_perp/deps/bucket_v2_framework/sheet.js +1 -3
- package/dist/src/generated/waterx_perp/events.d.ts +181 -181
- package/dist/src/generated/waterx_perp/events.js +87 -173
- package/dist/src/generated/waterx_perp/global_config.d.ts +3 -3
- package/dist/src/generated/waterx_perp/global_config.js +6 -12
- package/dist/src/generated/waterx_perp/keyed_big_vector.d.ts +9 -9
- package/dist/src/generated/waterx_perp/keyed_big_vector.js +1 -2
- package/dist/src/generated/waterx_perp/lp_pool.d.ts +115 -115
- package/dist/src/generated/waterx_perp/lp_pool.js +11 -22
- package/dist/src/generated/waterx_perp/market_config.d.ts +61 -43
- package/dist/src/generated/waterx_perp/market_config.js +29 -22
- package/dist/src/generated/waterx_perp/math.d.ts +7 -7
- package/dist/src/generated/waterx_perp/order_book.d.ts +47 -47
- package/dist/src/generated/waterx_perp/position.d.ts +99 -99
- package/dist/src/generated/waterx_perp/position.js +6 -12
- package/dist/src/generated/waterx_perp/request.d.ts +67 -67
- package/dist/src/generated/waterx_perp/request.js +2 -3
- package/dist/src/generated/waterx_perp/response.d.ts +35 -35
- package/dist/src/generated/waterx_perp/response.js +1 -2
- package/dist/src/generated/waterx_perp/trading.d.ts +303 -179
- package/dist/src/generated/waterx_perp/trading.js +99 -14
- package/dist/src/generated/waterx_perp_view/view.js +5 -10
- package/dist/src/generated/waterx_pyth_rule/pyth_rule.d.ts +5 -5
- package/dist/src/generated/waterx_pyth_rule/pyth_rule.js +1 -2
- package/dist/src/generated/waterx_referral/referral_table.d.ts +5 -5
- package/dist/src/generated/waterx_referral/referral_table.js +1 -2
- package/dist/src/generated/waterx_staking/waterx_staking.d.ts +19 -19
- package/dist/src/generated/waterx_staking/waterx_staking.js +10 -20
- package/dist/src/generated/waterx_supra_rule/deps/sui/vec_map.d.ts +36 -0
- package/dist/src/generated/waterx_supra_rule/deps/sui/vec_map.js +27 -0
- package/dist/src/generated/waterx_supra_rule/supra_rule.d.ts +158 -0
- package/dist/src/generated/waterx_supra_rule/supra_rule.js +148 -0
- package/dist/src/generated/withdrawal_queue/deps/bucket_v2_framework/float.d.ts +8 -0
- package/dist/src/generated/withdrawal_queue/deps/bucket_v2_framework/float.js +10 -0
- package/dist/src/generated/withdrawal_queue/deps/sui/vec_map.d.ts +36 -0
- package/dist/src/generated/withdrawal_queue/deps/sui/vec_map.js +27 -0
- package/dist/src/generated/withdrawal_queue/withdrawal_queue.d.ts +444 -4
- package/dist/src/generated/withdrawal_queue/withdrawal_queue.js +417 -4
- package/dist/src/generated/wormhole_bridge/wormhole_bridge.d.ts +214 -74
- package/dist/src/generated/wormhole_bridge/wormhole_bridge.js +158 -29
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.js +3 -2
- package/dist/src/prediction/account.d.ts +96 -0
- package/dist/src/prediction/account.js +230 -0
- package/dist/src/prediction/admin.d.ts +47 -0
- package/dist/src/prediction/admin.js +105 -0
- package/dist/src/prediction/bcs.d.ts +22 -0
- package/dist/src/prediction/bcs.js +240 -0
- package/dist/src/prediction/client.d.ts +75 -0
- package/dist/src/prediction/client.js +164 -0
- package/dist/src/prediction/config.d.ts +60 -0
- package/dist/src/prediction/config.js +75 -0
- package/dist/src/prediction/constants.d.ts +44 -0
- package/dist/src/prediction/constants.js +46 -0
- package/dist/src/prediction/fetch.d.ts +82 -0
- package/dist/src/prediction/fetch.js +270 -0
- package/dist/src/prediction/generated/bucket_v2_framework/account.d.ts +100 -0
- package/dist/src/prediction/generated/bucket_v2_framework/account.js +129 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/std/type_name.d.ts +6 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/std/type_name.js +19 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/balance.d.ts +10 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/balance.js +14 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_map.d.ts +36 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_map.js +27 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_set.d.ts +16 -0
- package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_set.js +19 -0
- package/dist/src/prediction/generated/bucket_v2_framework/double.d.ts +382 -0
- package/dist/src/prediction/generated/bucket_v2_framework/double.js +466 -0
- package/dist/src/prediction/generated/bucket_v2_framework/float.d.ts +362 -0
- package/dist/src/prediction/generated/bucket_v2_framework/float.js +440 -0
- package/dist/src/prediction/generated/bucket_v2_framework/liability.d.ts +193 -0
- package/dist/src/prediction/generated/bucket_v2_framework/liability.js +205 -0
- package/dist/src/prediction/generated/bucket_v2_framework/linked_table.d.ts +384 -0
- package/dist/src/prediction/generated/bucket_v2_framework/linked_table.js +382 -0
- package/dist/src/prediction/generated/bucket_v2_framework/sheet.d.ts +344 -0
- package/dist/src/prediction/generated/bucket_v2_framework/sheet.js +338 -0
- package/dist/src/prediction/generated/utils/index.d.ts +30 -0
- package/dist/src/prediction/generated/utils/index.js +160 -0
- package/dist/src/prediction/generated/waterx_account/account.d.ts +1589 -0
- package/dist/src/prediction/generated/waterx_account/account.js +1758 -0
- package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/liability.d.ts +7 -0
- package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/liability.js +13 -0
- package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/sheet.d.ts +7 -0
- package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/sheet.js +16 -0
- package/dist/src/prediction/generated/waterx_account/deps/std/type_name.d.ts +6 -0
- package/dist/src/prediction/generated/waterx_account/deps/std/type_name.js +19 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/balance.d.ts +10 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/balance.js +14 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/object_table.d.ts +12 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/object_table.js +19 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/table.d.ts +24 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/table.js +31 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/vec_map.d.ts +36 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/vec_map.js +27 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/vec_set.d.ts +16 -0
- package/dist/src/prediction/generated/waterx_account/deps/sui/vec_set.js +19 -0
- package/dist/src/prediction/generated/waterx_account/direct_rule.d.ts +75 -0
- package/dist/src/prediction/generated/waterx_account/direct_rule.js +78 -0
- package/dist/src/prediction/generated/waterx_account/events.d.ts +33 -0
- package/dist/src/prediction/generated/waterx_account/events.js +137 -0
- package/dist/src/prediction/generated/waterx_account/version.d.ts +10 -0
- package/dist/src/prediction/generated/waterx_account/version.js +8 -0
- package/dist/src/prediction/generated/waterx_prediction/account_data.d.ts +327 -0
- package/dist/src/prediction/generated/waterx_prediction/account_data.js +405 -0
- package/dist/src/prediction/generated/waterx_prediction/admin.d.ts +5 -0
- package/dist/src/prediction/generated/waterx_prediction/admin.js +9 -0
- package/dist/src/prediction/generated/waterx_prediction/bet_sharing.d.ts +60 -0
- package/dist/src/prediction/generated/waterx_prediction/bet_sharing.js +83 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/bucket_v2_framework/linked_table.d.ts +8 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/bucket_v2_framework/linked_table.js +18 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/sui/balance.d.ts +10 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/sui/balance.js +14 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/sui/table.d.ts +24 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/sui/table.js +31 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/sui/vec_set.d.ts +16 -0
- package/dist/src/prediction/generated/waterx_prediction/deps/sui/vec_set.js +19 -0
- package/dist/src/prediction/generated/waterx_prediction/events.d.ts +22 -0
- package/dist/src/prediction/generated/waterx_prediction/events.js +179 -0
- package/dist/src/prediction/generated/waterx_prediction/global_config.d.ts +116 -0
- package/dist/src/prediction/generated/waterx_prediction/global_config.js +141 -0
- package/dist/src/prediction/generated/waterx_prediction/order.d.ts +200 -0
- package/dist/src/prediction/generated/waterx_prediction/order.js +284 -0
- package/dist/src/prediction/generated/waterx_prediction/outcome.d.ts +58 -0
- package/dist/src/prediction/generated/waterx_prediction/outcome.js +73 -0
- package/dist/src/prediction/generated/waterx_prediction/position.d.ts +160 -0
- package/dist/src/prediction/generated/waterx_prediction/position.js +214 -0
- package/dist/src/prediction/generated/waterx_prediction/version.d.ts +10 -0
- package/dist/src/prediction/generated/waterx_prediction/version.js +8 -0
- package/dist/src/prediction/generated/waterx_prediction/view.d.ts +353 -0
- package/dist/src/prediction/generated/waterx_prediction/view.js +432 -0
- package/dist/src/prediction/generated/waterx_prediction/waterx_prediction.d.ts +1698 -0
- package/dist/src/prediction/generated/waterx_prediction/waterx_prediction.js +1733 -0
- package/dist/src/prediction/gift-link.d.ts +6 -0
- package/dist/src/prediction/gift-link.js +5 -0
- package/dist/src/prediction/gift.d.ts +223 -0
- package/dist/src/prediction/gift.js +451 -0
- package/dist/src/prediction/index.d.ts +29 -0
- package/dist/src/prediction/index.js +21 -0
- package/dist/src/prediction/prediction.d.ts +104 -0
- package/dist/src/prediction/prediction.js +317 -0
- package/dist/src/prediction/tx-builders.d.ts +44 -0
- package/dist/src/prediction/tx-builders.js +52 -0
- package/dist/src/prediction/types.d.ts +93 -0
- package/dist/src/prediction/types.js +1 -0
- package/dist/src/prediction/user/account.d.ts +2 -0
- package/dist/src/prediction/user/account.js +1 -0
- package/dist/src/prediction/user/admin.d.ts +6 -0
- package/dist/src/prediction/user/admin.js +3 -0
- package/dist/src/prediction/user/gift.d.ts +2 -0
- package/dist/src/prediction/user/gift.js +1 -0
- package/dist/src/prediction/user/index.d.ts +5 -0
- package/dist/src/prediction/user/index.js +3 -0
- package/dist/src/prediction/user/keeper.d.ts +2 -0
- package/dist/src/prediction/user/keeper.js +1 -0
- package/dist/src/prediction/user/order.d.ts +2 -0
- package/dist/src/prediction/user/order.js +1 -0
- package/dist/src/prediction/user/position.d.ts +2 -0
- package/dist/src/prediction/user/position.js +1 -0
- package/dist/src/prediction/utils/bcs.d.ts +1 -0
- package/dist/src/prediction/utils/bcs.js +1 -0
- package/dist/src/prediction/utils/index.d.ts +1 -0
- package/dist/src/prediction/utils/index.js +1 -0
- package/dist/src/prediction/utils.d.ts +30 -0
- package/dist/src/prediction/utils.js +177 -0
- package/dist/src/sdk.d.ts +18 -0
- package/dist/src/sdk.js +17 -0
- package/dist/src/tx-builders.d.ts +54 -0
- package/dist/src/tx-builders.js +141 -0
- package/dist/src/unified-client.d.ts +407 -0
- package/dist/src/unified-client.js +123 -0
- package/dist/src/user/account.d.ts +27 -0
- package/dist/src/user/account.js +34 -8
- package/dist/src/user/credit.d.ts +8 -14
- package/dist/src/user/credit.js +9 -23
- package/dist/src/user/custody.d.ts +4 -18
- package/dist/src/user/custody.js +14 -25
- package/dist/src/utils/consolidate-balance.d.ts +37 -0
- package/dist/src/utils/consolidate-balance.js +89 -0
- package/dist/src/utils/math.d.ts +86 -0
- package/dist/src/utils/math.js +100 -0
- package/dist/src/utils/pyth.d.ts +42 -7
- package/dist/src/utils/pyth.js +107 -31
- package/package.json +129 -34
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* `enqueueWithdrawal` parks a FIFO `Queue<CREDIT>` entry.
|
|
11
11
|
* - Keeper drains the queue via `executeWithdrawalWormhole` /
|
|
12
12
|
* `executeWithdrawalNative` (caller must be on the executor allowlist).
|
|
13
|
-
* - PSM: `custodyMint`
|
|
13
|
+
* - PSM: `custodyMint` against the native `CustodyVault` (direct burn was
|
|
14
|
+
* removed — audit L03/M14; redeem via the withdraw queue path above).
|
|
14
15
|
*
|
|
15
16
|
* Every builder that emits a hot potato returns its argument so the caller
|
|
16
17
|
* (or the high-level `tx-builders.ts` wrappers) can pair + consume it in the
|
|
@@ -55,6 +56,12 @@ export declare function routeWormhole(client: WaterXClient, tx: Transaction, par
|
|
|
55
56
|
export interface RouteNativeParams {
|
|
56
57
|
/** Fully-qualified backing asset Move type `T` (e.g. via `client.getNativeAsset`). */
|
|
57
58
|
assetType: string;
|
|
59
|
+
/**
|
|
60
|
+
* Minimum `Coin<T>` the user will accept after the native burn fee;
|
|
61
|
+
* `execute_native` aborts `EOutputBelowMin` if a later fee change would
|
|
62
|
+
* deliver less (audit M15). Defaults to `0` (opt out).
|
|
63
|
+
*/
|
|
64
|
+
minOutput?: bigint | number;
|
|
58
65
|
}
|
|
59
66
|
/** Build `withdrawal_queue::route_native<T>`. Returns the `extra_data` argument. */
|
|
60
67
|
export declare function routeNative(client: WaterXClient, tx: Transaction, params: RouteNativeParams): TransactionArgument;
|
|
@@ -120,16 +127,3 @@ export interface CustodyMintParams {
|
|
|
120
127
|
* {@link consumeCreditDeposit}).
|
|
121
128
|
*/
|
|
122
129
|
export declare function custodyMint(client: WaterXClient, tx: Transaction, params: CustodyMintParams): TransactionArgument;
|
|
123
|
-
export interface CustodyBurnParams {
|
|
124
|
-
/** wxa account ID the burned CREDIT belongs to (cap / fee key). */
|
|
125
|
-
accountId: string;
|
|
126
|
-
/** `Coin<CREDIT>` to burn. */
|
|
127
|
-
creditCoin: TransactionArgument;
|
|
128
|
-
assetType: string;
|
|
129
|
-
creditType?: string;
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Build `native_custody::custody_vault::burn<T, CREDIT>`. Returns the
|
|
133
|
-
* resulting `Coin<T>` argument.
|
|
134
|
-
*/
|
|
135
|
-
export declare function custodyBurn(client: WaterXClient, tx: Transaction, params: CustodyBurnParams): TransactionArgument;
|
package/dist/src/user/credit.js
CHANGED
|
@@ -10,14 +10,16 @@
|
|
|
10
10
|
* `enqueueWithdrawal` parks a FIFO `Queue<CREDIT>` entry.
|
|
11
11
|
* - Keeper drains the queue via `executeWithdrawalWormhole` /
|
|
12
12
|
* `executeWithdrawalNative` (caller must be on the executor allowlist).
|
|
13
|
-
* - PSM: `custodyMint`
|
|
13
|
+
* - PSM: `custodyMint` against the native `CustodyVault` (direct burn was
|
|
14
|
+
* removed — audit L03/M14; redeem via the withdraw queue path above).
|
|
14
15
|
*
|
|
15
16
|
* Every builder that emits a hot potato returns its argument so the caller
|
|
16
17
|
* (or the high-level `tx-builders.ts` wrappers) can pair + consume it in the
|
|
17
18
|
* same PTB.
|
|
18
19
|
*/
|
|
19
20
|
import { fromHex } from "@mysten/bcs";
|
|
20
|
-
import {
|
|
21
|
+
import { normalizeStructTag } from "@mysten/sui/utils";
|
|
22
|
+
import { mint as custodyMintCall } from "../generated/native_custody/custody_vault.js";
|
|
21
23
|
import { requestWithdraw as requestWithdrawCall } from "../generated/waterx_account/account.js";
|
|
22
24
|
import { consumeDepositDirect } from "../generated/waterx_account/direct_rule.js";
|
|
23
25
|
import { enqueue as enqueueCall, executeNative as executeNativeCall, executeWormhole as executeWormholeCall, routeNative as routeNativeCall, routeWormhole as routeWormholeCall, } from "../generated/withdrawal_queue/withdrawal_queue.js";
|
|
@@ -45,7 +47,7 @@ function toEvmAddressBytes(input, field) {
|
|
|
45
47
|
return bytes;
|
|
46
48
|
}
|
|
47
49
|
function creditTypeOf(client, override) {
|
|
48
|
-
return override ?? client.creditType();
|
|
50
|
+
return normalizeStructTag(override ?? client.creditType());
|
|
49
51
|
}
|
|
50
52
|
// Required-ID accessors: the credit/bridge package entries carry their
|
|
51
53
|
// shared object ids only after the relevant deploy phase has run, so each
|
|
@@ -143,7 +145,8 @@ export function routeWormhole(client, tx, params) {
|
|
|
143
145
|
export function routeNative(client, tx, params) {
|
|
144
146
|
const out = routeNativeCall({
|
|
145
147
|
package: queuePkg(client),
|
|
146
|
-
|
|
148
|
+
arguments: { minOutput: BigInt(params.minOutput ?? 0n) },
|
|
149
|
+
typeArguments: [normalizeStructTag(params.assetType)],
|
|
147
150
|
})(tx);
|
|
148
151
|
return out;
|
|
149
152
|
}
|
|
@@ -213,7 +216,7 @@ export function executeWithdrawalNative(client, tx, params) {
|
|
|
213
216
|
vault: tx.object(custodyVaultId(client)),
|
|
214
217
|
creditRegistry: tx.object(creditRegistryId(client)),
|
|
215
218
|
},
|
|
216
|
-
typeArguments: [params.assetType, creditTypeOf(client, params.creditType)],
|
|
219
|
+
typeArguments: [normalizeStructTag(params.assetType), creditTypeOf(client, params.creditType)],
|
|
217
220
|
})(tx);
|
|
218
221
|
}
|
|
219
222
|
/**
|
|
@@ -232,24 +235,7 @@ export function custodyMint(client, tx, params) {
|
|
|
232
235
|
assetCoin: params.assetCoin,
|
|
233
236
|
extraData: toBytes(params.extraData ?? new Uint8Array()),
|
|
234
237
|
},
|
|
235
|
-
typeArguments: [params.assetType, creditTypeOf(client, params.creditType)],
|
|
238
|
+
typeArguments: [normalizeStructTag(params.assetType), creditTypeOf(client, params.creditType)],
|
|
236
239
|
})(tx);
|
|
237
240
|
return req;
|
|
238
241
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Build `native_custody::custody_vault::burn<T, CREDIT>`. Returns the
|
|
241
|
-
* resulting `Coin<T>` argument.
|
|
242
|
-
*/
|
|
243
|
-
export function custodyBurn(client, tx, params) {
|
|
244
|
-
const out = custodyBurnCall({
|
|
245
|
-
package: custodyPkg(client),
|
|
246
|
-
arguments: {
|
|
247
|
-
vault: tx.object(custodyVaultId(client)),
|
|
248
|
-
registry: tx.object(creditRegistryId(client)),
|
|
249
|
-
accountId: params.accountId,
|
|
250
|
-
creditCoin: params.creditCoin,
|
|
251
|
-
},
|
|
252
|
-
typeArguments: [params.assetType, creditTypeOf(client, params.creditType)],
|
|
253
|
-
})(tx);
|
|
254
|
-
return out;
|
|
255
|
-
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builders for `native_custody::custody_vault` — the Sui-native PSM that
|
|
3
3
|
* mints the protocol CREDIT CoinType 1:1 against backing stable assets `T`
|
|
4
|
-
* (CCTP USDC, USDT, …)
|
|
4
|
+
* (CCTP USDC, USDT, …).
|
|
5
5
|
*
|
|
6
6
|
* `mintCredit` / `mintCreditFromRequest` return a `DepositRequest<CREDIT>`
|
|
7
7
|
* hot potato — it must be consumed in the same PTB by the deposit policy
|
|
8
8
|
* registered for CREDIT (the canonical policy is `direct_rule::DirectRule`).
|
|
9
9
|
* `mintCreditToAccount` chains that consume for you.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* There is no direct burn builder: the contract removed witness-free
|
|
12
|
+
* `custody_vault::burn` (audit L03/M14). CREDIT redemption routes through
|
|
13
|
+
* requestCreditWithdraw -> enqueueWithdrawal -> keeper executeWithdrawalNative.
|
|
13
14
|
*
|
|
14
15
|
* Requires `waterx_credit` + `native_custody` in the loaded config — both
|
|
15
16
|
* are optional in `WaterXConfig` since not every deployment ships the
|
|
@@ -54,18 +55,3 @@ export declare function mintCreditFromRequest(client: WaterXClient, tx: Transact
|
|
|
54
55
|
* Assumes CREDIT's deposit policy is `DirectRule` (the canonical setup).
|
|
55
56
|
*/
|
|
56
57
|
export declare function mintCreditToAccount(client: WaterXClient, tx: Transaction, params: MintCreditParams): void;
|
|
57
|
-
export interface BurnCreditParams {
|
|
58
|
-
/** wxa account ID the burned CREDIT belongs to (burn-cap + partner-fee key). */
|
|
59
|
-
accountId: string;
|
|
60
|
-
/** `Coin<CREDIT>` to redeem. */
|
|
61
|
-
creditCoin: TransactionArgument;
|
|
62
|
-
/** Fully-qualified backing-asset Move type `T` to redeem into. */
|
|
63
|
-
assetType: string;
|
|
64
|
-
/** CREDIT CoinType. Defaults to `client.creditType()`. */
|
|
65
|
-
creditType?: string;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Build `custody_vault::burn<T, CREDIT>`. Returns the redeemed `Coin<T>`
|
|
69
|
-
* argument for the caller to forward.
|
|
70
|
-
*/
|
|
71
|
-
export declare function burnCredit(client: WaterXClient, tx: Transaction, params: BurnCreditParams): TransactionArgument;
|
package/dist/src/user/custody.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builders for `native_custody::custody_vault` — the Sui-native PSM that
|
|
3
3
|
* mints the protocol CREDIT CoinType 1:1 against backing stable assets `T`
|
|
4
|
-
* (CCTP USDC, USDT, …)
|
|
4
|
+
* (CCTP USDC, USDT, …).
|
|
5
5
|
*
|
|
6
6
|
* `mintCredit` / `mintCreditFromRequest` return a `DepositRequest<CREDIT>`
|
|
7
7
|
* hot potato — it must be consumed in the same PTB by the deposit policy
|
|
8
8
|
* registered for CREDIT (the canonical policy is `direct_rule::DirectRule`).
|
|
9
9
|
* `mintCreditToAccount` chains that consume for you.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* There is no direct burn builder: the contract removed witness-free
|
|
12
|
+
* `custody_vault::burn` (audit L03/M14). CREDIT redemption routes through
|
|
13
|
+
* requestCreditWithdraw -> enqueueWithdrawal -> keeper executeWithdrawalNative.
|
|
13
14
|
*
|
|
14
15
|
* Requires `waterx_credit` + `native_custody` in the loaded config — both
|
|
15
16
|
* are optional in `WaterXConfig` since not every deployment ships the
|
|
16
17
|
* credit pipeline.
|
|
17
18
|
*/
|
|
19
|
+
import { normalizeStructTag } from "@mysten/sui/utils";
|
|
18
20
|
import * as custody from "../generated/native_custody/custody_vault.js";
|
|
19
21
|
import { consumeDepositDirect } from "../generated/waterx_account/direct_rule.js";
|
|
20
22
|
function requireCredit(client) {
|
|
@@ -48,7 +50,10 @@ export function mintCredit(client, tx, params) {
|
|
|
48
50
|
assetCoin: params.assetCoin,
|
|
49
51
|
extraData: Array.from(params.extraData ?? new Uint8Array()),
|
|
50
52
|
},
|
|
51
|
-
typeArguments: [
|
|
53
|
+
typeArguments: [
|
|
54
|
+
normalizeStructTag(params.assetType),
|
|
55
|
+
normalizeStructTag(params.creditType ?? client.creditType()),
|
|
56
|
+
],
|
|
52
57
|
})(tx);
|
|
53
58
|
return req;
|
|
54
59
|
}
|
|
@@ -68,7 +73,10 @@ export function mintCreditFromRequest(client, tx, params) {
|
|
|
68
73
|
accountRegistry: tx.object(client.config.packages.waterx_account.account_registry),
|
|
69
74
|
depositRequest: params.depositRequest,
|
|
70
75
|
},
|
|
71
|
-
typeArguments: [
|
|
76
|
+
typeArguments: [
|
|
77
|
+
normalizeStructTag(params.assetType),
|
|
78
|
+
normalizeStructTag(params.creditType ?? client.creditType()),
|
|
79
|
+
],
|
|
72
80
|
})(tx);
|
|
73
81
|
return req;
|
|
74
82
|
}
|
|
@@ -88,25 +96,6 @@ export function mintCreditToAccount(client, tx, params) {
|
|
|
88
96
|
registry: tx.object(client.config.packages.waterx_account.account_registry),
|
|
89
97
|
req: req,
|
|
90
98
|
},
|
|
91
|
-
typeArguments: [params.creditType ?? client.creditType()],
|
|
99
|
+
typeArguments: [normalizeStructTag(params.creditType ?? client.creditType())],
|
|
92
100
|
})(tx);
|
|
93
101
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Build `custody_vault::burn<T, CREDIT>`. Returns the redeemed `Coin<T>`
|
|
96
|
-
* argument for the caller to forward.
|
|
97
|
-
*/
|
|
98
|
-
export function burnCredit(client, tx, params) {
|
|
99
|
-
const credit = requireCredit(client);
|
|
100
|
-
const nc = requireCustody(client);
|
|
101
|
-
const [coin] = custody.burn({
|
|
102
|
-
package: nc.published_at,
|
|
103
|
-
arguments: {
|
|
104
|
-
vault: tx.object(nc.vault),
|
|
105
|
-
registry: tx.object(credit.credit_registry),
|
|
106
|
-
accountId: params.accountId,
|
|
107
|
-
creditCoin: params.creditCoin,
|
|
108
|
-
},
|
|
109
|
-
typeArguments: [params.assetType, params.creditType ?? client.creditType()],
|
|
110
|
-
})(tx);
|
|
111
|
-
return coin;
|
|
112
|
-
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared probe helpers for {@link appendConsolidateToUsd} and
|
|
3
|
+
* {@link getSpendableCreditBalance} — one asset list, one gRPC read pattern,
|
|
4
|
+
* so display totals match what the next async tx-builder would sweep.
|
|
5
|
+
*/
|
|
6
|
+
import type { WaterXClient } from "../client.ts";
|
|
7
|
+
/** CREDIT parked at a wxa account's Sui address (funds accumulator + owned coins). */
|
|
8
|
+
export interface AddressCreditBalance {
|
|
9
|
+
/** `getBalance.addressBalance` — funds accumulator path. */
|
|
10
|
+
fundsRaw: bigint;
|
|
11
|
+
/** Sum of `listCoins` object balances — TTO'd / owned `Coin<CREDIT>` path. */
|
|
12
|
+
coinsRaw: bigint;
|
|
13
|
+
}
|
|
14
|
+
/** One native-custody backing asset parked at a wxa account's Sui address. */
|
|
15
|
+
export interface ParkedBackingAssetBalance {
|
|
16
|
+
assetType: string;
|
|
17
|
+
decimals: number;
|
|
18
|
+
/** `getBalance.addressBalance` — funds accumulator (`send_funds` path). */
|
|
19
|
+
fundsRaw: bigint;
|
|
20
|
+
/** Sum of `listCoins` object balances — TTO'd / owned `Coin<T>` path. */
|
|
21
|
+
coinsRaw: bigint;
|
|
22
|
+
}
|
|
23
|
+
/** Rescale a u64 raw amount between token decimal precisions (truncates on downscale). */
|
|
24
|
+
export declare function rescaleRawAmount(raw: bigint, fromDecimals: number, toDecimals?: number): bigint;
|
|
25
|
+
/**
|
|
26
|
+
* Probe every backing asset registered on `native_custody` for non-zero balances
|
|
27
|
+
* parked at `accountId`'s Sui address. Matches the pre-tx scan inside
|
|
28
|
+
* {@link appendConsolidateToUsd}.
|
|
29
|
+
*/
|
|
30
|
+
export declare function probeParkedBackingAssets(client: WaterXClient, accountId: string): Promise<ParkedBackingAssetBalance[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Probe non-zero CREDIT parked at `accountId`'s Sui address. Matches the
|
|
33
|
+
* address-CREDIT legs inside {@link appendConsolidateAddressCredit}.
|
|
34
|
+
*/
|
|
35
|
+
export declare function probeAddressCreditBalance(client: WaterXClient, accountId: string): Promise<AddressCreditBalance>;
|
|
36
|
+
/** Sum parked backing assets into CREDIT base units at the 1:1 PSM peg. */
|
|
37
|
+
export declare function sumParkedBackingAsCreditRaw(parked: readonly ParkedBackingAssetBalance[], creditDecimals?: number): bigint;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { COLLATERAL_DECIMALS } from "../constants.js";
|
|
2
|
+
/** Rescale a u64 raw amount between token decimal precisions (truncates on downscale). */
|
|
3
|
+
export function rescaleRawAmount(raw, fromDecimals, toDecimals = COLLATERAL_DECIMALS) {
|
|
4
|
+
if (fromDecimals === toDecimals)
|
|
5
|
+
return raw;
|
|
6
|
+
if (fromDecimals < toDecimals) {
|
|
7
|
+
return raw * 10n ** BigInt(toDecimals - fromDecimals);
|
|
8
|
+
}
|
|
9
|
+
return raw / 10n ** BigInt(fromDecimals - toDecimals);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Probe every backing asset registered on `native_custody` for non-zero balances
|
|
13
|
+
* parked at `accountId`'s Sui address. Matches the pre-tx scan inside
|
|
14
|
+
* {@link appendConsolidateToUsd}.
|
|
15
|
+
*/
|
|
16
|
+
export async function probeParkedBackingAssets(client, accountId) {
|
|
17
|
+
if (!client.config.packages.native_custody?.vault)
|
|
18
|
+
return [];
|
|
19
|
+
if (!client.config.packages.waterx_credit?.credit_type)
|
|
20
|
+
return [];
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const asset of client.getNativeAssets()) {
|
|
23
|
+
const bal = (await client.getBalance({
|
|
24
|
+
owner: accountId,
|
|
25
|
+
coinType: asset.type,
|
|
26
|
+
}));
|
|
27
|
+
const fundsRaw = BigInt(bal.balance?.addressBalance ?? "0");
|
|
28
|
+
const coins = (await client.listCoins({
|
|
29
|
+
owner: accountId,
|
|
30
|
+
coinType: asset.type,
|
|
31
|
+
}));
|
|
32
|
+
let coinsRaw = 0n;
|
|
33
|
+
for (const coin of coins.objects ?? []) {
|
|
34
|
+
coinsRaw += BigInt(coin.balance ?? "0");
|
|
35
|
+
}
|
|
36
|
+
if (fundsRaw > 0n || coinsRaw > 0n) {
|
|
37
|
+
out.push({
|
|
38
|
+
assetType: asset.type,
|
|
39
|
+
decimals: asset.decimal,
|
|
40
|
+
fundsRaw,
|
|
41
|
+
coinsRaw,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Probe non-zero CREDIT parked at `accountId`'s Sui address. Matches the
|
|
49
|
+
* address-CREDIT legs inside {@link appendConsolidateAddressCredit}.
|
|
50
|
+
*/
|
|
51
|
+
export async function probeAddressCreditBalance(client, accountId) {
|
|
52
|
+
if (!client.config.packages.waterx_credit?.credit_type) {
|
|
53
|
+
return { fundsRaw: 0n, coinsRaw: 0n };
|
|
54
|
+
}
|
|
55
|
+
const creditType = client.creditType();
|
|
56
|
+
let fundsRaw = 0n;
|
|
57
|
+
let coinsRaw = 0n;
|
|
58
|
+
try {
|
|
59
|
+
const bal = (await client.getBalance({
|
|
60
|
+
owner: accountId,
|
|
61
|
+
coinType: creditType,
|
|
62
|
+
}));
|
|
63
|
+
fundsRaw = BigInt(bal.balance?.addressBalance ?? "0");
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// ignore — treat as zero parked funds
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const coins = (await client.listCoins({
|
|
70
|
+
owner: accountId,
|
|
71
|
+
coinType: creditType,
|
|
72
|
+
}));
|
|
73
|
+
for (const coin of coins.objects ?? []) {
|
|
74
|
+
coinsRaw += BigInt(coin.balance ?? "0");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// ignore — treat as zero owned coins
|
|
79
|
+
}
|
|
80
|
+
return { fundsRaw, coinsRaw };
|
|
81
|
+
}
|
|
82
|
+
/** Sum parked backing assets into CREDIT base units at the 1:1 PSM peg. */
|
|
83
|
+
export function sumParkedBackingAsCreditRaw(parked, creditDecimals = COLLATERAL_DECIMALS) {
|
|
84
|
+
let sum = 0n;
|
|
85
|
+
for (const row of parked) {
|
|
86
|
+
sum += rescaleRawAmount(row.fundsRaw + row.coinsRaw, row.decimals, creditDecimals);
|
|
87
|
+
}
|
|
88
|
+
return sum;
|
|
89
|
+
}
|
package/dist/src/utils/math.d.ts
CHANGED
|
@@ -33,6 +33,92 @@ export declare function calcEstLiqPrice(params: {
|
|
|
33
33
|
spotPrice: number;
|
|
34
34
|
totalFeesUsd: number;
|
|
35
35
|
}): number;
|
|
36
|
+
/**
|
|
37
|
+
* Effective (fee-adjusted) collateral in USD.
|
|
38
|
+
*
|
|
39
|
+
* Mirrors `calculate_effective_collateral_amount` in `trading.move`: the contract
|
|
40
|
+
* subtracts accrued borrow + trading fees and, **only when the position owes funding**
|
|
41
|
+
* (`fundingSign === true`, i.e. `unrealized_funding_sign`), the funding fee too. Funding
|
|
42
|
+
* *income* (position receives funding, `fundingSign === false`) is NOT added here —
|
|
43
|
+
* matching the contract's saturating-subtract path. Result clamps at 0.
|
|
44
|
+
*
|
|
45
|
+
* This is the collateral the contract actually uses for the max-leverage and
|
|
46
|
+
* min-collateral checks on `withdraw_collateral` — NOT the gross `collateral_amount`.
|
|
47
|
+
* Displaying leverage / max-reducible off gross collateral is the common UI bug
|
|
48
|
+
* (a position shows e.g. 23.3x on gross while the contract sees ~24.9x on effective).
|
|
49
|
+
*
|
|
50
|
+
* All inputs are human-readable USD. Convert raw collateral-token fee fields via
|
|
51
|
+
* `feeUsd = (rawFee / 10 ** collateralDecimal) * collateralPriceUsd`.
|
|
52
|
+
*
|
|
53
|
+
* @param grossCollateralUsd Position collateral in USD (`collateral_amount` → USD).
|
|
54
|
+
* @param borrowFeeUsd `unrealized_borrow_fee` in USD.
|
|
55
|
+
* @param fundingSign `unrealized_funding_sign` — true when the position owes funding.
|
|
56
|
+
* @param fundingFeeUsd `unrealized_funding_fee` magnitude in USD.
|
|
57
|
+
* @param tradingFeeUsd `unrealized_trading_fee` in USD.
|
|
58
|
+
* @param projectedTradingFeeUsd Closing fee to reserve (0 for a bare collateral withdrawal).
|
|
59
|
+
*/
|
|
60
|
+
export declare function calcEffectiveCollateralUsd(params: {
|
|
61
|
+
grossCollateralUsd: number;
|
|
62
|
+
borrowFeeUsd: number;
|
|
63
|
+
fundingSign: boolean;
|
|
64
|
+
fundingFeeUsd: number;
|
|
65
|
+
tradingFeeUsd: number;
|
|
66
|
+
projectedTradingFeeUsd?: number;
|
|
67
|
+
}): number;
|
|
68
|
+
/**
|
|
69
|
+
* Maximum collateral (in USD) a position can safely withdraw ("最大可减少").
|
|
70
|
+
*
|
|
71
|
+
* Reproduces the three post-withdrawal checks in `execute_withdraw_collateral`
|
|
72
|
+
* (`trading.move`), all evaluated on **effective** (fee-adjusted) collateral, and
|
|
73
|
+
* returns the smallest allowed withdrawal:
|
|
74
|
+
*
|
|
75
|
+
* (A) max leverage — `notional / (effLeverage − w) ≤ maxLeverage`
|
|
76
|
+
* (B) min collateral — `(effLeverage − w) ≥ minCollValueUsd`
|
|
77
|
+
* (C) not liquidatable — `(liqRemaining − w) > maintenanceMargin × notional`
|
|
78
|
+
*
|
|
79
|
+
* where
|
|
80
|
+
* notional = sizeInAsset × spotPrice
|
|
81
|
+
* effLeverage = effective collateral with projectedTradingFee = 0
|
|
82
|
+
* (the contract's leverage/min-coll checks ignore the closing fee and PnL)
|
|
83
|
+
* liqRemaining = grossCollateralUsd + signedPnl − borrow − trading − closingFee ∓ funding
|
|
84
|
+
* (the contract's `is_liquidatable` boundary; funding income is added back)
|
|
85
|
+
*
|
|
86
|
+
* The result is a USD figure (matching the "$X" the UI shows), already aligned so that
|
|
87
|
+
* converting it to raw collateral units with floor is abort-safe:
|
|
88
|
+
* `rawAmount = floor((maxReducibleUsd / collateralPriceUsd) * 10 ** collateralDecimal)`.
|
|
89
|
+
* The liquidation leg backs off one raw collateral unit because `is_liquidatable` aborts
|
|
90
|
+
* on `remaining <= maintenance` (inclusive) — the safe withdrawal must leave remaining
|
|
91
|
+
* *strictly* above maintenance. The leverage (`> max`) and min-collateral (`>=`) checks
|
|
92
|
+
* are equality-safe on their own and floor-rounding only adds margin, so they need no offset.
|
|
93
|
+
*
|
|
94
|
+
* Funding handling is signed (income added, expense subtracted) — a close approximation
|
|
95
|
+
* of the contract's deficit-aware sequencing, exact whenever the position is solvent
|
|
96
|
+
* (the only case where a withdrawal can succeed). Clamps at 0.
|
|
97
|
+
*
|
|
98
|
+
* @param maxLeverage Max leverage as a ratio (e.g. 25 for `max_leverage_bps` 250000).
|
|
99
|
+
* @param maintenanceMarginRate `maintenance_margin` as a fraction (e.g. 0.01 for 1%).
|
|
100
|
+
* @param minCollValueUsd `min_coll_value` in USD (raw scaled value ÷ 1e9).
|
|
101
|
+
* @param closingFeeUsd Full closing fee in USD (`close_fee` → USD).
|
|
102
|
+
* @param collateralPriceUsd Oracle price of the collateral token (USD per token).
|
|
103
|
+
* @param collateralDecimal Collateral token decimals — sets the smallest withdraw step.
|
|
104
|
+
*/
|
|
105
|
+
export declare function calcMaxReducibleCollateralUsd(params: {
|
|
106
|
+
grossCollateralUsd: number;
|
|
107
|
+
sizeInAsset: number;
|
|
108
|
+
spotPrice: number;
|
|
109
|
+
isLong: boolean;
|
|
110
|
+
entryPrice: number;
|
|
111
|
+
maxLeverage: number;
|
|
112
|
+
maintenanceMarginRate: number;
|
|
113
|
+
minCollValueUsd: number;
|
|
114
|
+
borrowFeeUsd: number;
|
|
115
|
+
tradingFeeUsd: number;
|
|
116
|
+
closingFeeUsd: number;
|
|
117
|
+
fundingSign: boolean;
|
|
118
|
+
fundingFeeUsd: number;
|
|
119
|
+
collateralPriceUsd: number;
|
|
120
|
+
collateralDecimal: number;
|
|
121
|
+
}): number;
|
|
36
122
|
/**
|
|
37
123
|
* Impact fee rate for an order (as a fraction, not bps).
|
|
38
124
|
*
|
package/dist/src/utils/math.js
CHANGED
|
@@ -59,6 +59,106 @@ export function calcEstLiqPrice(params) {
|
|
|
59
59
|
}
|
|
60
60
|
return avgPrice * (1 + ratio);
|
|
61
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Effective (fee-adjusted) collateral in USD.
|
|
64
|
+
*
|
|
65
|
+
* Mirrors `calculate_effective_collateral_amount` in `trading.move`: the contract
|
|
66
|
+
* subtracts accrued borrow + trading fees and, **only when the position owes funding**
|
|
67
|
+
* (`fundingSign === true`, i.e. `unrealized_funding_sign`), the funding fee too. Funding
|
|
68
|
+
* *income* (position receives funding, `fundingSign === false`) is NOT added here —
|
|
69
|
+
* matching the contract's saturating-subtract path. Result clamps at 0.
|
|
70
|
+
*
|
|
71
|
+
* This is the collateral the contract actually uses for the max-leverage and
|
|
72
|
+
* min-collateral checks on `withdraw_collateral` — NOT the gross `collateral_amount`.
|
|
73
|
+
* Displaying leverage / max-reducible off gross collateral is the common UI bug
|
|
74
|
+
* (a position shows e.g. 23.3x on gross while the contract sees ~24.9x on effective).
|
|
75
|
+
*
|
|
76
|
+
* All inputs are human-readable USD. Convert raw collateral-token fee fields via
|
|
77
|
+
* `feeUsd = (rawFee / 10 ** collateralDecimal) * collateralPriceUsd`.
|
|
78
|
+
*
|
|
79
|
+
* @param grossCollateralUsd Position collateral in USD (`collateral_amount` → USD).
|
|
80
|
+
* @param borrowFeeUsd `unrealized_borrow_fee` in USD.
|
|
81
|
+
* @param fundingSign `unrealized_funding_sign` — true when the position owes funding.
|
|
82
|
+
* @param fundingFeeUsd `unrealized_funding_fee` magnitude in USD.
|
|
83
|
+
* @param tradingFeeUsd `unrealized_trading_fee` in USD.
|
|
84
|
+
* @param projectedTradingFeeUsd Closing fee to reserve (0 for a bare collateral withdrawal).
|
|
85
|
+
*/
|
|
86
|
+
export function calcEffectiveCollateralUsd(params) {
|
|
87
|
+
const { grossCollateralUsd, borrowFeeUsd, fundingSign, fundingFeeUsd, tradingFeeUsd, projectedTradingFeeUsd = 0, } = params;
|
|
88
|
+
const eff = grossCollateralUsd -
|
|
89
|
+
borrowFeeUsd -
|
|
90
|
+
tradingFeeUsd -
|
|
91
|
+
projectedTradingFeeUsd -
|
|
92
|
+
(fundingSign ? fundingFeeUsd : 0);
|
|
93
|
+
return Math.max(0, eff);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Maximum collateral (in USD) a position can safely withdraw ("最大可减少").
|
|
97
|
+
*
|
|
98
|
+
* Reproduces the three post-withdrawal checks in `execute_withdraw_collateral`
|
|
99
|
+
* (`trading.move`), all evaluated on **effective** (fee-adjusted) collateral, and
|
|
100
|
+
* returns the smallest allowed withdrawal:
|
|
101
|
+
*
|
|
102
|
+
* (A) max leverage — `notional / (effLeverage − w) ≤ maxLeverage`
|
|
103
|
+
* (B) min collateral — `(effLeverage − w) ≥ minCollValueUsd`
|
|
104
|
+
* (C) not liquidatable — `(liqRemaining − w) > maintenanceMargin × notional`
|
|
105
|
+
*
|
|
106
|
+
* where
|
|
107
|
+
* notional = sizeInAsset × spotPrice
|
|
108
|
+
* effLeverage = effective collateral with projectedTradingFee = 0
|
|
109
|
+
* (the contract's leverage/min-coll checks ignore the closing fee and PnL)
|
|
110
|
+
* liqRemaining = grossCollateralUsd + signedPnl − borrow − trading − closingFee ∓ funding
|
|
111
|
+
* (the contract's `is_liquidatable` boundary; funding income is added back)
|
|
112
|
+
*
|
|
113
|
+
* The result is a USD figure (matching the "$X" the UI shows), already aligned so that
|
|
114
|
+
* converting it to raw collateral units with floor is abort-safe:
|
|
115
|
+
* `rawAmount = floor((maxReducibleUsd / collateralPriceUsd) * 10 ** collateralDecimal)`.
|
|
116
|
+
* The liquidation leg backs off one raw collateral unit because `is_liquidatable` aborts
|
|
117
|
+
* on `remaining <= maintenance` (inclusive) — the safe withdrawal must leave remaining
|
|
118
|
+
* *strictly* above maintenance. The leverage (`> max`) and min-collateral (`>=`) checks
|
|
119
|
+
* are equality-safe on their own and floor-rounding only adds margin, so they need no offset.
|
|
120
|
+
*
|
|
121
|
+
* Funding handling is signed (income added, expense subtracted) — a close approximation
|
|
122
|
+
* of the contract's deficit-aware sequencing, exact whenever the position is solvent
|
|
123
|
+
* (the only case where a withdrawal can succeed). Clamps at 0.
|
|
124
|
+
*
|
|
125
|
+
* @param maxLeverage Max leverage as a ratio (e.g. 25 for `max_leverage_bps` 250000).
|
|
126
|
+
* @param maintenanceMarginRate `maintenance_margin` as a fraction (e.g. 0.01 for 1%).
|
|
127
|
+
* @param minCollValueUsd `min_coll_value` in USD (raw scaled value ÷ 1e9).
|
|
128
|
+
* @param closingFeeUsd Full closing fee in USD (`close_fee` → USD).
|
|
129
|
+
* @param collateralPriceUsd Oracle price of the collateral token (USD per token).
|
|
130
|
+
* @param collateralDecimal Collateral token decimals — sets the smallest withdraw step.
|
|
131
|
+
*/
|
|
132
|
+
export function calcMaxReducibleCollateralUsd(params) {
|
|
133
|
+
const { grossCollateralUsd, sizeInAsset, spotPrice, isLong, entryPrice, maxLeverage, maintenanceMarginRate, minCollValueUsd, borrowFeeUsd, tradingFeeUsd, closingFeeUsd, fundingSign, fundingFeeUsd, collateralPriceUsd, collateralDecimal, } = params;
|
|
134
|
+
const notional = sizeInAsset * spotPrice;
|
|
135
|
+
// effLeverage: matches calculate_effective_collateral_amount(..., projectedTradingFee = 0).
|
|
136
|
+
const effLeverage = calcEffectiveCollateralUsd({
|
|
137
|
+
grossCollateralUsd,
|
|
138
|
+
borrowFeeUsd,
|
|
139
|
+
fundingSign,
|
|
140
|
+
fundingFeeUsd,
|
|
141
|
+
tradingFeeUsd,
|
|
142
|
+
});
|
|
143
|
+
// (A) max leverage and (B) min collateral, both bounded by effLeverage. Both checks
|
|
144
|
+
// pass at equality (`leverage_bps > max` / `collateral >= min`), so no offset needed.
|
|
145
|
+
const leverageHeadroom = maxLeverage > 0 ? effLeverage - notional / maxLeverage : effLeverage;
|
|
146
|
+
const minCollHeadroom = effLeverage - minCollValueUsd;
|
|
147
|
+
// (C) is_liquidatable: aborts on `remaining <= maintenance`, so the post-withdrawal
|
|
148
|
+
// remaining must stay STRICTLY above maintenance. Back off one raw collateral unit (the
|
|
149
|
+
// smallest withdrawable step) so the floored raw amount can never land on equality.
|
|
150
|
+
const signedPnl = calcUnrealizedPnl(isLong, entryPrice, spotPrice, sizeInAsset);
|
|
151
|
+
const liqRemaining = grossCollateralUsd +
|
|
152
|
+
signedPnl -
|
|
153
|
+
borrowFeeUsd -
|
|
154
|
+
tradingFeeUsd -
|
|
155
|
+
closingFeeUsd -
|
|
156
|
+
(fundingSign ? fundingFeeUsd : -fundingFeeUsd);
|
|
157
|
+
const maintenanceUsd = maintenanceMarginRate * notional;
|
|
158
|
+
const oneRawUnitUsd = collateralPriceUsd > 0 ? collateralPriceUsd / 10 ** collateralDecimal : 0;
|
|
159
|
+
const liquidationHeadroom = liqRemaining - maintenanceUsd - oneRawUnitUsd;
|
|
160
|
+
return Math.max(0, Math.min(leverageHeadroom, minCollHeadroom, liquidationHeadroom));
|
|
161
|
+
}
|
|
62
162
|
// ======== Impact fee ========
|
|
63
163
|
/**
|
|
64
164
|
* Cost integral used by the impact fee curve (internal helper).
|
package/dist/src/utils/pyth.d.ts
CHANGED
|
@@ -46,20 +46,55 @@ export declare function updatePythPrices(tx: Transaction, client: WaterXClient,
|
|
|
46
46
|
packageId: string;
|
|
47
47
|
}): Promise<string[]>;
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* Aggregate one ticker's price into the shared `Oracle`: build a collector, feed
|
|
50
|
+
* every rule the ticker is configured for, then `aggregate`. The fed rule set must
|
|
51
|
+
* match the on-chain weighted set for the ticker — `aggregator::remove_outliers`
|
|
52
|
+
* aborts `EMissingPriceSource` if a weighted rule is missing from the collector:
|
|
51
53
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
+
* - **Pyth** — fed when `priceInfoObjectId` is supplied (i.e. the ticker has a
|
|
55
|
+
* `pyth_rule.feeds` entry). Caller must run the Pyth update first so the
|
|
56
|
+
* `PriceInfoObject` is fresh.
|
|
57
|
+
* - **Supra** — fed alongside Pyth when supra is enabled + wired (abstains on-chain
|
|
58
|
+
* for symbols it has no pair for).
|
|
59
|
+
* - **Constant** — fed when the ticker is a constant ticker
|
|
60
|
+
* ({@link WaterXClient.isConstantTicker}).
|
|
61
|
+
*
|
|
62
|
+
* "Dual-feed" (Pyth + Constant) and "constant-only" are not special cases — they
|
|
63
|
+
* fall out of which rules the ticker is in: a constant ticker that also has a Pyth
|
|
64
|
+
* feed gets both; one with no Pyth feed (no `priceInfoObjectId`) gets constant only.
|
|
65
|
+
* Throws if no rule applies to the ticker.
|
|
66
|
+
*/
|
|
67
|
+
export declare function aggregateTicker(tx: Transaction, client: WaterXClient, args: {
|
|
68
|
+
ticker: string;
|
|
69
|
+
priceInfoObjectId?: string;
|
|
70
|
+
}): void;
|
|
71
|
+
/**
|
|
72
|
+
* Thin wrapper over {@link aggregateTicker} for a Pyth-fed ticker. Kept for
|
|
73
|
+
* back-compat (e.g. WLP mint builds). Caller must run the Pyth update first.
|
|
54
74
|
*/
|
|
55
75
|
export declare function aggregateTickerWithPyth(tx: Transaction, client: WaterXClient, args: {
|
|
56
76
|
ticker: string;
|
|
57
77
|
priceInfoObjectId: string;
|
|
58
78
|
}): void;
|
|
59
79
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
80
|
+
* {@link aggregateTicker} for a **constant-only** ticker (no Pyth update needed —
|
|
81
|
+
* the price comes from the on-chain `constant_rule::Config`).
|
|
82
|
+
*
|
|
83
|
+
* Throws if the ticker ALSO has a `pyth_rule.feeds` entry (a dual-feed transition
|
|
84
|
+
* ticker): feeding only the constant leg would leave the still-weighted Pyth rule
|
|
85
|
+
* absent from the collector and abort `aggregate` with `EMissingPriceSource`. Such
|
|
86
|
+
* tickers must go through {@link aggregateTicker} with a `priceInfoObjectId` (or
|
|
87
|
+
* {@link refreshOraclePrices}), which feeds both.
|
|
88
|
+
*/
|
|
89
|
+
export declare function aggregateTickerWithConstant(tx: Transaction, client: WaterXClient, args: {
|
|
90
|
+
ticker: string;
|
|
91
|
+
}): void;
|
|
92
|
+
/**
|
|
93
|
+
* Refresh multiple tickers in one PTB. For each ticker {@link aggregateTicker}
|
|
94
|
+
* feeds whichever rules it is configured for (Pyth if it has a `pyth_rule.feeds`
|
|
95
|
+
* entry, Supra when enabled, Constant when it's a constant ticker). Tickers with a
|
|
96
|
+
* Pyth feed are updated on-chain via one shared Pyth accumulator first; the rest
|
|
97
|
+
* (constant-only) skip Pyth entirely.
|
|
63
98
|
*/
|
|
64
99
|
export declare function refreshOraclePrices(tx: Transaction, client: WaterXClient, tickers: string[], opts?: {
|
|
65
100
|
cache?: PythCache;
|