@metamask-previews/perps-controller 5.0.0-preview-4e0ae1bc9 → 5.0.0-preview-bd0d4d2e9
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/CHANGELOG.md +6 -0
- package/dist/constants/hyperLiquidConfig.cjs +1 -1
- package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
- package/dist/constants/hyperLiquidConfig.d.cts +1 -1
- package/dist/constants/hyperLiquidConfig.d.mts +1 -1
- package/dist/constants/hyperLiquidConfig.mjs +1 -1
- package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
- package/dist/constants/perpsConfig.cjs +15 -3
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +8 -1
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +8 -1
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +14 -2
- package/dist/constants/perpsConfig.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +33 -21
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +33 -21
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +127 -27
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts +4 -12
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts +4 -12
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.mjs +128 -28
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/types/hyperliquid-types.cjs +11 -8
- package/dist/types/hyperliquid-types.cjs.map +1 -1
- package/dist/types/hyperliquid-types.d.cts +24 -9
- package/dist/types/hyperliquid-types.d.cts.map +1 -1
- package/dist/types/hyperliquid-types.d.mts +24 -9
- package/dist/types/hyperliquid-types.d.mts.map +1 -1
- package/dist/types/hyperliquid-types.mjs +11 -8
- package/dist/types/hyperliquid-types.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +26 -3
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +26 -3
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/accountUtils.cjs +49 -35
- package/dist/utils/accountUtils.cjs.map +1 -1
- package/dist/utils/accountUtils.d.cts +30 -4
- package/dist/utils/accountUtils.d.cts.map +1 -1
- package/dist/utils/accountUtils.d.mts +30 -4
- package/dist/utils/accountUtils.d.mts.map +1 -1
- package/dist/utils/accountUtils.mjs +49 -35
- package/dist/utils/accountUtils.mjs.map +1 -1
- package/dist/utils/hyperLiquidAdapter.cjs +3 -2
- package/dist/utils/hyperLiquidAdapter.cjs.map +1 -1
- package/dist/utils/hyperLiquidAdapter.d.cts.map +1 -1
- package/dist/utils/hyperLiquidAdapter.d.mts.map +1 -1
- package/dist/utils/hyperLiquidAdapter.mjs +3 -2
- package/dist/utils/hyperLiquidAdapter.mjs.map +1 -1
- package/dist/utils/hyperLiquidValidation.cjs +11 -11
- package/dist/utils/hyperLiquidValidation.cjs.map +1 -1
- package/dist/utils/hyperLiquidValidation.d.cts +2 -2
- package/dist/utils/hyperLiquidValidation.d.cts.map +1 -1
- package/dist/utils/hyperLiquidValidation.d.mts +2 -2
- package/dist/utils/hyperLiquidValidation.d.mts.map +1 -1
- package/dist/utils/hyperLiquidValidation.mjs +11 -11
- package/dist/utils/hyperLiquidValidation.mjs.map +1 -1
- package/dist/utils/myxAdapter.cjs +2 -2
- package/dist/utils/myxAdapter.cjs.map +1 -1
- package/dist/utils/myxAdapter.mjs +2 -2
- package/dist/utils/myxAdapter.mjs.map +1 -1
- package/dist/utils/orderCalculations.cjs +5 -5
- package/dist/utils/orderCalculations.cjs.map +1 -1
- package/dist/utils/orderCalculations.d.cts +1 -1
- package/dist/utils/orderCalculations.d.mts +1 -1
- package/dist/utils/orderCalculations.mjs +5 -5
- package/dist/utils/orderCalculations.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -17,15 +17,41 @@ export type ReturnOnEquityInput = {
|
|
|
17
17
|
returnOnEquity: string | number;
|
|
18
18
|
};
|
|
19
19
|
export declare function calculateWeightedReturnOnEquity(accounts: ReturnOnEquityInput[]): string;
|
|
20
|
+
export declare function getSpotBalance(spotState?: SpotClearinghouseStateResponse | null): number;
|
|
21
|
+
export declare function getSpotHold(spotState?: SpotClearinghouseStateResponse | null): number;
|
|
22
|
+
/**
|
|
23
|
+
* Options controlling how `addSpotBalanceToAccountState` folds spot balance
|
|
24
|
+
* into the three-field AccountState contract.
|
|
25
|
+
*/
|
|
20
26
|
export type AddSpotBalanceOptions = {
|
|
21
27
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
28
|
+
* When `true`, free spot USDC contributes to both `spendableBalance` and
|
|
29
|
+
* `withdrawableBalance` in addition to `totalBalance` — appropriate for
|
|
30
|
+
* venues where spot is automatically used as perps collateral (e.g.
|
|
31
|
+
* HyperLiquid Unified/Portfolio mode, where `withdraw3` draws from the
|
|
32
|
+
* unified ledger).
|
|
33
|
+
*
|
|
34
|
+
* When `false`, free spot contributes to `totalBalance` only; spendable
|
|
35
|
+
* and withdrawable stay perps-only — appropriate for venues where spot
|
|
36
|
+
* is a separate ledger the backend cannot auto-draw from (e.g. HL
|
|
37
|
+
* Standard mode). The caller is responsible for translating
|
|
38
|
+
* provider-specific state into this flag.
|
|
39
|
+
*
|
|
40
|
+
* Defaults to `true` for backward compatibility with call sites that
|
|
41
|
+
* haven't yet been wired with provider-specific context.
|
|
24
42
|
*/
|
|
25
43
|
foldIntoCollateral?: boolean;
|
|
26
44
|
};
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Add spot USDC to the AccountState contract. Caller decides whether the
|
|
47
|
+
* spot balance counts as perps collateral via `options.foldIntoCollateral`
|
|
48
|
+
* — the util stays provider-agnostic.
|
|
49
|
+
*
|
|
50
|
+
* @param accountState - Base AccountState produced by a provider adapter.
|
|
51
|
+
* @param spotState - Raw spot clearinghouse response (HL-shaped); null or missing means no spot balance and the state is returned unchanged.
|
|
52
|
+
* @param options - See {@link AddSpotBalanceOptions}.
|
|
53
|
+
* @returns AccountState with spot folded into `totalBalance` always, and into spendable/withdrawable when `foldIntoCollateral` is true.
|
|
54
|
+
*/
|
|
29
55
|
export declare function addSpotBalanceToAccountState(accountState: AccountState, spotState?: SpotClearinghouseStateResponse | null, options?: AddSpotBalanceOptions): AccountState;
|
|
30
56
|
/**
|
|
31
57
|
* Aggregate multiple per-DEX AccountState objects into one by summing numeric fields.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountUtils.d.cts","sourceRoot":"","sources":["../../src/utils/accountUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,2BAAiB;AACnE,OAAO,KAAK,EAAE,8BAA8B,EAAE,uCAAmC;AAQjF,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD,eAAe,GAAG,oBAAoB,GAAG,IAAI,CAM/C;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGjC;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAEjC;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC,CAAC;AAEF,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,mBAAmB,EAAE,GAC9B,MAAM,CA4CR;
|
|
1
|
+
{"version":3,"file":"accountUtils.d.cts","sourceRoot":"","sources":["../../src/utils/accountUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,2BAAiB;AACnE,OAAO,KAAK,EAAE,8BAA8B,EAAE,uCAAmC;AAQjF,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD,eAAe,GAAG,oBAAoB,GAAG,IAAI,CAM/C;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGjC;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAEjC;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC,CAAC;AAEF,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,mBAAmB,EAAE,GAC9B,MAAM,CA4CR;AAMD,wBAAgB,cAAc,CAC5B,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,GAChD,MAAM,CAeR;AAED,wBAAgB,WAAW,CACzB,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,GAChD,MAAM,CAeR;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,YAAY,EAC1B,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,EACjD,OAAO,CAAC,EAAE,qBAAqB,GAC9B,YAAY,CA0Dd;AAsBD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAqD3E"}
|
|
@@ -17,15 +17,41 @@ export type ReturnOnEquityInput = {
|
|
|
17
17
|
returnOnEquity: string | number;
|
|
18
18
|
};
|
|
19
19
|
export declare function calculateWeightedReturnOnEquity(accounts: ReturnOnEquityInput[]): string;
|
|
20
|
+
export declare function getSpotBalance(spotState?: SpotClearinghouseStateResponse | null): number;
|
|
21
|
+
export declare function getSpotHold(spotState?: SpotClearinghouseStateResponse | null): number;
|
|
22
|
+
/**
|
|
23
|
+
* Options controlling how `addSpotBalanceToAccountState` folds spot balance
|
|
24
|
+
* into the three-field AccountState contract.
|
|
25
|
+
*/
|
|
20
26
|
export type AddSpotBalanceOptions = {
|
|
21
27
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
28
|
+
* When `true`, free spot USDC contributes to both `spendableBalance` and
|
|
29
|
+
* `withdrawableBalance` in addition to `totalBalance` — appropriate for
|
|
30
|
+
* venues where spot is automatically used as perps collateral (e.g.
|
|
31
|
+
* HyperLiquid Unified/Portfolio mode, where `withdraw3` draws from the
|
|
32
|
+
* unified ledger).
|
|
33
|
+
*
|
|
34
|
+
* When `false`, free spot contributes to `totalBalance` only; spendable
|
|
35
|
+
* and withdrawable stay perps-only — appropriate for venues where spot
|
|
36
|
+
* is a separate ledger the backend cannot auto-draw from (e.g. HL
|
|
37
|
+
* Standard mode). The caller is responsible for translating
|
|
38
|
+
* provider-specific state into this flag.
|
|
39
|
+
*
|
|
40
|
+
* Defaults to `true` for backward compatibility with call sites that
|
|
41
|
+
* haven't yet been wired with provider-specific context.
|
|
24
42
|
*/
|
|
25
43
|
foldIntoCollateral?: boolean;
|
|
26
44
|
};
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Add spot USDC to the AccountState contract. Caller decides whether the
|
|
47
|
+
* spot balance counts as perps collateral via `options.foldIntoCollateral`
|
|
48
|
+
* — the util stays provider-agnostic.
|
|
49
|
+
*
|
|
50
|
+
* @param accountState - Base AccountState produced by a provider adapter.
|
|
51
|
+
* @param spotState - Raw spot clearinghouse response (HL-shaped); null or missing means no spot balance and the state is returned unchanged.
|
|
52
|
+
* @param options - See {@link AddSpotBalanceOptions}.
|
|
53
|
+
* @returns AccountState with spot folded into `totalBalance` always, and into spendable/withdrawable when `foldIntoCollateral` is true.
|
|
54
|
+
*/
|
|
29
55
|
export declare function addSpotBalanceToAccountState(accountState: AccountState, spotState?: SpotClearinghouseStateResponse | null, options?: AddSpotBalanceOptions): AccountState;
|
|
30
56
|
/**
|
|
31
57
|
* Aggregate multiple per-DEX AccountState objects into one by summing numeric fields.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountUtils.d.mts","sourceRoot":"","sources":["../../src/utils/accountUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,2BAAiB;AACnE,OAAO,KAAK,EAAE,8BAA8B,EAAE,uCAAmC;AAQjF,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD,eAAe,GAAG,oBAAoB,GAAG,IAAI,CAM/C;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGjC;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAEjC;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC,CAAC;AAEF,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,mBAAmB,EAAE,GAC9B,MAAM,CA4CR;
|
|
1
|
+
{"version":3,"file":"accountUtils.d.mts","sourceRoot":"","sources":["../../src/utils/accountUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,2BAAiB;AACnE,OAAO,KAAK,EAAE,8BAA8B,EAAE,uCAAmC;AAQjF,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD,eAAe,GAAG,oBAAoB,GAAG,IAAI,CAM/C;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGjC;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,GACnD;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAEjC;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC,CAAC;AAEF,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,mBAAmB,EAAE,GAC9B,MAAM,CA4CR;AAMD,wBAAgB,cAAc,CAC5B,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,GAChD,MAAM,CAeR;AAED,wBAAgB,WAAW,CACzB,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,GAChD,MAAM,CAeR;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,YAAY,EAC1B,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,EACjD,OAAO,CAAC,EAAE,qBAAqB,GAC9B,YAAY,CA0Dd;AAsBD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAqD3E"}
|
|
@@ -74,6 +74,16 @@ export function getSpotHold(spotState) {
|
|
|
74
74
|
return Number.isFinite(value) ? sum + value : sum;
|
|
75
75
|
}, 0);
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Add spot USDC to the AccountState contract. Caller decides whether the
|
|
79
|
+
* spot balance counts as perps collateral via `options.foldIntoCollateral`
|
|
80
|
+
* — the util stays provider-agnostic.
|
|
81
|
+
*
|
|
82
|
+
* @param accountState - Base AccountState produced by a provider adapter.
|
|
83
|
+
* @param spotState - Raw spot clearinghouse response (HL-shaped); null or missing means no spot balance and the state is returned unchanged.
|
|
84
|
+
* @param options - See {@link AddSpotBalanceOptions}.
|
|
85
|
+
* @returns AccountState with spot folded into `totalBalance` always, and into spendable/withdrawable when `foldIntoCollateral` is true.
|
|
86
|
+
*/
|
|
77
87
|
export function addSpotBalanceToAccountState(accountState, spotState, options) {
|
|
78
88
|
// Fail-closed default: align with `hyperLiquidModeFoldsSpot(null) → false`.
|
|
79
89
|
// A caller that omits `options` should NOT silently fold spot — that would
|
|
@@ -83,43 +93,53 @@ export function addSpotBalanceToAccountState(accountState, spotState, options) {
|
|
|
83
93
|
const spotHold = getSpotHold(spotState);
|
|
84
94
|
const freeSpot = Math.max(0, spotBalance - spotHold);
|
|
85
95
|
const currentTotal = parseFloat(accountState.totalBalance);
|
|
86
|
-
const
|
|
96
|
+
const currentSpendable = parseFloat(accountState.spendableBalance);
|
|
97
|
+
const currentWithdrawable = parseFloat(accountState.withdrawableBalance);
|
|
87
98
|
// Preserve sentinel totals (e.g. PERPS_CONSTANTS.FallbackDataDisplay '--')
|
|
88
99
|
// rather than coercing them to NaN.
|
|
89
100
|
if (!Number.isFinite(currentTotal)) {
|
|
90
101
|
return accountState;
|
|
91
102
|
}
|
|
92
103
|
if (spotBalance === 0) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
? currentAvailable.toString()
|
|
97
|
-
: accountState.availableBalance,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
// Folding is gated strictly on the resolved abstraction mode. Standard /
|
|
101
|
-
// DEX-abstraction users keep perps and spot independent, so spot must NOT
|
|
102
|
-
// surface as a perps-withdrawable balance for them — withdraw3 only draws
|
|
103
|
-
// from the perps ledger in those modes. Unified / portfolio-margin users
|
|
104
|
-
// get the fold; live callers fail-CLOSED via `hyperLiquidModeFoldsSpot`
|
|
105
|
-
// when mode is unresolved (avoids over-reporting funds withdraw3 cannot
|
|
106
|
-
// actually draw during the initial subscription window).
|
|
107
|
-
let availableToTrade = accountState.availableBalance;
|
|
108
|
-
if (foldIntoCollateral) {
|
|
109
|
-
availableToTrade = Number.isFinite(currentAvailable)
|
|
110
|
-
? (currentAvailable + freeSpot).toString()
|
|
111
|
-
: freeSpot.toString();
|
|
104
|
+
// No spot wealth means no hold either in the HL payload shape, so the
|
|
105
|
+
// later totalBalance adjustment would also be a no-op.
|
|
106
|
+
return accountState;
|
|
112
107
|
}
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
108
|
+
// Folding is gated strictly on the resolved abstraction mode (see callers'
|
|
109
|
+
// `foldIntoCollateral` argument). Standard / DEX-abstraction users keep
|
|
110
|
+
// perps and spot independent, so spot must NOT surface as a perps-
|
|
111
|
+
// withdrawable balance for them — withdraw3 only draws from the perps
|
|
112
|
+
// ledger in those modes. Unified / portfolio-margin users get the fold;
|
|
113
|
+
// live callers fail-CLOSED via `hyperLiquidModeFoldsSpot` when mode is
|
|
114
|
+
// unresolved.
|
|
115
|
+
const nextSpendable = resolveFoldedBalance(currentSpendable, accountState.spendableBalance, freeSpot, foldIntoCollateral);
|
|
116
|
+
const nextWithdrawable = resolveFoldedBalance(currentWithdrawable, accountState.withdrawableBalance, freeSpot, foldIntoCollateral);
|
|
117
|
+
// Total always reflects combined wealth: subtract spotHold to avoid
|
|
118
|
+
// double-counting on Unified/PM accounts where marginSummary.accountValue
|
|
119
|
+
// already includes the margin that HL surfaces via spot.hold. Standard
|
|
120
|
+
// mode has spotHold = 0 by construction, so the subtraction is a no-op.
|
|
116
121
|
const nextTotal = currentTotal + spotBalance - spotHold;
|
|
117
122
|
return {
|
|
118
123
|
...accountState,
|
|
119
124
|
totalBalance: nextTotal.toString(),
|
|
120
|
-
|
|
125
|
+
spendableBalance: nextSpendable,
|
|
126
|
+
withdrawableBalance: nextWithdrawable,
|
|
121
127
|
};
|
|
122
128
|
}
|
|
129
|
+
function resolveFoldedBalance(currentNumeric, currentRaw, freeSpot, foldIntoCollateral) {
|
|
130
|
+
if (!foldIntoCollateral) {
|
|
131
|
+
return currentRaw;
|
|
132
|
+
}
|
|
133
|
+
if (Number.isFinite(currentNumeric)) {
|
|
134
|
+
return (currentNumeric + freeSpot).toString();
|
|
135
|
+
}
|
|
136
|
+
// Non-finite currentNumeric means the adapter passed a sentinel like
|
|
137
|
+
// `PERPS_CONSTANTS.FallbackDataDisplay` ("--") during loading. Preserve
|
|
138
|
+
// the sentinel rather than synthesising a numeric fold; the caller's
|
|
139
|
+
// UI treats "--" as "loading" and would otherwise show a misleading
|
|
140
|
+
// spot-only figure while the per-DEX perps fetch is still in flight.
|
|
141
|
+
return currentRaw;
|
|
142
|
+
}
|
|
123
143
|
/**
|
|
124
144
|
* Aggregate multiple per-DEX AccountState objects into one by summing numeric fields.
|
|
125
145
|
* ROE is recalculated as (totalUnrealizedPnl / totalMarginUsed) * 100.
|
|
@@ -129,7 +149,8 @@ export function addSpotBalanceToAccountState(accountState, spotState, options) {
|
|
|
129
149
|
*/
|
|
130
150
|
export function aggregateAccountStates(states) {
|
|
131
151
|
const fallback = {
|
|
132
|
-
|
|
152
|
+
spendableBalance: PERPS_CONSTANTS.FallbackDataDisplay,
|
|
153
|
+
withdrawableBalance: PERPS_CONSTANTS.FallbackDataDisplay,
|
|
133
154
|
totalBalance: PERPS_CONSTANTS.FallbackDataDisplay,
|
|
134
155
|
marginUsed: PERPS_CONSTANTS.FallbackDataDisplay,
|
|
135
156
|
unrealizedPnl: PERPS_CONSTANTS.FallbackDataDisplay,
|
|
@@ -142,17 +163,10 @@ export function aggregateAccountStates(states) {
|
|
|
142
163
|
if (index === 0) {
|
|
143
164
|
return { ...state };
|
|
144
165
|
}
|
|
145
|
-
const accAvailableToTrade = parseFloat(acc.availableToTradeBalance ?? acc.availableBalance);
|
|
146
|
-
const stateAvailableToTrade = parseFloat(state.availableToTradeBalance ?? state.availableBalance);
|
|
147
|
-
const availableToTradeSum = Number.isFinite(accAvailableToTrade) &&
|
|
148
|
-
Number.isFinite(stateAvailableToTrade)
|
|
149
|
-
? (accAvailableToTrade + stateAvailableToTrade).toString()
|
|
150
|
-
: undefined;
|
|
151
166
|
return {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}),
|
|
167
|
+
spendableBalance: (parseFloat(acc.spendableBalance) + parseFloat(state.spendableBalance)).toString(),
|
|
168
|
+
withdrawableBalance: (parseFloat(acc.withdrawableBalance) +
|
|
169
|
+
parseFloat(state.withdrawableBalance)).toString(),
|
|
156
170
|
totalBalance: (parseFloat(acc.totalBalance) + parseFloat(state.totalBalance)).toString(),
|
|
157
171
|
marginUsed: (parseFloat(acc.marginUsed) + parseFloat(state.marginUsed)).toString(),
|
|
158
172
|
unrealizedPnl: (parseFloat(acc.unrealizedPnl) + parseFloat(state.unrealizedPnl)).toString(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountUtils.mjs","sourceRoot":"","sources":["../../src/utils/accountUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Account utilities for Perps components\n * Handles account selection and EVM account filtering\n */\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig';\nimport type { AccountState, PerpsInternalAccount } from '../types';\nimport type { SpotClearinghouseStateResponse } from '../types/hyperliquid-types';\n\nconst EVM_ACCOUNT_TYPES = new Set(['eip155:eoa', 'eip155:erc4337']);\n\nfunction isEvmAccountType(type: string): boolean {\n return EVM_ACCOUNT_TYPES.has(type);\n}\n\nexport function findEvmAccount(\n accounts: (InternalAccount | PerpsInternalAccount)[],\n): InternalAccount | PerpsInternalAccount | null {\n const evmAccount = accounts.find(\n (account) =>\n account && isEvmAccountType(account.type as InternalAccount['type']),\n );\n return evmAccount ?? null;\n}\n\nexport function getEvmAccountFromAccountGroup(\n accounts: (InternalAccount | PerpsInternalAccount)[],\n): { address: string } | undefined {\n const evmAccount = findEvmAccount(accounts);\n return evmAccount ? { address: evmAccount.address } : undefined;\n}\n\nexport function getSelectedEvmAccount(\n accounts: (InternalAccount | PerpsInternalAccount)[],\n): { address: string } | undefined {\n return getEvmAccountFromAccountGroup(accounts);\n}\n\nexport type ReturnOnEquityInput = {\n unrealizedPnl: string | number;\n returnOnEquity: string | number;\n};\n\nexport function calculateWeightedReturnOnEquity(\n accounts: ReturnOnEquityInput[],\n): string {\n if (accounts.length === 0) {\n return '0';\n }\n\n let totalWeightedROE = 0;\n let totalMarginUsed = 0;\n\n for (const account of accounts) {\n const unrealizedPnl =\n typeof account.unrealizedPnl === 'string'\n ? Number.parseFloat(account.unrealizedPnl)\n : account.unrealizedPnl;\n const returnOnEquity =\n typeof account.returnOnEquity === 'string'\n ? Number.parseFloat(account.returnOnEquity)\n : account.returnOnEquity;\n\n if (Number.isNaN(unrealizedPnl) || Number.isNaN(returnOnEquity)) {\n continue;\n }\n\n if (returnOnEquity === 0) {\n continue;\n }\n\n const marginUsed = (unrealizedPnl / returnOnEquity) * 100;\n\n if (Number.isNaN(marginUsed) || marginUsed <= 0) {\n continue;\n }\n\n const roeDecimal = returnOnEquity / 100;\n\n totalWeightedROE += roeDecimal * marginUsed;\n totalMarginUsed += marginUsed;\n }\n\n if (totalMarginUsed <= 0) {\n return '0';\n }\n\n const weightedROE = (totalWeightedROE / totalMarginUsed) * 100;\n return weightedROE.toString();\n}\n\nexport type AddSpotBalanceOptions = {\n /**\n * Whether the user's abstraction mode folds spot balances into perps\n * collateral. Standard / DEX abstraction keep spot separate.\n */\n foldIntoCollateral?: boolean;\n};\n\n// The release-branch balance bridge is USDC-only. Non-USDC spot assets must\n// not inflate the balances shown or validated by withdraw/payment flows.\nconst SPOT_COLLATERAL_COINS = new Set<string>(['USDC']);\n\nexport function getSpotBalance(\n spotState?: SpotClearinghouseStateResponse | null,\n): number {\n if (!spotState?.balances || !Array.isArray(spotState.balances)) {\n return 0;\n }\n\n return spotState.balances.reduce(\n (sum: number, balance: { coin?: string; total?: string }) => {\n if (!balance.coin || !SPOT_COLLATERAL_COINS.has(balance.coin)) {\n return sum;\n }\n const value = parseFloat(balance.total ?? '0');\n return Number.isFinite(value) ? sum + value : sum;\n },\n 0,\n );\n}\n\nexport function getSpotHold(\n spotState?: SpotClearinghouseStateResponse | null,\n): number {\n if (!spotState?.balances || !Array.isArray(spotState.balances)) {\n return 0;\n }\n\n return spotState.balances.reduce(\n (sum: number, balance: { coin?: string; hold?: string }) => {\n if (!balance.coin || !SPOT_COLLATERAL_COINS.has(balance.coin)) {\n return sum;\n }\n const value = parseFloat(balance.hold ?? '0');\n return Number.isFinite(value) ? sum + value : sum;\n },\n 0,\n );\n}\n\nexport function addSpotBalanceToAccountState(\n accountState: AccountState,\n spotState?: SpotClearinghouseStateResponse | null,\n options?: AddSpotBalanceOptions,\n): AccountState {\n // Fail-closed default: align with `hyperLiquidModeFoldsSpot(null) → false`.\n // A caller that omits `options` should NOT silently fold spot — that would\n // over-report withdrawable funds for Standard / dexAbstraction users.\n const foldIntoCollateral = options?.foldIntoCollateral ?? false;\n const spotBalance = getSpotBalance(spotState);\n const spotHold = getSpotHold(spotState);\n const freeSpot = Math.max(0, spotBalance - spotHold);\n\n const currentTotal = parseFloat(accountState.totalBalance);\n const currentAvailable = parseFloat(accountState.availableBalance);\n\n // Preserve sentinel totals (e.g. PERPS_CONSTANTS.FallbackDataDisplay '--')\n // rather than coercing them to NaN.\n if (!Number.isFinite(currentTotal)) {\n return accountState;\n }\n\n if (spotBalance === 0) {\n return {\n ...accountState,\n availableToTradeBalance: Number.isFinite(currentAvailable)\n ? currentAvailable.toString()\n : accountState.availableBalance,\n };\n }\n\n // Folding is gated strictly on the resolved abstraction mode. Standard /\n // DEX-abstraction users keep perps and spot independent, so spot must NOT\n // surface as a perps-withdrawable balance for them — withdraw3 only draws\n // from the perps ledger in those modes. Unified / portfolio-margin users\n // get the fold; live callers fail-CLOSED via `hyperLiquidModeFoldsSpot`\n // when mode is unresolved (avoids over-reporting funds withdraw3 cannot\n // actually draw during the initial subscription window).\n let availableToTrade = accountState.availableBalance;\n if (foldIntoCollateral) {\n availableToTrade = Number.isFinite(currentAvailable)\n ? (currentAvailable + freeSpot).toString()\n : freeSpot.toString();\n }\n\n // Subtract spotHold to avoid double-counting on Unified/PM accounts:\n // marginSummary.accountValue already includes the margin that HL\n // surfaces via spot.hold. Standard mode has spotHold = 0, no-op.\n const nextTotal = currentTotal + spotBalance - spotHold;\n\n return {\n ...accountState,\n totalBalance: nextTotal.toString(),\n availableToTradeBalance: availableToTrade,\n };\n}\n\n/**\n * Aggregate multiple per-DEX AccountState objects into one by summing numeric fields.\n * ROE is recalculated as (totalUnrealizedPnl / totalMarginUsed) * 100.\n *\n * @param states - The array of per-DEX account states to aggregate.\n * @returns The combined account state with summed balances and recalculated ROE.\n */\nexport function aggregateAccountStates(states: AccountState[]): AccountState {\n const fallback: AccountState = {\n availableBalance: PERPS_CONSTANTS.FallbackDataDisplay,\n totalBalance: PERPS_CONSTANTS.FallbackDataDisplay,\n marginUsed: PERPS_CONSTANTS.FallbackDataDisplay,\n unrealizedPnl: PERPS_CONSTANTS.FallbackDataDisplay,\n returnOnEquity: PERPS_CONSTANTS.FallbackDataDisplay,\n };\n\n if (states.length === 0) {\n return fallback;\n }\n\n const aggregated = states.reduce<AccountState>((acc, state, index) => {\n if (index === 0) {\n return { ...state };\n }\n const accAvailableToTrade = parseFloat(\n acc.availableToTradeBalance ?? acc.availableBalance,\n );\n const stateAvailableToTrade = parseFloat(\n state.availableToTradeBalance ?? state.availableBalance,\n );\n const availableToTradeSum =\n Number.isFinite(accAvailableToTrade) &&\n Number.isFinite(stateAvailableToTrade)\n ? (accAvailableToTrade + stateAvailableToTrade).toString()\n : undefined;\n\n return {\n availableBalance: (\n parseFloat(acc.availableBalance) + parseFloat(state.availableBalance)\n ).toString(),\n ...(availableToTradeSum !== undefined && {\n availableToTradeBalance: availableToTradeSum,\n }),\n totalBalance: (\n parseFloat(acc.totalBalance) + parseFloat(state.totalBalance)\n ).toString(),\n marginUsed: (\n parseFloat(acc.marginUsed) + parseFloat(state.marginUsed)\n ).toString(),\n unrealizedPnl: (\n parseFloat(acc.unrealizedPnl) + parseFloat(state.unrealizedPnl)\n ).toString(),\n returnOnEquity: '0',\n };\n }, fallback);\n\n // Recalculate ROE across all DEXs\n const totalMarginUsed = parseFloat(aggregated.marginUsed);\n const totalUnrealizedPnl = parseFloat(aggregated.unrealizedPnl);\n if (totalMarginUsed > 0) {\n aggregated.returnOnEquity = (\n (totalUnrealizedPnl / totalMarginUsed) *\n 100\n ).toString();\n } else {\n aggregated.returnOnEquity = '0';\n }\n\n return aggregated;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"accountUtils.mjs","sourceRoot":"","sources":["../../src/utils/accountUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Account utilities for Perps components\n * Handles account selection and EVM account filtering\n */\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig';\nimport type { AccountState, PerpsInternalAccount } from '../types';\nimport type { SpotClearinghouseStateResponse } from '../types/hyperliquid-types';\n\nconst EVM_ACCOUNT_TYPES = new Set(['eip155:eoa', 'eip155:erc4337']);\n\nfunction isEvmAccountType(type: string): boolean {\n return EVM_ACCOUNT_TYPES.has(type);\n}\n\nexport function findEvmAccount(\n accounts: (InternalAccount | PerpsInternalAccount)[],\n): InternalAccount | PerpsInternalAccount | null {\n const evmAccount = accounts.find(\n (account) =>\n account && isEvmAccountType(account.type as InternalAccount['type']),\n );\n return evmAccount ?? null;\n}\n\nexport function getEvmAccountFromAccountGroup(\n accounts: (InternalAccount | PerpsInternalAccount)[],\n): { address: string } | undefined {\n const evmAccount = findEvmAccount(accounts);\n return evmAccount ? { address: evmAccount.address } : undefined;\n}\n\nexport function getSelectedEvmAccount(\n accounts: (InternalAccount | PerpsInternalAccount)[],\n): { address: string } | undefined {\n return getEvmAccountFromAccountGroup(accounts);\n}\n\nexport type ReturnOnEquityInput = {\n unrealizedPnl: string | number;\n returnOnEquity: string | number;\n};\n\nexport function calculateWeightedReturnOnEquity(\n accounts: ReturnOnEquityInput[],\n): string {\n if (accounts.length === 0) {\n return '0';\n }\n\n let totalWeightedROE = 0;\n let totalMarginUsed = 0;\n\n for (const account of accounts) {\n const unrealizedPnl =\n typeof account.unrealizedPnl === 'string'\n ? Number.parseFloat(account.unrealizedPnl)\n : account.unrealizedPnl;\n const returnOnEquity =\n typeof account.returnOnEquity === 'string'\n ? Number.parseFloat(account.returnOnEquity)\n : account.returnOnEquity;\n\n if (Number.isNaN(unrealizedPnl) || Number.isNaN(returnOnEquity)) {\n continue;\n }\n\n if (returnOnEquity === 0) {\n continue;\n }\n\n const marginUsed = (unrealizedPnl / returnOnEquity) * 100;\n\n if (Number.isNaN(marginUsed) || marginUsed <= 0) {\n continue;\n }\n\n const roeDecimal = returnOnEquity / 100;\n\n totalWeightedROE += roeDecimal * marginUsed;\n totalMarginUsed += marginUsed;\n }\n\n if (totalMarginUsed <= 0) {\n return '0';\n }\n\n const weightedROE = (totalWeightedROE / totalMarginUsed) * 100;\n return weightedROE.toString();\n}\n\n// The release-branch balance bridge is USDC-only. Non-USDC spot assets must\n// not inflate the balances shown or validated by withdraw/payment flows.\nconst SPOT_COLLATERAL_COINS = new Set<string>(['USDC']);\n\nexport function getSpotBalance(\n spotState?: SpotClearinghouseStateResponse | null,\n): number {\n if (!spotState?.balances || !Array.isArray(spotState.balances)) {\n return 0;\n }\n\n return spotState.balances.reduce(\n (sum: number, balance: { coin?: string; total?: string }) => {\n if (!balance.coin || !SPOT_COLLATERAL_COINS.has(balance.coin)) {\n return sum;\n }\n const value = parseFloat(balance.total ?? '0');\n return Number.isFinite(value) ? sum + value : sum;\n },\n 0,\n );\n}\n\nexport function getSpotHold(\n spotState?: SpotClearinghouseStateResponse | null,\n): number {\n if (!spotState?.balances || !Array.isArray(spotState.balances)) {\n return 0;\n }\n\n return spotState.balances.reduce(\n (sum: number, balance: { coin?: string; hold?: string }) => {\n if (!balance.coin || !SPOT_COLLATERAL_COINS.has(balance.coin)) {\n return sum;\n }\n const value = parseFloat(balance.hold ?? '0');\n return Number.isFinite(value) ? sum + value : sum;\n },\n 0,\n );\n}\n\n/**\n * Options controlling how `addSpotBalanceToAccountState` folds spot balance\n * into the three-field AccountState contract.\n */\nexport type AddSpotBalanceOptions = {\n /**\n * When `true`, free spot USDC contributes to both `spendableBalance` and\n * `withdrawableBalance` in addition to `totalBalance` — appropriate for\n * venues where spot is automatically used as perps collateral (e.g.\n * HyperLiquid Unified/Portfolio mode, where `withdraw3` draws from the\n * unified ledger).\n *\n * When `false`, free spot contributes to `totalBalance` only; spendable\n * and withdrawable stay perps-only — appropriate for venues where spot\n * is a separate ledger the backend cannot auto-draw from (e.g. HL\n * Standard mode). The caller is responsible for translating\n * provider-specific state into this flag.\n *\n * Defaults to `true` for backward compatibility with call sites that\n * haven't yet been wired with provider-specific context.\n */\n foldIntoCollateral?: boolean;\n};\n\n/**\n * Add spot USDC to the AccountState contract. Caller decides whether the\n * spot balance counts as perps collateral via `options.foldIntoCollateral`\n * — the util stays provider-agnostic.\n *\n * @param accountState - Base AccountState produced by a provider adapter.\n * @param spotState - Raw spot clearinghouse response (HL-shaped); null or missing means no spot balance and the state is returned unchanged.\n * @param options - See {@link AddSpotBalanceOptions}.\n * @returns AccountState with spot folded into `totalBalance` always, and into spendable/withdrawable when `foldIntoCollateral` is true.\n */\nexport function addSpotBalanceToAccountState(\n accountState: AccountState,\n spotState?: SpotClearinghouseStateResponse | null,\n options?: AddSpotBalanceOptions,\n): AccountState {\n // Fail-closed default: align with `hyperLiquidModeFoldsSpot(null) → false`.\n // A caller that omits `options` should NOT silently fold spot — that would\n // over-report withdrawable funds for Standard / dexAbstraction users.\n const foldIntoCollateral = options?.foldIntoCollateral ?? false;\n\n const spotBalance = getSpotBalance(spotState);\n const spotHold = getSpotHold(spotState);\n const freeSpot = Math.max(0, spotBalance - spotHold);\n\n const currentTotal = parseFloat(accountState.totalBalance);\n const currentSpendable = parseFloat(accountState.spendableBalance);\n const currentWithdrawable = parseFloat(accountState.withdrawableBalance);\n\n // Preserve sentinel totals (e.g. PERPS_CONSTANTS.FallbackDataDisplay '--')\n // rather than coercing them to NaN.\n if (!Number.isFinite(currentTotal)) {\n return accountState;\n }\n\n if (spotBalance === 0) {\n // No spot wealth means no hold either in the HL payload shape, so the\n // later totalBalance adjustment would also be a no-op.\n return accountState;\n }\n\n // Folding is gated strictly on the resolved abstraction mode (see callers'\n // `foldIntoCollateral` argument). Standard / DEX-abstraction users keep\n // perps and spot independent, so spot must NOT surface as a perps-\n // withdrawable balance for them — withdraw3 only draws from the perps\n // ledger in those modes. Unified / portfolio-margin users get the fold;\n // live callers fail-CLOSED via `hyperLiquidModeFoldsSpot` when mode is\n // unresolved.\n const nextSpendable = resolveFoldedBalance(\n currentSpendable,\n accountState.spendableBalance,\n freeSpot,\n foldIntoCollateral,\n );\n const nextWithdrawable = resolveFoldedBalance(\n currentWithdrawable,\n accountState.withdrawableBalance,\n freeSpot,\n foldIntoCollateral,\n );\n\n // Total always reflects combined wealth: subtract spotHold to avoid\n // double-counting on Unified/PM accounts where marginSummary.accountValue\n // already includes the margin that HL surfaces via spot.hold. Standard\n // mode has spotHold = 0 by construction, so the subtraction is a no-op.\n const nextTotal = currentTotal + spotBalance - spotHold;\n\n return {\n ...accountState,\n totalBalance: nextTotal.toString(),\n spendableBalance: nextSpendable,\n withdrawableBalance: nextWithdrawable,\n };\n}\n\nfunction resolveFoldedBalance(\n currentNumeric: number,\n currentRaw: string,\n freeSpot: number,\n foldIntoCollateral: boolean,\n): string {\n if (!foldIntoCollateral) {\n return currentRaw;\n }\n if (Number.isFinite(currentNumeric)) {\n return (currentNumeric + freeSpot).toString();\n }\n // Non-finite currentNumeric means the adapter passed a sentinel like\n // `PERPS_CONSTANTS.FallbackDataDisplay` (\"--\") during loading. Preserve\n // the sentinel rather than synthesising a numeric fold; the caller's\n // UI treats \"--\" as \"loading\" and would otherwise show a misleading\n // spot-only figure while the per-DEX perps fetch is still in flight.\n return currentRaw;\n}\n\n/**\n * Aggregate multiple per-DEX AccountState objects into one by summing numeric fields.\n * ROE is recalculated as (totalUnrealizedPnl / totalMarginUsed) * 100.\n *\n * @param states - The array of per-DEX account states to aggregate.\n * @returns The combined account state with summed balances and recalculated ROE.\n */\nexport function aggregateAccountStates(states: AccountState[]): AccountState {\n const fallback: AccountState = {\n spendableBalance: PERPS_CONSTANTS.FallbackDataDisplay,\n withdrawableBalance: PERPS_CONSTANTS.FallbackDataDisplay,\n totalBalance: PERPS_CONSTANTS.FallbackDataDisplay,\n marginUsed: PERPS_CONSTANTS.FallbackDataDisplay,\n unrealizedPnl: PERPS_CONSTANTS.FallbackDataDisplay,\n returnOnEquity: PERPS_CONSTANTS.FallbackDataDisplay,\n };\n\n if (states.length === 0) {\n return fallback;\n }\n\n const aggregated = states.reduce<AccountState>((acc, state, index) => {\n if (index === 0) {\n return { ...state };\n }\n\n return {\n spendableBalance: (\n parseFloat(acc.spendableBalance) + parseFloat(state.spendableBalance)\n ).toString(),\n withdrawableBalance: (\n parseFloat(acc.withdrawableBalance) +\n parseFloat(state.withdrawableBalance)\n ).toString(),\n totalBalance: (\n parseFloat(acc.totalBalance) + parseFloat(state.totalBalance)\n ).toString(),\n marginUsed: (\n parseFloat(acc.marginUsed) + parseFloat(state.marginUsed)\n ).toString(),\n unrealizedPnl: (\n parseFloat(acc.unrealizedPnl) + parseFloat(state.unrealizedPnl)\n ).toString(),\n returnOnEquity: '0',\n };\n }, fallback);\n\n // Recalculate ROE across all DEXs\n const totalMarginUsed = parseFloat(aggregated.marginUsed);\n const totalUnrealizedPnl = parseFloat(aggregated.unrealizedPnl);\n if (totalMarginUsed > 0) {\n aggregated.returnOnEquity = (\n (totalUnrealizedPnl / totalMarginUsed) *\n 100\n ).toString();\n } else {\n aggregated.returnOnEquity = '0';\n }\n\n return aggregated;\n}\n"]}
|
|
@@ -204,9 +204,10 @@ function adaptAccountStateFromSDK(perpsState) {
|
|
|
204
204
|
? ((weightedReturnOnEquity / totalMarginUsed) * 100).toString()
|
|
205
205
|
: '0';
|
|
206
206
|
const perpsBalance = parseFloat(perpsState.marginSummary.accountValue);
|
|
207
|
+
const withdrawable = perpsState.withdrawable || '0';
|
|
207
208
|
const accountState = {
|
|
208
|
-
|
|
209
|
-
|
|
209
|
+
spendableBalance: withdrawable,
|
|
210
|
+
withdrawableBalance: withdrawable,
|
|
210
211
|
totalBalance: perpsBalance.toString() || '0',
|
|
211
212
|
marginUsed: perpsState.marginSummary.totalMarginUsed || '0',
|
|
212
213
|
unrealizedPnl: totalUnrealizedPnl.toString() || '0',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hyperLiquidAdapter.cjs","sourceRoot":"","sources":["../../src/utils/hyperLiquidAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { hasProperty, Hex, isHexString } from '@metamask/utils';\n\nimport { HIP3_ASSET_ID_CONFIG } from '../constants/hyperLiquidConfig';\nimport { DECIMAL_PRECISION_CONFIG } from '../constants/perpsConfig';\nimport type {\n AccountState,\n MarketInfo,\n Order,\n OrderParams as PerpsOrderParams,\n Position,\n RawLedgerUpdate,\n UserHistoryItem,\n} from '../types';\nimport type {\n AssetPosition,\n FrontendOrder,\n ClearinghouseStateResponse,\n MetaResponse,\n SDKOrderParams,\n} from '../types/hyperliquid-types';\nimport {\n countSignificantFigures,\n roundToSignificantFigures,\n} from './significantFigures';\n\ntype FrontendOrderWithParentTpsl = FrontendOrder & {\n takeProfitPrice?: unknown;\n stopLossPrice?: unknown;\n takeProfitOrderId?: unknown;\n stopLossOrderId?: unknown;\n};\n\nconst readOptionalString = (value: unknown): string | undefined =>\n typeof value === 'string' && value.length > 0 ? value : undefined;\n\nconst readOptionalOrderId = (value: unknown): string | undefined => {\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value.toString();\n }\n\n return undefined;\n};\n\nconst getParentTpslMetadata = (\n rawOrder: FrontendOrderWithParentTpsl,\n): {\n takeProfitPrice?: string;\n stopLossPrice?: string;\n takeProfitOrderId?: string;\n stopLossOrderId?: string;\n} => ({\n takeProfitPrice: readOptionalString(rawOrder.takeProfitPrice),\n stopLossPrice: readOptionalString(rawOrder.stopLossPrice),\n takeProfitOrderId: readOptionalOrderId(rawOrder.takeProfitOrderId),\n stopLossOrderId: readOptionalOrderId(rawOrder.stopLossOrderId),\n});\n\n/**\n * HyperLiquid SDK Adapter Utilities\n *\n * These functions transform between MetaMask Perps API types and HyperLiquid SDK types.\n * The SDK uses cryptic property names for efficiency, but our API uses descriptive names\n * to provide a consistent interface across different perps protocols.\n */\n\nexport function adaptOrderToSDK(\n order: PerpsOrderParams,\n symbolToAssetId: Map<string, number>,\n): SDKOrderParams {\n const assetId = symbolToAssetId.get(order.symbol);\n if (assetId === undefined) {\n const availableDexs = new Set<string>();\n symbolToAssetId.forEach((_, symbol) => {\n if (symbol.includes(':')) {\n const dex = symbol.split(':')[0];\n availableDexs.add(dex);\n }\n });\n\n const dexHint =\n availableDexs.size > 0\n ? ` Available HIP-3 DEXs: ${Array.from(availableDexs).join(', ')}`\n : ' No HIP-3 DEXs currently available.';\n\n throw new Error(\n `Asset ${order.symbol} not found in asset mapping.${dexHint} Check console logs for \"HyperLiquidProvider: Asset mapping built\" to see available assets.`,\n );\n }\n\n return {\n a: assetId,\n b: order.isBuy,\n p: order.price ?? '0',\n s: order.size,\n r: order.reduceOnly ?? false,\n t:\n order.orderType === 'limit'\n ? {\n limit: { tif: 'Gtc' },\n }\n : {\n limit: { tif: 'FrontendMarket' },\n },\n c:\n order.clientOrderId && isHexString(order.clientOrderId)\n ? (order.clientOrderId as Hex)\n : undefined,\n };\n}\n\nexport function adaptPositionFromSDK(assetPosition: AssetPosition): Position {\n const pos = assetPosition.position;\n return {\n symbol: pos.coin,\n size: pos.szi,\n entryPrice: pos.entryPx,\n positionValue: pos.positionValue,\n unrealizedPnl: pos.unrealizedPnl,\n marginUsed: pos.marginUsed,\n leverage: {\n type: pos.leverage.type,\n value: pos.leverage.value,\n rawUsd:\n pos.leverage.type === 'isolated' ? pos.leverage.rawUsd : undefined,\n },\n liquidationPrice: pos.liquidationPx,\n maxLeverage: pos.maxLeverage,\n returnOnEquity: pos.returnOnEquity,\n cumulativeFunding: pos.cumFunding,\n takeProfitCount: 0,\n stopLossCount: 0,\n };\n}\n\nexport function adaptOrderFromSDK(\n rawOrder: FrontendOrder,\n position?: Position,\n): Order {\n // TODO: Remove this widened boundary type when FrontendOrder includes\n // takeProfitPrice/stopLossPrice and takeProfitOrderId/stopLossOrderId.\n const parentTpslMetadata = getParentTpslMetadata(\n rawOrder as FrontendOrderWithParentTpsl,\n );\n\n // Extract basic fields with appropriate conversions\n const orderId = rawOrder.oid.toString();\n const symbol = rawOrder.coin;\n const side: 'buy' | 'sell' = rawOrder.side === 'B' ? 'buy' : 'sell';\n const detailedOrderType = rawOrder.orderType;\n const { isTrigger } = rawOrder;\n const { reduceOnly } = rawOrder;\n\n let orderType: 'limit' | 'market' = 'market';\n if (detailedOrderType.toLowerCase().includes('limit') || rawOrder.limitPx) {\n orderType = 'limit';\n }\n\n const price = rawOrder.limitPx || rawOrder.triggerPx || '0';\n\n let size = rawOrder.sz;\n let originalSize = rawOrder.origSz || size;\n\n let currentSize = parseFloat(size);\n let origSize = parseFloat(originalSize);\n\n if (rawOrder.isPositionTpsl && origSize === 0 && position) {\n const absPositionSize = Math.abs(parseFloat(position.size));\n currentSize = absPositionSize;\n origSize = absPositionSize;\n size = absPositionSize.toString();\n originalSize = absPositionSize.toString();\n }\n\n const filledSize = origSize - currentSize;\n\n let takeProfitPrice: string | undefined;\n let stopLossPrice: string | undefined;\n let takeProfitOrderId: string | undefined;\n let stopLossOrderId: string | undefined;\n\n // TODO: We assume that there can only be 1 TP and 1 SL as children but there can be several TPSLs as children\n if (rawOrder.children && rawOrder.children.length > 0) {\n rawOrder.children.forEach((childUnknown) => {\n const child = childUnknown as FrontendOrder;\n if (child.isTrigger && child.orderType) {\n if (child.orderType.includes('Take Profit')) {\n takeProfitPrice = child.triggerPx || child.limitPx;\n takeProfitOrderId = child.oid.toString();\n } else if (child.orderType.includes('Stop')) {\n stopLossPrice = child.triggerPx || child.limitPx;\n stopLossOrderId = child.oid.toString();\n }\n }\n });\n }\n\n // Fallback: preserve parent-level TP/SL metadata when children are absent.\n takeProfitPrice ??= parentTpslMetadata.takeProfitPrice;\n stopLossPrice ??= parentTpslMetadata.stopLossPrice;\n takeProfitOrderId ??= parentTpslMetadata.takeProfitOrderId;\n stopLossOrderId ??= parentTpslMetadata.stopLossOrderId;\n\n // Build the order object\n const order: Order = {\n orderId,\n symbol,\n side,\n orderType,\n size,\n originalSize,\n price,\n filledSize: filledSize.toString(),\n remainingSize: size,\n status: 'open' as const,\n timestamp: rawOrder.timestamp,\n detailedOrderType,\n isTrigger,\n reduceOnly,\n };\n\n if (typeof rawOrder.isPositionTpsl === 'boolean') {\n order.isPositionTpsl = rawOrder.isPositionTpsl;\n }\n\n if (takeProfitPrice) {\n order.takeProfitPrice = takeProfitPrice;\n order.takeProfitOrderId = takeProfitOrderId;\n }\n if (stopLossPrice) {\n order.stopLossPrice = stopLossPrice;\n order.stopLossOrderId = stopLossOrderId;\n }\n if (rawOrder.triggerPx) {\n order.triggerPrice = rawOrder.triggerPx;\n }\n\n return order;\n}\n\nexport function adaptMarketFromSDK(\n sdkMarket: MetaResponse['universe'][number],\n): MarketInfo {\n return {\n name: sdkMarket.name,\n szDecimals: sdkMarket.szDecimals,\n maxLeverage: sdkMarket.maxLeverage,\n marginTableId: sdkMarket.marginTableId,\n onlyIsolated: sdkMarket.onlyIsolated,\n isDelisted: sdkMarket.isDelisted,\n };\n}\n\n// Perps-only account adapter. Spot balances are layered on afterwards by\n// addSpotBalanceToAccountState, which enforces the USDC-only policy via\n// SPOT_COLLATERAL_COINS. Keeping spot logic out of here preserves a single\n// source of truth for spot balance math.\nexport function adaptAccountStateFromSDK(\n perpsState: ClearinghouseStateResponse,\n): AccountState {\n const { totalUnrealizedPnl, weightedReturnOnEquity } =\n perpsState.assetPositions.reduce(\n (acc, assetPos: AssetPosition) => {\n const unrealizedPnl = parseFloat(\n assetPos.position.unrealizedPnl || '0',\n );\n const marginUsed = parseFloat(assetPos.position.marginUsed || '0');\n const returnOnEquity = parseFloat(\n assetPos.position.returnOnEquity || '0',\n );\n acc.totalUnrealizedPnl += unrealizedPnl;\n acc.weightedReturnOnEquity += returnOnEquity * marginUsed;\n return acc;\n },\n {\n totalUnrealizedPnl: 0,\n weightedReturnOnEquity: 0,\n },\n );\n const totalMarginUsed = parseFloat(\n perpsState.marginSummary.totalMarginUsed || '0',\n );\n const totalReturnOnEquityPercentage =\n totalMarginUsed > 0\n ? ((weightedReturnOnEquity / totalMarginUsed) * 100).toString()\n : '0';\n\n const perpsBalance = parseFloat(perpsState.marginSummary.accountValue);\n\n const accountState: AccountState = {\n availableBalance: perpsState.withdrawable || '0',\n availableToTradeBalance: perpsState.withdrawable || '0',\n totalBalance: perpsBalance.toString() || '0',\n marginUsed: perpsState.marginSummary.totalMarginUsed || '0',\n unrealizedPnl: totalUnrealizedPnl.toString() || '0',\n returnOnEquity: totalReturnOnEquityPercentage || '0',\n };\n\n return accountState;\n}\n\nexport function buildAssetMapping(params: {\n metaUniverse: MetaResponse['universe'];\n dex?: string | null;\n perpDexIndex: number;\n}): {\n symbolToAssetId: Map<string, number>;\n assetIdToSymbol: Map<number, string>;\n} {\n const { metaUniverse, perpDexIndex } = params;\n const symbolToAssetId = new Map<string, number>();\n const assetIdToSymbol = new Map<number, string>();\n\n metaUniverse.forEach((asset, index) => {\n const assetId = calculateHip3AssetId(perpDexIndex, index);\n symbolToAssetId.set(asset.name, assetId);\n assetIdToSymbol.set(assetId, asset.name);\n });\n\n return { symbolToAssetId, assetIdToSymbol };\n}\n\nexport function formatHyperLiquidPrice(params: {\n price: string | number;\n szDecimals: number;\n}): string {\n const { price, szDecimals } = params;\n const priceNum = typeof price === 'string' ? parseFloat(price) : price;\n\n if (Number.isInteger(priceNum)) {\n return priceNum.toString();\n }\n\n const maxDecimalPlaces =\n DECIMAL_PRECISION_CONFIG.MaxPriceDecimals - szDecimals;\n\n let formattedPrice = priceNum.toFixed(maxDecimalPlaces);\n formattedPrice = parseFloat(formattedPrice).toString();\n\n const significantDigits = countSignificantFigures(formattedPrice);\n\n if (significantDigits > DECIMAL_PRECISION_CONFIG.MaxSignificantFigures) {\n formattedPrice = roundToSignificantFigures(formattedPrice);\n }\n\n return formattedPrice;\n}\n\nexport function formatHyperLiquidSize(params: {\n size: string | number;\n szDecimals: number;\n}): string {\n const { size, szDecimals } = params;\n const number = typeof size === 'string' ? parseFloat(size) : size;\n\n if (isNaN(number)) {\n return '0';\n }\n\n const formatted = number.toFixed(szDecimals);\n\n if (!formatted.includes('.')) {\n return formatted;\n }\n\n return formatted.replace(/\\.?0+$/u, '');\n}\n\nexport function calculatePositionSize(params: {\n usdValue: number;\n leverage: number;\n assetPrice: number;\n}): number {\n const { usdValue, leverage, assetPrice } = params;\n return (usdValue * leverage) / assetPrice;\n}\n\nexport function calculateHip3AssetId(\n perpDexIndex: number,\n indexInMeta: number,\n): number {\n if (perpDexIndex === 0) {\n return indexInMeta;\n }\n return (\n HIP3_ASSET_ID_CONFIG.BaseAssetId +\n perpDexIndex * HIP3_ASSET_ID_CONFIG.DexMultiplier +\n indexInMeta\n );\n}\n\nexport function parseAssetName(assetName: string): {\n dex: string | null;\n symbol: string;\n} {\n const colonIndex = assetName.indexOf(':');\n if (colonIndex === -1) {\n return { dex: null, symbol: assetName };\n }\n return {\n dex: assetName.substring(0, colonIndex),\n symbol: assetName.substring(colonIndex + 1),\n };\n}\n\nexport function adaptHyperLiquidLedgerUpdateToUserHistoryItem(\n rawLedgerUpdates: RawLedgerUpdate[],\n): UserHistoryItem[] {\n return (rawLedgerUpdates || [])\n .filter((update) => {\n if (update.delta.type === 'deposit') {\n return true;\n }\n if (update.delta.type === 'withdraw') {\n return true;\n }\n if (update.delta.type === 'internalTransfer') {\n const usdc = Number.parseFloat(update.delta.usdc ?? '0');\n if (Number.isNaN(usdc)) {\n return false;\n }\n return usdc > 0;\n }\n return false;\n })\n .map((update) => {\n let amount = '0';\n let asset = 'USDC';\n\n if (hasProperty(update.delta, 'usdc') && update.delta.usdc) {\n amount = Math.abs(parseFloat(update.delta.usdc)).toString();\n }\n if (\n hasProperty(update.delta, 'coin') &&\n typeof update.delta.coin === 'string'\n ) {\n asset = update.delta.coin;\n }\n\n return {\n id: `history-${update.hash}`,\n timestamp: update.time,\n amount,\n asset,\n txHash: update.hash,\n status: 'completed' as const,\n type: update.delta.type === 'withdraw' ? 'withdrawal' : 'deposit',\n details: {\n source: '',\n bridgeContract: undefined,\n recipient: undefined,\n blockNumber: undefined,\n chainId: undefined,\n synthetic: undefined,\n },\n };\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"hyperLiquidAdapter.cjs","sourceRoot":"","sources":["../../src/utils/hyperLiquidAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { hasProperty, Hex, isHexString } from '@metamask/utils';\n\nimport { HIP3_ASSET_ID_CONFIG } from '../constants/hyperLiquidConfig';\nimport { DECIMAL_PRECISION_CONFIG } from '../constants/perpsConfig';\nimport type {\n AccountState,\n MarketInfo,\n Order,\n OrderParams as PerpsOrderParams,\n Position,\n RawLedgerUpdate,\n UserHistoryItem,\n} from '../types';\nimport type {\n AssetPosition,\n FrontendOrder,\n ClearinghouseStateResponse,\n MetaResponse,\n SDKOrderParams,\n} from '../types/hyperliquid-types';\nimport {\n countSignificantFigures,\n roundToSignificantFigures,\n} from './significantFigures';\n\ntype FrontendOrderWithParentTpsl = FrontendOrder & {\n takeProfitPrice?: unknown;\n stopLossPrice?: unknown;\n takeProfitOrderId?: unknown;\n stopLossOrderId?: unknown;\n};\n\nconst readOptionalString = (value: unknown): string | undefined =>\n typeof value === 'string' && value.length > 0 ? value : undefined;\n\nconst readOptionalOrderId = (value: unknown): string | undefined => {\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value.toString();\n }\n\n return undefined;\n};\n\nconst getParentTpslMetadata = (\n rawOrder: FrontendOrderWithParentTpsl,\n): {\n takeProfitPrice?: string;\n stopLossPrice?: string;\n takeProfitOrderId?: string;\n stopLossOrderId?: string;\n} => ({\n takeProfitPrice: readOptionalString(rawOrder.takeProfitPrice),\n stopLossPrice: readOptionalString(rawOrder.stopLossPrice),\n takeProfitOrderId: readOptionalOrderId(rawOrder.takeProfitOrderId),\n stopLossOrderId: readOptionalOrderId(rawOrder.stopLossOrderId),\n});\n\n/**\n * HyperLiquid SDK Adapter Utilities\n *\n * These functions transform between MetaMask Perps API types and HyperLiquid SDK types.\n * The SDK uses cryptic property names for efficiency, but our API uses descriptive names\n * to provide a consistent interface across different perps protocols.\n */\n\nexport function adaptOrderToSDK(\n order: PerpsOrderParams,\n symbolToAssetId: Map<string, number>,\n): SDKOrderParams {\n const assetId = symbolToAssetId.get(order.symbol);\n if (assetId === undefined) {\n const availableDexs = new Set<string>();\n symbolToAssetId.forEach((_, symbol) => {\n if (symbol.includes(':')) {\n const dex = symbol.split(':')[0];\n availableDexs.add(dex);\n }\n });\n\n const dexHint =\n availableDexs.size > 0\n ? ` Available HIP-3 DEXs: ${Array.from(availableDexs).join(', ')}`\n : ' No HIP-3 DEXs currently available.';\n\n throw new Error(\n `Asset ${order.symbol} not found in asset mapping.${dexHint} Check console logs for \"HyperLiquidProvider: Asset mapping built\" to see available assets.`,\n );\n }\n\n return {\n a: assetId,\n b: order.isBuy,\n p: order.price ?? '0',\n s: order.size,\n r: order.reduceOnly ?? false,\n t:\n order.orderType === 'limit'\n ? {\n limit: { tif: 'Gtc' },\n }\n : {\n limit: { tif: 'FrontendMarket' },\n },\n c:\n order.clientOrderId && isHexString(order.clientOrderId)\n ? (order.clientOrderId as Hex)\n : undefined,\n };\n}\n\nexport function adaptPositionFromSDK(assetPosition: AssetPosition): Position {\n const pos = assetPosition.position;\n return {\n symbol: pos.coin,\n size: pos.szi,\n entryPrice: pos.entryPx,\n positionValue: pos.positionValue,\n unrealizedPnl: pos.unrealizedPnl,\n marginUsed: pos.marginUsed,\n leverage: {\n type: pos.leverage.type,\n value: pos.leverage.value,\n rawUsd:\n pos.leverage.type === 'isolated' ? pos.leverage.rawUsd : undefined,\n },\n liquidationPrice: pos.liquidationPx,\n maxLeverage: pos.maxLeverage,\n returnOnEquity: pos.returnOnEquity,\n cumulativeFunding: pos.cumFunding,\n takeProfitCount: 0,\n stopLossCount: 0,\n };\n}\n\nexport function adaptOrderFromSDK(\n rawOrder: FrontendOrder,\n position?: Position,\n): Order {\n // TODO: Remove this widened boundary type when FrontendOrder includes\n // takeProfitPrice/stopLossPrice and takeProfitOrderId/stopLossOrderId.\n const parentTpslMetadata = getParentTpslMetadata(\n rawOrder as FrontendOrderWithParentTpsl,\n );\n\n // Extract basic fields with appropriate conversions\n const orderId = rawOrder.oid.toString();\n const symbol = rawOrder.coin;\n const side: 'buy' | 'sell' = rawOrder.side === 'B' ? 'buy' : 'sell';\n const detailedOrderType = rawOrder.orderType;\n const { isTrigger } = rawOrder;\n const { reduceOnly } = rawOrder;\n\n let orderType: 'limit' | 'market' = 'market';\n if (detailedOrderType.toLowerCase().includes('limit') || rawOrder.limitPx) {\n orderType = 'limit';\n }\n\n const price = rawOrder.limitPx || rawOrder.triggerPx || '0';\n\n let size = rawOrder.sz;\n let originalSize = rawOrder.origSz || size;\n\n let currentSize = parseFloat(size);\n let origSize = parseFloat(originalSize);\n\n if (rawOrder.isPositionTpsl && origSize === 0 && position) {\n const absPositionSize = Math.abs(parseFloat(position.size));\n currentSize = absPositionSize;\n origSize = absPositionSize;\n size = absPositionSize.toString();\n originalSize = absPositionSize.toString();\n }\n\n const filledSize = origSize - currentSize;\n\n let takeProfitPrice: string | undefined;\n let stopLossPrice: string | undefined;\n let takeProfitOrderId: string | undefined;\n let stopLossOrderId: string | undefined;\n\n // TODO: We assume that there can only be 1 TP and 1 SL as children but there can be several TPSLs as children\n if (rawOrder.children && rawOrder.children.length > 0) {\n rawOrder.children.forEach((childUnknown) => {\n const child = childUnknown as FrontendOrder;\n if (child.isTrigger && child.orderType) {\n if (child.orderType.includes('Take Profit')) {\n takeProfitPrice = child.triggerPx || child.limitPx;\n takeProfitOrderId = child.oid.toString();\n } else if (child.orderType.includes('Stop')) {\n stopLossPrice = child.triggerPx || child.limitPx;\n stopLossOrderId = child.oid.toString();\n }\n }\n });\n }\n\n // Fallback: preserve parent-level TP/SL metadata when children are absent.\n takeProfitPrice ??= parentTpslMetadata.takeProfitPrice;\n stopLossPrice ??= parentTpslMetadata.stopLossPrice;\n takeProfitOrderId ??= parentTpslMetadata.takeProfitOrderId;\n stopLossOrderId ??= parentTpslMetadata.stopLossOrderId;\n\n // Build the order object\n const order: Order = {\n orderId,\n symbol,\n side,\n orderType,\n size,\n originalSize,\n price,\n filledSize: filledSize.toString(),\n remainingSize: size,\n status: 'open' as const,\n timestamp: rawOrder.timestamp,\n detailedOrderType,\n isTrigger,\n reduceOnly,\n };\n\n if (typeof rawOrder.isPositionTpsl === 'boolean') {\n order.isPositionTpsl = rawOrder.isPositionTpsl;\n }\n\n if (takeProfitPrice) {\n order.takeProfitPrice = takeProfitPrice;\n order.takeProfitOrderId = takeProfitOrderId;\n }\n if (stopLossPrice) {\n order.stopLossPrice = stopLossPrice;\n order.stopLossOrderId = stopLossOrderId;\n }\n if (rawOrder.triggerPx) {\n order.triggerPrice = rawOrder.triggerPx;\n }\n\n return order;\n}\n\nexport function adaptMarketFromSDK(\n sdkMarket: MetaResponse['universe'][number],\n): MarketInfo {\n return {\n name: sdkMarket.name,\n szDecimals: sdkMarket.szDecimals,\n maxLeverage: sdkMarket.maxLeverage,\n marginTableId: sdkMarket.marginTableId,\n onlyIsolated: sdkMarket.onlyIsolated,\n isDelisted: sdkMarket.isDelisted,\n };\n}\n\n// Perps-only account adapter. Spot balances are layered on afterwards by\n// addSpotBalanceToAccountState, which enforces the USDC-only policy via\n// SPOT_COLLATERAL_COINS. Keeping spot logic out of here preserves a single\n// source of truth for spot balance math.\nexport function adaptAccountStateFromSDK(\n perpsState: ClearinghouseStateResponse,\n): AccountState {\n const { totalUnrealizedPnl, weightedReturnOnEquity } =\n perpsState.assetPositions.reduce(\n (acc, assetPos: AssetPosition) => {\n const unrealizedPnl = parseFloat(\n assetPos.position.unrealizedPnl || '0',\n );\n const marginUsed = parseFloat(assetPos.position.marginUsed || '0');\n const returnOnEquity = parseFloat(\n assetPos.position.returnOnEquity || '0',\n );\n acc.totalUnrealizedPnl += unrealizedPnl;\n acc.weightedReturnOnEquity += returnOnEquity * marginUsed;\n return acc;\n },\n {\n totalUnrealizedPnl: 0,\n weightedReturnOnEquity: 0,\n },\n );\n const totalMarginUsed = parseFloat(\n perpsState.marginSummary.totalMarginUsed || '0',\n );\n const totalReturnOnEquityPercentage =\n totalMarginUsed > 0\n ? ((weightedReturnOnEquity / totalMarginUsed) * 100).toString()\n : '0';\n\n const perpsBalance = parseFloat(perpsState.marginSummary.accountValue);\n\n const withdrawable = perpsState.withdrawable || '0';\n const accountState: AccountState = {\n spendableBalance: withdrawable,\n withdrawableBalance: withdrawable,\n totalBalance: perpsBalance.toString() || '0',\n marginUsed: perpsState.marginSummary.totalMarginUsed || '0',\n unrealizedPnl: totalUnrealizedPnl.toString() || '0',\n returnOnEquity: totalReturnOnEquityPercentage || '0',\n };\n\n return accountState;\n}\n\nexport function buildAssetMapping(params: {\n metaUniverse: MetaResponse['universe'];\n dex?: string | null;\n perpDexIndex: number;\n}): {\n symbolToAssetId: Map<string, number>;\n assetIdToSymbol: Map<number, string>;\n} {\n const { metaUniverse, perpDexIndex } = params;\n const symbolToAssetId = new Map<string, number>();\n const assetIdToSymbol = new Map<number, string>();\n\n metaUniverse.forEach((asset, index) => {\n const assetId = calculateHip3AssetId(perpDexIndex, index);\n symbolToAssetId.set(asset.name, assetId);\n assetIdToSymbol.set(assetId, asset.name);\n });\n\n return { symbolToAssetId, assetIdToSymbol };\n}\n\nexport function formatHyperLiquidPrice(params: {\n price: string | number;\n szDecimals: number;\n}): string {\n const { price, szDecimals } = params;\n const priceNum = typeof price === 'string' ? parseFloat(price) : price;\n\n if (Number.isInteger(priceNum)) {\n return priceNum.toString();\n }\n\n const maxDecimalPlaces =\n DECIMAL_PRECISION_CONFIG.MaxPriceDecimals - szDecimals;\n\n let formattedPrice = priceNum.toFixed(maxDecimalPlaces);\n formattedPrice = parseFloat(formattedPrice).toString();\n\n const significantDigits = countSignificantFigures(formattedPrice);\n\n if (significantDigits > DECIMAL_PRECISION_CONFIG.MaxSignificantFigures) {\n formattedPrice = roundToSignificantFigures(formattedPrice);\n }\n\n return formattedPrice;\n}\n\nexport function formatHyperLiquidSize(params: {\n size: string | number;\n szDecimals: number;\n}): string {\n const { size, szDecimals } = params;\n const number = typeof size === 'string' ? parseFloat(size) : size;\n\n if (isNaN(number)) {\n return '0';\n }\n\n const formatted = number.toFixed(szDecimals);\n\n if (!formatted.includes('.')) {\n return formatted;\n }\n\n return formatted.replace(/\\.?0+$/u, '');\n}\n\nexport function calculatePositionSize(params: {\n usdValue: number;\n leverage: number;\n assetPrice: number;\n}): number {\n const { usdValue, leverage, assetPrice } = params;\n return (usdValue * leverage) / assetPrice;\n}\n\nexport function calculateHip3AssetId(\n perpDexIndex: number,\n indexInMeta: number,\n): number {\n if (perpDexIndex === 0) {\n return indexInMeta;\n }\n return (\n HIP3_ASSET_ID_CONFIG.BaseAssetId +\n perpDexIndex * HIP3_ASSET_ID_CONFIG.DexMultiplier +\n indexInMeta\n );\n}\n\nexport function parseAssetName(assetName: string): {\n dex: string | null;\n symbol: string;\n} {\n const colonIndex = assetName.indexOf(':');\n if (colonIndex === -1) {\n return { dex: null, symbol: assetName };\n }\n return {\n dex: assetName.substring(0, colonIndex),\n symbol: assetName.substring(colonIndex + 1),\n };\n}\n\nexport function adaptHyperLiquidLedgerUpdateToUserHistoryItem(\n rawLedgerUpdates: RawLedgerUpdate[],\n): UserHistoryItem[] {\n return (rawLedgerUpdates || [])\n .filter((update) => {\n if (update.delta.type === 'deposit') {\n return true;\n }\n if (update.delta.type === 'withdraw') {\n return true;\n }\n if (update.delta.type === 'internalTransfer') {\n const usdc = Number.parseFloat(update.delta.usdc ?? '0');\n if (Number.isNaN(usdc)) {\n return false;\n }\n return usdc > 0;\n }\n return false;\n })\n .map((update) => {\n let amount = '0';\n let asset = 'USDC';\n\n if (hasProperty(update.delta, 'usdc') && update.delta.usdc) {\n amount = Math.abs(parseFloat(update.delta.usdc)).toString();\n }\n if (\n hasProperty(update.delta, 'coin') &&\n typeof update.delta.coin === 'string'\n ) {\n asset = update.delta.coin;\n }\n\n return {\n id: `history-${update.hash}`,\n timestamp: update.time,\n amount,\n asset,\n txHash: update.hash,\n status: 'completed' as const,\n type: update.delta.type === 'withdraw' ? 'withdrawal' : 'deposit',\n details: {\n source: '',\n bridgeContract: undefined,\n recipient: undefined,\n blockNumber: undefined,\n chainId: undefined,\n synthetic: undefined,\n },\n };\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hyperLiquidAdapter.d.cts","sourceRoot":"","sources":["../../src/utils/hyperLiquidAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,KAAK,EACL,WAAW,IAAI,gBAAgB,EAC/B,QAAQ,EACR,eAAe,EACf,eAAe,EAChB,2BAAiB;AAClB,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,cAAc,EACf,uCAAmC;AA0CpC;;;;;;GAMG;AAEH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,cAAc,CAwChB;AAED,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,aAAa,GAAG,QAAQ,CAsB3E;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,QAAQ,CAAC,EAAE,QAAQ,GAClB,KAAK,CAoGP;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAC1C,UAAU,CASZ;AAMD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,0BAA0B,GACrC,YAAY,
|
|
1
|
+
{"version":3,"file":"hyperLiquidAdapter.d.cts","sourceRoot":"","sources":["../../src/utils/hyperLiquidAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,KAAK,EACL,WAAW,IAAI,gBAAgB,EAC/B,QAAQ,EACR,eAAe,EACf,eAAe,EAChB,2BAAiB;AAClB,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,cAAc,EACf,uCAAmC;AA0CpC;;;;;;GAMG;AAEH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,cAAc,CAwChB;AAED,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,aAAa,GAAG,QAAQ,CAsB3E;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,QAAQ,CAAC,EAAE,QAAQ,GAClB,KAAK,CAoGP;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAC1C,UAAU,CASZ;AAMD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,0BAA0B,GACrC,YAAY,CAyCd;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACvC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG;IACF,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CAYA;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAqBT;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAeT;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAGT;AAED,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CASR;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;IACjD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CASA;AAED,wBAAgB,6CAA6C,CAC3D,gBAAgB,EAAE,eAAe,EAAE,GAClC,eAAe,EAAE,CAkDnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hyperLiquidAdapter.d.mts","sourceRoot":"","sources":["../../src/utils/hyperLiquidAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,KAAK,EACL,WAAW,IAAI,gBAAgB,EAC/B,QAAQ,EACR,eAAe,EACf,eAAe,EAChB,2BAAiB;AAClB,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,cAAc,EACf,uCAAmC;AA0CpC;;;;;;GAMG;AAEH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,cAAc,CAwChB;AAED,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,aAAa,GAAG,QAAQ,CAsB3E;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,QAAQ,CAAC,EAAE,QAAQ,GAClB,KAAK,CAoGP;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAC1C,UAAU,CASZ;AAMD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,0BAA0B,GACrC,YAAY,
|
|
1
|
+
{"version":3,"file":"hyperLiquidAdapter.d.mts","sourceRoot":"","sources":["../../src/utils/hyperLiquidAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,KAAK,EACL,WAAW,IAAI,gBAAgB,EAC/B,QAAQ,EACR,eAAe,EACf,eAAe,EAChB,2BAAiB;AAClB,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,cAAc,EACf,uCAAmC;AA0CpC;;;;;;GAMG;AAEH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,cAAc,CAwChB;AAED,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,aAAa,GAAG,QAAQ,CAsB3E;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,QAAQ,CAAC,EAAE,QAAQ,GAClB,KAAK,CAoGP;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAC1C,UAAU,CASZ;AAMD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,0BAA0B,GACrC,YAAY,CAyCd;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACvC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG;IACF,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CAYA;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAqBT;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAeT;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAGT;AAED,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CASR;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;IACjD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CASA;AAED,wBAAgB,6CAA6C,CAC3D,gBAAgB,EAAE,eAAe,EAAE,GAClC,eAAe,EAAE,CAkDnB"}
|
|
@@ -197,9 +197,10 @@ export function adaptAccountStateFromSDK(perpsState) {
|
|
|
197
197
|
? ((weightedReturnOnEquity / totalMarginUsed) * 100).toString()
|
|
198
198
|
: '0';
|
|
199
199
|
const perpsBalance = parseFloat(perpsState.marginSummary.accountValue);
|
|
200
|
+
const withdrawable = perpsState.withdrawable || '0';
|
|
200
201
|
const accountState = {
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
spendableBalance: withdrawable,
|
|
203
|
+
withdrawableBalance: withdrawable,
|
|
203
204
|
totalBalance: perpsBalance.toString() || '0',
|
|
204
205
|
marginUsed: perpsState.marginSummary.totalMarginUsed || '0',
|
|
205
206
|
unrealizedPnl: totalUnrealizedPnl.toString() || '0',
|