@waterx/sdk 4.0.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +37 -17
  2. package/dist/cjs/src/account/account.js +2 -1
  3. package/dist/cjs/src/account/config.d.ts +3 -2
  4. package/dist/cjs/src/account/funding/balance.d.ts +25 -2
  5. package/dist/cjs/src/account/funding/balance.js +36 -24
  6. package/dist/cjs/src/account/funding/credit.js +6 -10
  7. package/dist/cjs/src/constants.d.ts +15 -1
  8. package/dist/cjs/src/constants.js +18 -4
  9. package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
  10. package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +13 -0
  11. package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
  12. package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.js +31 -0
  13. package/dist/cjs/src/generated/waterx_rule/waterx_rule.d.ts +813 -0
  14. package/dist/cjs/src/generated/waterx_rule/waterx_rule.js +946 -0
  15. package/dist/cjs/src/oracle/aggregate.d.ts +23 -21
  16. package/dist/cjs/src/oracle/aggregate.js +133 -59
  17. package/dist/cjs/src/oracle/config.d.ts +82 -41
  18. package/dist/cjs/src/oracle/config.js +0 -42
  19. package/dist/cjs/src/oracle/host.d.ts +26 -11
  20. package/dist/cjs/src/oracle/index.d.ts +6 -2
  21. package/dist/cjs/src/oracle/index.js +36 -8
  22. package/dist/cjs/src/oracle/price-update-rule.d.ts +16 -10
  23. package/dist/cjs/src/oracle/price-update-rule.js +3 -3
  24. package/dist/cjs/src/oracle/pyth.d.ts +44 -0
  25. package/dist/cjs/src/oracle/pyth.js +48 -6
  26. package/dist/cjs/src/oracle/read-plane.d.ts +70 -0
  27. package/dist/cjs/src/oracle/read-plane.js +78 -0
  28. package/dist/cjs/src/oracle/rule-registry.d.ts +14 -11
  29. package/dist/cjs/src/oracle/rule-registry.js +16 -11
  30. package/dist/cjs/src/oracle/rules/pyth-core-rule.js +4 -4
  31. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
  32. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +29 -4
  33. package/dist/cjs/src/oracle/rules/pyth-rule.js +5 -4
  34. package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +126 -0
  35. package/dist/cjs/src/oracle/rules/waterx-rule.js +312 -0
  36. package/dist/cjs/src/perp/client.d.ts +71 -20
  37. package/dist/cjs/src/perp/client.js +35 -13
  38. package/dist/cjs/src/perp/config.d.ts +6 -7
  39. package/dist/cjs/src/perp/config.js +12 -11
  40. package/dist/cjs/src/perp/constants.d.ts +0 -6
  41. package/dist/cjs/src/perp/constants.js +11 -9
  42. package/dist/cjs/src/perp/fetch/account.js +3 -0
  43. package/dist/cjs/src/perp/fetch/bridge.js +2 -1
  44. package/dist/cjs/src/perp/fetch/market.js +2 -1
  45. package/dist/cjs/src/perp/fetch/positions.d.ts +16 -10
  46. package/dist/cjs/src/perp/fetch/positions.js +23 -20
  47. package/dist/cjs/src/perp/index.d.ts +9 -5
  48. package/dist/cjs/src/perp/index.js +16 -7
  49. package/dist/cjs/src/perp/liq-view.d.ts +64 -0
  50. package/dist/cjs/src/perp/liq-view.js +74 -0
  51. package/dist/cjs/src/perp/user/order.d.ts +13 -0
  52. package/dist/cjs/src/perp/user/order.js +30 -16
  53. package/dist/cjs/src/perp/user/staking.js +3 -2
  54. package/dist/cjs/src/perp/user/trading.js +25 -24
  55. package/dist/cjs/src/perp/user/wlp.js +6 -5
  56. package/dist/cjs/src/prediction/utils.d.ts +11 -2
  57. package/dist/cjs/src/prediction/utils.js +22 -22
  58. package/dist/cjs/src/unified-client.d.ts +41 -15
  59. package/dist/cjs/src/unified-client.js +4 -2
  60. package/dist/cjs/src/utils/format.d.ts +14 -0
  61. package/dist/cjs/src/utils/format.js +24 -0
  62. package/dist/cjs/src/utils/math.d.ts +304 -12
  63. package/dist/cjs/src/utils/math.js +397 -17
  64. package/dist/cjs/src/utils/validate.d.ts +69 -0
  65. package/dist/cjs/src/utils/validate.js +183 -0
  66. package/dist/src/account/account.js +2 -1
  67. package/dist/src/account/config.d.ts +3 -2
  68. package/dist/src/account/funding/balance.d.ts +25 -2
  69. package/dist/src/account/funding/balance.js +36 -24
  70. package/dist/src/account/funding/credit.js +6 -10
  71. package/dist/src/constants.d.ts +15 -1
  72. package/dist/src/constants.js +17 -3
  73. package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
  74. package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +10 -0
  75. package/dist/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
  76. package/dist/src/generated/waterx_rule/deps/sui/vec_map.js +27 -0
  77. package/dist/src/generated/waterx_rule/waterx_rule.d.ts +813 -0
  78. package/dist/src/generated/waterx_rule/waterx_rule.js +855 -0
  79. package/dist/src/oracle/aggregate.d.ts +23 -21
  80. package/dist/src/oracle/aggregate.js +133 -59
  81. package/dist/src/oracle/config.d.ts +82 -41
  82. package/dist/src/oracle/config.js +1 -41
  83. package/dist/src/oracle/host.d.ts +26 -11
  84. package/dist/src/oracle/index.d.ts +6 -2
  85. package/dist/src/oracle/index.js +27 -9
  86. package/dist/src/oracle/price-update-rule.d.ts +16 -10
  87. package/dist/src/oracle/price-update-rule.js +3 -3
  88. package/dist/src/oracle/pyth.d.ts +44 -0
  89. package/dist/src/oracle/pyth.js +45 -5
  90. package/dist/src/oracle/read-plane.d.ts +70 -0
  91. package/dist/src/oracle/read-plane.js +74 -0
  92. package/dist/src/oracle/rule-registry.d.ts +14 -11
  93. package/dist/src/oracle/rule-registry.js +16 -11
  94. package/dist/src/oracle/rules/pyth-core-rule.js +5 -5
  95. package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
  96. package/dist/src/oracle/rules/pyth-lazer-rule.js +28 -3
  97. package/dist/src/oracle/rules/pyth-rule.js +5 -4
  98. package/dist/src/oracle/rules/waterx-rule.d.ts +126 -0
  99. package/dist/src/oracle/rules/waterx-rule.js +305 -0
  100. package/dist/src/perp/client.d.ts +71 -20
  101. package/dist/src/perp/client.js +36 -14
  102. package/dist/src/perp/config.d.ts +6 -7
  103. package/dist/src/perp/config.js +11 -9
  104. package/dist/src/perp/constants.d.ts +0 -6
  105. package/dist/src/perp/constants.js +10 -8
  106. package/dist/src/perp/fetch/account.js +3 -0
  107. package/dist/src/perp/fetch/bridge.js +2 -1
  108. package/dist/src/perp/fetch/market.js +2 -1
  109. package/dist/src/perp/fetch/positions.d.ts +16 -10
  110. package/dist/src/perp/fetch/positions.js +28 -20
  111. package/dist/src/perp/index.d.ts +9 -5
  112. package/dist/src/perp/index.js +6 -4
  113. package/dist/src/perp/liq-view.d.ts +64 -0
  114. package/dist/src/perp/liq-view.js +71 -0
  115. package/dist/src/perp/user/order.d.ts +13 -0
  116. package/dist/src/perp/user/order.js +30 -16
  117. package/dist/src/perp/user/staking.js +3 -2
  118. package/dist/src/perp/user/trading.js +25 -24
  119. package/dist/src/perp/user/wlp.js +6 -5
  120. package/dist/src/prediction/utils.d.ts +11 -2
  121. package/dist/src/prediction/utils.js +22 -22
  122. package/dist/src/unified-client.d.ts +41 -15
  123. package/dist/src/unified-client.js +4 -2
  124. package/dist/src/utils/format.d.ts +14 -0
  125. package/dist/src/utils/format.js +21 -0
  126. package/dist/src/utils/math.d.ts +304 -12
  127. package/dist/src/utils/math.js +394 -17
  128. package/dist/src/utils/validate.d.ts +69 -0
  129. package/dist/src/utils/validate.js +167 -0
  130. package/package.json +4 -1
@@ -3,17 +3,17 @@
3
3
  * `waterx-config` repo (default: GitHub raw).
4
4
  *
5
5
  * The schema mirrors the canonical JSON layout one-to-one (each package
6
- * groups its own object IDs + per-ticker maps). External chain infra
7
- * (Pyth state, Wormhole state/core, Hermes & Wormholescan endpoints) is
8
- * **not** in the JSON — it lives in `PYTH_DEFAULTS` / `WORMHOLE_DEFAULTS`
9
- * below, keyed by network.
6
+ * groups its own object IDs + per-ticker maps). External chain infra is
7
+ * **not** in the JSON each oracle source owns its own per-network table
8
+ * (`PYTH_CORE_INFRA` in `oracle/pyth.ts`, `LAZER_INFRA` in
9
+ * `oracle/rules/pyth-lazer-rule.ts`); Wormhole bridge infra lives in
10
+ * `WORMHOLE_DEFAULTS` below.
10
11
  */
11
12
  import type { AccountPackages, BasePackageEntry, WormholeInfraConfig } from "../account/config.ts";
12
13
  import type { OraclePackages } from "../oracle/config.ts";
13
14
  import type { Network } from "./constants.ts";
14
15
  export type { AccountConfig, AccountPackages, BasePackageEntry, NativeCustodyAsset, NativeCustodyPackage, WaterxCreditPackage, WaterxReferralPackage, WithdrawalQueuePackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "../account/config.ts";
15
- export type { ConstantFeedEntry, OracleConfig, OraclePackages, PythFetchPolicy, PythInfraConfig, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, WaterxConstantRulePackage, WaterxOraclePackage, } from "../oracle/config.ts";
16
- export { PYTH_DEFAULTS } from "../oracle/config.ts";
16
+ export type { ConstantFeedEntry, OracleConfig, OraclePackages, PythAccessConfig, PythFetchPolicy, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, WaterxConstantRulePackage, WaterxAccessConfig, WaterxOraclePackage, WaterxRulePackage, } from "../oracle/config.ts";
17
17
  export interface WaterxPerpMarketEntry {
18
18
  market: string;
19
19
  config: string;
@@ -71,7 +71,6 @@ export interface WaterXPackages extends AccountPackages, OraclePackages {
71
71
  mock_usdc?: MockCoinPackage;
72
72
  mock_usdsui?: MockCoinPackage;
73
73
  mock_sui?: MockCoinPackage;
74
- waterx_rule?: BasePackageEntry;
75
74
  waterx_rule_nautilus_enclave?: BasePackageEntry;
76
75
  }
77
76
  export declare const WORMHOLE_DEFAULTS: Record<Network, WormholeInfraConfig>;
@@ -3,23 +3,25 @@
3
3
  * `waterx-config` repo (default: GitHub raw).
4
4
  *
5
5
  * The schema mirrors the canonical JSON layout one-to-one (each package
6
- * groups its own object IDs + per-ticker maps). External chain infra
7
- * (Pyth state, Wormhole state/core, Hermes & Wormholescan endpoints) is
8
- * **not** in the JSON — it lives in `PYTH_DEFAULTS` / `WORMHOLE_DEFAULTS`
9
- * below, keyed by network.
6
+ * groups its own object IDs + per-ticker maps). External chain infra is
7
+ * **not** in the JSON each oracle source owns its own per-network table
8
+ * (`PYTH_CORE_INFRA` in `oracle/pyth.ts`, `LAZER_INFRA` in
9
+ * `oracle/rules/pyth-lazer-rule.ts`); Wormhole bridge infra lives in
10
+ * `WORMHOLE_DEFAULTS` below.
10
11
  */
11
12
  import { fetchWithPolicy, rethrowExhaustedFetch } from "../oracle/update-fetch.js";
12
- export { PYTH_DEFAULTS } from "../oracle/config.js";
13
13
  // ============================================================================
14
- // Wormhole / Hermes — external chain infra, defaults by network
14
+ // Wormhole — external chain infra, defaults by network
15
15
  // ============================================================================
16
16
  //
17
- // `PythInfraConfig` + `PYTH_DEFAULTS` live in `oracle/config.ts` (shared infra)
18
- // and are re-exported at the top of this file.
17
+ // Oracle-source infra lives with each source (`PYTH_CORE_INFRA` in
18
+ // `oracle/pyth.ts`, `LAZER_INFRA` in `oracle/rules/pyth-lazer-rule.ts`);
19
+ // `client.pyth` is the caller-supplied access slice only (`PythAccessConfig`,
20
+ // re-exported at the top of this file).
19
21
  // `WormholeInfraConfig` is defined in `account/config.ts` (funding base) and
20
22
  // re-exported at the top of this file. `state_id` is the same shared Sui
21
23
  // Wormhole `State` object Pyth uses (kept in sync with
22
- // `PYTH_DEFAULTS[*].wormhole_state_id`).
24
+ // `PYTH_CORE_INFRA[*].wormhole_state_id`).
23
25
  export const WORMHOLE_DEFAULTS = {
24
26
  MAINNET: {
25
27
  state_id: "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c",
@@ -1,10 +1,4 @@
1
1
  export * from "../constants.ts";
2
- /** Default crypto market trading fee rate (3 bps). Per-market value lives in MarketConfig. */
3
- export declare const CRYPTO_FEE_RATE = 0.0003;
4
- /** Default stock / commodity market trading fee rate (5 bps). Per-market value lives in MarketConfig. */
5
- export declare const STOCK_FEE_RATE = 0.0005;
6
- /** Default maintenance margin rate (150 bps = 1.5%). Per-market value lives in MarketConfig. */
7
- export declare const MAINTENANCE_MARGIN_RATE = 0.015;
8
2
  export declare const PERM_OPEN_POSITION = 1;
9
3
  export declare const PERM_CLOSE_POSITION = 2;
10
4
  export declare const PERM_INCREASE_POSITION = 4;
@@ -1,15 +1,17 @@
1
1
  // Perp-line domain constants (trading permissions / order tags / action codes /
2
- // fee rates / well-known addresses). Re-exports the shared primitives from
2
+ // well-known addresses). Re-exports the shared primitives from
3
3
  // `../constants.ts` so perp code and the `./perp` barrel get the full set from
4
4
  // a single import.
5
+ //
6
+ // NOTE: there are deliberately NO fee-rate / maintenance-margin constants here.
7
+ // `CRYPTO_FEE_RATE` / `STOCK_FEE_RATE` / `MAINTENANCE_MARGIN_RATE` were removed
8
+ // — they were defaults masquerading as truth; per-market `MarketConfig` on
9
+ // chain is the only source for fee and margin parameters (real MMRs span
10
+ // 0.5%–5%; the flat 1.5% understated AAPLX-class risk >3x — mainnet incident
11
+ // 2026-07-28: shorts displayed liq ~$364 but were liquidated at ~$343). When
12
+ // the market rate is unavailable, treat the value as NOT estimable and fail
13
+ // safe — never substitute a flat default.
5
14
  export * from "../constants.js";
6
- // ======== Fee rates & risk parameters ========
7
- /** Default crypto market trading fee rate (3 bps). Per-market value lives in MarketConfig. */
8
- export const CRYPTO_FEE_RATE = 0.0003;
9
- /** Default stock / commodity market trading fee rate (5 bps). Per-market value lives in MarketConfig. */
10
- export const STOCK_FEE_RATE = 0.0005;
11
- /** Default maintenance margin rate (150 bps = 1.5%). Per-market value lives in MarketConfig. */
12
- export const MAINTENANCE_MARGIN_RATE = 0.015;
13
15
  // ======== Permission Bitmasks (matches account_data.move) ========
14
16
  export const PERM_OPEN_POSITION = 1;
15
17
  export const PERM_CLOSE_POSITION = 2;
@@ -51,6 +51,9 @@ export async function getSpendableCreditBalance(client, accountId) {
51
51
  probeParkedBackingAssets(client, accountId),
52
52
  probeAddressCreditBalance(client, accountId),
53
53
  ]);
54
+ // COLLATERAL_DECIMALS here is the CREDIT/wxUSD *target* scale (collateral-typed;
55
+ // 6 on all current deployments — config carries no credit decimal). The
56
+ // per-asset backing decimals come from config via each row's `decimals`.
54
57
  const pendingBackingRaw = sumParkedBackingAsCreditRaw(parkedBacking, COLLATERAL_DECIMALS);
55
58
  const pendingCreditAtAddressRaw = addressCredit.fundsRaw + addressCredit.coinsRaw;
56
59
  const totalRaw = internalRaw + pendingBackingRaw + pendingCreditAtAddressRaw;
@@ -6,6 +6,7 @@ import { bcs } from "@mysten/sui/bcs";
6
6
  import { Transaction } from "@mysten/sui/transactions";
7
7
  import { bridgeFeeAmount as bridgeFeeAmountCall, bridgeFeeRate as bridgeFeeRateCall, bridgeMinFee as bridgeMinFeeCall, wouldExecuteWormhole as wouldExecuteWormholeCall, } from "../../generated/withdrawal_queue/withdrawal_queue.js";
8
8
  import { dailyBurned as dailyBurnedCall, dailyBurnLimit as dailyBurnLimitCall, dailyMinted as dailyMintedCall, dailyMintLimit as dailyMintLimitCall, maxBurnPerTx as maxBurnPerTxCall, maxMintPerTx as maxMintPerTxCall, mintedFor as mintedForCall, paused as pausedCall, personalBurnCapAmount as personalBurnCapAmountCall, personalBurned as personalBurnedCall, } from "../../generated/wormhole_bridge/wormhole_bridge.js";
9
+ import { toU64 } from "../../utils/validate.js";
9
10
  import { extractAt, simulateRaw } from "./simulate.js";
10
11
  /**
11
12
  * Batched read of the bridge's rate-limit / cap state in a single simulate.
@@ -96,7 +97,7 @@ function requireWithdrawalQueue(client) {
96
97
  */
97
98
  export async function getBridgeFee(client, args) {
98
99
  const { pkg, queue } = requireWithdrawalQueue(client);
99
- const amount = BigInt(args.amount);
100
+ const amount = toU64(args.amount, "amount");
100
101
  const common = {
101
102
  package: pkg,
102
103
  typeArguments: [args.creditType ?? client.creditType()],
@@ -5,6 +5,7 @@
5
5
  import { bcs } from "@mysten/sui/bcs";
6
6
  import { Transaction } from "@mysten/sui/transactions";
7
7
  import { AccountData, accountData as accountDataCall, GlobalConfigData, globalConfigData as globalConfigDataCall, MarketData, marketData as marketDataCall, PoolData, poolData as poolDataCall, TokenPoolData, tokenPoolData as tokenPoolDataCall, } from "../../generated/waterx_perp_view/view.js";
8
+ import { toU64 } from "../../utils/validate.js";
8
9
  import { simulateAndExtract, withLp } from "./simulate.js";
9
10
  /**
10
11
  * Look up the registered AccountData for a given wxa account ID.
@@ -52,7 +53,7 @@ export async function getTokenPoolData(client, args) {
52
53
  package: client.config.packages.waterx_perp_view.published_at,
53
54
  arguments: {
54
55
  pool: tx.object(client.config.packages.wlp.wlp_pool),
55
- tokenIndex: args.tokenIndex,
56
+ tokenIndex: toU64(args.tokenIndex, "tokenIndex"),
56
57
  },
57
58
  typeArguments: [withLp(client, args.lpType)],
58
59
  })(tx);
@@ -3,7 +3,9 @@
3
3
  * list (`waterx_perp_view`).
4
4
  */
5
5
  import { OrderData, PositionData, RedeemRequestData } from "../../generated/waterx_perp_view/view.ts";
6
+ import { parseWholeDollarU64, type WholeDollarUsdPrice } from "../../utils/validate.ts";
6
7
  import type { PerpClient } from "../client.ts";
8
+ export { parseWholeDollarU64, type WholeDollarUsdPrice };
7
9
  export type PositionDataView = ReturnType<typeof PositionData.parse>;
8
10
  export declare function positionExists(client: PerpClient, args: {
9
11
  ticker: string;
@@ -13,9 +15,8 @@ export declare function positionExists(client: PerpClient, args: {
13
15
  export declare function getPosition(client: PerpClient, args: {
14
16
  ticker: string;
15
17
  positionId: bigint | number;
16
- /** Human-readable USD prices for Pnl / liq price calc; pass 0n if unsure. */
17
- basePriceUsd: bigint | number;
18
- collateralPriceUsd: bigint | number;
18
+ basePriceUsd: WholeDollarUsdPrice;
19
+ collateralPriceUsd: WholeDollarUsdPrice;
19
20
  lpType?: string;
20
21
  }): Promise<PositionDataView>;
21
22
  export type OrderDataView = ReturnType<typeof OrderData.parse>;
@@ -23,8 +24,9 @@ export declare function getOrder(client: PerpClient, args: {
23
24
  ticker: string;
24
25
  orderId: bigint | number;
25
26
  orderTypeTag: number;
27
+ /** Raw 1e9-scaled u128 order-book key — same scale as tx-build `rawPrice()`. */
26
28
  triggerPrice: bigint | number;
27
- basePriceUsd: bigint | number;
29
+ basePriceUsd: WholeDollarUsdPrice;
28
30
  lpType?: string;
29
31
  }): Promise<OrderDataView>;
30
32
  export interface PageOpts {
@@ -33,7 +35,8 @@ export interface PageOpts {
33
35
  }
34
36
  export declare function getMarketOrders(client: PerpClient, args: {
35
37
  ticker: string;
36
- basePriceUsd?: bigint | number;
38
+ /** Defaults to `0n`. */
39
+ basePriceUsd?: WholeDollarUsdPrice;
37
40
  lpType?: string;
38
41
  } & PageOpts): Promise<{
39
42
  orders: OrderDataView[];
@@ -41,8 +44,9 @@ export declare function getMarketOrders(client: PerpClient, args: {
41
44
  }>;
42
45
  export declare function getMarketPositions(client: PerpClient, args: {
43
46
  ticker: string;
44
- basePriceUsd: bigint | number;
45
- collateralPriceUsd?: bigint | number;
47
+ basePriceUsd: WholeDollarUsdPrice;
48
+ /** Defaults to `0n`. */
49
+ collateralPriceUsd?: WholeDollarUsdPrice;
46
50
  lpType?: string;
47
51
  } & PageOpts): Promise<{
48
52
  positions: PositionDataView[];
@@ -51,14 +55,16 @@ export declare function getMarketPositions(client: PerpClient, args: {
51
55
  export declare function getAccountPositions(client: PerpClient, args: {
52
56
  ticker: string;
53
57
  accountObjectAddress: string;
54
- basePriceUsd: bigint | number;
55
- collateralPriceUsd?: bigint | number;
58
+ basePriceUsd: WholeDollarUsdPrice;
59
+ /** Defaults to `0n`. */
60
+ collateralPriceUsd?: WholeDollarUsdPrice;
56
61
  lpType?: string;
57
62
  }): Promise<PositionDataView[]>;
58
63
  export declare function getAccountOrders(client: PerpClient, args: {
59
64
  ticker: string;
60
65
  accountObjectAddress: string;
61
- basePriceUsd?: bigint | number;
66
+ /** Defaults to `0n`. */
67
+ basePriceUsd?: WholeDollarUsdPrice;
62
68
  lpType?: string;
63
69
  }): Promise<OrderDataView[]>;
64
70
  export type RedeemRequestDataView = ReturnType<typeof RedeemRequestData.parse>;
@@ -5,8 +5,16 @@
5
5
  import { bcs } from "@mysten/sui/bcs";
6
6
  import { Transaction } from "@mysten/sui/transactions";
7
7
  import { getAccountOrders as getAccountOrdersCall, getAccountPositions as getAccountPositionsCall, getMarketOrders as getMarketOrdersCall, getMarketPositions as getMarketPositionsCall, getRedeemRequests as getRedeemRequestsCall, OrderData, orderData as orderDataCall, PositionData, positionData as positionDataCall, positionExists as positionExistsCall, RedeemRequestData, } from "../../generated/waterx_perp_view/view.js";
8
+ import { parseWholeDollarU64, toU8, toU64, toU128, } from "../../utils/validate.js";
8
9
  import { DRY_RUN_SENDER } from "../constants.js";
9
10
  import { simulateAndExtract, toBytes, withLp } from "./simulate.js";
11
+ // The whole-dollar USD price domain is a pure numeric guard with no chain/fetch
12
+ // dependency, so it lives with the rest of that vocabulary in
13
+ // `utils/validate.ts`. It is re-exported HERE — unchanged — because this module
14
+ // is its published home: `perp/fetch` → `@waterx/sdk`. Every read param below
15
+ // is typed `WholeDollarUsdPrice`, so the type and its parser stay one hop from
16
+ // the functions that consume them.
17
+ export { parseWholeDollarU64 };
10
18
  export async function positionExists(client, args) {
11
19
  const tx = new Transaction();
12
20
  positionExistsCall({
@@ -14,7 +22,7 @@ export async function positionExists(client, args) {
14
22
  arguments: {
15
23
  marketRegistry: tx.object(client.config.packages.waterx_perp.market_registry_wlp),
16
24
  ticker: args.ticker,
17
- positionId: args.positionId,
25
+ positionId: toU64(args.positionId, "positionId"),
18
26
  },
19
27
  typeArguments: [withLp(client, args.lpType)],
20
28
  })(tx);
@@ -29,9 +37,9 @@ export async function getPosition(client, args) {
29
37
  marketRegistry: tx.object(client.config.packages.waterx_perp.market_registry_wlp),
30
38
  ticker: args.ticker,
31
39
  pool: tx.object(client.config.packages.wlp.wlp_pool),
32
- basePriceUsd: args.basePriceUsd,
33
- collateralPriceUsd: args.collateralPriceUsd,
34
- positionId: args.positionId,
40
+ basePriceUsd: toU64(args.basePriceUsd, "basePriceUsd"),
41
+ collateralPriceUsd: toU64(args.collateralPriceUsd, "collateralPriceUsd"),
42
+ positionId: toU64(args.positionId, "positionId"),
35
43
  },
36
44
  typeArguments: [withLp(client, args.lpType)],
37
45
  })(tx);
@@ -44,10 +52,10 @@ export async function getOrder(client, args) {
44
52
  arguments: {
45
53
  marketRegistry: tx.object(client.config.packages.waterx_perp.market_registry_wlp),
46
54
  ticker: args.ticker,
47
- basePriceUsd: args.basePriceUsd,
48
- orderTypeTag: args.orderTypeTag,
49
- triggerPrice: args.triggerPrice,
50
- orderId: args.orderId,
55
+ basePriceUsd: toU64(args.basePriceUsd, "basePriceUsd"),
56
+ orderTypeTag: toU8(args.orderTypeTag, "orderTypeTag"),
57
+ triggerPrice: toU128(args.triggerPrice, "triggerPrice"),
58
+ orderId: toU64(args.orderId, "orderId"),
51
59
  },
52
60
  typeArguments: [withLp(client, args.lpType)],
53
61
  })(tx);
@@ -60,9 +68,9 @@ export async function getMarketOrders(client, args) {
60
68
  arguments: {
61
69
  marketRegistry: tx.object(client.config.packages.waterx_perp.market_registry_wlp),
62
70
  ticker: args.ticker,
63
- basePriceUsd: args.basePriceUsd ?? 0n,
64
- cursor: args.cursor ?? 0n,
65
- pageSize: args.pageSize ?? 100n,
71
+ basePriceUsd: toU64(args.basePriceUsd ?? 0n, "basePriceUsd"),
72
+ cursor: toU64(args.cursor ?? 0n, "cursor"),
73
+ pageSize: toU64(args.pageSize ?? 100n, "pageSize"),
66
74
  },
67
75
  typeArguments: [withLp(client, args.lpType)],
68
76
  })(tx);
@@ -94,10 +102,10 @@ export async function getMarketPositions(client, args) {
94
102
  marketRegistry: tx.object(client.config.packages.waterx_perp.market_registry_wlp),
95
103
  ticker: args.ticker,
96
104
  pool: tx.object(client.config.packages.wlp.wlp_pool),
97
- basePriceUsd: args.basePriceUsd,
98
- collateralPriceUsd: args.collateralPriceUsd ?? 0n,
99
- cursor: args.cursor ?? 0n,
100
- pageSize: args.pageSize ?? 100n,
105
+ basePriceUsd: toU64(args.basePriceUsd, "basePriceUsd"),
106
+ collateralPriceUsd: toU64(args.collateralPriceUsd ?? 0n, "collateralPriceUsd"),
107
+ cursor: toU64(args.cursor ?? 0n, "cursor"),
108
+ pageSize: toU64(args.pageSize ?? 100n, "pageSize"),
101
109
  },
102
110
  typeArguments: [withLp(client, args.lpType)],
103
111
  })(tx);
@@ -130,8 +138,8 @@ export async function getAccountPositions(client, args) {
130
138
  ticker: args.ticker,
131
139
  pool: tx.object(client.config.packages.wlp.wlp_pool),
132
140
  wxaRegistry: tx.object(client.config.packages.waterx_account.account_registry),
133
- basePriceUsd: args.basePriceUsd,
134
- collateralPriceUsd: args.collateralPriceUsd ?? 0n,
141
+ basePriceUsd: toU64(args.basePriceUsd, "basePriceUsd"),
142
+ collateralPriceUsd: toU64(args.collateralPriceUsd ?? 0n, "collateralPriceUsd"),
135
143
  accountObjectAddress: args.accountObjectAddress,
136
144
  },
137
145
  typeArguments: [withLp(client, args.lpType)],
@@ -145,7 +153,7 @@ export async function getAccountOrders(client, args) {
145
153
  arguments: {
146
154
  marketRegistry: tx.object(client.config.packages.waterx_perp.market_registry_wlp),
147
155
  ticker: args.ticker,
148
- basePriceUsd: args.basePriceUsd ?? 0n,
156
+ basePriceUsd: toU64(args.basePriceUsd ?? 0n, "basePriceUsd"),
149
157
  accountObjectAddress: args.accountObjectAddress,
150
158
  },
151
159
  typeArguments: [withLp(client, args.lpType)],
@@ -158,8 +166,8 @@ export async function getRedeemRequests(client, args = {}) {
158
166
  package: client.config.packages.waterx_perp_view.published_at,
159
167
  arguments: {
160
168
  pool: tx.object(client.config.packages.wlp.wlp_pool),
161
- cursor: args.cursor ?? 0n,
162
- pageSize: args.pageSize ?? 100n,
169
+ cursor: toU64(args.cursor ?? 0n, "cursor"),
170
+ pageSize: toU64(args.pageSize ?? 100n, "pageSize"),
163
171
  },
164
172
  typeArguments: [withLp(client, args.lpType)],
165
173
  })(tx);
@@ -1,15 +1,19 @@
1
1
  export { PerpClient } from "./client.ts";
2
2
  export type { CreateClientOptions } from "./client.ts";
3
- export { PYTH_DEFAULTS, WORMHOLE_DEFAULTS, clearConfigCache, loadConfig } from "./config.ts";
4
- export type { BasePackageEntry, ConstantFeedEntry, WaterxReferralPackage, LoadConfigOptions, NativeCustodyAsset, NativeCustodyPackage, PythFetchPolicy, PythInfraConfig, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, TestnetFaucetPackage, WaterXConfig, WaterXPackages, WaterxCreditPackage, WaterxOraclePackage, WaterxPerpMarketEntry, WaterxPerpPackage, WaterxStakingPackage, WithdrawalQueuePackage, WlpPackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "./config.ts";
5
- export { ACTION_ADD_PRE_ORDER, ACTION_CANCEL_ORDER, ACTION_CANCEL_PRE_ORDER, ACTION_CLOSE_POSITION, ACTION_DECREASE_POSITION, ACTION_DEPOSIT_COLLATERAL, ACTION_INCREASE_POSITION, ACTION_LIQUIDATE, ACTION_OPEN_POSITION, ACTION_PLACE_ORDER, ACTION_UPDATE_ORDER, ACTION_WITHDRAW_COLLATERAL, BPS_SCALE, CRYPTO_FEE_RATE, DOUBLE_SCALE, DRY_RUN_SENDER, FLOAT_SCALE, MAINTENANCE_MARGIN_RATE, ORDER_LIMIT_BUY, ORDER_LIMIT_SELL, ORDER_STOP_BUY, ORDER_STOP_SELL, ORDER_TAG_WILDCARD, PERM_ALL, PERM_ALL_TRADING, PERM_CANCEL_ORDER, PERM_CLOSE_POSITION, PERM_DECREASE_POSITION, PERM_DEPOSIT_COLLATERAL, PERM_INCREASE_POSITION, PERM_MINT_WLP, PERM_OPEN_POSITION, PERM_PLACE_ORDER, PERM_REDEEM_WLP, PERM_WITHDRAW_COLLATERAL, STAKING_PERM_DEPOSIT_STAKE, STAKING_PERM_REDEEM_STAKE, STAKING_PERM_CLAIM_REWARD, STAKING_PERM_ALL, STOCK_FEE_RATE, MS_PER_YEAR, SUI_DECIMALS, WLP_DECIMALS, COLLATERAL_DECIMALS, TOKEN_DECIMALS, } from "./constants.ts";
3
+ export { WORMHOLE_DEFAULTS, clearConfigCache, loadConfig } from "./config.ts";
4
+ export type { BasePackageEntry, ConstantFeedEntry, WaterxReferralPackage, LoadConfigOptions, NativeCustodyAsset, NativeCustodyPackage, PythAccessConfig, PythFetchPolicy, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, TestnetFaucetPackage, WaterXConfig, WaterXPackages, WaterxCreditPackage, WaterxOraclePackage, WaterxPerpMarketEntry, WaterxPerpPackage, WaterxStakingPackage, WithdrawalQueuePackage, WlpPackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "./config.ts";
5
+ export { ACTION_ADD_PRE_ORDER, ACTION_CANCEL_ORDER, ACTION_CANCEL_PRE_ORDER, ACTION_CLOSE_POSITION, ACTION_DECREASE_POSITION, ACTION_DEPOSIT_COLLATERAL, ACTION_INCREASE_POSITION, ACTION_LIQUIDATE, ACTION_OPEN_POSITION, ACTION_PLACE_ORDER, ACTION_UPDATE_ORDER, ACTION_WITHDRAW_COLLATERAL, BPS_SCALE, DOUBLE_SCALE, DRY_RUN_SENDER, FLOAT_SCALE, ORDER_LIMIT_BUY, ORDER_LIMIT_SELL, ORDER_STOP_BUY, ORDER_STOP_SELL, ORDER_TAG_WILDCARD, PERM_ALL, PERM_ALL_TRADING, PERM_CANCEL_ORDER, PERM_CLOSE_POSITION, PERM_DECREASE_POSITION, PERM_DEPOSIT_COLLATERAL, PERM_INCREASE_POSITION, PERM_MINT_WLP, PERM_OPEN_POSITION, PERM_PLACE_ORDER, PERM_REDEEM_WLP, PERM_WITHDRAW_COLLATERAL, STAKING_PERM_DEPOSIT_STAKE, STAKING_PERM_REDEEM_STAKE, STAKING_PERM_CLAIM_REWARD, STAKING_PERM_ALL, MS_PER_MINUTE, MS_PER_HOUR, MS_PER_YEAR, SUI_DECIMALS, WLP_DECIMALS, COLLATERAL_DECIMALS, TOKEN_DECIMALS, } from "./constants.ts";
6
6
  export type { Network } from "./constants.ts";
7
7
  export { getMarketTickers, getCollateralAssets } from "../utils/config.ts";
8
- export { annualizedApyFromRatio, annualizeFundingRate, calcBorrowRate, calcBorrowRateAccrual, calcDynamicFeeBps, calcEffectiveCollateralUsd, calcEstLiqPrice, calcFee, calcFundingFeeUsd, calcFundingRate, calcImpactFeeRate, calcLeverage, calcMaxReducibleCollateralUsd, calcNotional, calcPositionBorrowFee, calcTokenUtilizationBps, calcTotalTradingFeeRate, calcUnrealizedPnl, calcWlpIncentiveApy, calcWlpMintOut, calcWlpPrice, calcWlpRedeemOut, decodeFundingIndexDelta, rawPrice, } from "../utils/math.ts";
8
+ export { annualizedApyFromRatio, annualizeFundingRate, calcBorrowRate, calcBorrowRateAccrual, calcDynamicFeeBps, calcEffectiveCollateralUsd, calcEstLiqPrice, calcEstLiqPriceRaw, calcFee, calcFundingFeeUsd, calcFundingRate, calcImpactFeeRate, calcLeverage, calcMaxReducibleCollateralUsd, calcNotional, calcPositionBorrowFee, calcRealLiqNetCostUsd, calcTokenUtilizationBps, calcTotalTradingFeeRate, calcUnrealizedPnl, calcViewEstLiqFeesUsd, calcWlpIncentiveApy, calcWlpMintOut, calcWlpPrice, calcWlpRedeemOut, decodeFundingIndexDelta, rawPrice, } from "../utils/math.ts";
9
+ export type { ExactDecimalUsd, LiqFeeBundle, RawPriceInput } from "../utils/math.ts";
10
+ export { formatFundingInterval } from "../utils/format.ts";
11
+ export { calcEstLiqPriceRawFromView } from "./liq-view.ts";
12
+ export type { EstLiqPriceViewOpts } from "./liq-view.ts";
9
13
  export * from "./user/index.ts";
10
14
  export * from "./tx-builders.ts";
11
15
  export * from "./fetch.ts";
12
- export { FetchPolicyError, LazerApiKeyMissingError, OracleFeeSourceUnavailableError, OracleSourceNotImplementedError, PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, refreshOraclePrices, updatePythPrices, } from "../oracle/index.ts";
16
+ export { FetchPolicyError, LazerApiKeyMissingError, OracleFeeSourceUnavailableError, OracleSourceNotImplementedError, PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, pythCoreHermesEndpoint, pythProHermesEndpoint, resolveHermesReadEndpoint, waterxQuoteCenterEndpoint, refreshOraclePrices, updatePythPrices, } from "../oracle/index.ts";
13
17
  export type { FetchPolicy, OracleFeeSource, OracleSource, UpdateDataProvider, } from "../oracle/index.ts";
14
18
  export { fetchDepositVaa, fetchVaa, listBridgeWithdrawalVaas, listVaasByEmitter, padEvmEmitter, toWormholescanEmitter, vaaBase64ToBytes, vaaBase64ToHex, vaaBytesToBase64, waitForVaa, } from "../account/funding/wormhole.ts";
15
19
  export type { VaaListItem, VaaResponse, WormholescanOptions } from "../account/funding/wormhole.ts";
@@ -1,11 +1,13 @@
1
1
  // ======== Core ========
2
2
  export { PerpClient } from "./client.js";
3
- export { PYTH_DEFAULTS, WORMHOLE_DEFAULTS, clearConfigCache, loadConfig } from "./config.js";
3
+ export { WORMHOLE_DEFAULTS, clearConfigCache, loadConfig } from "./config.js";
4
4
  // ======== Constants & enums ========
5
- export { ACTION_ADD_PRE_ORDER, ACTION_CANCEL_ORDER, ACTION_CANCEL_PRE_ORDER, ACTION_CLOSE_POSITION, ACTION_DECREASE_POSITION, ACTION_DEPOSIT_COLLATERAL, ACTION_INCREASE_POSITION, ACTION_LIQUIDATE, ACTION_OPEN_POSITION, ACTION_PLACE_ORDER, ACTION_UPDATE_ORDER, ACTION_WITHDRAW_COLLATERAL, BPS_SCALE, CRYPTO_FEE_RATE, DOUBLE_SCALE, DRY_RUN_SENDER, FLOAT_SCALE, MAINTENANCE_MARGIN_RATE, ORDER_LIMIT_BUY, ORDER_LIMIT_SELL, ORDER_STOP_BUY, ORDER_STOP_SELL, ORDER_TAG_WILDCARD, PERM_ALL, PERM_ALL_TRADING, PERM_CANCEL_ORDER, PERM_CLOSE_POSITION, PERM_DECREASE_POSITION, PERM_DEPOSIT_COLLATERAL, PERM_INCREASE_POSITION, PERM_MINT_WLP, PERM_OPEN_POSITION, PERM_PLACE_ORDER, PERM_REDEEM_WLP, PERM_WITHDRAW_COLLATERAL, STAKING_PERM_DEPOSIT_STAKE, STAKING_PERM_REDEEM_STAKE, STAKING_PERM_CLAIM_REWARD, STAKING_PERM_ALL, STOCK_FEE_RATE, MS_PER_YEAR, SUI_DECIMALS, WLP_DECIMALS, COLLATERAL_DECIMALS, TOKEN_DECIMALS, } from "./constants.js";
5
+ export { ACTION_ADD_PRE_ORDER, ACTION_CANCEL_ORDER, ACTION_CANCEL_PRE_ORDER, ACTION_CLOSE_POSITION, ACTION_DECREASE_POSITION, ACTION_DEPOSIT_COLLATERAL, ACTION_INCREASE_POSITION, ACTION_LIQUIDATE, ACTION_OPEN_POSITION, ACTION_PLACE_ORDER, ACTION_UPDATE_ORDER, ACTION_WITHDRAW_COLLATERAL, BPS_SCALE, DOUBLE_SCALE, DRY_RUN_SENDER, FLOAT_SCALE, ORDER_LIMIT_BUY, ORDER_LIMIT_SELL, ORDER_STOP_BUY, ORDER_STOP_SELL, ORDER_TAG_WILDCARD, PERM_ALL, PERM_ALL_TRADING, PERM_CANCEL_ORDER, PERM_CLOSE_POSITION, PERM_DECREASE_POSITION, PERM_DEPOSIT_COLLATERAL, PERM_INCREASE_POSITION, PERM_MINT_WLP, PERM_OPEN_POSITION, PERM_PLACE_ORDER, PERM_REDEEM_WLP, PERM_WITHDRAW_COLLATERAL, STAKING_PERM_DEPOSIT_STAKE, STAKING_PERM_REDEEM_STAKE, STAKING_PERM_CLAIM_REWARD, STAKING_PERM_ALL, MS_PER_MINUTE, MS_PER_HOUR, MS_PER_YEAR, SUI_DECIMALS, WLP_DECIMALS, COLLATERAL_DECIMALS, TOKEN_DECIMALS, } from "./constants.js";
6
6
  // ======== Utilities ========
7
7
  export { getMarketTickers, getCollateralAssets } from "../utils/config.js";
8
- export { annualizedApyFromRatio, annualizeFundingRate, calcBorrowRate, calcBorrowRateAccrual, calcDynamicFeeBps, calcEffectiveCollateralUsd, calcEstLiqPrice, calcFee, calcFundingFeeUsd, calcFundingRate, calcImpactFeeRate, calcLeverage, calcMaxReducibleCollateralUsd, calcNotional, calcPositionBorrowFee, calcTokenUtilizationBps, calcTotalTradingFeeRate, calcUnrealizedPnl, calcWlpIncentiveApy, calcWlpMintOut, calcWlpPrice, calcWlpRedeemOut, decodeFundingIndexDelta, rawPrice, } from "../utils/math.js";
8
+ export { annualizedApyFromRatio, annualizeFundingRate, calcBorrowRate, calcBorrowRateAccrual, calcDynamicFeeBps, calcEffectiveCollateralUsd, calcEstLiqPrice, calcEstLiqPriceRaw, calcFee, calcFundingFeeUsd, calcFundingRate, calcImpactFeeRate, calcLeverage, calcMaxReducibleCollateralUsd, calcNotional, calcPositionBorrowFee, calcRealLiqNetCostUsd, calcTokenUtilizationBps, calcTotalTradingFeeRate, calcUnrealizedPnl, calcViewEstLiqFeesUsd, calcWlpIncentiveApy, calcWlpMintOut, calcWlpPrice, calcWlpRedeemOut, decodeFundingIndexDelta, rawPrice, } from "../utils/math.js";
9
+ export { formatFundingInterval } from "../utils/format.js";
10
+ export { calcEstLiqPriceRawFromView } from "./liq-view.js";
9
11
  // ======== Transaction builders (user-side) ========
10
12
  export * from "./user/index.js";
11
13
  // ======== High-level Tx builders ========
@@ -13,7 +15,7 @@ export * from "./tx-builders.js";
13
15
  // ======== Read-only queries ========
14
16
  export * from "./fetch.js";
15
17
  // ======== Oracle utilities (Pyth source + rule aggregation) ========
16
- export { FetchPolicyError, LazerApiKeyMissingError, OracleFeeSourceUnavailableError, OracleSourceNotImplementedError, PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, refreshOraclePrices, updatePythPrices, } from "../oracle/index.js";
18
+ export { FetchPolicyError, LazerApiKeyMissingError, OracleFeeSourceUnavailableError, OracleSourceNotImplementedError, PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, pythCoreHermesEndpoint, pythProHermesEndpoint, resolveHermesReadEndpoint, waterxQuoteCenterEndpoint, refreshOraclePrices, updatePythPrices, } from "../oracle/index.js";
17
19
  // ======== Wormhole / Wormholescan utilities (credit bridge) ========
18
20
  export { fetchDepositVaa, fetchVaa, listBridgeWithdrawalVaas, listVaasByEmitter, padEvmEmitter, toWormholescanEmitter, vaaBase64ToBytes, vaaBase64ToHex, vaaBytesToBase64, waitForVaa, } from "../account/funding/wormhole.js";
19
21
  // ======== Generated BCS types (sui-ts-codegen) ========
@@ -0,0 +1,64 @@
1
+ /**
2
+ * View→raw adapter for the canonical liquidation-price estimate.
3
+ *
4
+ * `calcEstLiqPriceRaw` (`utils/math.ts`) takes the twelve RAW on-chain values
5
+ * the Move view takes, so every consumer that already holds a fetched
6
+ * `PositionDataView` row had to hand-map nine of them 1:1 off the row (the
7
+ * other three are the probe prices + maintenance margin, which the row does not
8
+ * carry) — and hand-carry the price invariant below in prose. That mapping is
9
+ * the SDK's job, so it lives here.
10
+ *
11
+ * ## Why perp-side and not in `utils/math.ts`
12
+ *
13
+ * `PositionDataView` is a perp read type (`perp/fetch/positions.ts`, decoded
14
+ * from the `waterx_perp_view` BCS struct). `utils/` is the shared base that
15
+ * `perp/` imports FROM — pulling a perp view type down into `utils/math.ts`
16
+ * would invert that direction and couple the line-agnostic math to the perp
17
+ * read layer. So the pure math stays in `utils/`, and the adapter that knows
18
+ * the perp row shape sits here, one layer up. Kept out of
19
+ * `perp/fetch/positions.ts` too: that module is transport (build PTB →
20
+ * simulate → decode), this is a pure field mapping with no client.
21
+ */
22
+ import type { PositionDataView } from "./fetch/positions.ts";
23
+ /**
24
+ * Probe prices the position row was READ AT — see the invariant on
25
+ * {@link calcEstLiqPriceRawFromView}. Whole-dollar u64, exactly as passed to
26
+ * the `perp/fetch` read (`WholeDollarUsdPrice`), plus the market's maintenance
27
+ * margin, which lives on `MarketData`, not on the position row.
28
+ */
29
+ export type EstLiqPriceViewOpts = {
30
+ /** `MarketData.maintenance_margin` — raw 1e9-scaled Float value. */
31
+ maintenanceMarginRaw: bigint;
32
+ /** The SAME `basePriceUsd` passed to the read that produced `position`. */
33
+ basePriceUsd: bigint;
34
+ /** The SAME `collateralPriceUsd` passed to the read that produced `position`. */
35
+ collateralPriceUsd: bigint;
36
+ };
37
+ /**
38
+ * Estimated liquidation price from a fetched `PositionDataView` row —
39
+ * bit-identical to that row's `est_liq_price`.
40
+ *
41
+ * Maps the row's nine raw fields onto {@link calcEstLiqPriceRaw} (the op-for-op
42
+ * mirror of `view.move::calculate_est_liq_price`) and takes the remaining
43
+ * three — the two probe prices plus the market's maintenance margin — from
44
+ * `opts`. Returns the raw 1e9-scaled u128 price; `0n` = already liquidatable /
45
+ * zero size.
46
+ *
47
+ * ## INVARIANT — the prices must be the ones the row was READ AT
48
+ *
49
+ * `opts.basePriceUsd` / `opts.collateralPriceUsd` MUST be the same whole-dollar
50
+ * values you passed to the `perp/fetch` read that produced `position`
51
+ * (`getPosition`, `getMarketPositions`, `getAccountPositions`, …).
52
+ *
53
+ * `PositionDataView` does NOT carry the probe prices it was computed at, so
54
+ * NOTHING — not this adapter, not the type system — can check this for you.
55
+ * Feed different prices and the row's fee / notional-derived fields were
56
+ * computed against one price while the estimate is computed against another:
57
+ * the result is a plausible-looking number that silently disagrees with
58
+ * `position.est_liq_price`. Thread the prices through from the read call site;
59
+ * never re-fetch or re-guess them here.
60
+ *
61
+ * @throws RangeError via `calcEstLiqPriceRaw` when any raw value is negative or
62
+ * `collateral_decimal` is outside `[0, 19]`.
63
+ */
64
+ export declare function calcEstLiqPriceRawFromView(position: PositionDataView, opts: EstLiqPriceViewOpts): bigint;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * View→raw adapter for the canonical liquidation-price estimate.
3
+ *
4
+ * `calcEstLiqPriceRaw` (`utils/math.ts`) takes the twelve RAW on-chain values
5
+ * the Move view takes, so every consumer that already holds a fetched
6
+ * `PositionDataView` row had to hand-map nine of them 1:1 off the row (the
7
+ * other three are the probe prices + maintenance margin, which the row does not
8
+ * carry) — and hand-carry the price invariant below in prose. That mapping is
9
+ * the SDK's job, so it lives here.
10
+ *
11
+ * ## Why perp-side and not in `utils/math.ts`
12
+ *
13
+ * `PositionDataView` is a perp read type (`perp/fetch/positions.ts`, decoded
14
+ * from the `waterx_perp_view` BCS struct). `utils/` is the shared base that
15
+ * `perp/` imports FROM — pulling a perp view type down into `utils/math.ts`
16
+ * would invert that direction and couple the line-agnostic math to the perp
17
+ * read layer. So the pure math stays in `utils/`, and the adapter that knows
18
+ * the perp row shape sits here, one layer up. Kept out of
19
+ * `perp/fetch/positions.ts` too: that module is transport (build PTB →
20
+ * simulate → decode), this is a pure field mapping with no client.
21
+ */
22
+ import { calcEstLiqPriceRaw } from "../utils/math.js";
23
+ /**
24
+ * Estimated liquidation price from a fetched `PositionDataView` row —
25
+ * bit-identical to that row's `est_liq_price`.
26
+ *
27
+ * Maps the row's nine raw fields onto {@link calcEstLiqPriceRaw} (the op-for-op
28
+ * mirror of `view.move::calculate_est_liq_price`) and takes the remaining
29
+ * three — the two probe prices plus the market's maintenance margin — from
30
+ * `opts`. Returns the raw 1e9-scaled u128 price; `0n` = already liquidatable /
31
+ * zero size.
32
+ *
33
+ * ## INVARIANT — the prices must be the ones the row was READ AT
34
+ *
35
+ * `opts.basePriceUsd` / `opts.collateralPriceUsd` MUST be the same whole-dollar
36
+ * values you passed to the `perp/fetch` read that produced `position`
37
+ * (`getPosition`, `getMarketPositions`, `getAccountPositions`, …).
38
+ *
39
+ * `PositionDataView` does NOT carry the probe prices it was computed at, so
40
+ * NOTHING — not this adapter, not the type system — can check this for you.
41
+ * Feed different prices and the row's fee / notional-derived fields were
42
+ * computed against one price while the estimate is computed against another:
43
+ * the result is a plausible-looking number that silently disagrees with
44
+ * `position.est_liq_price`. Thread the prices through from the read call site;
45
+ * never re-fetch or re-guess them here.
46
+ *
47
+ * @throws RangeError via `calcEstLiqPriceRaw` when any raw value is negative or
48
+ * `collateral_decimal` is outside `[0, 19]`.
49
+ */
50
+ export function calcEstLiqPriceRawFromView(position, opts) {
51
+ return calcEstLiqPriceRaw({
52
+ isLong: position.is_long,
53
+ sizeRaw: BigInt(position.size),
54
+ avgPriceRaw: BigInt(position.average_price),
55
+ collateralAmountRaw: BigInt(position.collateral_amount),
56
+ collateralDecimal: position.collateral_decimal,
57
+ basePriceUsd: opts.basePriceUsd,
58
+ collateralPriceUsd: opts.collateralPriceUsd,
59
+ maintenanceMarginRaw: opts.maintenanceMarginRaw,
60
+ // The view pre-combines accrued + unrealized into `borrow_fee` / `funding_fee`
61
+ // — take those, NOT the `unrealized_*` pair, which would UNDER-count:
62
+ // `view.move` sets `borrow_fee = calculate_borrow_fee(cumul) +
63
+ // unrealized_borrow_fee`, and `position.move::calculate_funding_fee` returns
64
+ // the unrealized leg combined with the current period's, so the row's
65
+ // `unrealized_*` fields are strict SUBSETS of the combined pair.
66
+ borrowFeeRaw: BigInt(position.borrow_fee),
67
+ fundingSign: position.funding_fee_positive,
68
+ fundingFeeRaw: BigInt(position.funding_fee),
69
+ tradingFeeRaw: BigInt(position.unrealized_trading_fee),
70
+ });
71
+ }
@@ -7,6 +7,19 @@
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 type { Transaction, TransactionArgument } from "@mysten/sui/transactions";
12
25
  import type { PerpClient } from "../client.ts";