@lifi/perps-sdk-provider-hyperliquid 13.0.1 → 14.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/README.md +115 -0
- package/dist/cjs/HyperliquidProvider.d.ts.map +1 -1
- package/dist/cjs/HyperliquidProvider.js +1 -2
- package/dist/cjs/HyperliquidProvider.js.map +1 -1
- package/dist/cjs/constants.d.ts +1 -0
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +2 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +2 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/services/getAccount.d.ts.map +1 -1
- package/dist/cjs/services/getAccount.js +5 -2
- package/dist/cjs/services/getAccount.js.map +1 -1
- package/dist/cjs/services/getActivity.d.ts.map +1 -1
- package/dist/cjs/services/getActivity.js +40 -7
- package/dist/cjs/services/getActivity.js.map +1 -1
- package/dist/cjs/services/getFills.d.ts.map +1 -1
- package/dist/cjs/services/getFills.js +3 -0
- package/dist/cjs/services/getFills.js.map +1 -1
- package/dist/cjs/services/getOrder.d.ts.map +1 -1
- package/dist/cjs/services/getOrder.js +14 -3
- package/dist/cjs/services/getOrder.js.map +1 -1
- package/dist/cjs/services/getOrders.d.ts +2 -7
- package/dist/cjs/services/getOrders.d.ts.map +1 -1
- package/dist/cjs/services/getOrders.js +94 -31
- package/dist/cjs/services/getOrders.js.map +1 -1
- package/dist/cjs/services/getPositions.d.ts.map +1 -1
- package/dist/cjs/services/getPositions.js +1 -1
- package/dist/cjs/services/getPositions.js.map +1 -1
- package/dist/cjs/types/explorer.d.ts +10 -0
- package/dist/cjs/types/explorer.d.ts.map +1 -0
- package/dist/cjs/types/explorer.js +17 -0
- package/dist/cjs/types/explorer.js.map +1 -0
- package/dist/cjs/types/fill.d.ts +6 -0
- package/dist/cjs/types/fill.d.ts.map +1 -1
- 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/ledger.d.ts +24 -1
- package/dist/cjs/types/ledger.d.ts.map +1 -1
- package/dist/cjs/types/ledger.js +5 -1
- package/dist/cjs/types/ledger.js.map +1 -1
- package/dist/cjs/types/order.d.ts +24 -0
- package/dist/cjs/types/order.d.ts.map +1 -1
- package/dist/cjs/types/ws.d.ts +14 -0
- package/dist/cjs/types/ws.d.ts.map +1 -1
- package/dist/cjs/utils/assetId.d.ts +1 -0
- package/dist/cjs/utils/assetId.d.ts.map +1 -1
- package/dist/cjs/utils/assetId.js +6 -1
- package/dist/cjs/utils/assetId.js.map +1 -1
- package/dist/cjs/utils/explorer.d.ts +7 -0
- package/dist/cjs/utils/explorer.d.ts.map +1 -0
- package/dist/cjs/utils/explorer.js +49 -0
- package/dist/cjs/utils/explorer.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +4 -3
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +7 -6
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/infoClient.d.ts +1 -0
- package/dist/cjs/utils/infoClient.d.ts.map +1 -1
- package/dist/cjs/utils/infoClient.js +16 -10
- package/dist/cjs/utils/infoClient.js.map +1 -1
- package/dist/cjs/utils/mapActivity.d.ts +5 -3
- package/dist/cjs/utils/mapActivity.d.ts.map +1 -1
- package/dist/cjs/utils/mapActivity.js +116 -48
- package/dist/cjs/utils/mapActivity.js.map +1 -1
- package/dist/cjs/utils/mapFill.d.ts.map +1 -1
- package/dist/cjs/utils/mapFill.js +0 -1
- package/dist/cjs/utils/mapFill.js.map +1 -1
- package/dist/cjs/utils/mapOrder.d.ts +4 -9
- package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
- package/dist/cjs/utils/mapOrder.js +149 -135
- package/dist/cjs/utils/mapOrder.js.map +1 -1
- package/dist/cjs/utils/spotBalance.d.ts.map +1 -1
- package/dist/cjs/utils/spotBalance.js +10 -6
- package/dist/cjs/utils/spotBalance.js.map +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.d.ts +3 -0
- package/dist/cjs/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.js +100 -29
- package/dist/cjs/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/esm/HyperliquidProvider.d.ts.map +1 -1
- package/dist/esm/HyperliquidProvider.js +1 -2
- package/dist/esm/HyperliquidProvider.js.map +1 -1
- package/dist/esm/constants.d.ts +8 -0
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.js +8 -0
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/index.d.ts +1 -3
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/services/getAccount.d.ts.map +1 -1
- package/dist/esm/services/getAccount.js +6 -3
- package/dist/esm/services/getAccount.js.map +1 -1
- package/dist/esm/services/getActivity.d.ts +2 -2
- package/dist/esm/services/getActivity.d.ts.map +1 -1
- package/dist/esm/services/getActivity.js +44 -9
- package/dist/esm/services/getActivity.js.map +1 -1
- package/dist/esm/services/getFills.d.ts.map +1 -1
- package/dist/esm/services/getFills.js +4 -1
- package/dist/esm/services/getFills.js.map +1 -1
- package/dist/esm/services/getOrder.d.ts.map +1 -1
- package/dist/esm/services/getOrder.js +15 -4
- package/dist/esm/services/getOrder.js.map +1 -1
- package/dist/esm/services/getOrders.d.ts +4 -24
- package/dist/esm/services/getOrders.d.ts.map +1 -1
- package/dist/esm/services/getOrders.js +115 -42
- package/dist/esm/services/getOrders.js.map +1 -1
- package/dist/esm/services/getPositions.d.ts.map +1 -1
- package/dist/esm/services/getPositions.js +2 -2
- package/dist/esm/services/getPositions.js.map +1 -1
- package/dist/esm/types/explorer.d.ts +27 -0
- package/dist/esm/types/explorer.d.ts.map +1 -0
- package/dist/esm/types/explorer.js +20 -0
- package/dist/esm/types/explorer.js.map +1 -0
- package/dist/esm/types/fill.d.ts +11 -0
- package/dist/esm/types/fill.d.ts.map +1 -1
- 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/ledger.d.ts +28 -1
- package/dist/esm/types/ledger.d.ts.map +1 -1
- package/dist/esm/types/ledger.js +4 -0
- package/dist/esm/types/ledger.js.map +1 -1
- package/dist/esm/types/order.d.ts +26 -0
- package/dist/esm/types/order.d.ts.map +1 -1
- package/dist/esm/types/ws.d.ts +15 -0
- package/dist/esm/types/ws.d.ts.map +1 -1
- package/dist/esm/utils/assetId.d.ts +9 -0
- package/dist/esm/utils/assetId.d.ts.map +1 -1
- package/dist/esm/utils/assetId.js +13 -0
- package/dist/esm/utils/assetId.js.map +1 -1
- package/dist/esm/utils/explorer.d.ts +31 -0
- package/dist/esm/utils/explorer.d.ts.map +1 -0
- package/dist/esm/utils/explorer.js +68 -0
- package/dist/esm/utils/explorer.js.map +1 -0
- package/dist/esm/utils/index.d.ts +4 -3
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +4 -3
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/infoClient.d.ts +14 -3
- package/dist/esm/utils/infoClient.d.ts.map +1 -1
- package/dist/esm/utils/infoClient.js +29 -14
- package/dist/esm/utils/infoClient.js.map +1 -1
- package/dist/esm/utils/mapActivity.d.ts +16 -13
- package/dist/esm/utils/mapActivity.d.ts.map +1 -1
- package/dist/esm/utils/mapActivity.js +128 -72
- package/dist/esm/utils/mapActivity.js.map +1 -1
- package/dist/esm/utils/mapFill.d.ts.map +1 -1
- package/dist/esm/utils/mapFill.js +1 -2
- package/dist/esm/utils/mapFill.js.map +1 -1
- package/dist/esm/utils/mapOrder.d.ts +8 -73
- package/dist/esm/utils/mapOrder.d.ts.map +1 -1
- package/dist/esm/utils/mapOrder.js +148 -187
- package/dist/esm/utils/mapOrder.js.map +1 -1
- package/dist/esm/utils/spotBalance.d.ts +1 -1
- package/dist/esm/utils/spotBalance.d.ts.map +1 -1
- package/dist/esm/utils/spotBalance.js +12 -7
- package/dist/esm/utils/spotBalance.js.map +1 -1
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts +5 -1
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/HyperliquidWsProvider.js +105 -34
- package/dist/esm/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/types/HyperliquidProvider.d.ts.map +1 -1
- package/dist/types/constants.d.ts +8 -0
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/services/getAccount.d.ts.map +1 -1
- package/dist/types/services/getActivity.d.ts +2 -2
- package/dist/types/services/getActivity.d.ts.map +1 -1
- package/dist/types/services/getFills.d.ts.map +1 -1
- package/dist/types/services/getOrder.d.ts.map +1 -1
- package/dist/types/services/getOrders.d.ts +4 -24
- package/dist/types/services/getOrders.d.ts.map +1 -1
- package/dist/types/services/getPositions.d.ts.map +1 -1
- package/dist/types/types/explorer.d.ts +27 -0
- package/dist/types/types/explorer.d.ts.map +1 -0
- package/dist/types/types/fill.d.ts +11 -0
- package/dist/types/types/fill.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/types/ledger.d.ts +28 -1
- package/dist/types/types/ledger.d.ts.map +1 -1
- package/dist/types/types/order.d.ts +26 -0
- package/dist/types/types/order.d.ts.map +1 -1
- package/dist/types/types/ws.d.ts +15 -0
- package/dist/types/types/ws.d.ts.map +1 -1
- package/dist/types/utils/assetId.d.ts +9 -0
- package/dist/types/utils/assetId.d.ts.map +1 -1
- package/dist/types/utils/explorer.d.ts +31 -0
- package/dist/types/utils/explorer.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +4 -3
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/infoClient.d.ts +14 -3
- package/dist/types/utils/infoClient.d.ts.map +1 -1
- package/dist/types/utils/mapActivity.d.ts +16 -13
- package/dist/types/utils/mapActivity.d.ts.map +1 -1
- package/dist/types/utils/mapFill.d.ts.map +1 -1
- package/dist/types/utils/mapOrder.d.ts +8 -73
- package/dist/types/utils/mapOrder.d.ts.map +1 -1
- package/dist/types/utils/spotBalance.d.ts +1 -1
- package/dist/types/utils/spotBalance.d.ts.map +1 -1
- package/dist/types/websocket/HyperliquidWsProvider.d.ts +5 -1
- package/dist/types/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/HyperliquidProvider.ts +1 -13
- package/src/constants.ts +10 -0
- package/src/index.ts +1 -2
- package/src/services/getAccount.ts +8 -4
- package/src/services/getActivity.ts +81 -6
- package/src/services/getFills.ts +4 -1
- package/src/services/getOrder.ts +29 -5
- package/src/services/getOrders.ts +185 -70
- package/src/services/getPositions.ts +4 -1
- package/src/types/explorer.ts +39 -0
- package/src/types/fill.ts +12 -0
- package/src/types/index.ts +1 -0
- package/src/types/ledger.ts +37 -0
- package/src/types/order.ts +25 -0
- package/src/types/ws.ts +16 -0
- package/src/utils/assetId.ts +16 -0
- package/src/utils/explorer.ts +93 -0
- package/src/utils/index.ts +16 -7
- package/src/utils/infoClient.ts +46 -24
- package/src/utils/mapActivity.ts +163 -75
- package/src/utils/mapFill.ts +0 -2
- package/src/utils/mapOrder.ts +163 -212
- package/src/utils/spotBalance.ts +12 -7
- package/src/websocket/HyperliquidWsProvider.ts +127 -40
- package/dist/cjs/services/getRunningTwaps.d.ts +0 -10
- package/dist/cjs/services/getRunningTwaps.d.ts.map +0 -1
- package/dist/cjs/services/getRunningTwaps.js +0 -46
- package/dist/cjs/services/getRunningTwaps.js.map +0 -1
- package/dist/esm/services/getRunningTwaps.d.ts +0 -12
- package/dist/esm/services/getRunningTwaps.d.ts.map +0 -1
- package/dist/esm/services/getRunningTwaps.js +0 -40
- package/dist/esm/services/getRunningTwaps.js.map +0 -1
- package/dist/types/services/getRunningTwaps.d.ts +0 -12
- package/dist/types/services/getRunningTwaps.d.ts.map +0 -1
- package/src/services/getRunningTwaps.ts +0 -90
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One HyperCore transaction as the explorer `userDetails` RPC reports it.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface HlExplorerTx {
|
|
7
|
+
time: number
|
|
8
|
+
user: string
|
|
9
|
+
/**
|
|
10
|
+
* The action body HyperCore received. Untyped because the shape varies by
|
|
11
|
+
* action type; read it through `getClientOrderIds`, not by field name.
|
|
12
|
+
*/
|
|
13
|
+
action: unknown
|
|
14
|
+
block: number
|
|
15
|
+
hash: string
|
|
16
|
+
/** `null` on a tx the engine applied, a message on one it landed but refused. */
|
|
17
|
+
error: string | null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Whether one `userDetails` entry carries every field this package reads. The
|
|
22
|
+
* explorer RPC is undocumented, so entries are checked one at a time and a
|
|
23
|
+
* drifted entry drops on its own instead of failing the whole window.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export const isHlExplorerTx = (value: unknown): value is HlExplorerTx =>
|
|
28
|
+
typeof value === 'object' &&
|
|
29
|
+
value !== null &&
|
|
30
|
+
'time' in value &&
|
|
31
|
+
typeof value.time === 'number' &&
|
|
32
|
+
'user' in value &&
|
|
33
|
+
typeof value.user === 'string' &&
|
|
34
|
+
'block' in value &&
|
|
35
|
+
typeof value.block === 'number' &&
|
|
36
|
+
'hash' in value &&
|
|
37
|
+
typeof value.hash === 'string' &&
|
|
38
|
+
'error' in value &&
|
|
39
|
+
(value.error === null || typeof value.error === 'string')
|
package/src/types/fill.ts
CHANGED
|
@@ -34,6 +34,18 @@ export type HlUserFill = {
|
|
|
34
34
|
crossed: boolean
|
|
35
35
|
time: number
|
|
36
36
|
startPosition: string
|
|
37
|
+
/**
|
|
38
|
+
* Present on both sides of a liquidation fill. `liquidatedUser` names the
|
|
39
|
+
* account that was liquidated; the other party is the liquidator.
|
|
40
|
+
*/
|
|
41
|
+
liquidation?: HlFillLiquidation
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Liquidation detail Hyperliquid attaches to a fill. @public */
|
|
45
|
+
export type HlFillLiquidation = {
|
|
46
|
+
liquidatedUser: string
|
|
47
|
+
markPx: string
|
|
48
|
+
method: string
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
/** All fills returned by the unbounded `userFills` query. @public */
|
package/src/types/index.ts
CHANGED
package/src/types/ledger.ts
CHANGED
|
@@ -50,6 +50,41 @@ export type HlSendAssetDelta = {
|
|
|
50
50
|
feeToken: string
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/** USDC transfers between Hyperliquid accounts, including subaccounts. @public */
|
|
54
|
+
export type HlCollateralTransferDelta = {
|
|
55
|
+
type: 'internalTransfer' | 'subAccountTransfer'
|
|
56
|
+
usdc: string
|
|
57
|
+
user: Address
|
|
58
|
+
destination: Address
|
|
59
|
+
fee?: string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Narrow the USDC account-transfer ledger variants. @public */
|
|
63
|
+
export const isCollateralTransferDelta = (
|
|
64
|
+
delta: HlLedgerDelta
|
|
65
|
+
): delta is HlCollateralTransferDelta =>
|
|
66
|
+
delta.type === 'internalTransfer' || delta.type === 'subAccountTransfer'
|
|
67
|
+
|
|
68
|
+
/** USDC movements into or out of a vault, including withdrawal accounting. @public */
|
|
69
|
+
export type HlVaultTransferDelta =
|
|
70
|
+
| { type: 'vaultDeposit'; vault: Address; usdc: string }
|
|
71
|
+
| {
|
|
72
|
+
type: 'vaultWithdraw'
|
|
73
|
+
vault: Address
|
|
74
|
+
user: Address
|
|
75
|
+
requestedUsd: string
|
|
76
|
+
commission: string
|
|
77
|
+
closingCost: string
|
|
78
|
+
basis: string
|
|
79
|
+
netWithdrawnUsd: string
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Narrow the vault fund-movement ledger variants. @public */
|
|
83
|
+
export const isVaultTransferDelta = (
|
|
84
|
+
delta: HlLedgerDelta
|
|
85
|
+
): delta is HlVaultTransferDelta =>
|
|
86
|
+
delta.type === 'vaultDeposit' || delta.type === 'vaultWithdraw'
|
|
87
|
+
|
|
53
88
|
/**
|
|
54
89
|
* Hyperliquid `deposit` ledger delta. Perp-collateral deposits are always
|
|
55
90
|
* USDC-denominated, which is why the amount arrives in a field named `usdc`.
|
|
@@ -103,6 +138,8 @@ export type HlLiquidationDelta = {
|
|
|
103
138
|
export type HlLedgerDelta =
|
|
104
139
|
| HlSpotTransferDelta
|
|
105
140
|
| HlSendAssetDelta
|
|
141
|
+
| HlCollateralTransferDelta
|
|
142
|
+
| HlVaultTransferDelta
|
|
106
143
|
| HlDepositDelta
|
|
107
144
|
| HlWithdrawDelta
|
|
108
145
|
| HlLiquidationDelta
|
package/src/types/order.ts
CHANGED
|
@@ -17,6 +17,7 @@ export type HlFrontendOpenOrder = {
|
|
|
17
17
|
reduceOnly: boolean
|
|
18
18
|
timestamp: number
|
|
19
19
|
isTrigger: boolean
|
|
20
|
+
tpsl?: 'tp' | 'sl'
|
|
20
21
|
isPositionTpsl: boolean
|
|
21
22
|
triggerCondition: string
|
|
22
23
|
triggerPx: string
|
|
@@ -49,6 +50,10 @@ export type HlOrderDetail = {
|
|
|
49
50
|
cloid: string | null
|
|
50
51
|
triggerCondition: string
|
|
51
52
|
triggerPx: string | null
|
|
53
|
+
isTrigger?: boolean
|
|
54
|
+
tpsl?: 'tp' | 'sl'
|
|
55
|
+
children?: HlFrontendOpenOrder[]
|
|
56
|
+
isPositionTpsl?: boolean
|
|
52
57
|
}
|
|
53
58
|
status: string
|
|
54
59
|
statusTimestamp: number
|
|
@@ -68,3 +73,23 @@ export type HlOrderStatusFound = {
|
|
|
68
73
|
export type HlOrderStatusResponse =
|
|
69
74
|
| HlOrderStatusFound
|
|
70
75
|
| { status: 'unknownOid' }
|
|
76
|
+
|
|
77
|
+
/** Rows returned by the `historicalOrders` info query. */
|
|
78
|
+
export type HlHistoricalOrders = HlOrderDetail[]
|
|
79
|
+
|
|
80
|
+
/** TWAP execution state returned by `twapHistory`; time uses epoch seconds. */
|
|
81
|
+
export interface HlTwapHistoryEntry {
|
|
82
|
+
state: {
|
|
83
|
+
coin: string
|
|
84
|
+
executedNtl: string
|
|
85
|
+
executedSz: string
|
|
86
|
+
minutes: number
|
|
87
|
+
side: string
|
|
88
|
+
sz: string
|
|
89
|
+
timestamp: number
|
|
90
|
+
reduceOnly: boolean
|
|
91
|
+
}
|
|
92
|
+
status: { status: string; description?: string }
|
|
93
|
+
time: number
|
|
94
|
+
twapId?: number
|
|
95
|
+
}
|
package/src/types/ws.ts
CHANGED
|
@@ -6,6 +6,22 @@ import type { HlUserFill } from './fill.js'
|
|
|
6
6
|
|
|
7
7
|
type HlWsNumberString = string | number
|
|
8
8
|
|
|
9
|
+
/** Sparse order update returned by the `orderUpdates` WebSocket subscription. */
|
|
10
|
+
export interface HlWsOrder {
|
|
11
|
+
order: {
|
|
12
|
+
coin: string
|
|
13
|
+
side: string
|
|
14
|
+
limitPx: string
|
|
15
|
+
sz: string
|
|
16
|
+
oid: number
|
|
17
|
+
timestamp: number
|
|
18
|
+
origSz: string
|
|
19
|
+
cloid?: string
|
|
20
|
+
}
|
|
21
|
+
status: string
|
|
22
|
+
statusTimestamp: number
|
|
23
|
+
}
|
|
24
|
+
|
|
9
25
|
/**
|
|
10
26
|
* Perp asset context as carried on the `allDexsAssetCtxs` WS feed. Extends the
|
|
11
27
|
* REST `/info` `HlAssetCtx` shape with the wire-only `coin` tag, the order-book
|
package/src/utils/assetId.ts
CHANGED
|
@@ -5,6 +5,22 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export const assetIsSpot = (assetId: string): boolean => assetId.startsWith('@')
|
|
7
7
|
|
|
8
|
+
/** Lowest numeric asset ID Hyperliquid assigns to an outcome market. */
|
|
9
|
+
const OUTCOME_ASSET_ID_BASE = 100_000_000
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Return whether a Hyperliquid asset identity belongs to an HIP-4 outcome
|
|
13
|
+
* market: spot coin `#<encoding>`, token name `+<encoding>`, or numeric asset
|
|
14
|
+
* ID `100000000 + encoding`. LI.FI supports no outcome market, and the backend
|
|
15
|
+
* market list holds none, so the provider skips every such identity.
|
|
16
|
+
* @param assetId - Raw Hyperliquid coin, token name, or numeric asset ID.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export const assetIsOutcome = (assetId: string | number): boolean =>
|
|
20
|
+
typeof assetId === 'number'
|
|
21
|
+
? assetId >= OUTCOME_ASSET_ID_BASE
|
|
22
|
+
: assetId.startsWith('#') || assetId.startsWith('+')
|
|
23
|
+
|
|
8
24
|
/**
|
|
9
25
|
* Calculate Hyperliquid's numeric asset ID from a perp DEX index and the
|
|
10
26
|
* asset's zero-based index within that DEX. The main DEX uses the index
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { OrderBase } from '@lifi/perps-types'
|
|
2
|
+
import { isHex } from 'viem'
|
|
3
|
+
import { HYPERLIQUID_EXPLORER_RPC_URL } from '../constants.js'
|
|
4
|
+
import { type HlExplorerTx, isHlExplorerTx } from '../types/explorer.js'
|
|
5
|
+
import { hlPostJson, type InfoRequestOptions } from './infoClient.js'
|
|
6
|
+
|
|
7
|
+
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
8
|
+
typeof value === 'object' && value !== null
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Read the address's recent HyperCore transactions from the explorer RPC.
|
|
12
|
+
*
|
|
13
|
+
* The surface is undocumented, so it is read defensively: an address the
|
|
14
|
+
* explorer has never indexed answers `200` with no `txs` array, and each entry
|
|
15
|
+
* is checked on its own so one drifted entry cannot drop the rest.
|
|
16
|
+
*
|
|
17
|
+
* @throws {PerpsError} On a non-2xx status or a transport failure.
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export const fetchUserTransactions = async (
|
|
21
|
+
address: string,
|
|
22
|
+
options?: InfoRequestOptions
|
|
23
|
+
): Promise<HlExplorerTx[]> => {
|
|
24
|
+
const body = await hlPostJson<{ txs?: unknown } | null>(
|
|
25
|
+
HYPERLIQUID_EXPLORER_RPC_URL,
|
|
26
|
+
'explorer userDetails',
|
|
27
|
+
{ type: 'userDetails', user: address },
|
|
28
|
+
options
|
|
29
|
+
)
|
|
30
|
+
const txs = body?.txs
|
|
31
|
+
return Array.isArray(txs) ? txs.filter(isHlExplorerTx) : []
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Every client order id an action names: `orders[].c` on a placement, `order.c`
|
|
36
|
+
* on a single modify, and `modifies[].order.c` on a batch modify. A batched
|
|
37
|
+
* placement names one id per leg, so every id is returned, not just the first.
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export const getClientOrderIds = (
|
|
42
|
+
action: Record<string, unknown>
|
|
43
|
+
): string[] => {
|
|
44
|
+
const wires: unknown[] = [
|
|
45
|
+
...(Array.isArray(action.orders) ? action.orders : []),
|
|
46
|
+
...(Array.isArray(action.modifies)
|
|
47
|
+
? action.modifies.map((modify) =>
|
|
48
|
+
isRecord(modify) ? modify.order : undefined
|
|
49
|
+
)
|
|
50
|
+
: []),
|
|
51
|
+
action.order,
|
|
52
|
+
]
|
|
53
|
+
const ids: string[] = []
|
|
54
|
+
for (const wire of wires) {
|
|
55
|
+
if (!isRecord(wire)) {
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
const cloid = wire.c
|
|
59
|
+
if (
|
|
60
|
+
typeof cloid === 'string' &&
|
|
61
|
+
cloid !== '0x' &&
|
|
62
|
+
isHex(cloid, { strict: true })
|
|
63
|
+
) {
|
|
64
|
+
ids.push(cloid)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return ids
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The hash of the transaction whose action names the order's client order id.
|
|
72
|
+
*
|
|
73
|
+
* @returns The transaction hash, or `undefined` when the order carries no
|
|
74
|
+
* client order id or no transaction in the window names it.
|
|
75
|
+
* @public
|
|
76
|
+
*/
|
|
77
|
+
export const matchOrderActionHash = (
|
|
78
|
+
txs: HlExplorerTx[],
|
|
79
|
+
order: Pick<OrderBase, 'clientOrderId'>
|
|
80
|
+
): string | undefined => {
|
|
81
|
+
const { clientOrderId } = order
|
|
82
|
+
if (clientOrderId === undefined) {
|
|
83
|
+
return undefined
|
|
84
|
+
}
|
|
85
|
+
// A client order id is hex, so the venue may echo a case the placer did not send.
|
|
86
|
+
const wanted = clientOrderId.toLowerCase()
|
|
87
|
+
const match = txs.find(
|
|
88
|
+
(tx) =>
|
|
89
|
+
isRecord(tx.action) &&
|
|
90
|
+
getClientOrderIds(tx.action).some((id) => id.toLowerCase() === wanted)
|
|
91
|
+
)
|
|
92
|
+
return match?.hash
|
|
93
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
// for the package's utility surface. Internal modules import per-file paths
|
|
3
3
|
// (e.g. `./assetId.js`, `./mapFill.js`) directly.
|
|
4
4
|
|
|
5
|
-
export {
|
|
5
|
+
export {
|
|
6
|
+
assetIsOutcome,
|
|
7
|
+
assetIsSpot,
|
|
8
|
+
calculateAssetId,
|
|
9
|
+
getProviderIndex,
|
|
10
|
+
} from './assetId.js'
|
|
6
11
|
export {
|
|
7
12
|
applyLogoOverride,
|
|
8
13
|
spotLogoURI,
|
|
@@ -12,26 +17,30 @@ export {
|
|
|
12
17
|
decodeCompressedJson,
|
|
13
18
|
decodeFastAssetCtxs,
|
|
14
19
|
} from './decodeFastAssetCtxs.js'
|
|
20
|
+
export {
|
|
21
|
+
fetchUserTransactions,
|
|
22
|
+
getClientOrderIds,
|
|
23
|
+
matchOrderActionHash,
|
|
24
|
+
} from './explorer.js'
|
|
15
25
|
export type { InfoRequestOptions } from './infoClient.js'
|
|
16
26
|
export { hlInfoOptions, infoRequest } from './infoClient.js'
|
|
17
27
|
export {
|
|
18
28
|
calculateLiquidationPrice,
|
|
19
29
|
calculateMaintenanceMarginRate,
|
|
20
30
|
} from './liquidation.js'
|
|
21
|
-
export {
|
|
31
|
+
export {
|
|
32
|
+
mapFundingActivity,
|
|
33
|
+
mapLedgerEntry,
|
|
34
|
+
mapLiquidationFills,
|
|
35
|
+
} from './mapActivity.js'
|
|
22
36
|
export { classifyFillFromPosition, mapFill } from './mapFill.js'
|
|
23
37
|
export { mapMarket } from './mapMarket.js'
|
|
24
38
|
export { mapMarketContext } from './mapMarketContext.js'
|
|
25
39
|
export {
|
|
26
40
|
type HlOrderLike,
|
|
27
|
-
isTriggerOrder,
|
|
28
|
-
isTriggerType,
|
|
29
|
-
mapOpenOrder,
|
|
30
41
|
mapOrder,
|
|
31
42
|
mapOrderStatus,
|
|
32
43
|
mapOrderType,
|
|
33
|
-
mapStatusReason,
|
|
34
|
-
mapTriggerOrder,
|
|
35
44
|
} from './mapOrder.js'
|
|
36
45
|
export { isOpenAssetPosition, mapPosition } from './mapPosition.js'
|
|
37
46
|
export { coinAsset, perpsDexNames } from './marketDisplay.js'
|
package/src/utils/infoClient.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
errorCodeFromStatus,
|
|
3
3
|
fetchWithRetry,
|
|
4
|
+
isAbortError,
|
|
4
5
|
PerpsError,
|
|
5
6
|
type PerpsSDKClient,
|
|
6
7
|
type ResolvedRetryPolicy,
|
|
@@ -57,7 +58,7 @@ export const HYPERLIQUID_RETRY_DEFAULTS: ResolvedRetryPolicy = {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
|
-
* Transport options for a direct Hyperliquid
|
|
61
|
+
* Transport options for a direct Hyperliquid REST request. `policy`
|
|
61
62
|
* controls retries, `signal` cancels the request, and `fetchImpl` overrides
|
|
62
63
|
* the runtime's global `fetch` implementation.
|
|
63
64
|
* @public
|
|
@@ -87,7 +88,7 @@ export const hlInfoOptions = (
|
|
|
87
88
|
})
|
|
88
89
|
|
|
89
90
|
/**
|
|
90
|
-
* POST to
|
|
91
|
+
* POST a JSON body to a Hyperliquid REST surface and return the parsed body.
|
|
91
92
|
*
|
|
92
93
|
* Direct-to-venue: no proxy, no AJV validation, no cache. The caller's type
|
|
93
94
|
* parameter is trusted; consumers should treat the response shape as
|
|
@@ -97,20 +98,24 @@ export const hlInfoOptions = (
|
|
|
97
98
|
* Non-2xx responses raise a {@link PerpsError} tagged with the Hyperliquid
|
|
98
99
|
* provider key, carrying the code the status resolves to: `RateLimitExceeded`
|
|
99
100
|
* for a 429, `Unauthorized` for a 401, `AgentUnauthorized` for a 403, and
|
|
100
|
-
* `ThirdPartyError` for every other status.
|
|
101
|
-
*
|
|
101
|
+
* `ThirdPartyError` for every other status. A transport failure and a 2xx body
|
|
102
|
+
* that is not JSON both raise `ServerError`, so every failure but a caller
|
|
103
|
+
* abort reaches the caller as a `PerpsError`. An abort rejects untouched.
|
|
104
|
+
*
|
|
105
|
+
* @param label - Names the surface in the error message, e.g. `info request`.
|
|
106
|
+
* @internal
|
|
102
107
|
*/
|
|
103
|
-
export async function
|
|
104
|
-
|
|
108
|
+
export async function hlPostJson<T>(
|
|
109
|
+
url: string,
|
|
110
|
+
label: string,
|
|
105
111
|
body: Record<string, unknown>,
|
|
106
112
|
options?: InfoRequestOptions
|
|
107
113
|
): Promise<T> {
|
|
108
114
|
const policy = options?.policy ?? HYPERLIQUID_RETRY_DEFAULTS
|
|
109
115
|
|
|
110
|
-
let response: Response
|
|
111
116
|
try {
|
|
112
|
-
response = await fetchWithRetry(
|
|
113
|
-
|
|
117
|
+
const response = await fetchWithRetry(
|
|
118
|
+
url,
|
|
114
119
|
{
|
|
115
120
|
method: 'POST',
|
|
116
121
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -122,27 +127,44 @@ export async function infoRequest<T>(
|
|
|
122
127
|
signal: options?.signal,
|
|
123
128
|
}
|
|
124
129
|
)
|
|
130
|
+
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
const err = new PerpsError(
|
|
133
|
+
errorCodeFromStatus(
|
|
134
|
+
response.status,
|
|
135
|
+
PerpsErrorCode.ThirdPartyError,
|
|
136
|
+
HYPERLIQUID_STATUS_ERROR_CODES
|
|
137
|
+
),
|
|
138
|
+
`Hyperliquid ${label} failed: ${response.status}`
|
|
139
|
+
)
|
|
140
|
+
err.tool = PROVIDER_KEY
|
|
141
|
+
throw err
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return (await response.json()) as T
|
|
125
145
|
} catch (error) {
|
|
146
|
+
if (error instanceof PerpsError || isAbortError(error)) {
|
|
147
|
+
throw error
|
|
148
|
+
}
|
|
126
149
|
const err = new PerpsError(
|
|
127
150
|
PerpsErrorCode.ServerError,
|
|
128
|
-
error instanceof Error ? error.message :
|
|
129
|
-
)
|
|
130
|
-
err.tool = PROVIDER_KEY
|
|
131
|
-
throw err
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (!response.ok) {
|
|
135
|
-
const err = new PerpsError(
|
|
136
|
-
errorCodeFromStatus(
|
|
137
|
-
response.status,
|
|
138
|
-
PerpsErrorCode.ThirdPartyError,
|
|
139
|
-
HYPERLIQUID_STATUS_ERROR_CODES
|
|
140
|
-
),
|
|
141
|
-
`Hyperliquid info request failed: ${response.status}`
|
|
151
|
+
error instanceof Error ? error.message : `Hyperliquid ${label} failed`
|
|
142
152
|
)
|
|
143
153
|
err.tool = PROVIDER_KEY
|
|
144
154
|
throw err
|
|
145
155
|
}
|
|
156
|
+
}
|
|
146
157
|
|
|
147
|
-
|
|
158
|
+
/**
|
|
159
|
+
* POST to the Hyperliquid `/info` endpoint and return the parsed JSON body.
|
|
160
|
+
* See {@link hlPostJson} for the transport and error contract.
|
|
161
|
+
*
|
|
162
|
+
* @public
|
|
163
|
+
*/
|
|
164
|
+
export function infoRequest<T>(
|
|
165
|
+
apiUrl: string,
|
|
166
|
+
body: Record<string, unknown>,
|
|
167
|
+
options?: InfoRequestOptions
|
|
168
|
+
): Promise<T> {
|
|
169
|
+
return hlPostJson<T>(`${apiUrl}/info`, 'info request', body, options)
|
|
148
170
|
}
|