@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
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
type ProviderGetPortfolioHistoryParams,
|
|
18
18
|
type ProviderGetPositionsParams,
|
|
19
19
|
type ProviderGetQuoteParams,
|
|
20
|
-
type ProviderGetRunningTwapsParams,
|
|
21
20
|
resolveQuote,
|
|
22
21
|
type SDKRequestOptions,
|
|
23
22
|
type SignActionsContext,
|
|
@@ -46,7 +45,6 @@ import {
|
|
|
46
45
|
type Quote,
|
|
47
46
|
type SignedActionStep,
|
|
48
47
|
type SigningMethod,
|
|
49
|
-
type TwapOrder,
|
|
50
48
|
} from '@lifi/perps-types'
|
|
51
49
|
import { type Address, type Hex, isAddress } from 'viem'
|
|
52
50
|
import { projectHyperliquidConfigSettings } from './accountConfig.js'
|
|
@@ -67,7 +65,6 @@ import { getOrder } from './services/getOrder.js'
|
|
|
67
65
|
import { getOrders } from './services/getOrders.js'
|
|
68
66
|
import { getPortfolioHistory } from './services/getPortfolioHistory.js'
|
|
69
67
|
import { getPositions } from './services/getPositions.js'
|
|
70
|
-
import { getRunningTwaps } from './services/getRunningTwaps.js'
|
|
71
68
|
import {
|
|
72
69
|
type HyperliquidAgent,
|
|
73
70
|
HyperliquidAgentStore,
|
|
@@ -331,22 +328,13 @@ export function hyperliquidProvider(
|
|
|
331
328
|
contextRef.require(),
|
|
332
329
|
{
|
|
333
330
|
address: params.address,
|
|
331
|
+
statuses: params.statuses,
|
|
334
332
|
marketId: params.marketId,
|
|
335
333
|
limit: params.limit,
|
|
336
334
|
},
|
|
337
335
|
opts
|
|
338
336
|
),
|
|
339
337
|
|
|
340
|
-
getRunningTwaps: (
|
|
341
|
-
params: ProviderGetRunningTwapsParams,
|
|
342
|
-
opts?: SDKRequestOptions
|
|
343
|
-
): Promise<TwapOrder[]> =>
|
|
344
|
-
getRunningTwaps(
|
|
345
|
-
contextRef.require(),
|
|
346
|
-
{ address: params.address, marketId: params.marketId },
|
|
347
|
-
opts
|
|
348
|
-
),
|
|
349
|
-
|
|
350
338
|
getOrder: (
|
|
351
339
|
params: ProviderGetOrderParams,
|
|
352
340
|
opts?: SDKRequestOptions
|
package/src/constants.ts
CHANGED
|
@@ -15,6 +15,16 @@ export const PROVIDER_KEY = 'hyperliquid'
|
|
|
15
15
|
*/
|
|
16
16
|
export const DEFAULT_HYPERLIQUID_API_URL = 'https://api.hyperliquid.xyz'
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Hyperliquid explorer RPC endpoint. It serves the `userDetails` transaction
|
|
20
|
+
* window from a host separate from the REST API, and it answers a browser
|
|
21
|
+
* cross-origin POST.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export const HYPERLIQUID_EXPLORER_RPC_URL =
|
|
26
|
+
'https://rpc.hyperliquid.xyz/explorer'
|
|
27
|
+
|
|
18
28
|
/**
|
|
19
29
|
* Approximate published baseline maker/taker fee tier for Hyperliquid, used to
|
|
20
30
|
* seed fee math before the live account `feeTier` resolves. Rates are fractions
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { projectHyperliquidConfigSettings } from './accountConfig.js'
|
|
|
15
15
|
export { getAccountSummary } from './accountSummary.js'
|
|
16
16
|
export {
|
|
17
17
|
DEFAULT_HYPERLIQUID_API_URL,
|
|
18
|
+
HYPERLIQUID_EXPLORER_RPC_URL,
|
|
18
19
|
HYPERLIQUID_FEE_TIER_FALLBACK,
|
|
19
20
|
PROVIDER_KEY as HYPERLIQUID_PROVIDER_KEY,
|
|
20
21
|
} from './constants.js'
|
|
@@ -39,8 +40,6 @@ export type { GetPortfolioHistoryParams } from './services/getPortfolioHistory.j
|
|
|
39
40
|
export { getPortfolioHistory } from './services/getPortfolioHistory.js'
|
|
40
41
|
export type { GetPositionsParams } from './services/getPositions.js'
|
|
41
42
|
export { getPositions } from './services/getPositions.js'
|
|
42
|
-
export type { GetRunningTwapsParams } from './services/getRunningTwaps.js'
|
|
43
|
-
export { getRunningTwaps } from './services/getRunningTwaps.js'
|
|
44
43
|
export type { HyperliquidAgent } from './signers/HyperliquidAgentStore.js'
|
|
45
44
|
export { HyperliquidAgentStore } from './signers/HyperliquidAgentStore.js'
|
|
46
45
|
export * from './types/index.js'
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import { isUnifiedAbstraction } from '../utils/abstractionMode.js'
|
|
27
27
|
import { toWireBig } from '../utils/decimal.js'
|
|
28
28
|
import {
|
|
29
|
+
assetIsOutcome,
|
|
29
30
|
partitionSpotBalances,
|
|
30
31
|
perpsDexNames,
|
|
31
32
|
spotAssetFromToken,
|
|
@@ -102,9 +103,9 @@ const buildBalances = (
|
|
|
102
103
|
quoteAssetByCategory: Map<string, Asset>
|
|
103
104
|
): BalancePartition => {
|
|
104
105
|
const { balances, collateralBalances } = partitionSpotBalances(
|
|
105
|
-
spotState.balances
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
spotState.balances
|
|
107
|
+
.filter((b) => !assetIsOutcome(b.coin))
|
|
108
|
+
.map((b) => spotBalance(spotAssetFromToken(b), b.total, priceById)),
|
|
108
109
|
quoteAssetIds,
|
|
109
110
|
abstraction === HlAbstractionMode.PORTFOLIO_MARGIN
|
|
110
111
|
)
|
|
@@ -127,6 +128,7 @@ const buildBalances = (
|
|
|
127
128
|
asset: quoteAssetByCategory.get(categoryId)!,
|
|
128
129
|
units: value.toFixed(),
|
|
129
130
|
valueUsd: value.toFixed(),
|
|
131
|
+
price: '1',
|
|
130
132
|
})
|
|
131
133
|
}
|
|
132
134
|
}
|
|
@@ -220,7 +222,9 @@ export const getAccount = async (
|
|
|
220
222
|
|
|
221
223
|
const positions: Position[] = stateResults.flatMap((state) =>
|
|
222
224
|
state.assetPositions
|
|
223
|
-
.filter(
|
|
225
|
+
.filter(
|
|
226
|
+
(ap) => !assetIsOutcome(ap.position.coin) && isOpenAssetPosition(ap)
|
|
227
|
+
)
|
|
224
228
|
.map((ap) =>
|
|
225
229
|
mapPosition(
|
|
226
230
|
ap,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type AssetRegistry,
|
|
3
|
+
getAssetRegistry,
|
|
4
|
+
getMarketRegistry,
|
|
5
|
+
type SDKRequestOptions,
|
|
6
|
+
} from '@lifi/perps-sdk'
|
|
2
7
|
import type {
|
|
3
8
|
ActivitiesResponse,
|
|
4
9
|
ActivityItem,
|
|
@@ -14,10 +19,24 @@ import {
|
|
|
14
19
|
} from '../constants.js'
|
|
15
20
|
import type { HyperliquidContext } from '../context.js'
|
|
16
21
|
import type {
|
|
22
|
+
HlUserFills,
|
|
17
23
|
HlUserFunding,
|
|
18
24
|
HlUserNonFundingLedgerUpdates,
|
|
19
25
|
} from '../types/index.js'
|
|
20
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
isCollateralTransferDelta,
|
|
28
|
+
isDepositDelta,
|
|
29
|
+
isLiquidationDelta,
|
|
30
|
+
isSendAssetDelta,
|
|
31
|
+
isSpotTransferDelta,
|
|
32
|
+
isVaultTransferDelta,
|
|
33
|
+
isWithdrawDelta,
|
|
34
|
+
} from '../types/index.js'
|
|
35
|
+
import {
|
|
36
|
+
mapFundingActivity,
|
|
37
|
+
mapLedgerEntry,
|
|
38
|
+
mapLiquidationFills,
|
|
39
|
+
} from '../utils/index.js'
|
|
21
40
|
import {
|
|
22
41
|
hlInfoOptions,
|
|
23
42
|
type InfoRequestOptions,
|
|
@@ -48,6 +67,12 @@ const MARKET_BEARING_TYPES: ReadonlySet<ActivityType> = new Set([
|
|
|
48
67
|
ActivityType.LIQUIDATION,
|
|
49
68
|
])
|
|
50
69
|
|
|
70
|
+
const ASSET_BEARING_TYPES: ReadonlySet<ActivityType> = new Set([
|
|
71
|
+
ActivityType.DEPOSIT,
|
|
72
|
+
ActivityType.WITHDRAWAL,
|
|
73
|
+
ActivityType.TRANSFER,
|
|
74
|
+
])
|
|
75
|
+
|
|
51
76
|
const needsMarkets = (typeFilter: ActivityType[] | undefined): boolean =>
|
|
52
77
|
!typeFilter || typeFilter.some((t) => MARKET_BEARING_TYPES.has(t))
|
|
53
78
|
|
|
@@ -55,14 +80,19 @@ const fetchActivityData = async (
|
|
|
55
80
|
apiUrl: string,
|
|
56
81
|
typeFilter: ActivityType[] | undefined,
|
|
57
82
|
timeParams: { user: Address; startTime?: number; endTime?: number },
|
|
83
|
+
assetRegistry: AssetRegistry,
|
|
58
84
|
resolveMarket: (coin: string) => MarketDisplay | undefined,
|
|
59
85
|
options?: InfoRequestOptions
|
|
60
86
|
): Promise<ActivityItem[]> => {
|
|
61
87
|
const needLedger =
|
|
62
88
|
!typeFilter || typeFilter.some((t) => t !== ActivityType.FUNDING)
|
|
63
89
|
const needFunding = !typeFilter || typeFilter.includes(ActivityType.FUNDING)
|
|
90
|
+
// A liquidation executed as a market order reaches the account as fills
|
|
91
|
+
// with a `liquidation` field and never as a ledger `liquidation` delta.
|
|
92
|
+
const needLiquidationFills =
|
|
93
|
+
!typeFilter || typeFilter.includes(ActivityType.LIQUIDATION)
|
|
64
94
|
|
|
65
|
-
const [ledgerUpdates, fundingUpdates] = await Promise.all([
|
|
95
|
+
const [ledgerUpdates, fundingUpdates, fills] = await Promise.all([
|
|
66
96
|
needLedger
|
|
67
97
|
? infoRequest<HlUserNonFundingLedgerUpdates>(
|
|
68
98
|
apiUrl,
|
|
@@ -77,14 +107,38 @@ const fetchActivityData = async (
|
|
|
77
107
|
options
|
|
78
108
|
)
|
|
79
109
|
: Promise.resolve([] as HlUserFunding),
|
|
110
|
+
needLiquidationFills
|
|
111
|
+
? infoRequest<HlUserFills>(
|
|
112
|
+
apiUrl,
|
|
113
|
+
timeParams.startTime === undefined
|
|
114
|
+
? { type: 'userFills', user: timeParams.user }
|
|
115
|
+
: { type: 'userFillsByTime', ...timeParams },
|
|
116
|
+
options
|
|
117
|
+
)
|
|
118
|
+
: Promise.resolve([] as HlUserFills),
|
|
80
119
|
])
|
|
81
120
|
|
|
82
121
|
const ledgerItems: ActivityItem[] = ledgerUpdates.flatMap(
|
|
83
122
|
(entry): ActivityItem[] => {
|
|
123
|
+
if (
|
|
124
|
+
typeFilter !== undefined &&
|
|
125
|
+
((isDepositDelta(entry.delta) &&
|
|
126
|
+
!typeFilter.includes(ActivityType.DEPOSIT)) ||
|
|
127
|
+
(isWithdrawDelta(entry.delta) &&
|
|
128
|
+
!typeFilter.includes(ActivityType.WITHDRAWAL)) ||
|
|
129
|
+
(!typeFilter.includes(ActivityType.TRANSFER) &&
|
|
130
|
+
(isSpotTransferDelta(entry.delta) ||
|
|
131
|
+
isSendAssetDelta(entry.delta) ||
|
|
132
|
+
isCollateralTransferDelta(entry.delta) ||
|
|
133
|
+
isVaultTransferDelta(entry.delta))))
|
|
134
|
+
) {
|
|
135
|
+
return []
|
|
136
|
+
}
|
|
84
137
|
const item = mapLedgerEntry(
|
|
85
138
|
entry,
|
|
86
139
|
PROVIDER_KEY,
|
|
87
140
|
timeParams.user,
|
|
141
|
+
assetRegistry,
|
|
88
142
|
resolveMarket
|
|
89
143
|
)
|
|
90
144
|
return item === null ? [] : [item]
|
|
@@ -98,7 +152,20 @@ const fetchActivityData = async (
|
|
|
98
152
|
}
|
|
99
153
|
)
|
|
100
154
|
|
|
101
|
-
const
|
|
155
|
+
const ledgerLiquidationHashes = new Set(
|
|
156
|
+
ledgerUpdates
|
|
157
|
+
.filter((entry) => isLiquidationDelta(entry.delta))
|
|
158
|
+
.map((entry) => entry.hash)
|
|
159
|
+
)
|
|
160
|
+
const liquidationItems = mapLiquidationFills(
|
|
161
|
+
fills,
|
|
162
|
+
PROVIDER_KEY,
|
|
163
|
+
timeParams.user,
|
|
164
|
+
resolveMarket,
|
|
165
|
+
ledgerLiquidationHashes
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
const merged = [...ledgerItems, ...fundingItems, ...liquidationItems].sort(
|
|
102
169
|
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
103
170
|
)
|
|
104
171
|
|
|
@@ -112,8 +179,8 @@ const fetchActivityData = async (
|
|
|
112
179
|
/**
|
|
113
180
|
* Fetch a chronological activity feed (deposits, withdrawals, transfers,
|
|
114
181
|
* liquidations, funding) for `address`. Combines results from Hyperliquid's
|
|
115
|
-
* `userNonFundingLedgerUpdates` and `
|
|
116
|
-
* newest-first.
|
|
182
|
+
* `userNonFundingLedgerUpdates`, `userFunding`, and `userFills` endpoints,
|
|
183
|
+
* sorted newest-first.
|
|
117
184
|
*
|
|
118
185
|
* Cursor-based pagination uses the ms-since-epoch timestamp of the last item
|
|
119
186
|
* on the current page.
|
|
@@ -131,6 +198,13 @@ export const getActivity = async (
|
|
|
131
198
|
if (needsMarkets(params.type)) {
|
|
132
199
|
await registry.sync()
|
|
133
200
|
}
|
|
201
|
+
const assetRegistry = getAssetRegistry(client, PROVIDER_KEY)
|
|
202
|
+
if (
|
|
203
|
+
params.type === undefined ||
|
|
204
|
+
params.type.some((type) => ASSET_BEARING_TYPES.has(type))
|
|
205
|
+
) {
|
|
206
|
+
await assetRegistry.sync()
|
|
207
|
+
}
|
|
134
208
|
const infoOpts = hlInfoOptions(client, options)
|
|
135
209
|
|
|
136
210
|
const limit = Math.min(
|
|
@@ -152,6 +226,7 @@ export const getActivity = async (
|
|
|
152
226
|
apiUrl,
|
|
153
227
|
params.type,
|
|
154
228
|
timeParams,
|
|
229
|
+
assetRegistry,
|
|
155
230
|
(coin) => registry.get(coin),
|
|
156
231
|
infoOpts
|
|
157
232
|
)
|
package/src/services/getFills.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
HlUserFills,
|
|
13
13
|
HlUserFillsByTime,
|
|
14
14
|
} from '../types/index.js'
|
|
15
|
-
import { mapFill } from '../utils/index.js'
|
|
15
|
+
import { assetIsOutcome, mapFill } from '../utils/index.js'
|
|
16
16
|
import { hlInfoOptions, infoRequest } from '../utils/infoClient.js'
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -112,6 +112,9 @@ export const getFills = async (
|
|
|
112
112
|
// only its own row instead of rejecting the whole page. The registry warns
|
|
113
113
|
// once per unresolved id. A delisted market still resolves, so its rows stay.
|
|
114
114
|
const items = page.flatMap((f): Fill[] => {
|
|
115
|
+
if (assetIsOutcome(f.coin)) {
|
|
116
|
+
return []
|
|
117
|
+
}
|
|
115
118
|
const market = registry.get(f.coin)
|
|
116
119
|
return market === undefined ? [] : [mapFill(f, market)]
|
|
117
120
|
})
|
package/src/services/getOrder.ts
CHANGED
|
@@ -8,8 +8,11 @@ import type { Order } from '@lifi/perps-types'
|
|
|
8
8
|
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
9
9
|
import { PROVIDER_KEY } from '../constants.js'
|
|
10
10
|
import type { HyperliquidContext } from '../context.js'
|
|
11
|
-
import type {
|
|
12
|
-
|
|
11
|
+
import type {
|
|
12
|
+
HlOrderStatusResponse,
|
|
13
|
+
HlTwapHistoryEntry,
|
|
14
|
+
} from '../types/index.js'
|
|
15
|
+
import { assetIsOutcome, mapOrder } from '../utils/index.js'
|
|
13
16
|
import { hlInfoOptions, infoRequest } from '../utils/infoClient.js'
|
|
14
17
|
|
|
15
18
|
/**
|
|
@@ -30,11 +33,15 @@ export const getOrder = async (
|
|
|
30
33
|
params: GetOrderParams,
|
|
31
34
|
options?: SDKRequestOptions
|
|
32
35
|
): Promise<Order> => {
|
|
33
|
-
const
|
|
34
|
-
|
|
36
|
+
const isClientId = /^0x[0-9a-fA-F]{32}$/.test(params.id)
|
|
37
|
+
const oid = isClientId ? params.id : Number(params.id)
|
|
38
|
+
if (
|
|
39
|
+
!isClientId &&
|
|
40
|
+
(!/^[0-9]+$/.test(params.id) || !Number.isSafeInteger(oid))
|
|
41
|
+
) {
|
|
35
42
|
const err = new PerpsError(
|
|
36
43
|
PerpsErrorCode.ValidationError,
|
|
37
|
-
`Invalid order ID: ${params.id}.
|
|
44
|
+
`Invalid order ID: ${params.id}. Expected a numeric oid or a 128-bit cloid.`
|
|
38
45
|
)
|
|
39
46
|
err.tool = PROVIDER_KEY
|
|
40
47
|
throw err
|
|
@@ -47,6 +54,23 @@ export const getOrder = async (
|
|
|
47
54
|
)
|
|
48
55
|
|
|
49
56
|
if (status.status !== 'order') {
|
|
57
|
+
const history = await infoRequest<HlTwapHistoryEntry[]>(
|
|
58
|
+
apiUrl,
|
|
59
|
+
{ type: 'twapHistory', user: params.address },
|
|
60
|
+
hlInfoOptions(client, options)
|
|
61
|
+
)
|
|
62
|
+
const twap = history.find(
|
|
63
|
+
(entry) =>
|
|
64
|
+
String(entry.twapId) === params.id && !assetIsOutcome(entry.state.coin)
|
|
65
|
+
)
|
|
66
|
+
if (twap !== undefined) {
|
|
67
|
+
const registry = getMarketRegistry(client, PROVIDER_KEY)
|
|
68
|
+
await registry.sync()
|
|
69
|
+
return mapOrder(twap, registry.require(twap.state.coin))
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (status.status !== 'order' || assetIsOutcome(status.order.order.coin)) {
|
|
50
74
|
const err = new PerpsError(
|
|
51
75
|
PerpsErrorCode.OrderNotFound,
|
|
52
76
|
`Order not found: ${params.id}`
|
|
@@ -1,102 +1,217 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
ACTIVE_ORDER_STATUSES,
|
|
3
|
+
createWarnOnce,
|
|
4
|
+
ExplorerChainId,
|
|
5
|
+
explorerTxUrl,
|
|
6
|
+
getMarketRegistry,
|
|
7
|
+
isActiveOrderStatus,
|
|
8
|
+
type MarketRegistry,
|
|
9
|
+
PerpsError,
|
|
10
|
+
type ProviderGetOrdersParams,
|
|
11
|
+
type SDKRequestOptions,
|
|
12
|
+
} from '@lifi/perps-sdk'
|
|
13
|
+
import type { MarketDisplay, Order, OrdersResponse } from '@lifi/perps-types'
|
|
4
14
|
import { PROVIDER_KEY } from '../constants.js'
|
|
5
15
|
import type { HyperliquidContext } from '../context.js'
|
|
6
16
|
import type {
|
|
7
|
-
|
|
17
|
+
HlExplorerTx,
|
|
8
18
|
HlFrontendOpenOrders,
|
|
19
|
+
HlHistoricalOrders,
|
|
20
|
+
HlTwapHistoryEntry,
|
|
9
21
|
} from '../types/index.js'
|
|
10
22
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
23
|
+
assetIsOutcome,
|
|
24
|
+
fetchUserTransactions,
|
|
25
|
+
mapOrder,
|
|
26
|
+
matchOrderActionHash,
|
|
14
27
|
perpsDexNames,
|
|
15
28
|
} from '../utils/index.js'
|
|
16
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
hlInfoOptions,
|
|
31
|
+
type InfoRequestOptions,
|
|
32
|
+
infoRequest,
|
|
33
|
+
} from '../utils/infoClient.js'
|
|
34
|
+
|
|
35
|
+
/** Parameters for a lifecycle-filtered Hyperliquid order read. */
|
|
36
|
+
export type GetOrdersParams = ProviderGetOrdersParams
|
|
37
|
+
|
|
38
|
+
const warn = createWarnOnce()
|
|
39
|
+
|
|
40
|
+
const warnOnce = (key: string, detail?: string): void => {
|
|
41
|
+
warn(
|
|
42
|
+
key,
|
|
43
|
+
`[${PROVIDER_KEY}] ${detail === undefined ? key : `${key}: ${detail}`}`
|
|
44
|
+
)
|
|
45
|
+
}
|
|
17
46
|
|
|
18
47
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
48
|
+
* Map one venue row, or drop it. An outcome market identity, a coin the backend
|
|
49
|
+
* market list does not hold, and a row the mapper rejects each drop only their
|
|
50
|
+
* own row instead of rejecting the whole page; each distinct mapper message
|
|
51
|
+
* warns once.
|
|
22
52
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
53
|
+
const mapRow = (
|
|
54
|
+
coin: string,
|
|
55
|
+
registry: MarketRegistry,
|
|
56
|
+
map: (market: MarketDisplay) => Order
|
|
57
|
+
): Order | undefined => {
|
|
58
|
+
if (assetIsOutcome(coin)) {
|
|
59
|
+
return undefined
|
|
60
|
+
}
|
|
61
|
+
const market = registry.get(coin)
|
|
62
|
+
if (market === undefined) {
|
|
63
|
+
return undefined
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
return map(market)
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (!(error instanceof PerpsError)) {
|
|
69
|
+
throw error
|
|
70
|
+
}
|
|
71
|
+
warnOnce(`dropped order row: ${error.message}`)
|
|
72
|
+
return undefined
|
|
73
|
+
}
|
|
29
74
|
}
|
|
30
75
|
|
|
31
76
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `frontendOpenOrders` is read direct.
|
|
38
|
-
* @throws {PerpsError} On Hyperliquid REST error, network, or parsing failures.
|
|
39
|
-
* @public
|
|
77
|
+
* Set `explorerLink` on each row whose placement transaction the explorer
|
|
78
|
+
* window still holds. One explorer read serves the whole page, and it is
|
|
79
|
+
* skipped when no row carries a client order id to match on. The link is
|
|
80
|
+
* supplementary, so an explorer failure warns and leaves the rows unlinked
|
|
81
|
+
* instead of failing the order read.
|
|
40
82
|
*/
|
|
83
|
+
const withExplorerLinks = async (
|
|
84
|
+
orders: Order[],
|
|
85
|
+
address: string,
|
|
86
|
+
options: InfoRequestOptions
|
|
87
|
+
): Promise<Order[]> => {
|
|
88
|
+
if (!orders.some((order) => order.clientOrderId !== undefined)) {
|
|
89
|
+
return orders
|
|
90
|
+
}
|
|
91
|
+
let txs: HlExplorerTx[]
|
|
92
|
+
try {
|
|
93
|
+
txs = await fetchUserTransactions(address, options)
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (!(error instanceof PerpsError)) {
|
|
96
|
+
throw error
|
|
97
|
+
}
|
|
98
|
+
// The message stays out of the key: a transport failure names hosts and
|
|
99
|
+
// ports, so keying on it would let the dedupe set grow without bound.
|
|
100
|
+
warnOnce('explorer link lookup failed', error.message)
|
|
101
|
+
return orders
|
|
102
|
+
}
|
|
103
|
+
return orders.map((order) => {
|
|
104
|
+
const explorerLink = explorerTxUrl(
|
|
105
|
+
ExplorerChainId.HYPERLIQUID,
|
|
106
|
+
matchOrderActionHash(txs, order)
|
|
107
|
+
)
|
|
108
|
+
return explorerLink === undefined ? order : { ...order, explorerLink }
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Read regular, trigger, and TWAP orders from the requested lifecycle feeds. */
|
|
41
113
|
export const getOrders = async (
|
|
42
114
|
{ client, apiUrl }: HyperliquidContext,
|
|
43
115
|
params: GetOrdersParams,
|
|
44
116
|
options?: SDKRequestOptions
|
|
45
117
|
): Promise<OrdersResponse> => {
|
|
118
|
+
const statuses = params.statuses ?? [...ACTIVE_ORDER_STATUSES]
|
|
119
|
+
if (statuses.length === 0) {
|
|
120
|
+
return {
|
|
121
|
+
provider: PROVIDER_KEY,
|
|
122
|
+
orders: [],
|
|
123
|
+
pagination: { limit: params.limit ?? 0, hasMore: false },
|
|
124
|
+
}
|
|
125
|
+
}
|
|
46
126
|
const registry = getMarketRegistry(client, PROVIDER_KEY)
|
|
47
127
|
const markets = await registry.sync()
|
|
48
128
|
const infoOpts = hlInfoOptions(client, options)
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
129
|
+
const active = statuses.some(isActiveOrderStatus)
|
|
130
|
+
const terminal = statuses.some((status) => !isActiveOrderStatus(status))
|
|
131
|
+
const [open, historical, twaps] = await Promise.all([
|
|
132
|
+
active
|
|
133
|
+
? Promise.all(
|
|
134
|
+
perpsDexNames(markets).map((name) =>
|
|
135
|
+
infoRequest<HlFrontendOpenOrders>(
|
|
136
|
+
apiUrl,
|
|
137
|
+
{
|
|
138
|
+
type: 'frontendOpenOrders',
|
|
139
|
+
user: params.address,
|
|
140
|
+
...(name ? { dex: name } : {}),
|
|
141
|
+
},
|
|
142
|
+
infoOpts
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
)
|
|
146
|
+
: [],
|
|
147
|
+
terminal
|
|
148
|
+
? infoRequest<HlHistoricalOrders>(
|
|
149
|
+
apiUrl,
|
|
150
|
+
{ type: 'historicalOrders', user: params.address },
|
|
151
|
+
infoOpts
|
|
152
|
+
)
|
|
153
|
+
: [],
|
|
154
|
+
infoRequest<HlTwapHistoryEntry[]>(
|
|
155
|
+
apiUrl,
|
|
156
|
+
{ type: 'twapHistory', user: params.address },
|
|
157
|
+
infoOpts
|
|
158
|
+
),
|
|
159
|
+
])
|
|
160
|
+
const rows = new Map<string, Order>()
|
|
161
|
+
const keep = (key: string, order: Order | undefined): void => {
|
|
162
|
+
if (order !== undefined) {
|
|
163
|
+
rows.set(key, order)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (const detail of historical) {
|
|
167
|
+
const key = String(detail.order.oid)
|
|
168
|
+
// The feed carries one row per lifecycle transition, newest first, and a
|
|
169
|
+
// terminal row shares its timestamp with the `open` row beneath it, so
|
|
170
|
+
// only the first row of an id states that order's current status.
|
|
171
|
+
if (rows.has(key)) {
|
|
172
|
+
continue
|
|
173
|
+
}
|
|
174
|
+
keep(
|
|
175
|
+
key,
|
|
176
|
+
mapRow(detail.order.coin, registry, (market) => mapOrder(detail, market))
|
|
61
177
|
)
|
|
178
|
+
}
|
|
179
|
+
const raw = open.flat()
|
|
180
|
+
const childIds = new Set(
|
|
181
|
+
raw.flatMap((order) => (order.children ?? []).map((child) => child.oid))
|
|
62
182
|
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
183
|
+
for (const order of raw) {
|
|
184
|
+
if (!childIds.has(order.oid)) {
|
|
185
|
+
keep(
|
|
186
|
+
String(order.oid),
|
|
187
|
+
mapRow(order.coin, registry, (market) => mapOrder(order, market))
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
for (const child of order.children ?? []) {
|
|
191
|
+
keep(
|
|
192
|
+
String(child.oid),
|
|
193
|
+
mapRow(child.coin, registry, (market) =>
|
|
194
|
+
mapOrder(child, market, String(order.oid))
|
|
195
|
+
)
|
|
196
|
+
)
|
|
70
197
|
}
|
|
71
198
|
}
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
let triggerOrders: TriggerOrder[] = [
|
|
80
|
-
...nonChild
|
|
81
|
-
.filter((o) => isTriggerOrder(o))
|
|
82
|
-
.map((o) => mapTriggerOrder(o, registry.require(o.coin))),
|
|
83
|
-
...raw
|
|
84
|
-
.filter((o) => childOids.has(o.oid))
|
|
85
|
-
.map((o) => mapTriggerOrder(o, registry.require(o.coin))),
|
|
86
|
-
]
|
|
87
|
-
|
|
88
|
-
if (params.marketId !== undefined) {
|
|
89
|
-
openOrders = openOrders.filter((o) => o.market.id === params.marketId)
|
|
90
|
-
triggerOrders = triggerOrders.filter((o) => o.market.id === params.marketId)
|
|
199
|
+
// TWAP ids and regular order ids occupy separate venue namespaces.
|
|
200
|
+
for (const twap of twaps) {
|
|
201
|
+
keep(
|
|
202
|
+
`twap:${twap.twapId}`,
|
|
203
|
+
mapRow(twap.state.coin, registry, (market) => mapOrder(twap, market))
|
|
204
|
+
)
|
|
91
205
|
}
|
|
92
|
-
|
|
206
|
+
const matching = [...rows.values()].filter(
|
|
207
|
+
(order) =>
|
|
208
|
+
statuses.includes(order.status) &&
|
|
209
|
+
(params.marketId === undefined || order.market.id === params.marketId)
|
|
210
|
+
)
|
|
211
|
+
const orders = await withExplorerLinks(matching, params.address, infoOpts)
|
|
93
212
|
return {
|
|
94
213
|
provider: PROVIDER_KEY,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
pagination: {
|
|
98
|
-
limit: params.limit ?? openOrders.length + triggerOrders.length,
|
|
99
|
-
hasMore: false,
|
|
100
|
-
},
|
|
214
|
+
orders,
|
|
215
|
+
pagination: { limit: params.limit ?? orders.length, hasMore: false },
|
|
101
216
|
}
|
|
102
217
|
}
|
|
@@ -9,6 +9,7 @@ import { PROVIDER_KEY } from '../constants.js'
|
|
|
9
9
|
import type { HyperliquidContext } from '../context.js'
|
|
10
10
|
import type { HlClearinghouseState } from '../types/index.js'
|
|
11
11
|
import {
|
|
12
|
+
assetIsOutcome,
|
|
12
13
|
isOpenAssetPosition,
|
|
13
14
|
mapPosition,
|
|
14
15
|
perpsDexNames,
|
|
@@ -61,7 +62,9 @@ export const getPositions = async (
|
|
|
61
62
|
|
|
62
63
|
let positions = stateResults.flatMap((state) =>
|
|
63
64
|
state.assetPositions
|
|
64
|
-
.filter(
|
|
65
|
+
.filter(
|
|
66
|
+
(ap) => !assetIsOutcome(ap.position.coin) && isOpenAssetPosition(ap)
|
|
67
|
+
)
|
|
65
68
|
.map((ap) =>
|
|
66
69
|
mapPosition(
|
|
67
70
|
ap,
|