@lifi/perps-sdk-provider-hyperliquid 13.0.0 → 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.
Files changed (245) hide show
  1. package/README.md +115 -0
  2. package/dist/cjs/HyperliquidProvider.d.ts.map +1 -1
  3. package/dist/cjs/HyperliquidProvider.js +1 -2
  4. package/dist/cjs/HyperliquidProvider.js.map +1 -1
  5. package/dist/cjs/constants.d.ts +1 -0
  6. package/dist/cjs/constants.d.ts.map +1 -1
  7. package/dist/cjs/constants.js +2 -1
  8. package/dist/cjs/constants.js.map +1 -1
  9. package/dist/cjs/index.d.ts +1 -3
  10. package/dist/cjs/index.d.ts.map +1 -1
  11. package/dist/cjs/index.js +2 -3
  12. package/dist/cjs/index.js.map +1 -1
  13. package/dist/cjs/services/getAccount.d.ts.map +1 -1
  14. package/dist/cjs/services/getAccount.js +16 -9
  15. package/dist/cjs/services/getAccount.js.map +1 -1
  16. package/dist/cjs/services/getActivity.d.ts.map +1 -1
  17. package/dist/cjs/services/getActivity.js +40 -7
  18. package/dist/cjs/services/getActivity.js.map +1 -1
  19. package/dist/cjs/services/getFills.d.ts.map +1 -1
  20. package/dist/cjs/services/getFills.js +3 -0
  21. package/dist/cjs/services/getFills.js.map +1 -1
  22. package/dist/cjs/services/getOrder.d.ts.map +1 -1
  23. package/dist/cjs/services/getOrder.js +14 -3
  24. package/dist/cjs/services/getOrder.js.map +1 -1
  25. package/dist/cjs/services/getOrders.d.ts +2 -7
  26. package/dist/cjs/services/getOrders.d.ts.map +1 -1
  27. package/dist/cjs/services/getOrders.js +94 -31
  28. package/dist/cjs/services/getOrders.js.map +1 -1
  29. package/dist/cjs/services/getPositions.d.ts.map +1 -1
  30. package/dist/cjs/services/getPositions.js +1 -1
  31. package/dist/cjs/services/getPositions.js.map +1 -1
  32. package/dist/cjs/types/explorer.d.ts +10 -0
  33. package/dist/cjs/types/explorer.d.ts.map +1 -0
  34. package/dist/cjs/types/explorer.js +17 -0
  35. package/dist/cjs/types/explorer.js.map +1 -0
  36. package/dist/cjs/types/fill.d.ts +6 -0
  37. package/dist/cjs/types/fill.d.ts.map +1 -1
  38. package/dist/cjs/types/index.d.ts +1 -0
  39. package/dist/cjs/types/index.d.ts.map +1 -1
  40. package/dist/cjs/types/index.js +1 -0
  41. package/dist/cjs/types/index.js.map +1 -1
  42. package/dist/cjs/types/ledger.d.ts +24 -1
  43. package/dist/cjs/types/ledger.d.ts.map +1 -1
  44. package/dist/cjs/types/ledger.js +5 -1
  45. package/dist/cjs/types/ledger.js.map +1 -1
  46. package/dist/cjs/types/order.d.ts +24 -0
  47. package/dist/cjs/types/order.d.ts.map +1 -1
  48. package/dist/cjs/types/ws.d.ts +14 -0
  49. package/dist/cjs/types/ws.d.ts.map +1 -1
  50. package/dist/cjs/utils/assetId.d.ts +1 -0
  51. package/dist/cjs/utils/assetId.d.ts.map +1 -1
  52. package/dist/cjs/utils/assetId.js +6 -1
  53. package/dist/cjs/utils/assetId.js.map +1 -1
  54. package/dist/cjs/utils/explorer.d.ts +7 -0
  55. package/dist/cjs/utils/explorer.d.ts.map +1 -0
  56. package/dist/cjs/utils/explorer.js +49 -0
  57. package/dist/cjs/utils/explorer.js.map +1 -0
  58. package/dist/cjs/utils/index.d.ts +4 -3
  59. package/dist/cjs/utils/index.d.ts.map +1 -1
  60. package/dist/cjs/utils/index.js +7 -6
  61. package/dist/cjs/utils/index.js.map +1 -1
  62. package/dist/cjs/utils/infoClient.d.ts +1 -0
  63. package/dist/cjs/utils/infoClient.d.ts.map +1 -1
  64. package/dist/cjs/utils/infoClient.js +16 -10
  65. package/dist/cjs/utils/infoClient.js.map +1 -1
  66. package/dist/cjs/utils/mapActivity.d.ts +5 -3
  67. package/dist/cjs/utils/mapActivity.d.ts.map +1 -1
  68. package/dist/cjs/utils/mapActivity.js +116 -48
  69. package/dist/cjs/utils/mapActivity.js.map +1 -1
  70. package/dist/cjs/utils/mapFill.d.ts.map +1 -1
  71. package/dist/cjs/utils/mapFill.js +0 -1
  72. package/dist/cjs/utils/mapFill.js.map +1 -1
  73. package/dist/cjs/utils/mapOrder.d.ts +4 -9
  74. package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
  75. package/dist/cjs/utils/mapOrder.js +149 -135
  76. package/dist/cjs/utils/mapOrder.js.map +1 -1
  77. package/dist/cjs/utils/spotBalance.d.ts.map +1 -1
  78. package/dist/cjs/utils/spotBalance.js +10 -6
  79. package/dist/cjs/utils/spotBalance.js.map +1 -1
  80. package/dist/cjs/websocket/HyperliquidWsProvider.d.ts +3 -0
  81. package/dist/cjs/websocket/HyperliquidWsProvider.d.ts.map +1 -1
  82. package/dist/cjs/websocket/HyperliquidWsProvider.js +100 -29
  83. package/dist/cjs/websocket/HyperliquidWsProvider.js.map +1 -1
  84. package/dist/esm/HyperliquidProvider.d.ts.map +1 -1
  85. package/dist/esm/HyperliquidProvider.js +1 -2
  86. package/dist/esm/HyperliquidProvider.js.map +1 -1
  87. package/dist/esm/constants.d.ts +8 -0
  88. package/dist/esm/constants.d.ts.map +1 -1
  89. package/dist/esm/constants.js +8 -0
  90. package/dist/esm/constants.js.map +1 -1
  91. package/dist/esm/index.d.ts +1 -3
  92. package/dist/esm/index.d.ts.map +1 -1
  93. package/dist/esm/index.js +1 -2
  94. package/dist/esm/index.js.map +1 -1
  95. package/dist/esm/services/getAccount.d.ts.map +1 -1
  96. package/dist/esm/services/getAccount.js +14 -10
  97. package/dist/esm/services/getAccount.js.map +1 -1
  98. package/dist/esm/services/getActivity.d.ts +2 -2
  99. package/dist/esm/services/getActivity.d.ts.map +1 -1
  100. package/dist/esm/services/getActivity.js +44 -9
  101. package/dist/esm/services/getActivity.js.map +1 -1
  102. package/dist/esm/services/getFills.d.ts.map +1 -1
  103. package/dist/esm/services/getFills.js +4 -1
  104. package/dist/esm/services/getFills.js.map +1 -1
  105. package/dist/esm/services/getOrder.d.ts.map +1 -1
  106. package/dist/esm/services/getOrder.js +15 -4
  107. package/dist/esm/services/getOrder.js.map +1 -1
  108. package/dist/esm/services/getOrders.d.ts +4 -24
  109. package/dist/esm/services/getOrders.d.ts.map +1 -1
  110. package/dist/esm/services/getOrders.js +115 -42
  111. package/dist/esm/services/getOrders.js.map +1 -1
  112. package/dist/esm/services/getPositions.d.ts.map +1 -1
  113. package/dist/esm/services/getPositions.js +2 -2
  114. package/dist/esm/services/getPositions.js.map +1 -1
  115. package/dist/esm/types/explorer.d.ts +27 -0
  116. package/dist/esm/types/explorer.d.ts.map +1 -0
  117. package/dist/esm/types/explorer.js +20 -0
  118. package/dist/esm/types/explorer.js.map +1 -0
  119. package/dist/esm/types/fill.d.ts +11 -0
  120. package/dist/esm/types/fill.d.ts.map +1 -1
  121. package/dist/esm/types/index.d.ts +1 -0
  122. package/dist/esm/types/index.d.ts.map +1 -1
  123. package/dist/esm/types/index.js +1 -0
  124. package/dist/esm/types/index.js.map +1 -1
  125. package/dist/esm/types/ledger.d.ts +28 -1
  126. package/dist/esm/types/ledger.d.ts.map +1 -1
  127. package/dist/esm/types/ledger.js +4 -0
  128. package/dist/esm/types/ledger.js.map +1 -1
  129. package/dist/esm/types/order.d.ts +26 -0
  130. package/dist/esm/types/order.d.ts.map +1 -1
  131. package/dist/esm/types/ws.d.ts +15 -0
  132. package/dist/esm/types/ws.d.ts.map +1 -1
  133. package/dist/esm/utils/assetId.d.ts +9 -0
  134. package/dist/esm/utils/assetId.d.ts.map +1 -1
  135. package/dist/esm/utils/assetId.js +13 -0
  136. package/dist/esm/utils/assetId.js.map +1 -1
  137. package/dist/esm/utils/explorer.d.ts +31 -0
  138. package/dist/esm/utils/explorer.d.ts.map +1 -0
  139. package/dist/esm/utils/explorer.js +68 -0
  140. package/dist/esm/utils/explorer.js.map +1 -0
  141. package/dist/esm/utils/index.d.ts +4 -3
  142. package/dist/esm/utils/index.d.ts.map +1 -1
  143. package/dist/esm/utils/index.js +4 -3
  144. package/dist/esm/utils/index.js.map +1 -1
  145. package/dist/esm/utils/infoClient.d.ts +14 -3
  146. package/dist/esm/utils/infoClient.d.ts.map +1 -1
  147. package/dist/esm/utils/infoClient.js +29 -14
  148. package/dist/esm/utils/infoClient.js.map +1 -1
  149. package/dist/esm/utils/mapActivity.d.ts +16 -13
  150. package/dist/esm/utils/mapActivity.d.ts.map +1 -1
  151. package/dist/esm/utils/mapActivity.js +128 -72
  152. package/dist/esm/utils/mapActivity.js.map +1 -1
  153. package/dist/esm/utils/mapFill.d.ts.map +1 -1
  154. package/dist/esm/utils/mapFill.js +1 -2
  155. package/dist/esm/utils/mapFill.js.map +1 -1
  156. package/dist/esm/utils/mapOrder.d.ts +8 -73
  157. package/dist/esm/utils/mapOrder.d.ts.map +1 -1
  158. package/dist/esm/utils/mapOrder.js +148 -187
  159. package/dist/esm/utils/mapOrder.js.map +1 -1
  160. package/dist/esm/utils/spotBalance.d.ts +1 -1
  161. package/dist/esm/utils/spotBalance.d.ts.map +1 -1
  162. package/dist/esm/utils/spotBalance.js +12 -7
  163. package/dist/esm/utils/spotBalance.js.map +1 -1
  164. package/dist/esm/websocket/HyperliquidWsProvider.d.ts +5 -1
  165. package/dist/esm/websocket/HyperliquidWsProvider.d.ts.map +1 -1
  166. package/dist/esm/websocket/HyperliquidWsProvider.js +105 -34
  167. package/dist/esm/websocket/HyperliquidWsProvider.js.map +1 -1
  168. package/dist/types/HyperliquidProvider.d.ts.map +1 -1
  169. package/dist/types/constants.d.ts +8 -0
  170. package/dist/types/constants.d.ts.map +1 -1
  171. package/dist/types/index.d.ts +1 -3
  172. package/dist/types/index.d.ts.map +1 -1
  173. package/dist/types/services/getAccount.d.ts.map +1 -1
  174. package/dist/types/services/getActivity.d.ts +2 -2
  175. package/dist/types/services/getActivity.d.ts.map +1 -1
  176. package/dist/types/services/getFills.d.ts.map +1 -1
  177. package/dist/types/services/getOrder.d.ts.map +1 -1
  178. package/dist/types/services/getOrders.d.ts +4 -24
  179. package/dist/types/services/getOrders.d.ts.map +1 -1
  180. package/dist/types/services/getPositions.d.ts.map +1 -1
  181. package/dist/types/types/explorer.d.ts +27 -0
  182. package/dist/types/types/explorer.d.ts.map +1 -0
  183. package/dist/types/types/fill.d.ts +11 -0
  184. package/dist/types/types/fill.d.ts.map +1 -1
  185. package/dist/types/types/index.d.ts +1 -0
  186. package/dist/types/types/index.d.ts.map +1 -1
  187. package/dist/types/types/ledger.d.ts +28 -1
  188. package/dist/types/types/ledger.d.ts.map +1 -1
  189. package/dist/types/types/order.d.ts +26 -0
  190. package/dist/types/types/order.d.ts.map +1 -1
  191. package/dist/types/types/ws.d.ts +15 -0
  192. package/dist/types/types/ws.d.ts.map +1 -1
  193. package/dist/types/utils/assetId.d.ts +9 -0
  194. package/dist/types/utils/assetId.d.ts.map +1 -1
  195. package/dist/types/utils/explorer.d.ts +31 -0
  196. package/dist/types/utils/explorer.d.ts.map +1 -0
  197. package/dist/types/utils/index.d.ts +4 -3
  198. package/dist/types/utils/index.d.ts.map +1 -1
  199. package/dist/types/utils/infoClient.d.ts +14 -3
  200. package/dist/types/utils/infoClient.d.ts.map +1 -1
  201. package/dist/types/utils/mapActivity.d.ts +16 -13
  202. package/dist/types/utils/mapActivity.d.ts.map +1 -1
  203. package/dist/types/utils/mapFill.d.ts.map +1 -1
  204. package/dist/types/utils/mapOrder.d.ts +8 -73
  205. package/dist/types/utils/mapOrder.d.ts.map +1 -1
  206. package/dist/types/utils/spotBalance.d.ts +1 -1
  207. package/dist/types/utils/spotBalance.d.ts.map +1 -1
  208. package/dist/types/websocket/HyperliquidWsProvider.d.ts +5 -1
  209. package/dist/types/websocket/HyperliquidWsProvider.d.ts.map +1 -1
  210. package/package.json +3 -3
  211. package/src/HyperliquidProvider.ts +1 -13
  212. package/src/constants.ts +10 -0
  213. package/src/index.ts +1 -2
  214. package/src/services/getAccount.ts +22 -14
  215. package/src/services/getActivity.ts +81 -6
  216. package/src/services/getFills.ts +4 -1
  217. package/src/services/getOrder.ts +29 -5
  218. package/src/services/getOrders.ts +185 -70
  219. package/src/services/getPositions.ts +4 -1
  220. package/src/types/explorer.ts +39 -0
  221. package/src/types/fill.ts +12 -0
  222. package/src/types/index.ts +1 -0
  223. package/src/types/ledger.ts +37 -0
  224. package/src/types/order.ts +25 -0
  225. package/src/types/ws.ts +16 -0
  226. package/src/utils/assetId.ts +16 -0
  227. package/src/utils/explorer.ts +93 -0
  228. package/src/utils/index.ts +16 -7
  229. package/src/utils/infoClient.ts +46 -24
  230. package/src/utils/mapActivity.ts +163 -75
  231. package/src/utils/mapFill.ts +0 -2
  232. package/src/utils/mapOrder.ts +163 -212
  233. package/src/utils/spotBalance.ts +12 -7
  234. package/src/websocket/HyperliquidWsProvider.ts +127 -40
  235. package/dist/cjs/services/getRunningTwaps.d.ts +0 -10
  236. package/dist/cjs/services/getRunningTwaps.d.ts.map +0 -1
  237. package/dist/cjs/services/getRunningTwaps.js +0 -46
  238. package/dist/cjs/services/getRunningTwaps.js.map +0 -1
  239. package/dist/esm/services/getRunningTwaps.d.ts +0 -12
  240. package/dist/esm/services/getRunningTwaps.d.ts.map +0 -1
  241. package/dist/esm/services/getRunningTwaps.js +0 -40
  242. package/dist/esm/services/getRunningTwaps.js.map +0 -1
  243. package/dist/types/services/getRunningTwaps.d.ts +0 -12
  244. package/dist/types/services/getRunningTwaps.d.ts.map +0 -1
  245. 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'
@@ -13,7 +13,7 @@ import type {
13
13
  HyperliquidAccountConfig,
14
14
  Position,
15
15
  } from '@lifi/perps-types'
16
- import type Big from 'big.js'
16
+ import Big from 'big.js'
17
17
  import { PROVIDER_KEY } from '../constants.js'
18
18
  import type { HyperliquidContext } from '../context.js'
19
19
  import {
@@ -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,
@@ -48,8 +49,11 @@ export type GetAccountParams = ProviderGetAccountParams
48
49
  const getAccountValue = (state: HlClearinghouseState): Big =>
49
50
  toWireBig(state.marginSummary.accountValue, 'marginSummary.accountValue')
50
51
 
51
- const getTotalMarginUsed = (state: HlClearinghouseState): number =>
52
- Number.parseFloat(state.marginSummary.totalMarginUsed)
52
+ const getTotalMarginUsed = (state: HlClearinghouseState): Big =>
53
+ toWireBig(
54
+ state.marginSummary.totalMarginUsed,
55
+ 'marginSummary.totalMarginUsed'
56
+ )
53
57
 
54
58
  const getMarginUsed = (
55
59
  abstraction: HlAbstractionMode | null,
@@ -63,25 +67,26 @@ const getMarginUsed = (
63
67
  // Per HL docs, individual per-dex states are not meaningful for these
64
68
  // modes; derive total margin from the already-mapped positions.
65
69
  const total = positions.reduce(
66
- (sum, p) => sum + Number.parseFloat(p.marginUsed),
67
- 0
70
+ (sum, position) =>
71
+ sum.plus(toWireBig(position.marginUsed, 'positions.marginUsed')),
72
+ new Big(0)
68
73
  )
69
- return total.toString()
74
+ return total.toFixed()
70
75
  }
71
76
 
72
77
  if (abstraction === HlAbstractionMode.DEX_ABSTRACTION) {
73
- let total = 0
78
+ let total = new Big(0)
74
79
  for (const [, state] of stateByDex) {
75
- total += getTotalMarginUsed(state)
80
+ total = total.plus(getTotalMarginUsed(state))
76
81
  }
77
- return total.toString()
82
+ return total.toFixed()
78
83
  }
79
84
 
80
85
  const mainState = stateByDex.get('')
81
86
  if (!mainState) {
82
87
  return '0'
83
88
  }
84
- return getTotalMarginUsed(mainState).toString()
89
+ return getTotalMarginUsed(mainState).toFixed()
85
90
  }
86
91
 
87
92
  interface BalancePartition {
@@ -98,9 +103,9 @@ const buildBalances = (
98
103
  quoteAssetByCategory: Map<string, Asset>
99
104
  ): BalancePartition => {
100
105
  const { balances, collateralBalances } = partitionSpotBalances(
101
- spotState.balances.map((b) =>
102
- spotBalance(spotAssetFromToken(b), b.total, priceById)
103
- ),
106
+ spotState.balances
107
+ .filter((b) => !assetIsOutcome(b.coin))
108
+ .map((b) => spotBalance(spotAssetFromToken(b), b.total, priceById)),
104
109
  quoteAssetIds,
105
110
  abstraction === HlAbstractionMode.PORTFOLIO_MARGIN
106
111
  )
@@ -123,6 +128,7 @@ const buildBalances = (
123
128
  asset: quoteAssetByCategory.get(categoryId)!,
124
129
  units: value.toFixed(),
125
130
  valueUsd: value.toFixed(),
131
+ price: '1',
126
132
  })
127
133
  }
128
134
  }
@@ -216,7 +222,9 @@ export const getAccount = async (
216
222
 
217
223
  const positions: Position[] = stateResults.flatMap((state) =>
218
224
  state.assetPositions
219
- .filter(isOpenAssetPosition)
225
+ .filter(
226
+ (ap) => !assetIsOutcome(ap.position.coin) && isOpenAssetPosition(ap)
227
+ )
220
228
  .map((ap) =>
221
229
  mapPosition(
222
230
  ap,
@@ -1,4 +1,9 @@
1
- import { getMarketRegistry, type SDKRequestOptions } from '@lifi/perps-sdk'
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 { mapFundingActivity, mapLedgerEntry } from '../utils/index.js'
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 merged = [...ledgerItems, ...fundingItems].sort(
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 `userFunding` endpoints, sorted
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
  )
@@ -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
  })
@@ -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 { HlOrderStatusResponse } from '../types/index.js'
12
- import { mapOrder } from '../utils/index.js'
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 oid = Number.parseInt(params.id, 10)
34
- if (Number.isNaN(oid)) {
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}. Must be a numeric oid.`
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}`