@lifi/perps-sdk-provider-hyperliquid 12.1.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/HyperliquidProvider.d.ts.map +1 -1
- package/dist/cjs/HyperliquidProvider.js +2 -0
- package/dist/cjs/HyperliquidProvider.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/services/getAccount.d.ts.map +1 -1
- package/dist/cjs/services/getAccount.js +2 -3
- package/dist/cjs/services/getAccount.js.map +1 -1
- package/dist/cjs/services/getPortfolioHistory.d.ts +10 -0
- package/dist/cjs/services/getPortfolioHistory.d.ts.map +1 -0
- package/dist/cjs/services/getPortfolioHistory.js +59 -0
- package/dist/cjs/services/getPortfolioHistory.js.map +1 -0
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/portfolio.d.ts +9 -0
- package/dist/cjs/types/portfolio.d.ts.map +1 -0
- package/dist/cjs/types/portfolio.js +3 -0
- package/dist/cjs/types/portfolio.js.map +1 -0
- package/dist/cjs/utils/abstractionMode.d.ts +3 -0
- package/dist/cjs/utils/abstractionMode.d.ts.map +1 -0
- package/dist/cjs/utils/abstractionMode.js +8 -0
- package/dist/cjs/utils/abstractionMode.js.map +1 -0
- package/dist/cjs/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.js +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/esm/HyperliquidProvider.d.ts.map +1 -1
- package/dist/esm/HyperliquidProvider.js +2 -0
- package/dist/esm/HyperliquidProvider.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/services/getAccount.d.ts.map +1 -1
- package/dist/esm/services/getAccount.js +2 -3
- package/dist/esm/services/getAccount.js.map +1 -1
- package/dist/esm/services/getPortfolioHistory.d.ts +18 -0
- package/dist/esm/services/getPortfolioHistory.d.ts.map +1 -0
- package/dist/esm/services/getPortfolioHistory.js +71 -0
- package/dist/esm/services/getPortfolioHistory.js.map +1 -0
- package/dist/esm/types/index.d.ts +1 -0
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/types/portfolio.d.ts +17 -0
- package/dist/esm/types/portfolio.d.ts.map +1 -0
- package/dist/esm/types/portfolio.js +3 -0
- package/dist/esm/types/portfolio.js.map +1 -0
- package/dist/esm/utils/abstractionMode.d.ts +8 -0
- package/dist/esm/utils/abstractionMode.d.ts.map +1 -0
- package/dist/esm/utils/abstractionMode.js +9 -0
- package/dist/esm/utils/abstractionMode.js.map +1 -0
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts +1 -1
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/HyperliquidWsProvider.js +2 -2
- package/dist/esm/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/types/HyperliquidProvider.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/services/getAccount.d.ts.map +1 -1
- package/dist/types/services/getPortfolioHistory.d.ts +18 -0
- package/dist/types/services/getPortfolioHistory.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/types/portfolio.d.ts +17 -0
- package/dist/types/types/portfolio.d.ts.map +1 -0
- package/dist/types/utils/abstractionMode.d.ts +8 -0
- package/dist/types/utils/abstractionMode.d.ts.map +1 -0
- package/dist/types/websocket/HyperliquidWsProvider.d.ts +1 -1
- package/dist/types/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/HyperliquidProvider.ts +13 -0
- package/src/index.ts +2 -0
- package/src/services/getAccount.ts +2 -5
- package/src/services/getPortfolioHistory.ts +118 -0
- package/src/types/index.ts +1 -0
- package/src/types/portfolio.ts +29 -0
- package/src/utils/abstractionMode.ts +12 -0
- package/src/websocket/HyperliquidWsProvider.ts +8 -5
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** `[Unix milliseconds, decimal string]` sample of one portfolio series. @public */
|
|
2
|
+
export type HlPortfolioSample = [number, string];
|
|
3
|
+
/**
|
|
4
|
+
* One window of the Hyperliquid `portfolio` info response. `vlm` is the
|
|
5
|
+
* traded volume in the window; `pnlHistory` is cumulative from its start.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export type HlPortfolioWindow = {
|
|
9
|
+
accountValueHistory: HlPortfolioSample[];
|
|
10
|
+
pnlHistory: HlPortfolioSample[];
|
|
11
|
+
vlm: string;
|
|
12
|
+
};
|
|
13
|
+
/** Hyperliquid `portfolio` window keys. @public */
|
|
14
|
+
export type HlPortfolioPeriod = 'day' | 'week' | 'month' | 'allTime' | 'perpDay' | 'perpWeek' | 'perpMonth' | 'perpAllTime';
|
|
15
|
+
/** Hyperliquid `portfolio` info response: a list of `[period, window]` pairs. @public */
|
|
16
|
+
export type HlPortfolio = [HlPortfolioPeriod, HlPortfolioWindow][];
|
|
17
|
+
//# sourceMappingURL=portfolio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio.d.ts","sourceRoot":"","sources":["../../../src/types/portfolio.ts"],"names":[],"mappings":"AAEA,oFAAoF;AACpF,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAEhD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,mBAAmB,EAAE,iBAAiB,EAAE,CAAA;IACxC,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,mDAAmD;AACnD,MAAM,MAAM,iBAAiB,GACzB,KAAK,GACL,MAAM,GACN,OAAO,GACP,SAAS,GACT,SAAS,GACT,UAAU,GACV,WAAW,GACX,aAAa,CAAA;AAEjB,yFAAyF;AACzF,MAAM,MAAM,WAAW,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { HlAbstractionMode } from '../types/account.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether the mode holds the account's collateral in spot. Unified and
|
|
4
|
+
* portfolio-margin accounts do; every other mode keeps perps collateral
|
|
5
|
+
* per-dex, apart from the spot balances.
|
|
6
|
+
*/
|
|
7
|
+
export declare const isUnifiedAbstraction: (abstraction: HlAbstractionMode | null) => boolean;
|
|
8
|
+
//# sourceMappingURL=abstractionMode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstractionMode.d.ts","sourceRoot":"","sources":["../../../src/utils/abstractionMode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEvD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,aAAa,iBAAiB,GAAG,IAAI,KACpC,OAEiD,CAAA"}
|
|
@@ -11,7 +11,7 @@ import type { Subscription } from '@lifi/perps-types';
|
|
|
11
11
|
*/
|
|
12
12
|
export declare const hyperliquidWsProvider: () => WsProviderFactory;
|
|
13
13
|
/**
|
|
14
|
-
* Hyperliquid
|
|
14
|
+
* Hyperliquid WebSocket {@link WsProvider}: multiplexes markets context,
|
|
15
15
|
* positions, orders, fills and spot balances over a single
|
|
16
16
|
* {@link ReconnectingWebSocket}.
|
|
17
17
|
* Construct via {@link hyperliquidWsProvider}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HyperliquidWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/HyperliquidWsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAGzB,cAAc,EACd,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"HyperliquidWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/HyperliquidWsProvider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/perps-sdk-provider-hyperliquid",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "Hyperliquid provider plugin for @lifi/perps-sdk",
|
|
5
5
|
"homepage": "https://github.com/lifinance/perps-sdk",
|
|
6
6
|
"bugs": {
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"big.js": "^7.0.1",
|
|
51
51
|
"viem": "^2.55.18",
|
|
52
|
-
"@lifi/perps-types": "^12.
|
|
52
|
+
"@lifi/perps-types": "^12.3.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@lifi/perps-sdk": "^
|
|
55
|
+
"@lifi/perps-sdk": "^13.0.0"
|
|
56
56
|
},
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
type ProviderGetMarketSettingsParams,
|
|
15
15
|
type ProviderGetOrderParams,
|
|
16
16
|
type ProviderGetOrdersParams,
|
|
17
|
+
type ProviderGetPortfolioHistoryParams,
|
|
17
18
|
type ProviderGetPositionsParams,
|
|
18
19
|
type ProviderGetQuoteParams,
|
|
19
20
|
type ProviderGetRunningTwapsParams,
|
|
@@ -38,6 +39,7 @@ import {
|
|
|
38
39
|
PerpsErrorCode,
|
|
39
40
|
type PerpsMarket,
|
|
40
41
|
PerpsSigner,
|
|
42
|
+
type PortfolioHistoryResponse,
|
|
41
43
|
type Position,
|
|
42
44
|
type PositionsResponse,
|
|
43
45
|
type ProviderAction,
|
|
@@ -63,6 +65,7 @@ import { getFills } from './services/getFills.js'
|
|
|
63
65
|
import { getMarketSettings } from './services/getMarketSettings.js'
|
|
64
66
|
import { getOrder } from './services/getOrder.js'
|
|
65
67
|
import { getOrders } from './services/getOrders.js'
|
|
68
|
+
import { getPortfolioHistory } from './services/getPortfolioHistory.js'
|
|
66
69
|
import { getPositions } from './services/getPositions.js'
|
|
67
70
|
import { getRunningTwaps } from './services/getRunningTwaps.js'
|
|
68
71
|
import {
|
|
@@ -387,6 +390,16 @@ export function hyperliquidProvider(
|
|
|
387
390
|
opts
|
|
388
391
|
),
|
|
389
392
|
|
|
393
|
+
getPortfolioHistory: (
|
|
394
|
+
params: ProviderGetPortfolioHistoryParams,
|
|
395
|
+
opts?: SDKRequestOptions
|
|
396
|
+
): Promise<PortfolioHistoryResponse> =>
|
|
397
|
+
getPortfolioHistory(
|
|
398
|
+
contextRef.require(),
|
|
399
|
+
{ address: params.address, range: params.range },
|
|
400
|
+
opts
|
|
401
|
+
),
|
|
402
|
+
|
|
390
403
|
getQuote: (
|
|
391
404
|
params: ProviderGetQuoteParams,
|
|
392
405
|
opts?: SDKRequestOptions
|
package/src/index.ts
CHANGED
|
@@ -35,6 +35,8 @@ export type { GetOrderParams } from './services/getOrder.js'
|
|
|
35
35
|
export { getOrder } from './services/getOrder.js'
|
|
36
36
|
export type { GetOrdersParams } from './services/getOrders.js'
|
|
37
37
|
export { getOrders } from './services/getOrders.js'
|
|
38
|
+
export type { GetPortfolioHistoryParams } from './services/getPortfolioHistory.js'
|
|
39
|
+
export { getPortfolioHistory } from './services/getPortfolioHistory.js'
|
|
38
40
|
export type { GetPositionsParams } from './services/getPositions.js'
|
|
39
41
|
export { getPositions } from './services/getPositions.js'
|
|
40
42
|
export type { GetRunningTwapsParams } from './services/getRunningTwaps.js'
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
type HlSpotClearinghouseState,
|
|
24
24
|
type HlUserFees,
|
|
25
25
|
} from '../types/index.js'
|
|
26
|
+
import { isUnifiedAbstraction } from '../utils/abstractionMode.js'
|
|
26
27
|
import { toWireBig } from '../utils/decimal.js'
|
|
27
28
|
import {
|
|
28
29
|
partitionSpotBalances,
|
|
@@ -83,10 +84,6 @@ const getMarginUsed = (
|
|
|
83
84
|
return getTotalMarginUsed(mainState).toString()
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
const isUnifiedMode = (abstraction: HlAbstractionMode | null): boolean =>
|
|
87
|
-
abstraction === HlAbstractionMode.UNIFIED_ACCOUNT ||
|
|
88
|
-
abstraction === HlAbstractionMode.PORTFOLIO_MARGIN
|
|
89
|
-
|
|
90
87
|
interface BalancePartition {
|
|
91
88
|
balances: Balance[]
|
|
92
89
|
collateralBalances: Balance[]
|
|
@@ -112,7 +109,7 @@ const buildBalances = (
|
|
|
112
109
|
// double-count. Only disabled/dexAbstraction carry separate venue collateral.
|
|
113
110
|
// `accountValue` is the dex's TOTAL equity: locked margin and unrealized
|
|
114
111
|
// PnL are already included, so summaries must not add them on top.
|
|
115
|
-
if (!
|
|
112
|
+
if (!isUnifiedAbstraction(abstraction)) {
|
|
116
113
|
for (const [dex, state] of stateByDex) {
|
|
117
114
|
const categoryId = dex || PROVIDER_KEY
|
|
118
115
|
const value = getAccountValue(state)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { PerpsError, type SDKRequestOptions } from '@lifi/perps-sdk'
|
|
2
|
+
import {
|
|
3
|
+
PerpsErrorCode,
|
|
4
|
+
type PortfolioHistoryPoint,
|
|
5
|
+
type PortfolioHistoryRange,
|
|
6
|
+
type PortfolioHistoryResponse,
|
|
7
|
+
} from '@lifi/perps-types'
|
|
8
|
+
import type { Address } from 'viem'
|
|
9
|
+
import type { HyperliquidContext } from '../context.js'
|
|
10
|
+
import type {
|
|
11
|
+
HlAbstractionMode,
|
|
12
|
+
HlPortfolio,
|
|
13
|
+
HlPortfolioPeriod,
|
|
14
|
+
HlPortfolioWindow,
|
|
15
|
+
} from '../types/index.js'
|
|
16
|
+
import { isUnifiedAbstraction } from '../utils/abstractionMode.js'
|
|
17
|
+
import { hlInfoOptions, infoRequest } from '../utils/infoClient.js'
|
|
18
|
+
|
|
19
|
+
/** Parameters for {@link getPortfolioHistory}. @public */
|
|
20
|
+
export interface GetPortfolioHistoryParams {
|
|
21
|
+
address: Address
|
|
22
|
+
range: PortfolioHistoryRange
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const COMBINED_PERIOD_BY_RANGE: Record<
|
|
26
|
+
PortfolioHistoryRange,
|
|
27
|
+
HlPortfolioPeriod
|
|
28
|
+
> = {
|
|
29
|
+
'24h': 'day',
|
|
30
|
+
'7d': 'week',
|
|
31
|
+
'30d': 'month',
|
|
32
|
+
all: 'allTime',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const PERP_PERIOD_BY_RANGE: Record<PortfolioHistoryRange, HlPortfolioPeriod> = {
|
|
36
|
+
'24h': 'perpDay',
|
|
37
|
+
'7d': 'perpWeek',
|
|
38
|
+
'30d': 'perpMonth',
|
|
39
|
+
all: 'perpAllTime',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Join the window's two series on their timestamps. `pnlHistory` is cumulative
|
|
44
|
+
* from the window's start, so a point with no PnL sample carries the last
|
|
45
|
+
* sampled value — `'0'` before the first one.
|
|
46
|
+
*/
|
|
47
|
+
const joinWindow = (
|
|
48
|
+
window: HlPortfolioWindow,
|
|
49
|
+
period: HlPortfolioPeriod
|
|
50
|
+
): PortfolioHistoryPoint[] => {
|
|
51
|
+
const pnlByTimestamp = new Map(window.pnlHistory)
|
|
52
|
+
let matched = 0
|
|
53
|
+
let cumulative = '0'
|
|
54
|
+
const points = window.accountValueHistory.map(([timestamp, accountValue]) => {
|
|
55
|
+
const sample = pnlByTimestamp.get(timestamp)
|
|
56
|
+
if (sample !== undefined) {
|
|
57
|
+
matched += 1
|
|
58
|
+
cumulative = sample
|
|
59
|
+
}
|
|
60
|
+
return { timestamp, accountValue, pnl: cumulative }
|
|
61
|
+
})
|
|
62
|
+
if (points.length > 0 && window.pnlHistory.length > 0 && matched === 0) {
|
|
63
|
+
throw new PerpsError(
|
|
64
|
+
PerpsErrorCode.ThirdPartyError,
|
|
65
|
+
`Hyperliquid portfolio window '${period}' samples PnL on no ` +
|
|
66
|
+
'account-value timestamp.'
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
return points
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Read the account's portfolio value and cumulative PnL for `params.range`
|
|
74
|
+
* from one `portfolio` info request. An account whose collateral lives
|
|
75
|
+
* per-dex reads the perps-only window; a unified or portfolio-margin account
|
|
76
|
+
* holds its collateral in spot, so it reads the combined window.
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export async function getPortfolioHistory(
|
|
80
|
+
ctx: HyperliquidContext,
|
|
81
|
+
params: GetPortfolioHistoryParams,
|
|
82
|
+
options?: SDKRequestOptions
|
|
83
|
+
): Promise<PortfolioHistoryResponse> {
|
|
84
|
+
const { client, apiUrl } = ctx
|
|
85
|
+
const infoOpts = hlInfoOptions(client, options)
|
|
86
|
+
const [portfolio, abstraction] = await Promise.all([
|
|
87
|
+
infoRequest<HlPortfolio>(
|
|
88
|
+
apiUrl,
|
|
89
|
+
{ type: 'portfolio', user: params.address },
|
|
90
|
+
infoOpts
|
|
91
|
+
),
|
|
92
|
+
// "Never set abstraction" is a successful 200 `null` body, not an error —
|
|
93
|
+
// so a fetch failure must propagate, never be coerced to `null` (which
|
|
94
|
+
// would silently read the combined window for a perps-only account).
|
|
95
|
+
infoRequest<HlAbstractionMode | null>(
|
|
96
|
+
apiUrl,
|
|
97
|
+
{ type: 'userAbstraction', user: params.address },
|
|
98
|
+
infoOpts
|
|
99
|
+
),
|
|
100
|
+
])
|
|
101
|
+
const period = isUnifiedAbstraction(abstraction)
|
|
102
|
+
? COMBINED_PERIOD_BY_RANGE[params.range]
|
|
103
|
+
: PERP_PERIOD_BY_RANGE[params.range]
|
|
104
|
+
const window = portfolio.find(([key]) => key === period)?.[1]
|
|
105
|
+
if (window === undefined) {
|
|
106
|
+
throw new PerpsError(
|
|
107
|
+
PerpsErrorCode.ThirdPartyError,
|
|
108
|
+
`Hyperliquid portfolio response has no '${period}' window.`
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
range: params.range,
|
|
114
|
+
points: joinWindow(window, period),
|
|
115
|
+
volume: window.vlm,
|
|
116
|
+
totalPnl: window.pnlHistory.at(-1)?.[1],
|
|
117
|
+
}
|
|
118
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// `portfolio` info response shapes.
|
|
2
|
+
|
|
3
|
+
/** `[Unix milliseconds, decimal string]` sample of one portfolio series. @public */
|
|
4
|
+
export type HlPortfolioSample = [number, string]
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* One window of the Hyperliquid `portfolio` info response. `vlm` is the
|
|
8
|
+
* traded volume in the window; `pnlHistory` is cumulative from its start.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export type HlPortfolioWindow = {
|
|
12
|
+
accountValueHistory: HlPortfolioSample[]
|
|
13
|
+
pnlHistory: HlPortfolioSample[]
|
|
14
|
+
vlm: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Hyperliquid `portfolio` window keys. @public */
|
|
18
|
+
export type HlPortfolioPeriod =
|
|
19
|
+
| 'day'
|
|
20
|
+
| 'week'
|
|
21
|
+
| 'month'
|
|
22
|
+
| 'allTime'
|
|
23
|
+
| 'perpDay'
|
|
24
|
+
| 'perpWeek'
|
|
25
|
+
| 'perpMonth'
|
|
26
|
+
| 'perpAllTime'
|
|
27
|
+
|
|
28
|
+
/** Hyperliquid `portfolio` info response: a list of `[period, window]` pairs. @public */
|
|
29
|
+
export type HlPortfolio = [HlPortfolioPeriod, HlPortfolioWindow][]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { HlAbstractionMode } from '../types/account.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Whether the mode holds the account's collateral in spot. Unified and
|
|
5
|
+
* portfolio-margin accounts do; every other mode keeps perps collateral
|
|
6
|
+
* per-dex, apart from the spot balances.
|
|
7
|
+
*/
|
|
8
|
+
export const isUnifiedAbstraction = (
|
|
9
|
+
abstraction: HlAbstractionMode | null
|
|
10
|
+
): boolean =>
|
|
11
|
+
abstraction === HlAbstractionMode.UNIFIED_ACCOUNT ||
|
|
12
|
+
abstraction === HlAbstractionMode.PORTFOLIO_MARGIN
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
toPerpsMarketDisplay,
|
|
14
14
|
WsProviderBase,
|
|
15
15
|
type WsProviderFactory,
|
|
16
|
+
type WsProviderFactoryParams,
|
|
16
17
|
type WsStatusListener,
|
|
17
18
|
wsLog,
|
|
18
19
|
} from '@lifi/perps-sdk'
|
|
@@ -95,13 +96,15 @@ const normalizeHlAddress = (address: string): string =>
|
|
|
95
96
|
*
|
|
96
97
|
* @public
|
|
97
98
|
*/
|
|
98
|
-
export const hyperliquidWsProvider =
|
|
99
|
-
(
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
export const hyperliquidWsProvider = (): WsProviderFactory =>
|
|
100
|
+
Object.assign(
|
|
101
|
+
({ provider, wsUrl, client }: WsProviderFactoryParams) =>
|
|
102
|
+
new HyperliquidWsProvider(wsUrl, provider, client),
|
|
103
|
+
{ streamsCandles: true }
|
|
104
|
+
)
|
|
102
105
|
|
|
103
106
|
/**
|
|
104
|
-
* Hyperliquid
|
|
107
|
+
* Hyperliquid WebSocket {@link WsProvider}: multiplexes markets context,
|
|
105
108
|
* positions, orders, fills and spot balances over a single
|
|
106
109
|
* {@link ReconnectingWebSocket}.
|
|
107
110
|
* Construct via {@link hyperliquidWsProvider}.
|