@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
@@ -3,6 +3,7 @@ import {
3
3
  isActiveMarket,
4
4
  isActiveOrderStatus,
5
5
  type MarketRegistry,
6
+ PerpsError,
6
7
  type PerpsSDKClient,
7
8
  type ProviderGetQuoteParams,
8
9
  type QuoteListener,
@@ -21,13 +22,13 @@ import type {
21
22
  AccountResponse,
22
23
  Balance,
23
24
  MarketContext,
24
- OpenOrder,
25
+ Order,
25
26
  OrderbookLevel,
26
27
  OrderbookResponse,
27
28
  Position,
28
29
  Subscription,
29
- TriggerOrder,
30
30
  } from '@lifi/perps-types'
31
+ import { PerpsErrorCode } from '@lifi/perps-types'
31
32
  import Big from 'big.js'
32
33
  import { isAddress } from 'viem'
33
34
  import {
@@ -38,6 +39,7 @@ import {
38
39
  import type {
39
40
  HlAssetPosition,
40
41
  HlOrderDetail,
42
+ HlOrderStatusResponse,
41
43
  HlUserFill,
42
44
  HlWsActiveAssetCtxData,
43
45
  HlWsActiveSpotAssetCtxData,
@@ -49,6 +51,7 @@ import type {
49
51
  HlWsL2BookData,
50
52
  HlWsL2Data,
51
53
  HlWsMessage,
54
+ HlWsOrder,
52
55
  HlWsPacData,
53
56
  HlWsPerpAssetCtx,
54
57
  HlWsPerpAssetCtxPayload,
@@ -61,18 +64,16 @@ import type {
61
64
  import { HlAbstractionMode } from '../types/index.js'
62
65
  import { toWireBig } from '../utils/decimal.js'
63
66
  import {
67
+ assetIsOutcome,
64
68
  decodeCompressedJson,
65
69
  decodeFastAssetCtxs,
66
70
  hlInfoOptions,
67
71
  infoRequest,
68
72
  isOpenAssetPosition,
69
- isTriggerOrder,
70
73
  mapFill,
71
74
  mapMarketContext,
72
- mapOpenOrder,
73
- mapOrderStatus,
75
+ mapOrder,
74
76
  mapPosition,
75
- mapTriggerOrder,
76
77
  partitionSpotBalances,
77
78
  priceStepToAggregation,
78
79
  spotAssetFromToken,
@@ -119,6 +120,8 @@ export const hyperliquidWsProvider = (): WsProviderFactory =>
119
120
  */
120
121
  export class HyperliquidWsProvider extends WsProviderBase<object> {
121
122
  private orderUpdatesKey: string | undefined
123
+ private orderUpdatesEpoch = 0
124
+ private readonly orderApiUrl: string
122
125
  private readonly clearinghouseRefs = new Map<string, number>()
123
126
  private readonly client: PerpsSDKClient | undefined
124
127
  private readonly registry: MarketRegistry | undefined
@@ -191,6 +194,10 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
191
194
  'every',
192
195
  this.reportDecodeFailure
193
196
  )
197
+ private readonly orderUpdateChain = new DecodeChain(
198
+ 'every',
199
+ this.reportDecodeFailure
200
+ )
194
201
 
195
202
  constructor(wsUrl: string, providerKey: string, client?: PerpsSDKClient) {
196
203
  super(
@@ -199,6 +206,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
199
206
  )
200
207
  this.client = client
201
208
  this.registry = client && getMarketRegistry(client, providerKey)
209
+ const orderApiUrl = new URL(wsUrl)
210
+ orderApiUrl.protocol = orderApiUrl.protocol === 'wss:' ? 'https:' : 'http:'
211
+ this.orderApiUrl = orderApiUrl.origin
202
212
  }
203
213
 
204
214
  override async subscribe(
@@ -350,6 +360,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
350
360
  this.unregisterSub(key)
351
361
  if (this.orderUpdatesKey === key) {
352
362
  this.orderUpdatesKey = undefined
363
+ this.orderUpdatesEpoch++
353
364
  }
354
365
  this.rws.send(
355
366
  JSON.stringify({
@@ -383,6 +394,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
383
394
  `${key.slice('orderUpdates:'.length)}.`
384
395
  )
385
396
  }
397
+ if (active !== key) {
398
+ this.orderUpdatesEpoch++
399
+ }
386
400
  this.orderUpdatesKey = key
387
401
  }
388
402
 
@@ -456,6 +470,8 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
456
470
  this.pacDecodeChain.reset()
457
471
  this.sacDecodeChain.reset()
458
472
  this.orderbookDecodeChain.reset()
473
+ this.orderUpdateChain.reset()
474
+ this.orderUpdatesEpoch++
459
475
  this.orderUpdatesKey = undefined
460
476
  }
461
477
 
@@ -627,7 +643,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
627
643
  this.handleTrades(msg.data as HlWsTrade[])
628
644
  break
629
645
  case 'orderUpdates':
630
- this.handleOrderUpdates(msg.data as HlOrderDetail[])
646
+ this.handleOrderUpdates(msg.data as HlWsOrder[])
631
647
  break
632
648
  case 'userFills':
633
649
  this.handleUserFills(msg.data as HlWsUserFillsData)
@@ -675,7 +691,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
675
691
  }
676
692
  for (const ctx of ctxs) {
677
693
  const marketId = ctx.coin
678
- if (marketId === undefined) {
694
+ if (marketId === undefined || assetIsOutcome(marketId)) {
679
695
  continue
680
696
  }
681
697
  const merged = mergePerpAssetCtx(byMarketId[marketId], marketId, ctx)
@@ -694,6 +710,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
694
710
  const ctxs = await decodeCompressedJson<HlWsSacData>(base64)
695
711
  const touched = new Set<string>()
696
712
  for (const [sacKey, ctx] of Object.entries(ctxs)) {
713
+ if (assetIsOutcome(sacKey)) {
714
+ continue
715
+ }
697
716
  const marketId = spotMarketIdBySacKey.get(sacKey)
698
717
  if (marketId === undefined) {
699
718
  continue
@@ -733,14 +752,19 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
733
752
  private handleFastAssetCtxs(base64: string) {
734
753
  this.fastDecodeChain.push(async () => {
735
754
  const ctxs = await decodeFastAssetCtxs(base64)
755
+ const touched: string[] = []
736
756
  for (const [marketId, ctx] of Object.entries(ctxs)) {
757
+ if (assetIsOutcome(marketId)) {
758
+ continue
759
+ }
737
760
  const prev = this.fastCtxByMarketId[marketId]
738
761
  this.fastCtxByMarketId[marketId] = {
739
762
  markPx: 'markPx' in ctx ? ctx.markPx : prev?.markPx,
740
763
  midPx: 'midPx' in ctx ? ctx.midPx : prev?.midPx,
741
764
  }
765
+ touched.push(marketId)
742
766
  }
743
- this.emitMarketsContext(Object.keys(ctxs))
767
+ this.emitMarketsContext(touched)
744
768
  })
745
769
  }
746
770
 
@@ -770,12 +794,15 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
770
794
  * Context for one market from the cached feeds: spot asset context when it
771
795
  * maps, else perp asset context with mid + mark overlaid from
772
796
  * `fastAssetCtxs`, else the fast feed alone — each price standing in for the
773
- * other where it carries only one of mid/mark.
797
+ * other where it carries only one of mid/mark. An attached registry gates the
798
+ * market id: an id it does not list, or lists as delisted, yields no context.
774
799
  */
775
800
  private computeMarketContext(marketId: string): MarketContext | undefined {
776
- const market = this.registry?.get(marketId)
777
- if (market !== undefined && !isActiveMarket(market)) {
778
- return undefined
801
+ if (this.registry !== undefined) {
802
+ const market = this.registry.get(marketId)
803
+ if (market === undefined || !isActiveMarket(market)) {
804
+ return undefined
805
+ }
779
806
  }
780
807
  const fast = this.fastCtxByMarketId[marketId]
781
808
  const spotCtx = this.spotCtxByMarketId[marketId]
@@ -801,6 +828,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
801
828
  }
802
829
 
803
830
  private handleActiveAssetCtx(data: HlWsActiveAssetCtxData, raw: string) {
831
+ if (assetIsOutcome(data.coin)) {
832
+ return
833
+ }
804
834
  const ctx = activePerpAssetCtx(data.coin, data.ctx)
805
835
  if (ctx === undefined) {
806
836
  wsLog.parseFailure(this.providerKey, raw)
@@ -813,6 +843,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
813
843
  }
814
844
 
815
845
  private handleActiveSpotAssetCtx(data: HlWsActiveSpotAssetCtxData) {
846
+ if (assetIsOutcome(data.coin)) {
847
+ return
848
+ }
816
849
  const context = mapSpotMarketContext(data.coin, data.ctx)
817
850
  if (context === undefined) {
818
851
  return
@@ -943,6 +976,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
943
976
  }
944
977
 
945
978
  private handleCandle(data: HlWsCandleData) {
979
+ if (assetIsOutcome(data.s)) {
980
+ return
981
+ }
946
982
  this.emit(`candle:${data.s}:${data.i}`, {
947
983
  channel: 'candle',
948
984
  data: {
@@ -958,6 +994,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
958
994
 
959
995
  private handleTrades(data: HlWsTrade[]) {
960
996
  for (const trade of data) {
997
+ if (assetIsOutcome(trade.coin)) {
998
+ continue
999
+ }
961
1000
  this.emit(`trades:${trade.coin}`, {
962
1001
  channel: 'trades',
963
1002
  data: [
@@ -975,36 +1014,76 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
975
1014
  }
976
1015
  }
977
1016
 
978
- private handleOrderUpdates(data: HlOrderDetail[]) {
979
- // Untagged frame: attributable only via the single-address invariant.
1017
+ private handleOrderUpdates(data: HlWsOrder[]) {
980
1018
  const key = this.orderUpdatesKey
981
- if (key === undefined) {
1019
+ const client = this.client
1020
+ const epoch = this.orderUpdatesEpoch
1021
+ if (key === undefined || client === undefined) {
982
1022
  return
983
1023
  }
984
- const openOrders: OpenOrder[] = []
985
- const triggerOrders: TriggerOrder[] = []
986
- const terminated: string[] = []
987
- for (const detail of data) {
988
- const o = detail.order
989
- const orderId = String(o.oid)
990
- if (!isActiveOrderStatus(mapOrderStatus(detail.status))) {
991
- terminated.push(orderId)
992
- continue
1024
+ this.orderUpdateChain.push(async () => {
1025
+ if (epoch !== this.orderUpdatesEpoch || key !== this.orderUpdatesKey) {
1026
+ return
993
1027
  }
994
- // Unknown market id (absent from the synced snapshot); skip just this item.
995
- const market = this.registry?.get(o.coin)
996
- if (!market) {
997
- continue
1028
+ const mapped = await Promise.all(
1029
+ data.map(async (update) => {
1030
+ const basic = update.order
1031
+ if (assetIsOutcome(basic.coin)) {
1032
+ return undefined
1033
+ }
1034
+ const market = this.registry?.get(basic.coin)
1035
+ if (market === undefined) {
1036
+ return undefined
1037
+ }
1038
+ const response = await infoRequest<HlOrderStatusResponse>(
1039
+ this.orderApiUrl,
1040
+ {
1041
+ type: 'orderStatus',
1042
+ user: key.slice('orderUpdates:'.length),
1043
+ oid: basic.oid,
1044
+ },
1045
+ hlInfoOptions(client)
1046
+ )
1047
+ if (response.status !== 'order') {
1048
+ throw new PerpsError(
1049
+ PerpsErrorCode.OrderNotFound,
1050
+ `Hyperliquid order metadata not found: ${basic.oid}`
1051
+ )
1052
+ }
1053
+ // REST supplies execution metadata; the stream owns this event's lifecycle and quantities.
1054
+ const detail: HlOrderDetail = {
1055
+ status: update.status,
1056
+ statusTimestamp: update.statusTimestamp,
1057
+ order: {
1058
+ ...response.order.order,
1059
+ coin: basic.coin,
1060
+ side: basic.side,
1061
+ limitPx: basic.limitPx,
1062
+ sz: basic.sz,
1063
+ oid: basic.oid,
1064
+ timestamp: basic.timestamp,
1065
+ origSz: basic.origSz,
1066
+ cloid: basic.cloid ?? response.order.order.cloid,
1067
+ },
1068
+ }
1069
+ return mapOrder(detail, market)
1070
+ })
1071
+ )
1072
+ if (epoch !== this.orderUpdatesEpoch || key !== this.orderUpdatesKey) {
1073
+ return
998
1074
  }
999
- if (isTriggerOrder(o)) {
1000
- triggerOrders.push(mapTriggerOrder(o, market))
1001
- } else {
1002
- openOrders.push(mapOpenOrder(o, market))
1075
+ const orders: Order[] = []
1076
+ const terminated: string[] = []
1077
+ for (const order of mapped) {
1078
+ if (order === undefined) {
1079
+ continue
1080
+ }
1081
+ orders.push(order)
1082
+ if (!isActiveOrderStatus(order.status)) {
1083
+ terminated.push(order.orderId)
1084
+ }
1003
1085
  }
1004
- }
1005
- this.emit(key, {
1006
- channel: 'orderUpdates',
1007
- data: { openOrders, triggerOrders, terminated },
1086
+ this.emit(key, { channel: 'orderUpdates', data: { orders, terminated } })
1008
1087
  })
1009
1088
  }
1010
1089
 
@@ -1017,6 +1096,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
1017
1096
  const items = data.isSnapshot
1018
1097
  ? []
1019
1098
  : data.fills.flatMap((f) => {
1099
+ if (assetIsOutcome(f.coin)) {
1100
+ return []
1101
+ }
1020
1102
  const market = this.registry?.get(f.coin)
1021
1103
  return market ? [mapFill(f as HlUserFill, market)] : []
1022
1104
  })
@@ -1031,7 +1113,10 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
1031
1113
  ) {
1032
1114
  const positions = data.clearinghouseStates.flatMap(([, state]) =>
1033
1115
  state.assetPositions.flatMap((ap) => {
1034
- if (!isOpenAssetPosition(ap as HlAssetPosition)) {
1116
+ if (
1117
+ assetIsOutcome(ap.position.coin) ||
1118
+ !isOpenAssetPosition(ap as HlAssetPosition)
1119
+ ) {
1035
1120
  return []
1036
1121
  }
1037
1122
  const market = this.registry?.get(ap.position.coin)
@@ -1254,8 +1339,10 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
1254
1339
  const markets = this.registry?.activeMarkets ?? []
1255
1340
  const priceById = spotPriceById(markets, this.mergedMids())
1256
1341
  const rows = data.spotState.balances
1257
- .filter((balance) =>
1258
- toWireBig(balance.total, 'spotState.balances.total').gt(0)
1342
+ .filter(
1343
+ (balance) =>
1344
+ !assetIsOutcome(balance.coin) &&
1345
+ toWireBig(balance.total, 'spotState.balances.total').gt(0)
1259
1346
  )
1260
1347
  .map((balance) => ({
1261
1348
  balance: spotBalance(
@@ -1,10 +0,0 @@
1
- import { type SDKRequestOptions } from '@lifi/perps-sdk';
2
- import { type TwapOrder } from '@lifi/perps-types';
3
- import type { Address } from 'viem';
4
- import type { HyperliquidContext } from '../context.js';
5
- export interface GetRunningTwapsParams {
6
- address: Address;
7
- marketId?: string;
8
- }
9
- export declare const getRunningTwaps: ({ client, apiUrl }: HyperliquidContext, params: GetRunningTwapsParams, options?: SDKRequestOptions) => Promise<TwapOrder[]>;
10
- //# sourceMappingURL=getRunningTwaps.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getRunningTwaps.d.ts","sourceRoot":"","sources":["../../../src/services/getRunningTwaps.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAqBvD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAGD,eAAO,MAAM,eAAe,GAC1B,oBAAoB,kBAAkB,EACtC,QAAQ,qBAAqB,EAC7B,UAAU,iBAAiB,KAC1B,OAAO,CAAC,SAAS,EAAE,CA2CrB,CAAA"}
@@ -1,46 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getRunningTwaps = void 0;
7
- const perps_sdk_1 = require("@lifi/perps-sdk");
8
- const perps_types_1 = require("@lifi/perps-types");
9
- const big_js_1 = __importDefault(require("big.js"));
10
- const constants_js_1 = require("../constants.js");
11
- const infoClient_js_1 = require("../utils/infoClient.js");
12
- const getRunningTwaps = async ({ client, apiUrl }, params, options) => {
13
- const registry = (0, perps_sdk_1.getMarketRegistry)(client, constants_js_1.PROVIDER_KEY);
14
- const [history] = await Promise.all([
15
- (0, infoClient_js_1.infoRequest)(apiUrl, { type: 'twapHistory', user: params.address }, (0, infoClient_js_1.hlInfoOptions)(client, options)),
16
- registry.sync(),
17
- ]);
18
- return history
19
- .filter((entry) => entry.status.status === 'activated' &&
20
- (params.marketId === undefined || entry.state.coin === params.marketId))
21
- .map((entry) => {
22
- if (entry.twapId === undefined) {
23
- throw new perps_sdk_1.PerpsError(perps_types_1.PerpsErrorCode.ThirdPartyError, 'Hyperliquid returned an active TWAP without a twapId.');
24
- }
25
- const filledSize = new big_js_1.default(entry.state.executedSz);
26
- return {
27
- twapId: String(entry.twapId),
28
- market: (0, perps_sdk_1.toMarketDisplay)(registry.require(entry.state.coin)),
29
- side: entry.state.side === 'B' ? perps_types_1.OrderSide.BUY : perps_types_1.OrderSide.SELL,
30
- totalSize: entry.state.sz,
31
- filledSize: entry.state.executedSz,
32
- ...(filledSize.eq(0)
33
- ? {}
34
- : {
35
- avgFillPrice: new big_js_1.default(entry.state.executedNtl)
36
- .div(filledSize)
37
- .toString(),
38
- }),
39
- startedAt: new Date(entry.state.timestamp).toISOString(),
40
- durationSeconds: entry.state.minutes * 60,
41
- status: perps_types_1.TwapOrderStatus.RUNNING,
42
- };
43
- });
44
- };
45
- exports.getRunningTwaps = getRunningTwaps;
46
- //# sourceMappingURL=getRunningTwaps.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getRunningTwaps.js","sourceRoot":"","sources":["../../../src/services/getRunningTwaps.ts"],"names":[],"mappings":";;;;;;AAAA,+CAKwB;AACxB,mDAK0B;AAC1B,oDAAwB;AAExB,kDAA8C;AAE9C,0DAAmE;AA0B5D,MAAM,eAAe,GAAG,KAAK,EAClC,EAAE,MAAM,EAAE,MAAM,EAAsB,EACtC,MAA6B,EAC7B,OAA2B,EACL,EAAE;IACxB,MAAM,QAAQ,GAAG,IAAA,6BAAiB,EAAC,MAAM,EAAE,2BAAY,CAAC,CAAA;IACxD,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClC,IAAA,2BAAW,EACT,MAAM,EACN,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,EAC7C,IAAA,6BAAa,EAAC,MAAM,EAAE,OAAO,CAAC,CAC/B;QACD,QAAQ,CAAC,IAAI,EAAE;KAChB,CAAC,CAAA;IAEF,OAAO,OAAO;SACX,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW;QACnC,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,CAC1E;SACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,sBAAU,CAClB,4BAAc,CAAC,eAAe,EAC9B,uDAAuD,CACxD,CAAA;QACH,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,gBAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QAClD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YAC5B,MAAM,EAAE,IAAA,2BAAe,EAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,uBAAS,CAAC,GAAG,CAAC,CAAC,CAAC,uBAAS,CAAC,IAAI;YAC/D,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;YACzB,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU;YAClC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;gBAClB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,YAAY,EAAE,IAAI,gBAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;yBAC3C,GAAG,CAAC,UAAU,CAAC;yBACf,QAAQ,EAAE;iBACd,CAAC;YACN,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;YACxD,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE;YACzC,MAAM,EAAE,6BAAe,CAAC,OAAO;SAChC,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC,CAAA;AA/CY,QAAA,eAAe,mBA+C3B"}
@@ -1,12 +0,0 @@
1
- import { type SDKRequestOptions } from '@lifi/perps-sdk';
2
- import { type TwapOrder } from '@lifi/perps-types';
3
- import type { Address } from 'viem';
4
- import type { HyperliquidContext } from '../context.js';
5
- /** Parameters for {@link getRunningTwaps}. @public */
6
- export interface GetRunningTwapsParams {
7
- address: Address;
8
- marketId?: string;
9
- }
10
- /** Fetch the user's active TWAP states from Hyperliquid's `twapHistory` info request. */
11
- export declare const getRunningTwaps: ({ client, apiUrl }: HyperliquidContext, params: GetRunningTwapsParams, options?: SDKRequestOptions) => Promise<TwapOrder[]>;
12
- //# sourceMappingURL=getRunningTwaps.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getRunningTwaps.d.ts","sourceRoot":"","sources":["../../../src/services/getRunningTwaps.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAoBvD,sDAAsD;AACtD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,yFAAyF;AACzF,eAAO,MAAM,eAAe,GAC1B,oBAAoB,kBAAkB,EACtC,QAAQ,qBAAqB,EAC7B,UAAU,iBAAiB,KAC1B,OAAO,CAAC,SAAS,EAAE,CA2CrB,CAAA"}
@@ -1,40 +0,0 @@
1
- import { getMarketRegistry, PerpsError, toMarketDisplay, } from '@lifi/perps-sdk';
2
- import { OrderSide, PerpsErrorCode, TwapOrderStatus, } from '@lifi/perps-types';
3
- import Big from 'big.js';
4
- import { PROVIDER_KEY } from '../constants.js';
5
- import { hlInfoOptions, infoRequest } from '../utils/infoClient.js';
6
- /** Fetch the user's active TWAP states from Hyperliquid's `twapHistory` info request. */
7
- export const getRunningTwaps = async ({ client, apiUrl }, params, options) => {
8
- const registry = getMarketRegistry(client, PROVIDER_KEY);
9
- const [history] = await Promise.all([
10
- infoRequest(apiUrl, { type: 'twapHistory', user: params.address }, hlInfoOptions(client, options)),
11
- registry.sync(),
12
- ]);
13
- return history
14
- .filter((entry) => entry.status.status === 'activated' &&
15
- (params.marketId === undefined || entry.state.coin === params.marketId))
16
- .map((entry) => {
17
- if (entry.twapId === undefined) {
18
- throw new PerpsError(PerpsErrorCode.ThirdPartyError, 'Hyperliquid returned an active TWAP without a twapId.');
19
- }
20
- const filledSize = new Big(entry.state.executedSz);
21
- return {
22
- twapId: String(entry.twapId),
23
- market: toMarketDisplay(registry.require(entry.state.coin)),
24
- side: entry.state.side === 'B' ? OrderSide.BUY : OrderSide.SELL,
25
- totalSize: entry.state.sz,
26
- filledSize: entry.state.executedSz,
27
- ...(filledSize.eq(0)
28
- ? {}
29
- : {
30
- avgFillPrice: new Big(entry.state.executedNtl)
31
- .div(filledSize)
32
- .toString(),
33
- }),
34
- startedAt: new Date(entry.state.timestamp).toISOString(),
35
- durationSeconds: entry.state.minutes * 60,
36
- status: TwapOrderStatus.RUNNING,
37
- };
38
- });
39
- };
40
- //# sourceMappingURL=getRunningTwaps.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getRunningTwaps.js","sourceRoot":"","sources":["../../../src/services/getRunningTwaps.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,UAAU,EAEV,eAAe,GAChB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,SAAS,EACT,cAAc,EAEd,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,GAAG,MAAM,QAAQ,CAAA;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAyBnE,yFAAyF;AACzF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,EAAE,MAAM,EAAE,MAAM,EAAsB,EACtC,MAA6B,EAC7B,OAA2B,EACL,EAAE;IACxB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACxD,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClC,WAAW,CACT,MAAM,EACN,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,EAC7C,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAC/B;QACD,QAAQ,CAAC,IAAI,EAAE;KAChB,CAAC,CAAA;IAEF,OAAO,OAAO;SACX,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW;QACnC,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,CAC1E;SACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,UAAU,CAClB,cAAc,CAAC,eAAe,EAC9B,uDAAuD,CACxD,CAAA;QACH,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QAClD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YAC5B,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI;YAC/D,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;YACzB,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU;YAClC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;gBAClB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,YAAY,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;yBAC3C,GAAG,CAAC,UAAU,CAAC;yBACf,QAAQ,EAAE;iBACd,CAAC;YACN,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;YACxD,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE;YACzC,MAAM,EAAE,eAAe,CAAC,OAAO;SAChC,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC,CAAA"}
@@ -1,12 +0,0 @@
1
- import { type SDKRequestOptions } from '@lifi/perps-sdk';
2
- import { type TwapOrder } from '@lifi/perps-types';
3
- import type { Address } from 'viem';
4
- import type { HyperliquidContext } from '../context.js';
5
- /** Parameters for {@link getRunningTwaps}. @public */
6
- export interface GetRunningTwapsParams {
7
- address: Address;
8
- marketId?: string;
9
- }
10
- /** Fetch the user's active TWAP states from Hyperliquid's `twapHistory` info request. */
11
- export declare const getRunningTwaps: ({ client, apiUrl }: HyperliquidContext, params: GetRunningTwapsParams, options?: SDKRequestOptions) => Promise<TwapOrder[]>;
12
- //# sourceMappingURL=getRunningTwaps.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getRunningTwaps.d.ts","sourceRoot":"","sources":["../../../src/services/getRunningTwaps.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAoBvD,sDAAsD;AACtD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,yFAAyF;AACzF,eAAO,MAAM,eAAe,GAC1B,oBAAoB,kBAAkB,EACtC,QAAQ,qBAAqB,EAC7B,UAAU,iBAAiB,KAC1B,OAAO,CAAC,SAAS,EAAE,CA2CrB,CAAA"}
@@ -1,90 +0,0 @@
1
- import {
2
- getMarketRegistry,
3
- PerpsError,
4
- type SDKRequestOptions,
5
- toMarketDisplay,
6
- } from '@lifi/perps-sdk'
7
- import {
8
- OrderSide,
9
- PerpsErrorCode,
10
- type TwapOrder,
11
- TwapOrderStatus,
12
- } from '@lifi/perps-types'
13
- import Big from 'big.js'
14
- import type { Address } from 'viem'
15
- import { PROVIDER_KEY } from '../constants.js'
16
- import type { HyperliquidContext } from '../context.js'
17
- import { hlInfoOptions, infoRequest } from '../utils/infoClient.js'
18
-
19
- interface HlTwapState {
20
- coin: string
21
- executedNtl: string
22
- executedSz: string
23
- minutes: number
24
- side: 'A' | 'B'
25
- sz: string
26
- timestamp: number
27
- }
28
-
29
- interface HlTwapHistoryEntry {
30
- state: HlTwapState
31
- status: { status: string; description?: string }
32
- time: number
33
- twapId?: number
34
- }
35
-
36
- /** Parameters for {@link getRunningTwaps}. @public */
37
- export interface GetRunningTwapsParams {
38
- address: Address
39
- marketId?: string
40
- }
41
-
42
- /** Fetch the user's active TWAP states from Hyperliquid's `twapHistory` info request. */
43
- export const getRunningTwaps = async (
44
- { client, apiUrl }: HyperliquidContext,
45
- params: GetRunningTwapsParams,
46
- options?: SDKRequestOptions
47
- ): Promise<TwapOrder[]> => {
48
- const registry = getMarketRegistry(client, PROVIDER_KEY)
49
- const [history] = await Promise.all([
50
- infoRequest<HlTwapHistoryEntry[]>(
51
- apiUrl,
52
- { type: 'twapHistory', user: params.address },
53
- hlInfoOptions(client, options)
54
- ),
55
- registry.sync(),
56
- ])
57
-
58
- return history
59
- .filter(
60
- (entry) =>
61
- entry.status.status === 'activated' &&
62
- (params.marketId === undefined || entry.state.coin === params.marketId)
63
- )
64
- .map((entry) => {
65
- if (entry.twapId === undefined) {
66
- throw new PerpsError(
67
- PerpsErrorCode.ThirdPartyError,
68
- 'Hyperliquid returned an active TWAP without a twapId.'
69
- )
70
- }
71
- const filledSize = new Big(entry.state.executedSz)
72
- return {
73
- twapId: String(entry.twapId),
74
- market: toMarketDisplay(registry.require(entry.state.coin)),
75
- side: entry.state.side === 'B' ? OrderSide.BUY : OrderSide.SELL,
76
- totalSize: entry.state.sz,
77
- filledSize: entry.state.executedSz,
78
- ...(filledSize.eq(0)
79
- ? {}
80
- : {
81
- avgFillPrice: new Big(entry.state.executedNtl)
82
- .div(filledSize)
83
- .toString(),
84
- }),
85
- startedAt: new Date(entry.state.timestamp).toISOString(),
86
- durationSeconds: entry.state.minutes * 60,
87
- status: TwapOrderStatus.RUNNING,
88
- }
89
- })
90
- }