@lifi/perps-sdk-provider-hyperliquid 0.2.0-alpha.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 (434) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +174 -0
  3. package/dist/cjs/HyperliquidProvider.d.ts +15 -0
  4. package/dist/cjs/HyperliquidProvider.d.ts.map +1 -0
  5. package/dist/cjs/HyperliquidProvider.js +135 -0
  6. package/dist/cjs/HyperliquidProvider.js.map +1 -0
  7. package/dist/cjs/accountConfig.d.ts +3 -0
  8. package/dist/cjs/accountConfig.d.ts.map +1 -0
  9. package/dist/cjs/accountConfig.js +45 -0
  10. package/dist/cjs/accountConfig.js.map +1 -0
  11. package/dist/cjs/accountSummary.d.ts +3 -0
  12. package/dist/cjs/accountSummary.d.ts.map +1 -0
  13. package/dist/cjs/accountSummary.js +12 -0
  14. package/dist/cjs/accountSummary.js.map +1 -0
  15. package/dist/cjs/constants.d.ts +11 -0
  16. package/dist/cjs/constants.d.ts.map +1 -0
  17. package/dist/cjs/constants.js +16 -0
  18. package/dist/cjs/constants.js.map +1 -0
  19. package/dist/cjs/context.d.ts +13 -0
  20. package/dist/cjs/context.d.ts.map +1 -0
  21. package/dist/cjs/context.js +24 -0
  22. package/dist/cjs/context.js.map +1 -0
  23. package/dist/cjs/index.d.ts +22 -0
  24. package/dist/cjs/index.d.ts.map +1 -0
  25. package/dist/cjs/index.js +47 -0
  26. package/dist/cjs/index.js.map +1 -0
  27. package/dist/cjs/package.json +1 -0
  28. package/dist/cjs/services/getAccount.d.ts +6 -0
  29. package/dist/cjs/services/getAccount.d.ts.map +1 -0
  30. package/dist/cjs/services/getAccount.js +109 -0
  31. package/dist/cjs/services/getAccount.js.map +1 -0
  32. package/dist/cjs/services/getActivity.d.ts +15 -0
  33. package/dist/cjs/services/getActivity.d.ts.map +1 -0
  34. package/dist/cjs/services/getActivity.js +65 -0
  35. package/dist/cjs/services/getActivity.js.map +1 -0
  36. package/dist/cjs/services/getFills.d.ts +13 -0
  37. package/dist/cjs/services/getFills.d.ts.map +1 -0
  38. package/dist/cjs/services/getFills.js +40 -0
  39. package/dist/cjs/services/getFills.js.map +1 -0
  40. package/dist/cjs/services/getOrder.d.ts +6 -0
  41. package/dist/cjs/services/getOrder.d.ts.map +1 -0
  42. package/dist/cjs/services/getOrder.js +27 -0
  43. package/dist/cjs/services/getOrder.js.map +1 -0
  44. package/dist/cjs/services/getOrders.d.ts +11 -0
  45. package/dist/cjs/services/getOrders.d.ts.map +1 -0
  46. package/dist/cjs/services/getOrders.js +51 -0
  47. package/dist/cjs/services/getOrders.js.map +1 -0
  48. package/dist/cjs/services/getPositions.d.ts +11 -0
  49. package/dist/cjs/services/getPositions.d.ts.map +1 -0
  50. package/dist/cjs/services/getPositions.js +33 -0
  51. package/dist/cjs/services/getPositions.js.map +1 -0
  52. package/dist/cjs/signers/HyperliquidAgentStore.d.ts +19 -0
  53. package/dist/cjs/signers/HyperliquidAgentStore.d.ts.map +1 -0
  54. package/dist/cjs/signers/HyperliquidAgentStore.js +110 -0
  55. package/dist/cjs/signers/HyperliquidAgentStore.js.map +1 -0
  56. package/dist/cjs/signers/index.d.ts +4 -0
  57. package/dist/cjs/signers/index.d.ts.map +1 -0
  58. package/dist/cjs/signers/index.js +8 -0
  59. package/dist/cjs/signers/index.js.map +1 -0
  60. package/dist/cjs/signers/signActions.d.ts +7 -0
  61. package/dist/cjs/signers/signActions.d.ts.map +1 -0
  62. package/dist/cjs/signers/signActions.js +33 -0
  63. package/dist/cjs/signers/signActions.js.map +1 -0
  64. package/dist/cjs/types/account.d.ts +51 -0
  65. package/dist/cjs/types/account.d.ts.map +1 -0
  66. package/dist/cjs/types/account.js +10 -0
  67. package/dist/cjs/types/account.js.map +1 -0
  68. package/dist/cjs/types/action.d.ts +51 -0
  69. package/dist/cjs/types/action.d.ts.map +1 -0
  70. package/dist/cjs/types/action.js +11 -0
  71. package/dist/cjs/types/action.js.map +1 -0
  72. package/dist/cjs/types/asset.d.ts +66 -0
  73. package/dist/cjs/types/asset.d.ts.map +1 -0
  74. package/dist/cjs/types/asset.js +3 -0
  75. package/dist/cjs/types/asset.js.map +1 -0
  76. package/dist/cjs/types/fill.d.ts +18 -0
  77. package/dist/cjs/types/fill.d.ts.map +1 -0
  78. package/dist/cjs/types/fill.js +3 -0
  79. package/dist/cjs/types/fill.js.map +1 -0
  80. package/dist/cjs/types/index.d.ts +8 -0
  81. package/dist/cjs/types/index.d.ts.map +1 -0
  82. package/dist/cjs/types/index.js +24 -0
  83. package/dist/cjs/types/index.js.map +1 -0
  84. package/dist/cjs/types/ledger.d.ts +53 -0
  85. package/dist/cjs/types/ledger.d.ts.map +1 -0
  86. package/dist/cjs/types/ledger.js +8 -0
  87. package/dist/cjs/types/ledger.js.map +1 -0
  88. package/dist/cjs/types/order.d.ts +46 -0
  89. package/dist/cjs/types/order.d.ts.map +1 -0
  90. package/dist/cjs/types/order.js +3 -0
  91. package/dist/cjs/types/order.js.map +1 -0
  92. package/dist/cjs/types/ws.d.ts +36 -0
  93. package/dist/cjs/types/ws.d.ts.map +1 -0
  94. package/dist/cjs/types/ws.js +3 -0
  95. package/dist/cjs/types/ws.js.map +1 -0
  96. package/dist/cjs/utils/assetId.d.ts +4 -0
  97. package/dist/cjs/utils/assetId.d.ts.map +1 -0
  98. package/dist/cjs/utils/assetId.js +21 -0
  99. package/dist/cjs/utils/assetId.js.map +1 -0
  100. package/dist/cjs/utils/index.d.ts +15 -0
  101. package/dist/cjs/utils/index.d.ts.map +1 -0
  102. package/dist/cjs/utils/index.js +49 -0
  103. package/dist/cjs/utils/index.js.map +1 -0
  104. package/dist/cjs/utils/infoClient.d.ts +10 -0
  105. package/dist/cjs/utils/infoClient.d.ts.map +1 -0
  106. package/dist/cjs/utils/infoClient.js +58 -0
  107. package/dist/cjs/utils/infoClient.js.map +1 -0
  108. package/dist/cjs/utils/liquidation.d.ts +3 -0
  109. package/dist/cjs/utils/liquidation.d.ts.map +1 -0
  110. package/dist/cjs/utils/liquidation.js +24 -0
  111. package/dist/cjs/utils/liquidation.js.map +1 -0
  112. package/dist/cjs/utils/mapActivity.d.ts +5 -0
  113. package/dist/cjs/utils/mapActivity.d.ts.map +1 -0
  114. package/dist/cjs/utils/mapActivity.js +133 -0
  115. package/dist/cjs/utils/mapActivity.js.map +1 -0
  116. package/dist/cjs/utils/mapFill.d.ts +6 -0
  117. package/dist/cjs/utils/mapFill.d.ts.map +1 -0
  118. package/dist/cjs/utils/mapFill.js +33 -0
  119. package/dist/cjs/utils/mapFill.js.map +1 -0
  120. package/dist/cjs/utils/mapMarket.d.ts +4 -0
  121. package/dist/cjs/utils/mapMarket.d.ts.map +1 -0
  122. package/dist/cjs/utils/mapMarket.js +22 -0
  123. package/dist/cjs/utils/mapMarket.js.map +1 -0
  124. package/dist/cjs/utils/mapMarketPrice.d.ts +4 -0
  125. package/dist/cjs/utils/mapMarketPrice.d.ts.map +1 -0
  126. package/dist/cjs/utils/mapMarketPrice.js +22 -0
  127. package/dist/cjs/utils/mapMarketPrice.js.map +1 -0
  128. package/dist/cjs/utils/mapOrder.d.ts +12 -0
  129. package/dist/cjs/utils/mapOrder.d.ts.map +1 -0
  130. package/dist/cjs/utils/mapOrder.js +156 -0
  131. package/dist/cjs/utils/mapOrder.js.map +1 -0
  132. package/dist/cjs/utils/mapPosition.d.ts +5 -0
  133. package/dist/cjs/utils/mapPosition.d.ts.map +1 -0
  134. package/dist/cjs/utils/mapPosition.js +28 -0
  135. package/dist/cjs/utils/mapPosition.js.map +1 -0
  136. package/dist/cjs/utils/marketDisplay.d.ts +4 -0
  137. package/dist/cjs/utils/marketDisplay.d.ts.map +1 -0
  138. package/dist/cjs/utils/marketDisplay.js +23 -0
  139. package/dist/cjs/utils/marketDisplay.js.map +1 -0
  140. package/dist/cjs/utils/orderFormatting.d.ts +4 -0
  141. package/dist/cjs/utils/orderFormatting.d.ts.map +1 -0
  142. package/dist/cjs/utils/orderFormatting.js +30 -0
  143. package/dist/cjs/utils/orderFormatting.js.map +1 -0
  144. package/dist/cjs/utils/priceStepToAggregation.d.ts +5 -0
  145. package/dist/cjs/utils/priceStepToAggregation.d.ts.map +1 -0
  146. package/dist/cjs/utils/priceStepToAggregation.js +36 -0
  147. package/dist/cjs/utils/priceStepToAggregation.js.map +1 -0
  148. package/dist/cjs/utils/spotBalance.d.ts +6 -0
  149. package/dist/cjs/utils/spotBalance.d.ts.map +1 -0
  150. package/dist/cjs/utils/spotBalance.js +34 -0
  151. package/dist/cjs/utils/spotBalance.js.map +1 -0
  152. package/dist/cjs/websocket/HyperliquidWsProvider.d.ts +29 -0
  153. package/dist/cjs/websocket/HyperliquidWsProvider.d.ts.map +1 -0
  154. package/dist/cjs/websocket/HyperliquidWsProvider.js +359 -0
  155. package/dist/cjs/websocket/HyperliquidWsProvider.js.map +1 -0
  156. package/dist/cjs/websocket/index.d.ts +2 -0
  157. package/dist/cjs/websocket/index.d.ts.map +1 -0
  158. package/dist/cjs/websocket/index.js +6 -0
  159. package/dist/cjs/websocket/index.js.map +1 -0
  160. package/dist/esm/HyperliquidProvider.d.ts +64 -0
  161. package/dist/esm/HyperliquidProvider.d.ts.map +1 -0
  162. package/dist/esm/HyperliquidProvider.js +162 -0
  163. package/dist/esm/HyperliquidProvider.js.map +1 -0
  164. package/dist/esm/accountConfig.d.ts +10 -0
  165. package/dist/esm/accountConfig.d.ts.map +1 -0
  166. package/dist/esm/accountConfig.js +65 -0
  167. package/dist/esm/accountConfig.js.map +1 -0
  168. package/dist/esm/accountSummary.d.ts +10 -0
  169. package/dist/esm/accountSummary.d.ts.map +1 -0
  170. package/dist/esm/accountSummary.js +22 -0
  171. package/dist/esm/accountSummary.js.map +1 -0
  172. package/dist/esm/constants.d.ts +40 -0
  173. package/dist/esm/constants.d.ts.map +1 -0
  174. package/dist/esm/constants.js +42 -0
  175. package/dist/esm/constants.js.map +1 -0
  176. package/dist/esm/context.d.ts +26 -0
  177. package/dist/esm/context.d.ts.map +1 -0
  178. package/dist/esm/context.js +25 -0
  179. package/dist/esm/context.js.map +1 -0
  180. package/dist/esm/index.d.ts +31 -0
  181. package/dist/esm/index.d.ts.map +1 -0
  182. package/dist/esm/index.js +26 -0
  183. package/dist/esm/index.js.map +1 -0
  184. package/dist/esm/package.json +1 -0
  185. package/dist/esm/services/getAccount.d.ts +28 -0
  186. package/dist/esm/services/getAccount.d.ts.map +1 -0
  187. package/dist/esm/services/getAccount.js +134 -0
  188. package/dist/esm/services/getAccount.js.map +1 -0
  189. package/dist/esm/services/getActivity.d.ts +33 -0
  190. package/dist/esm/services/getActivity.d.ts.map +1 -0
  191. package/dist/esm/services/getActivity.js +75 -0
  192. package/dist/esm/services/getActivity.js.map +1 -0
  193. package/dist/esm/services/getFills.d.ts +34 -0
  194. package/dist/esm/services/getFills.d.ts.map +1 -0
  195. package/dist/esm/services/getFills.js +49 -0
  196. package/dist/esm/services/getFills.js.map +1 -0
  197. package/dist/esm/services/getOrder.d.ts +17 -0
  198. package/dist/esm/services/getOrder.d.ts.map +1 -0
  199. package/dist/esm/services/getOrder.js +29 -0
  200. package/dist/esm/services/getOrder.js.map +1 -0
  201. package/dist/esm/services/getOrders.d.ts +27 -0
  202. package/dist/esm/services/getOrders.d.ts.map +1 -0
  203. package/dist/esm/services/getOrders.js +57 -0
  204. package/dist/esm/services/getOrders.js.map +1 -0
  205. package/dist/esm/services/getPositions.d.ts +26 -0
  206. package/dist/esm/services/getPositions.d.ts.map +1 -0
  207. package/dist/esm/services/getPositions.js +37 -0
  208. package/dist/esm/services/getPositions.js.map +1 -0
  209. package/dist/esm/signers/HyperliquidAgentStore.d.ts +54 -0
  210. package/dist/esm/signers/HyperliquidAgentStore.d.ts.map +1 -0
  211. package/dist/esm/signers/HyperliquidAgentStore.js +134 -0
  212. package/dist/esm/signers/HyperliquidAgentStore.js.map +1 -0
  213. package/dist/esm/signers/index.d.ts +4 -0
  214. package/dist/esm/signers/index.d.ts.map +1 -0
  215. package/dist/esm/signers/index.js +4 -0
  216. package/dist/esm/signers/index.js.map +1 -0
  217. package/dist/esm/signers/signActions.d.ts +15 -0
  218. package/dist/esm/signers/signActions.d.ts.map +1 -0
  219. package/dist/esm/signers/signActions.js +38 -0
  220. package/dist/esm/signers/signActions.js.map +1 -0
  221. package/dist/esm/types/account.d.ts +64 -0
  222. package/dist/esm/types/account.d.ts.map +1 -0
  223. package/dist/esm/types/account.js +13 -0
  224. package/dist/esm/types/account.js.map +1 -0
  225. package/dist/esm/types/action.d.ts +61 -0
  226. package/dist/esm/types/action.d.ts.map +1 -0
  227. package/dist/esm/types/action.js +16 -0
  228. package/dist/esm/types/action.js.map +1 -0
  229. package/dist/esm/types/asset.d.ts +82 -0
  230. package/dist/esm/types/asset.d.ts.map +1 -0
  231. package/dist/esm/types/asset.js +3 -0
  232. package/dist/esm/types/asset.js.map +1 -0
  233. package/dist/esm/types/fill.d.ts +21 -0
  234. package/dist/esm/types/fill.d.ts.map +1 -0
  235. package/dist/esm/types/fill.js +3 -0
  236. package/dist/esm/types/fill.js.map +1 -0
  237. package/dist/esm/types/index.d.ts +8 -0
  238. package/dist/esm/types/index.d.ts.map +1 -0
  239. package/dist/esm/types/index.js +11 -0
  240. package/dist/esm/types/index.js.map +1 -0
  241. package/dist/esm/types/ledger.d.ts +93 -0
  242. package/dist/esm/types/ledger.d.ts.map +1 -0
  243. package/dist/esm/types/ledger.js +16 -0
  244. package/dist/esm/types/ledger.js.map +1 -0
  245. package/dist/esm/types/order.d.ts +51 -0
  246. package/dist/esm/types/order.d.ts.map +1 -0
  247. package/dist/esm/types/order.js +3 -0
  248. package/dist/esm/types/order.js.map +1 -0
  249. package/dist/esm/types/ws.d.ts +43 -0
  250. package/dist/esm/types/ws.d.ts.map +1 -0
  251. package/dist/esm/types/ws.js +3 -0
  252. package/dist/esm/types/ws.js.map +1 -0
  253. package/dist/esm/utils/assetId.d.ts +20 -0
  254. package/dist/esm/utils/assetId.d.ts.map +1 -0
  255. package/dist/esm/utils/assetId.js +31 -0
  256. package/dist/esm/utils/assetId.js.map +1 -0
  257. package/dist/esm/utils/index.d.ts +15 -0
  258. package/dist/esm/utils/index.d.ts.map +1 -0
  259. package/dist/esm/utils/index.js +17 -0
  260. package/dist/esm/utils/index.js.map +1 -0
  261. package/dist/esm/utils/infoClient.d.ts +28 -0
  262. package/dist/esm/utils/infoClient.d.ts.map +1 -0
  263. package/dist/esm/utils/infoClient.js +70 -0
  264. package/dist/esm/utils/infoClient.js.map +1 -0
  265. package/dist/esm/utils/liquidation.d.ts +48 -0
  266. package/dist/esm/utils/liquidation.d.ts.map +1 -0
  267. package/dist/esm/utils/liquidation.js +65 -0
  268. package/dist/esm/utils/liquidation.js.map +1 -0
  269. package/dist/esm/utils/mapActivity.d.ts +15 -0
  270. package/dist/esm/utils/mapActivity.d.ts.map +1 -0
  271. package/dist/esm/utils/mapActivity.js +148 -0
  272. package/dist/esm/utils/mapActivity.js.map +1 -0
  273. package/dist/esm/utils/mapFill.d.ts +11 -0
  274. package/dist/esm/utils/mapFill.d.ts.map +1 -0
  275. package/dist/esm/utils/mapFill.js +34 -0
  276. package/dist/esm/utils/mapFill.js.map +1 -0
  277. package/dist/esm/utils/mapMarket.d.ts +12 -0
  278. package/dist/esm/utils/mapMarket.d.ts.map +1 -0
  279. package/dist/esm/utils/mapMarket.js +27 -0
  280. package/dist/esm/utils/mapMarket.js.map +1 -0
  281. package/dist/esm/utils/mapMarketPrice.d.ts +10 -0
  282. package/dist/esm/utils/mapMarketPrice.d.ts.map +1 -0
  283. package/dist/esm/utils/mapMarketPrice.js +24 -0
  284. package/dist/esm/utils/mapMarketPrice.js.map +1 -0
  285. package/dist/esm/utils/mapOrder.d.ts +49 -0
  286. package/dist/esm/utils/mapOrder.d.ts.map +1 -0
  287. package/dist/esm/utils/mapOrder.js +182 -0
  288. package/dist/esm/utils/mapOrder.js.map +1 -0
  289. package/dist/esm/utils/mapPosition.d.ts +12 -0
  290. package/dist/esm/utils/mapPosition.d.ts.map +1 -0
  291. package/dist/esm/utils/mapPosition.js +30 -0
  292. package/dist/esm/utils/mapPosition.js.map +1 -0
  293. package/dist/esm/utils/marketDisplay.d.ts +17 -0
  294. package/dist/esm/utils/marketDisplay.d.ts.map +1 -0
  295. package/dist/esm/utils/marketDisplay.js +31 -0
  296. package/dist/esm/utils/marketDisplay.js.map +1 -0
  297. package/dist/esm/utils/orderFormatting.d.ts +50 -0
  298. package/dist/esm/utils/orderFormatting.d.ts.map +1 -0
  299. package/dist/esm/utils/orderFormatting.js +78 -0
  300. package/dist/esm/utils/orderFormatting.js.map +1 -0
  301. package/dist/esm/utils/priceStepToAggregation.d.ts +20 -0
  302. package/dist/esm/utils/priceStepToAggregation.d.ts.map +1 -0
  303. package/dist/esm/utils/priceStepToAggregation.js +51 -0
  304. package/dist/esm/utils/priceStepToAggregation.js.map +1 -0
  305. package/dist/esm/utils/spotBalance.d.ts +18 -0
  306. package/dist/esm/utils/spotBalance.d.ts.map +1 -0
  307. package/dist/esm/utils/spotBalance.js +40 -0
  308. package/dist/esm/utils/spotBalance.js.map +1 -0
  309. package/dist/esm/websocket/HyperliquidWsProvider.d.ts +61 -0
  310. package/dist/esm/websocket/HyperliquidWsProvider.d.ts.map +1 -0
  311. package/dist/esm/websocket/HyperliquidWsProvider.js +406 -0
  312. package/dist/esm/websocket/HyperliquidWsProvider.js.map +1 -0
  313. package/dist/esm/websocket/index.d.ts +2 -0
  314. package/dist/esm/websocket/index.d.ts.map +1 -0
  315. package/dist/esm/websocket/index.js +3 -0
  316. package/dist/esm/websocket/index.js.map +1 -0
  317. package/dist/types/HyperliquidProvider.d.ts +64 -0
  318. package/dist/types/HyperliquidProvider.d.ts.map +1 -0
  319. package/dist/types/accountConfig.d.ts +10 -0
  320. package/dist/types/accountConfig.d.ts.map +1 -0
  321. package/dist/types/accountSummary.d.ts +10 -0
  322. package/dist/types/accountSummary.d.ts.map +1 -0
  323. package/dist/types/constants.d.ts +40 -0
  324. package/dist/types/constants.d.ts.map +1 -0
  325. package/dist/types/context.d.ts +26 -0
  326. package/dist/types/context.d.ts.map +1 -0
  327. package/dist/types/index.d.ts +31 -0
  328. package/dist/types/index.d.ts.map +1 -0
  329. package/dist/types/services/getAccount.d.ts +28 -0
  330. package/dist/types/services/getAccount.d.ts.map +1 -0
  331. package/dist/types/services/getActivity.d.ts +33 -0
  332. package/dist/types/services/getActivity.d.ts.map +1 -0
  333. package/dist/types/services/getFills.d.ts +34 -0
  334. package/dist/types/services/getFills.d.ts.map +1 -0
  335. package/dist/types/services/getOrder.d.ts +17 -0
  336. package/dist/types/services/getOrder.d.ts.map +1 -0
  337. package/dist/types/services/getOrders.d.ts +27 -0
  338. package/dist/types/services/getOrders.d.ts.map +1 -0
  339. package/dist/types/services/getPositions.d.ts +26 -0
  340. package/dist/types/services/getPositions.d.ts.map +1 -0
  341. package/dist/types/signers/HyperliquidAgentStore.d.ts +54 -0
  342. package/dist/types/signers/HyperliquidAgentStore.d.ts.map +1 -0
  343. package/dist/types/signers/index.d.ts +4 -0
  344. package/dist/types/signers/index.d.ts.map +1 -0
  345. package/dist/types/signers/signActions.d.ts +15 -0
  346. package/dist/types/signers/signActions.d.ts.map +1 -0
  347. package/dist/types/types/account.d.ts +64 -0
  348. package/dist/types/types/account.d.ts.map +1 -0
  349. package/dist/types/types/action.d.ts +61 -0
  350. package/dist/types/types/action.d.ts.map +1 -0
  351. package/dist/types/types/asset.d.ts +82 -0
  352. package/dist/types/types/asset.d.ts.map +1 -0
  353. package/dist/types/types/fill.d.ts +21 -0
  354. package/dist/types/types/fill.d.ts.map +1 -0
  355. package/dist/types/types/index.d.ts +8 -0
  356. package/dist/types/types/index.d.ts.map +1 -0
  357. package/dist/types/types/ledger.d.ts +93 -0
  358. package/dist/types/types/ledger.d.ts.map +1 -0
  359. package/dist/types/types/order.d.ts +51 -0
  360. package/dist/types/types/order.d.ts.map +1 -0
  361. package/dist/types/types/ws.d.ts +43 -0
  362. package/dist/types/types/ws.d.ts.map +1 -0
  363. package/dist/types/utils/assetId.d.ts +20 -0
  364. package/dist/types/utils/assetId.d.ts.map +1 -0
  365. package/dist/types/utils/index.d.ts +15 -0
  366. package/dist/types/utils/index.d.ts.map +1 -0
  367. package/dist/types/utils/infoClient.d.ts +28 -0
  368. package/dist/types/utils/infoClient.d.ts.map +1 -0
  369. package/dist/types/utils/liquidation.d.ts +48 -0
  370. package/dist/types/utils/liquidation.d.ts.map +1 -0
  371. package/dist/types/utils/mapActivity.d.ts +15 -0
  372. package/dist/types/utils/mapActivity.d.ts.map +1 -0
  373. package/dist/types/utils/mapFill.d.ts +11 -0
  374. package/dist/types/utils/mapFill.d.ts.map +1 -0
  375. package/dist/types/utils/mapMarket.d.ts +12 -0
  376. package/dist/types/utils/mapMarket.d.ts.map +1 -0
  377. package/dist/types/utils/mapMarketPrice.d.ts +10 -0
  378. package/dist/types/utils/mapMarketPrice.d.ts.map +1 -0
  379. package/dist/types/utils/mapOrder.d.ts +49 -0
  380. package/dist/types/utils/mapOrder.d.ts.map +1 -0
  381. package/dist/types/utils/mapPosition.d.ts +12 -0
  382. package/dist/types/utils/mapPosition.d.ts.map +1 -0
  383. package/dist/types/utils/marketDisplay.d.ts +17 -0
  384. package/dist/types/utils/marketDisplay.d.ts.map +1 -0
  385. package/dist/types/utils/orderFormatting.d.ts +50 -0
  386. package/dist/types/utils/orderFormatting.d.ts.map +1 -0
  387. package/dist/types/utils/priceStepToAggregation.d.ts +20 -0
  388. package/dist/types/utils/priceStepToAggregation.d.ts.map +1 -0
  389. package/dist/types/utils/spotBalance.d.ts +18 -0
  390. package/dist/types/utils/spotBalance.d.ts.map +1 -0
  391. package/dist/types/websocket/HyperliquidWsProvider.d.ts +61 -0
  392. package/dist/types/websocket/HyperliquidWsProvider.d.ts.map +1 -0
  393. package/dist/types/websocket/index.d.ts +2 -0
  394. package/dist/types/websocket/index.d.ts.map +1 -0
  395. package/package.json +73 -0
  396. package/src/HyperliquidProvider.ts +381 -0
  397. package/src/accountConfig.ts +89 -0
  398. package/src/accountSummary.ts +32 -0
  399. package/src/constants.ts +47 -0
  400. package/src/context.ts +41 -0
  401. package/src/index.ts +45 -0
  402. package/src/services/getAccount.ts +263 -0
  403. package/src/services/getActivity.ts +162 -0
  404. package/src/services/getFills.ts +96 -0
  405. package/src/services/getOrder.ts +61 -0
  406. package/src/services/getOrders.ts +101 -0
  407. package/src/services/getPositions.ts +76 -0
  408. package/src/signers/HyperliquidAgentStore.ts +176 -0
  409. package/src/signers/index.ts +5 -0
  410. package/src/signers/signActions.ts +78 -0
  411. package/src/types/account.ts +74 -0
  412. package/src/types/action.ts +66 -0
  413. package/src/types/asset.ts +96 -0
  414. package/src/types/fill.ts +24 -0
  415. package/src/types/index.ts +11 -0
  416. package/src/types/ledger.ts +111 -0
  417. package/src/types/order.ts +56 -0
  418. package/src/types/ws.ts +47 -0
  419. package/src/utils/assetId.ts +38 -0
  420. package/src/utils/index.ts +38 -0
  421. package/src/utils/infoClient.ts +111 -0
  422. package/src/utils/liquidation.ts +74 -0
  423. package/src/utils/mapActivity.ts +182 -0
  424. package/src/utils/mapFill.ts +48 -0
  425. package/src/utils/mapMarket.ts +33 -0
  426. package/src/utils/mapMarketPrice.ts +33 -0
  427. package/src/utils/mapOrder.ts +218 -0
  428. package/src/utils/mapPosition.ts +40 -0
  429. package/src/utils/marketDisplay.ts +38 -0
  430. package/src/utils/orderFormatting.ts +93 -0
  431. package/src/utils/priceStepToAggregation.ts +58 -0
  432. package/src/utils/spotBalance.ts +51 -0
  433. package/src/websocket/HyperliquidWsProvider.ts +533 -0
  434. package/src/websocket/index.ts +3 -0
@@ -0,0 +1,48 @@
1
+ import {
2
+ classifyFillFromPosition,
3
+ ExplorerChainId,
4
+ explorerTxUrl,
5
+ } from '@lifi/perps-sdk'
6
+ import type { Fill, MarketDisplay } from '@lifi/perps-types'
7
+ import {
8
+ FillClassification,
9
+ FillStatus,
10
+ LiquidityRole,
11
+ OrderSide,
12
+ OrderType,
13
+ } from '@lifi/perps-types'
14
+ import { SPOT_MARKET_ID } from '../constants.js'
15
+ import type { HlUserFill } from '../types/index.js'
16
+
17
+ export { classifyFillFromPosition }
18
+
19
+ /**
20
+ * Spot-ness comes from the resolved market's category, not the coin string —
21
+ * HL's canonical spot pair 0 is addressed as `PURR/USDC`, not `@0`.
22
+ * @public
23
+ */
24
+ export const mapFill = (fill: HlUserFill, market: MarketDisplay): Fill => ({
25
+ ...(market.categoryId === SPOT_MARKET_ID
26
+ ? { realizedPnl: fill.closedPnl }
27
+ : { realizedPnl: fill.closedPnl === '0' ? null : fill.closedPnl }),
28
+ id: String(fill.tid),
29
+ orderId: String(fill.oid),
30
+ market,
31
+ side: fill.side === 'B' ? OrderSide.BUY : OrderSide.SELL,
32
+ type: fill.dir?.includes('Limit') ? OrderType.LIMIT : OrderType.MARKET,
33
+ size: fill.sz,
34
+ price: fill.px,
35
+ status: FillStatus.FILLED,
36
+ liquidity: fill.crossed ? LiquidityRole.TAKER : LiquidityRole.MAKER,
37
+ filledSize: fill.sz,
38
+ fee: fill.fee,
39
+ startPosition: fill.startPosition,
40
+ explorerLink: explorerTxUrl(ExplorerChainId.HYPERLIQUID, fill.hash),
41
+ classification:
42
+ market.categoryId === SPOT_MARKET_ID
43
+ ? fill.side === 'B'
44
+ ? FillClassification.SPOT_BUY
45
+ : FillClassification.SPOT_SELL
46
+ : classifyFillFromPosition(fill.startPosition, fill.side, fill.sz),
47
+ createdAt: new Date(fill.time).toISOString(),
48
+ })
@@ -0,0 +1,33 @@
1
+ import type { PerpsMarket } from '@lifi/perps-types'
2
+ import { PROVIDER_KEY } from '../constants.js'
3
+ import type { HlUniverseItem } from '../types/index.js'
4
+ import { calculateMaintenanceMarginRate } from './liquidation.js'
5
+ import { coinAsset } from './marketDisplay.js'
6
+ import { getMaxPriceDecimals } from './orderFormatting.js'
7
+
8
+ /** Hyperliquid quotes every perp market in USDC. */
9
+ const QUOTE_SYMBOL = 'USDC'
10
+
11
+ /**
12
+ * Map a Hyperliquid universe entry to a {@link PerpsMarket}'s static instrument
13
+ * metadata. Live mark/stats fields live on the `/prices` item — see
14
+ * {@link mapMarketPrice}. `categoryId` is the `Provider.categories[].id` of the
15
+ * dex the entry was fetched from — known to the caller at fetch time, never
16
+ * re-derived from the coin string.
17
+ * @public
18
+ */
19
+ export const mapMarket = (
20
+ universe: HlUniverseItem,
21
+ categoryId: string
22
+ ): PerpsMarket => ({
23
+ providerId: PROVIDER_KEY,
24
+ id: universe.name,
25
+ categoryId,
26
+ baseAsset: coinAsset(universe.name),
27
+ quoteAsset: coinAsset(QUOTE_SYMBOL),
28
+ szDecimals: universe.szDecimals,
29
+ priceDecimals: getMaxPriceDecimals(universe.szDecimals),
30
+ maxLeverage: universe.maxLeverage,
31
+ onlyIsolated: universe.onlyIsolated === true,
32
+ maintenanceMarginRate: calculateMaintenanceMarginRate(universe.maxLeverage),
33
+ })
@@ -0,0 +1,33 @@
1
+ import type { MarketPrice } from '@lifi/perps-types'
2
+ import type { HlAssetCtx } from '../types/index.js'
3
+
4
+ const NEXT_FUNDING_INTERVAL_MS = 60 * 60 * 1000 // 1 hour
5
+
6
+ /**
7
+ * Map a Hyperliquid asset context plus its mid to a {@link MarketPrice} — the
8
+ * live mark/stats data for the `/prices` item. `mid` is the market mid from
9
+ * `allMids`, known to the caller; `HlAssetCtx` carries no mid of its own.
10
+ * @public
11
+ */
12
+ export const mapMarketPrice = (
13
+ marketId: string,
14
+ assetCtx: HlAssetCtx,
15
+ mid: string
16
+ ): MarketPrice => {
17
+ const now = Date.now()
18
+ const nextFundingTime =
19
+ Math.ceil(now / NEXT_FUNDING_INTERVAL_MS) * NEXT_FUNDING_INTERVAL_MS
20
+
21
+ return {
22
+ marketId,
23
+ price: mid,
24
+ markPrice: assetCtx.markPx,
25
+ prevDayPrice: assetCtx.prevDayPx,
26
+ volume24h: assetCtx.dayNtlVlm,
27
+ openInterest: assetCtx.openInterest,
28
+ funding: {
29
+ rate: assetCtx.funding,
30
+ nextFundingTime,
31
+ },
32
+ }
33
+ }
@@ -0,0 +1,218 @@
1
+ import type {
2
+ MarketDisplay,
3
+ OpenOrder,
4
+ Order,
5
+ TriggerOrder,
6
+ } from '@lifi/perps-types'
7
+ import {
8
+ OrderSide,
9
+ OrderStatus,
10
+ OrderType,
11
+ TimeInForce,
12
+ } from '@lifi/perps-types'
13
+ import type { HlFrontendOpenOrder, HlOrderDetail } from '../types/index.js'
14
+
15
+ /**
16
+ * Map a Hyperliquid orderType string to the OrderType enum.
17
+ *
18
+ * @public
19
+ */
20
+ export const mapOrderType = (orderType: string): OrderType => {
21
+ switch (orderType) {
22
+ case 'Take Profit Market':
23
+ return OrderType.TAKE_PROFIT_MARKET
24
+ case 'Take Profit Limit':
25
+ return OrderType.TAKE_PROFIT_LIMIT
26
+ case 'Stop Market':
27
+ return OrderType.STOP_MARKET
28
+ case 'Stop Limit':
29
+ return OrderType.STOP_LIMIT
30
+ case 'Market':
31
+ return OrderType.MARKET
32
+ default:
33
+ return OrderType.LIMIT
34
+ }
35
+ }
36
+
37
+ /** @public */
38
+ export const isTriggerType = (type: OrderType): boolean =>
39
+ type === OrderType.TAKE_PROFIT_MARKET ||
40
+ type === OrderType.TAKE_PROFIT_LIMIT ||
41
+ type === OrderType.STOP_MARKET ||
42
+ type === OrderType.STOP_LIMIT
43
+
44
+ /**
45
+ * Decide whether a raw Hyperliquid order belongs in the cross-provider
46
+ * `triggerOrders` bucket. Single source of truth for both the REST
47
+ * `getOrders` path (`HlFrontendOpenOrder` payload) and the `orderUpdates`
48
+ * WS handler (`HlOrderDetail.order`, a strict subset).
49
+ *
50
+ * Authoritative signals, in order:
51
+ * 1. `isTrigger` — REST-only boolean Hyperliquid sets on
52
+ * `frontendOpenOrders`. Definitive when present.
53
+ * 2. `isPositionTpsl` — REST-only flag for TP/SL legs attached to a
54
+ * position.
55
+ * 3. `triggerCondition !== 'N/A'` — present on both REST and WS payloads.
56
+ * Non-trigger orders carry the literal `'N/A'`.
57
+ * 4. `triggerPx` non-null and non-zero — present on both. The reliable
58
+ * trigger signal on the WS wire when `orderType` lies (HL pushes
59
+ * `'Limit'` for a freshly-placed TP/SL until REST refetch lands the
60
+ * corrected type).
61
+ * 5. `orderType` — final fall-back via `isTriggerType`.
62
+ * @public
63
+ */
64
+ export const isTriggerOrder = (
65
+ o: HlFrontendOpenOrder | HlOrderDetail['order']
66
+ ): boolean => {
67
+ if ('isTrigger' in o && o.isTrigger === true) {
68
+ return true
69
+ }
70
+ if ('isPositionTpsl' in o && o.isPositionTpsl === true) {
71
+ return true
72
+ }
73
+ if (o.triggerCondition && o.triggerCondition !== 'N/A') {
74
+ return true
75
+ }
76
+ if (
77
+ o.triggerPx != null &&
78
+ o.triggerPx !== '' &&
79
+ parseFloat(o.triggerPx) > 0
80
+ ) {
81
+ return true
82
+ }
83
+ return isTriggerType(mapOrderType(o.orderType))
84
+ }
85
+
86
+ /** @public */
87
+ export const mapOpenOrder = (
88
+ o: HlFrontendOpenOrder,
89
+ market: MarketDisplay
90
+ ): OpenOrder => ({
91
+ orderId: String(o.oid),
92
+ market,
93
+ side: o.side === 'B' ? OrderSide.BUY : OrderSide.SELL,
94
+ type: mapOrderType(o.orderType),
95
+ size: o.sz,
96
+ price: o.limitPx,
97
+ filledSize: o.origSz
98
+ ? (parseFloat(o.origSz) - parseFloat(o.sz)).toString()
99
+ : '0',
100
+ reduceOnly: o.reduceOnly ?? false,
101
+ label: o.isTrigger ? o.triggerCondition : undefined,
102
+ createdAt: new Date(o.timestamp).toISOString(),
103
+ })
104
+
105
+ /** @public */
106
+ export const mapTriggerOrder = (
107
+ o: HlFrontendOpenOrder,
108
+ market: MarketDisplay
109
+ ): TriggerOrder => {
110
+ const type = mapOrderType(o.orderType)
111
+ const isLimit =
112
+ type === OrderType.TAKE_PROFIT_LIMIT || type === OrderType.STOP_LIMIT
113
+ return {
114
+ orderId: String(o.oid),
115
+ market,
116
+ type,
117
+ size: o.sz,
118
+ triggerPrice: o.triggerPx,
119
+ ...(isLimit ? { limitPrice: o.limitPx } : {}),
120
+ label: o.triggerCondition,
121
+ createdAt: new Date(o.timestamp).toISOString(),
122
+ }
123
+ }
124
+
125
+ /** @public */
126
+ export const mapOrderStatus = (status: string): OrderStatus => {
127
+ switch (status) {
128
+ case 'open':
129
+ case 'resting':
130
+ return OrderStatus.OPEN
131
+ case 'filled':
132
+ return OrderStatus.FILLED
133
+ case 'canceled':
134
+ case 'cancelled':
135
+ return OrderStatus.CANCELLED
136
+ case 'rejected':
137
+ return OrderStatus.REJECTED
138
+ case 'triggered':
139
+ return OrderStatus.TRIGGERED
140
+ case 'marginCanceled':
141
+ return OrderStatus.CANCELLED
142
+ default:
143
+ return OrderStatus.PENDING
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Map a raw Hyperliquid order status to a short English sentence
149
+ * describing *why* the order ended in a terminal non-FILLED state. Bare
150
+ * `canceled`/`cancelled`/`rejected` carry no actionable detail and
151
+ * return `undefined`; so do non-terminal and unknown values.
152
+ * @public
153
+ */
154
+ export const mapStatusReason = (status: string): string | undefined => {
155
+ switch (status) {
156
+ case 'iocCanceled':
157
+ return 'Order cancelled: not enough liquidity to fill immediately.'
158
+ case 'reduceOnlyCanceled':
159
+ return 'Order cancelled: would not reduce your position.'
160
+ case 'marginCanceled':
161
+ return 'Order cancelled: insufficient margin.'
162
+ case 'liquidatedCanceled':
163
+ return 'Order cancelled: account was liquidated.'
164
+ case 'siblingFilledCanceled':
165
+ return 'Order cancelled: sibling OCO order filled first.'
166
+ case 'selfTradeCanceled':
167
+ return 'Order cancelled: would self-trade against your own resting order.'
168
+ case 'tickRejected':
169
+ return 'Order rejected: price did not match the tick size.'
170
+ case 'minTradeNtlRejected':
171
+ return 'Order rejected: notional value below the minimum trade size.'
172
+ case 'delistedRejected':
173
+ return 'Order rejected: market has been delisted.'
174
+ default:
175
+ return undefined
176
+ }
177
+ }
178
+
179
+ const mapTimeInForce = (tif: string | undefined): TimeInForce | undefined => {
180
+ switch (tif) {
181
+ case 'Gtc':
182
+ return TimeInForce.GTC
183
+ case 'Ioc':
184
+ return TimeInForce.IOC
185
+ case 'Alo':
186
+ return TimeInForce.POST_ONLY
187
+ default:
188
+ return undefined
189
+ }
190
+ }
191
+
192
+ /** @public */
193
+ export const mapOrder = (
194
+ detail: HlOrderDetail,
195
+ market: MarketDisplay
196
+ ): Order => {
197
+ const o = detail.order
198
+ const filled = parseFloat(o.origSz) - parseFloat(o.sz)
199
+
200
+ return {
201
+ orderId: String(o.oid),
202
+ market,
203
+ side: o.side === 'B' ? OrderSide.BUY : OrderSide.SELL,
204
+ type: mapOrderType(o.orderType),
205
+ price: o.limitPx,
206
+ originalSize: o.origSz,
207
+ remainingSize: o.sz,
208
+ filledSize: filled.toString(),
209
+ timeInForce: mapTimeInForce(o.tif ?? undefined),
210
+ reduceOnly: o.reduceOnly ?? undefined,
211
+ isTrigger: o.triggerCondition !== undefined && o.triggerCondition !== 'N/A',
212
+ triggerPrice: o.triggerPx ?? undefined,
213
+ status: mapOrderStatus(detail.status),
214
+ statusReason: mapStatusReason(detail.status),
215
+ createdAt: new Date(o.timestamp).toISOString(),
216
+ updatedAt: new Date(detail.statusTimestamp).toISOString(),
217
+ }
218
+ }
@@ -0,0 +1,40 @@
1
+ import type { MarketDisplay, Position } from '@lifi/perps-types'
2
+ import { MarginMode, PositionSide } from '@lifi/perps-types'
3
+ import type { HlAssetPosition } from '../types/index.js'
4
+
5
+ /**
6
+ * True when the assetPosition has non-zero size. Hyperliquid keeps zero-size
7
+ * rows in clearinghouse states after a close; both the REST and WS positions
8
+ * paths drop them so a close surfaces as absence from the open set.
9
+ * @public
10
+ */
11
+ export const isOpenAssetPosition = (ap: HlAssetPosition): boolean =>
12
+ Number.parseFloat(ap.position.szi) !== 0
13
+
14
+ /** @public */
15
+ export const mapPosition = (
16
+ ap: HlAssetPosition,
17
+ market: MarketDisplay
18
+ ): Position => {
19
+ const pos = ap.position
20
+ const szi = parseFloat(pos.szi)
21
+
22
+ return {
23
+ market,
24
+ side: szi >= 0 ? PositionSide.LONG : PositionSide.SHORT,
25
+ size: Math.abs(szi).toString(),
26
+ entryPrice: pos.entryPx ?? '0',
27
+ markPrice:
28
+ pos.positionValue && szi !== 0
29
+ ? (parseFloat(pos.positionValue) / Math.abs(szi)).toString()
30
+ : '0',
31
+ liquidationPrice: pos.liquidationPx ?? '0',
32
+ unrealizedPnl: pos.unrealizedPnl,
33
+ leverage: ap.position.leverage.value,
34
+ marginUsed: pos.marginUsed,
35
+ marginMode:
36
+ ap.position.leverage.type === 'cross'
37
+ ? MarginMode.CROSS
38
+ : MarginMode.ISOLATED,
39
+ }
40
+ }
@@ -0,0 +1,38 @@
1
+ import type { Asset, Market } from '@lifi/perps-types'
2
+ import {
3
+ MAIN_DEX_NAME,
4
+ MAIN_MARKET_ID,
5
+ PROVIDER_KEY,
6
+ SPOT_MARKET_ID,
7
+ } from '../constants.js'
8
+
9
+ /**
10
+ * Synthesise the {@link Asset} for a Hyperliquid wire coin. `id` and `logoURI`
11
+ * keep the raw coin — the logo CDN is keyed by it, HIP-3 `dex:` prefix
12
+ * included. `displaySymbol` drops the prefix: the category is carried by
13
+ * `categoryId`, never by the display string.
14
+ * @public
15
+ */
16
+ export const coinAsset = (coin: string): Asset => ({
17
+ providerId: PROVIDER_KEY,
18
+ id: coin,
19
+ displaySymbol: coin.includes(':') ? coin.slice(coin.indexOf(':') + 1) : coin,
20
+ logoURI: `https://app.hyperliquid.xyz/coins/${coin}.svg`,
21
+ })
22
+
23
+ /**
24
+ * Distinct wire `dex` names to fan `clearinghouseState` / `frontendOpenOrders`
25
+ * reads across, derived from the backend market list. Spot is excluded (it has
26
+ * no clearinghouseState); the main perp dex maps to the empty string.
27
+ * @public
28
+ */
29
+ export const perpsDexNames = (markets: readonly Market[]): string[] => {
30
+ const names = new Set<string>()
31
+ for (const m of markets) {
32
+ if (m.categoryId === SPOT_MARKET_ID) {
33
+ continue
34
+ }
35
+ names.add(m.categoryId === MAIN_MARKET_ID ? MAIN_DEX_NAME : m.categoryId)
36
+ }
37
+ return [...names]
38
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Hyperliquid order size and price formatting for exchange submission.
3
+ *
4
+ * These encode Hyperliquid-specific order submission rules. Getting size/price
5
+ * formatting wrong causes rejected orders.
6
+ *
7
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/tick-and-lot-size
8
+ */
9
+
10
+ import Big from 'big.js'
11
+
12
+ /**
13
+ * Max combined decimals (size + price) enforced by Hyperliquid.
14
+ * Perps: 6, Spot: 8
15
+ */
16
+ const MAX_DECIMALS_PERPS = 6
17
+ const MAX_DECIMALS_SPOT = 8
18
+
19
+ function getMaxDecimals(market?: string): number {
20
+ return market === 'spot' ? MAX_DECIMALS_SPOT : MAX_DECIMALS_PERPS
21
+ }
22
+
23
+ /**
24
+ * Derive the maximum number of price decimal places for a given asset.
25
+ *
26
+ * @param szDecimals - The asset's szDecimals (from market meta)
27
+ * @param market - Optional market type (e.g. 'spot'). Defaults to perps rules.
28
+ * @returns Maximum allowed price decimals
29
+ * @public
30
+ */
31
+ export function getMaxPriceDecimals(
32
+ szDecimals: number,
33
+ market?: string
34
+ ): number {
35
+ return Math.max(0, getMaxDecimals(market) - szDecimals)
36
+ }
37
+
38
+ /**
39
+ * Format a size value for order submission.
40
+ *
41
+ * Per Hyperliquid docs (tick-and-lot-size):
42
+ * - Size must be rounded to the asset's szDecimals
43
+ * - Trailing zeroes must be removed for signing
44
+ *
45
+ * @param size - The size value to format
46
+ * @param szDecimals - Number of decimal places allowed for this asset (from meta)
47
+ * @returns Size as a string with correct precision, no trailing zeros
48
+ * @public
49
+ */
50
+ export function formatOrderSize(size: number, szDecimals: number): string {
51
+ // Big.roundDown truncates toward zero — never round a size up, it could
52
+ // exceed available balance. Exact decimal arithmetic: flooring the float
53
+ // product dropped a lot step (0.29 * 100 === 28.999999999999996).
54
+ const truncated = new Big(size).round(szDecimals, Big.roundDown)
55
+ // toFixed() with no dp always emits plain notation; eq(0) guards '-0'
56
+ return truncated.eq(0) ? '0' : truncated.toFixed()
57
+ }
58
+
59
+ /**
60
+ * Format a price value for order submission.
61
+ *
62
+ * Per Hyperliquid docs (tick-and-lot-size):
63
+ * - Maximum 5 significant figures
64
+ * - Max decimals = MAX_DECIMALS - szDecimals (6 for perps, 8 for spot)
65
+ * - Integer prices always allowed regardless of significant figures
66
+ * - Trailing zeroes must be removed for signing
67
+ *
68
+ * Rounding is half-up (away from zero at exact halfway) on the true decimal
69
+ * value, not on the binary float — (1.005).toFixed(2) would give '1.00'.
70
+ *
71
+ * @param price - The price value to format
72
+ * @param szDecimals - The asset's szDecimals (affects max price decimals)
73
+ * @param market - Optional market type (e.g. 'spot'). Defaults to perps rules.
74
+ * @returns Price as a string with correct precision, no trailing zeros
75
+ * @public
76
+ */
77
+ export function formatOrderPrice(
78
+ price: number,
79
+ szDecimals: number,
80
+ market?: string
81
+ ): string {
82
+ const maxPriceDecimals = getMaxPriceDecimals(szDecimals, market)
83
+
84
+ let rounded = new Big(price).round(maxPriceDecimals, Big.roundHalfUp)
85
+
86
+ // Integer prices bypass the 5 sig-fig rule; prec() is a no-op below 6 sig figs
87
+ if (!rounded.mod(1).eq(0)) {
88
+ rounded = rounded.prec(5, Big.roundHalfUp)
89
+ }
90
+
91
+ // toFixed() with no dp always emits plain notation; eq(0) guards '-0'
92
+ return rounded.eq(0) ? '0' : rounded.toFixed()
93
+ }
@@ -0,0 +1,58 @@
1
+ /** Significant-figure bounds Hyperliquid's `l2Book` accepts; `undefined` is full precision. */
2
+ const HL_MIN_SIG_FIGS = 2
3
+ const HL_MAX_SIG_FIGS = 5
4
+ /** Mantissa sub-steps HL honours, but only when `nSigFigs === 5`. */
5
+ const HL_MANTISSA_VALUES: readonly [number, ...number[]] = [1, 2, 5]
6
+
7
+ /** Snap a leading-digit ratio to the nearest mantissa HL accepts (1, 2 or 5). */
8
+ function snapToMantissa(ratio: number): number {
9
+ let closest = HL_MANTISSA_VALUES[0]
10
+ for (const m of HL_MANTISSA_VALUES) {
11
+ if (Math.abs(ratio - m) < Math.abs(ratio - closest)) {
12
+ closest = m
13
+ }
14
+ }
15
+ return closest
16
+ }
17
+
18
+ /**
19
+ * Map a desired price `step` to Hyperliquid's server-side aggregation hint
20
+ * `(nSigFigs, mantissa)` against the order of magnitude of `referencePrice`
21
+ * (the market's mark price gives the digit count). HL buckets the book to
22
+ * `nSigFigs` significant figures, so the figures resolving a price to `step`
23
+ * granularity are `floor(log10(referencePrice)) - floor(log10(step)) + 1`.
24
+ *
25
+ * Returns `{}` (full precision) when the step is finer than HL's 5-sig-fig
26
+ * grid or the inputs are unusable; clamps to {@link HL_MIN_SIG_FIGS} when the
27
+ * step is coarser than HL's lowest granularity. `mantissa` is emitted only for
28
+ * a non-power-of-ten step that lands on the 5-sig-fig grid, since HL ignores
29
+ * it below `nSigFigs === 5`.
30
+ *
31
+ * @public
32
+ */
33
+ export function priceStepToAggregation(
34
+ step: number,
35
+ referencePrice: number
36
+ ): { nSigFigs?: number; mantissa?: number } {
37
+ if (!Number.isFinite(step) || step <= 0) {
38
+ return {}
39
+ }
40
+ if (!Number.isFinite(referencePrice) || referencePrice <= 0) {
41
+ return {}
42
+ }
43
+
44
+ const stepExp = Math.floor(Math.log10(step))
45
+ const priceExp = Math.floor(Math.log10(referencePrice))
46
+ const nSigFigs = priceExp - stepExp + 1
47
+
48
+ if (nSigFigs > HL_MAX_SIG_FIGS) {
49
+ return {}
50
+ }
51
+
52
+ const clamped = Math.max(HL_MIN_SIG_FIGS, nSigFigs)
53
+ const mantissa = snapToMantissa(step / 10 ** stepExp)
54
+ if (clamped === HL_MAX_SIG_FIGS && mantissa !== 1) {
55
+ return { nSigFigs: clamped, mantissa }
56
+ }
57
+ return { nSigFigs: clamped }
58
+ }
@@ -0,0 +1,51 @@
1
+ import { stringToFloat } from '@lifi/perps-sdk'
2
+ import type { Asset, Balance, Market } from '@lifi/perps-types'
3
+ import { SPOT_MARKET_ID } from '../constants.js'
4
+ import type { HlSpotBalance } from '../types/index.js'
5
+ import { coinAsset } from './marketDisplay.js'
6
+
7
+ /**
8
+ * USD price keyed by spot token index: each spot market's live USD price
9
+ * (from `priceByMarketId`, keyed by `Market.id`) under its base-asset id, and
10
+ * every market's quote-asset id at $1. A spot market absent from
11
+ * `priceByMarketId` values its token at 0.
12
+ */
13
+ export const spotPriceById = (
14
+ markets: readonly Market[],
15
+ priceByMarketId: ReadonlyMap<string, number>
16
+ ): Map<string, number> => {
17
+ const map = new Map<string, number>()
18
+ for (const m of markets) {
19
+ if (m.categoryId === SPOT_MARKET_ID) {
20
+ map.set(m.baseAsset.id, priceByMarketId.get(m.id) ?? 0)
21
+ }
22
+ }
23
+ for (const m of markets) {
24
+ if (!map.has(m.quoteAsset.id)) {
25
+ map.set(m.quoteAsset.id, 1)
26
+ }
27
+ }
28
+ return map
29
+ }
30
+
31
+ /**
32
+ * The held spot {@link Asset} for an HL balance: the venue token index
33
+ * (`b.token`) as `Asset.id` — equal to that token's spot `Market.baseAsset.id`
34
+ * — with display fields derived from the coin.
35
+ */
36
+ export const spotAssetFromToken = (b: HlSpotBalance): Asset => ({
37
+ ...coinAsset(b.coin),
38
+ id: String(b.token),
39
+ })
40
+
41
+ /** Assemble a typed spot {@link Balance} from its resolved asset and raw size. */
42
+ export const spotBalance = (
43
+ asset: Asset,
44
+ total: string,
45
+ priceById: Map<string, number>
46
+ ): Balance => ({
47
+ categoryId: SPOT_MARKET_ID,
48
+ asset,
49
+ units: total,
50
+ valueUsd: (stringToFloat(total) * (priceById.get(asset.id) ?? 0)).toString(),
51
+ })