@metamask-previews/perps-controller 0.0.0-preview-ae46ab603 → 0.0.0-preview-e4aa1532

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 (498) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/dist/PerpsController.cjs +2224 -66
  3. package/dist/PerpsController.cjs.map +1 -1
  4. package/dist/PerpsController.d.cts +933 -79
  5. package/dist/PerpsController.d.cts.map +1 -1
  6. package/dist/PerpsController.d.mts +933 -79
  7. package/dist/PerpsController.d.mts.map +1 -1
  8. package/dist/PerpsController.mjs +2221 -64
  9. package/dist/PerpsController.mjs.map +1 -1
  10. package/dist/__mocks__/hyperliquidMock.cjs +68 -0
  11. package/dist/__mocks__/hyperliquidMock.cjs.map +1 -0
  12. package/dist/__mocks__/hyperliquidMock.d.cts +15 -0
  13. package/dist/__mocks__/hyperliquidMock.d.cts.map +1 -0
  14. package/dist/__mocks__/hyperliquidMock.d.mts +15 -0
  15. package/dist/__mocks__/hyperliquidMock.d.mts.map +1 -0
  16. package/dist/__mocks__/hyperliquidMock.mjs +65 -0
  17. package/dist/__mocks__/hyperliquidMock.mjs.map +1 -0
  18. package/dist/__mocks__/providerMocks.cjs +144 -0
  19. package/dist/__mocks__/providerMocks.cjs.map +1 -0
  20. package/dist/__mocks__/providerMocks.d.cts +44 -0
  21. package/dist/__mocks__/providerMocks.d.cts.map +1 -0
  22. package/dist/__mocks__/providerMocks.d.mts +44 -0
  23. package/dist/__mocks__/providerMocks.d.mts.map +1 -0
  24. package/dist/__mocks__/providerMocks.mjs +136 -0
  25. package/dist/__mocks__/providerMocks.mjs.map +1 -0
  26. package/dist/__mocks__/serviceMocks.cjs +187 -0
  27. package/dist/__mocks__/serviceMocks.cjs.map +1 -0
  28. package/dist/__mocks__/serviceMocks.d.cts +58 -0
  29. package/dist/__mocks__/serviceMocks.d.cts.map +1 -0
  30. package/dist/__mocks__/serviceMocks.d.mts +58 -0
  31. package/dist/__mocks__/serviceMocks.d.mts.map +1 -0
  32. package/dist/__mocks__/serviceMocks.mjs +180 -0
  33. package/dist/__mocks__/serviceMocks.mjs.map +1 -0
  34. package/dist/aggregation/SubscriptionMultiplexer.cjs +459 -0
  35. package/dist/aggregation/SubscriptionMultiplexer.cjs.map +1 -0
  36. package/dist/aggregation/SubscriptionMultiplexer.d.cts +222 -0
  37. package/dist/aggregation/SubscriptionMultiplexer.d.cts.map +1 -0
  38. package/dist/aggregation/SubscriptionMultiplexer.d.mts +222 -0
  39. package/dist/aggregation/SubscriptionMultiplexer.d.mts.map +1 -0
  40. package/dist/aggregation/SubscriptionMultiplexer.mjs +455 -0
  41. package/dist/aggregation/SubscriptionMultiplexer.mjs.map +1 -0
  42. package/dist/aggregation/index.cjs +9 -0
  43. package/dist/aggregation/index.cjs.map +1 -0
  44. package/dist/aggregation/index.d.cts +6 -0
  45. package/dist/aggregation/index.d.cts.map +1 -0
  46. package/dist/aggregation/index.d.mts +6 -0
  47. package/dist/aggregation/index.d.mts.map +1 -0
  48. package/dist/aggregation/index.mjs +5 -0
  49. package/dist/aggregation/index.mjs.map +1 -0
  50. package/dist/constants/eventNames.cjs +117 -0
  51. package/dist/constants/eventNames.cjs.map +1 -0
  52. package/dist/constants/eventNames.d.cts +106 -0
  53. package/dist/constants/eventNames.d.cts.map +1 -0
  54. package/dist/constants/eventNames.d.mts +106 -0
  55. package/dist/constants/eventNames.d.mts.map +1 -0
  56. package/dist/constants/eventNames.mjs +114 -0
  57. package/dist/constants/eventNames.mjs.map +1 -0
  58. package/dist/constants/hyperLiquidConfig.cjs +366 -0
  59. package/dist/constants/hyperLiquidConfig.cjs.map +1 -0
  60. package/dist/constants/hyperLiquidConfig.d.cts +276 -0
  61. package/dist/constants/hyperLiquidConfig.d.cts.map +1 -0
  62. package/dist/constants/hyperLiquidConfig.d.mts +276 -0
  63. package/dist/constants/hyperLiquidConfig.d.mts.map +1 -0
  64. package/dist/constants/hyperLiquidConfig.mjs +357 -0
  65. package/dist/constants/hyperLiquidConfig.mjs.map +1 -0
  66. package/dist/constants/index.cjs +23 -0
  67. package/dist/constants/index.cjs.map +1 -0
  68. package/dist/constants/index.d.cts +7 -0
  69. package/dist/constants/index.d.cts.map +1 -0
  70. package/dist/constants/index.d.mts +7 -0
  71. package/dist/constants/index.d.mts.map +1 -0
  72. package/dist/constants/index.mjs +7 -0
  73. package/dist/constants/index.mjs.map +1 -0
  74. package/dist/constants/orderTypes.cjs +31 -0
  75. package/dist/constants/orderTypes.cjs.map +1 -0
  76. package/dist/constants/orderTypes.d.cts +19 -0
  77. package/dist/constants/orderTypes.d.cts.map +1 -0
  78. package/dist/constants/orderTypes.d.mts +19 -0
  79. package/dist/constants/orderTypes.d.mts.map +1 -0
  80. package/dist/constants/orderTypes.mjs +27 -0
  81. package/dist/constants/orderTypes.mjs.map +1 -0
  82. package/dist/constants/performanceMetrics.cjs +61 -0
  83. package/dist/constants/performanceMetrics.cjs.map +1 -0
  84. package/dist/constants/performanceMetrics.d.cts +44 -0
  85. package/dist/constants/performanceMetrics.d.cts.map +1 -0
  86. package/dist/constants/performanceMetrics.d.mts +44 -0
  87. package/dist/constants/performanceMetrics.d.mts.map +1 -0
  88. package/dist/constants/performanceMetrics.mjs +58 -0
  89. package/dist/constants/performanceMetrics.mjs.map +1 -0
  90. package/dist/constants/perpsConfig.cjs +461 -0
  91. package/dist/constants/perpsConfig.cjs.map +1 -0
  92. package/dist/constants/perpsConfig.d.cts +343 -0
  93. package/dist/constants/perpsConfig.d.cts.map +1 -0
  94. package/dist/constants/perpsConfig.d.mts +343 -0
  95. package/dist/constants/perpsConfig.d.mts.map +1 -0
  96. package/dist/constants/perpsConfig.mjs +458 -0
  97. package/dist/constants/perpsConfig.mjs.map +1 -0
  98. package/dist/constants/perpsErrorCodes.cjs +79 -0
  99. package/dist/constants/perpsErrorCodes.cjs.map +1 -0
  100. package/dist/constants/perpsErrorCodes.d.cts +64 -0
  101. package/dist/constants/perpsErrorCodes.d.cts.map +1 -0
  102. package/dist/constants/perpsErrorCodes.d.mts +64 -0
  103. package/dist/constants/perpsErrorCodes.d.mts.map +1 -0
  104. package/dist/constants/perpsErrorCodes.mjs +76 -0
  105. package/dist/constants/perpsErrorCodes.mjs.map +1 -0
  106. package/dist/index.cjs +32 -1
  107. package/dist/index.cjs.map +1 -1
  108. package/dist/index.d.cts +6 -2
  109. package/dist/index.d.cts.map +1 -1
  110. package/dist/index.d.mts +6 -2
  111. package/dist/index.d.mts.map +1 -1
  112. package/dist/index.mjs +9 -1
  113. package/dist/index.mjs.map +1 -1
  114. package/dist/platform-services/HyperLiquidClientService.cjs +857 -0
  115. package/dist/platform-services/HyperLiquidClientService.cjs.map +1 -0
  116. package/dist/platform-services/HyperLiquidClientService.d.cts +263 -0
  117. package/dist/platform-services/HyperLiquidClientService.d.cts.map +1 -0
  118. package/dist/platform-services/HyperLiquidClientService.d.mts +263 -0
  119. package/dist/platform-services/HyperLiquidClientService.d.mts.map +1 -0
  120. package/dist/platform-services/HyperLiquidClientService.mjs +853 -0
  121. package/dist/platform-services/HyperLiquidClientService.mjs.map +1 -0
  122. package/dist/platform-services/HyperLiquidSubscriptionService.cjs +2170 -0
  123. package/dist/platform-services/HyperLiquidSubscriptionService.cjs.map +1 -0
  124. package/dist/platform-services/HyperLiquidSubscriptionService.d.cts +424 -0
  125. package/dist/platform-services/HyperLiquidSubscriptionService.d.cts.map +1 -0
  126. package/dist/platform-services/HyperLiquidSubscriptionService.d.mts +424 -0
  127. package/dist/platform-services/HyperLiquidSubscriptionService.d.mts.map +1 -0
  128. package/dist/platform-services/HyperLiquidSubscriptionService.mjs +2166 -0
  129. package/dist/platform-services/HyperLiquidSubscriptionService.mjs.map +1 -0
  130. package/dist/platform-services/HyperLiquidWalletService.cjs +140 -0
  131. package/dist/platform-services/HyperLiquidWalletService.cjs.map +1 -0
  132. package/dist/platform-services/HyperLiquidWalletService.d.cts +78 -0
  133. package/dist/platform-services/HyperLiquidWalletService.d.cts.map +1 -0
  134. package/dist/platform-services/HyperLiquidWalletService.d.mts +78 -0
  135. package/dist/platform-services/HyperLiquidWalletService.d.mts.map +1 -0
  136. package/dist/platform-services/HyperLiquidWalletService.mjs +136 -0
  137. package/dist/platform-services/HyperLiquidWalletService.mjs.map +1 -0
  138. package/dist/providers/AggregatedPerpsProvider.cjs +777 -0
  139. package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -0
  140. package/dist/providers/AggregatedPerpsProvider.d.cts +466 -0
  141. package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -0
  142. package/dist/providers/AggregatedPerpsProvider.d.mts +466 -0
  143. package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -0
  144. package/dist/providers/AggregatedPerpsProvider.mjs +773 -0
  145. package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -0
  146. package/dist/providers/HyperLiquidProvider.cjs +5172 -0
  147. package/dist/providers/HyperLiquidProvider.cjs.map +1 -0
  148. package/dist/providers/HyperLiquidProvider.d.cts +881 -0
  149. package/dist/providers/HyperLiquidProvider.d.cts.map +1 -0
  150. package/dist/providers/HyperLiquidProvider.d.mts +881 -0
  151. package/dist/providers/HyperLiquidProvider.d.mts.map +1 -0
  152. package/dist/providers/HyperLiquidProvider.mjs +5168 -0
  153. package/dist/providers/HyperLiquidProvider.mjs.map +1 -0
  154. package/dist/providers/index.cjs +11 -0
  155. package/dist/providers/index.cjs.map +1 -0
  156. package/dist/providers/index.d.cts +6 -0
  157. package/dist/providers/index.d.cts.map +1 -0
  158. package/dist/providers/index.d.mts +6 -0
  159. package/dist/providers/index.d.mts.map +1 -0
  160. package/dist/providers/index.mjs +6 -0
  161. package/dist/providers/index.mjs.map +1 -0
  162. package/dist/routing/ProviderRouter.cjs +148 -0
  163. package/dist/routing/ProviderRouter.cjs.map +1 -0
  164. package/dist/routing/ProviderRouter.d.cts +124 -0
  165. package/dist/routing/ProviderRouter.d.cts.map +1 -0
  166. package/dist/routing/ProviderRouter.d.mts +124 -0
  167. package/dist/routing/ProviderRouter.d.mts.map +1 -0
  168. package/dist/routing/ProviderRouter.mjs +144 -0
  169. package/dist/routing/ProviderRouter.mjs.map +1 -0
  170. package/dist/routing/index.cjs +9 -0
  171. package/dist/routing/index.cjs.map +1 -0
  172. package/dist/routing/index.d.cts +6 -0
  173. package/dist/routing/index.d.cts.map +1 -0
  174. package/dist/routing/index.d.mts +6 -0
  175. package/dist/routing/index.d.mts.map +1 -0
  176. package/dist/routing/index.mjs +5 -0
  177. package/dist/routing/index.mjs.map +1 -0
  178. package/dist/selectors.cjs +161 -0
  179. package/dist/selectors.cjs.map +1 -0
  180. package/dist/selectors.d.cts +345 -0
  181. package/dist/selectors.d.cts.map +1 -0
  182. package/dist/selectors.d.mts +345 -0
  183. package/dist/selectors.d.mts.map +1 -0
  184. package/dist/selectors.mjs +153 -0
  185. package/dist/selectors.mjs.map +1 -0
  186. package/dist/services/AccountService.cjs +313 -0
  187. package/dist/services/AccountService.cjs.map +1 -0
  188. package/dist/services/AccountService.d.cts +53 -0
  189. package/dist/services/AccountService.d.cts.map +1 -0
  190. package/dist/services/AccountService.d.mts +53 -0
  191. package/dist/services/AccountService.d.mts.map +1 -0
  192. package/dist/services/AccountService.mjs +309 -0
  193. package/dist/services/AccountService.mjs.map +1 -0
  194. package/dist/services/DataLakeService.cjs +219 -0
  195. package/dist/services/DataLakeService.cjs.map +1 -0
  196. package/dist/services/DataLakeService.d.cts +49 -0
  197. package/dist/services/DataLakeService.d.cts.map +1 -0
  198. package/dist/services/DataLakeService.d.mts +49 -0
  199. package/dist/services/DataLakeService.d.mts.map +1 -0
  200. package/dist/services/DataLakeService.mjs +215 -0
  201. package/dist/services/DataLakeService.mjs.map +1 -0
  202. package/dist/services/DepositService.cjs +96 -0
  203. package/dist/services/DepositService.cjs.map +1 -0
  204. package/dist/services/DepositService.d.cts +37 -0
  205. package/dist/services/DepositService.d.cts.map +1 -0
  206. package/dist/services/DepositService.d.mts +37 -0
  207. package/dist/services/DepositService.d.mts.map +1 -0
  208. package/dist/services/DepositService.mjs +92 -0
  209. package/dist/services/DepositService.mjs.map +1 -0
  210. package/dist/services/EligibilityService.cjs +156 -0
  211. package/dist/services/EligibilityService.cjs.map +1 -0
  212. package/dist/services/EligibilityService.d.cts +48 -0
  213. package/dist/services/EligibilityService.d.cts.map +1 -0
  214. package/dist/services/EligibilityService.d.mts +48 -0
  215. package/dist/services/EligibilityService.d.mts.map +1 -0
  216. package/dist/services/EligibilityService.mjs +152 -0
  217. package/dist/services/EligibilityService.mjs.map +1 -0
  218. package/dist/services/FeatureFlagConfigurationService.cjs +258 -0
  219. package/dist/services/FeatureFlagConfigurationService.cjs.map +1 -0
  220. package/dist/services/FeatureFlagConfigurationService.d.cts +100 -0
  221. package/dist/services/FeatureFlagConfigurationService.d.cts.map +1 -0
  222. package/dist/services/FeatureFlagConfigurationService.d.mts +100 -0
  223. package/dist/services/FeatureFlagConfigurationService.d.mts.map +1 -0
  224. package/dist/services/FeatureFlagConfigurationService.mjs +254 -0
  225. package/dist/services/FeatureFlagConfigurationService.mjs.map +1 -0
  226. package/dist/services/MarketDataService.cjs +875 -0
  227. package/dist/services/MarketDataService.cjs.map +1 -0
  228. package/dist/services/MarketDataService.d.cts +289 -0
  229. package/dist/services/MarketDataService.d.cts.map +1 -0
  230. package/dist/services/MarketDataService.d.mts +289 -0
  231. package/dist/services/MarketDataService.d.mts.map +1 -0
  232. package/dist/services/MarketDataService.mjs +871 -0
  233. package/dist/services/MarketDataService.mjs.map +1 -0
  234. package/dist/services/RewardsIntegrationService.cjs +94 -0
  235. package/dist/services/RewardsIntegrationService.cjs.map +1 -0
  236. package/dist/services/RewardsIntegrationService.d.cts +30 -0
  237. package/dist/services/RewardsIntegrationService.d.cts.map +1 -0
  238. package/dist/services/RewardsIntegrationService.d.mts +30 -0
  239. package/dist/services/RewardsIntegrationService.d.mts.map +1 -0
  240. package/dist/services/RewardsIntegrationService.mjs +90 -0
  241. package/dist/services/RewardsIntegrationService.mjs.map +1 -0
  242. package/dist/services/ServiceContext.cjs +3 -0
  243. package/dist/services/ServiceContext.cjs.map +1 -0
  244. package/dist/services/ServiceContext.d.cts +110 -0
  245. package/dist/services/ServiceContext.d.cts.map +1 -0
  246. package/dist/services/ServiceContext.d.mts +110 -0
  247. package/dist/services/ServiceContext.d.mts.map +1 -0
  248. package/dist/services/ServiceContext.mjs +2 -0
  249. package/dist/services/ServiceContext.mjs.map +1 -0
  250. package/dist/services/TradingService.cjs +1481 -0
  251. package/dist/services/TradingService.cjs.map +1 -0
  252. package/dist/services/TradingService.d.cts +308 -0
  253. package/dist/services/TradingService.d.cts.map +1 -0
  254. package/dist/services/TradingService.d.mts +308 -0
  255. package/dist/services/TradingService.d.mts.map +1 -0
  256. package/dist/services/TradingService.mjs +1477 -0
  257. package/dist/services/TradingService.mjs.map +1 -0
  258. package/dist/services/index.cjs +26 -0
  259. package/dist/services/index.cjs.map +1 -0
  260. package/dist/services/index.d.cts +11 -0
  261. package/dist/services/index.d.cts.map +1 -0
  262. package/dist/services/index.d.mts +11 -0
  263. package/dist/services/index.d.mts.map +1 -0
  264. package/dist/services/index.mjs +10 -0
  265. package/dist/services/index.mjs.map +1 -0
  266. package/dist/services/utils.cjs +16 -0
  267. package/dist/services/utils.cjs.map +1 -0
  268. package/dist/services/utils.d.cts +8 -0
  269. package/dist/services/utils.d.cts.map +1 -0
  270. package/dist/services/utils.d.mts +8 -0
  271. package/dist/services/utils.d.mts.map +1 -0
  272. package/dist/services/utils.mjs +12 -0
  273. package/dist/services/utils.mjs.map +1 -0
  274. package/dist/types/chart.cjs +42 -0
  275. package/dist/types/chart.cjs.map +1 -0
  276. package/dist/types/chart.d.cts +62 -0
  277. package/dist/types/chart.d.cts.map +1 -0
  278. package/dist/types/chart.d.mts +62 -0
  279. package/dist/types/chart.d.mts.map +1 -0
  280. package/dist/types/chart.mjs +39 -0
  281. package/dist/types/chart.mjs.map +1 -0
  282. package/dist/types/hyperliquid-types.cjs +3 -0
  283. package/dist/types/hyperliquid-types.cjs.map +1 -0
  284. package/dist/types/hyperliquid-types.d.cts +52 -0
  285. package/dist/types/hyperliquid-types.d.cts.map +1 -0
  286. package/dist/types/hyperliquid-types.d.mts +52 -0
  287. package/dist/types/hyperliquid-types.d.mts.map +1 -0
  288. package/dist/types/hyperliquid-types.mjs +2 -0
  289. package/dist/types/hyperliquid-types.mjs.map +1 -0
  290. package/dist/types/index.cjs +96 -0
  291. package/dist/types/index.cjs.map +1 -0
  292. package/dist/types/index.d.cts +1153 -0
  293. package/dist/types/index.d.cts.map +1 -0
  294. package/dist/types/index.d.mts +1153 -0
  295. package/dist/types/index.d.mts.map +1 -0
  296. package/dist/types/index.mjs +79 -0
  297. package/dist/types/index.mjs.map +1 -0
  298. package/dist/types/transactionTypes.cjs +28 -0
  299. package/dist/types/transactionTypes.cjs.map +1 -0
  300. package/dist/types/transactionTypes.d.cts +64 -0
  301. package/dist/types/transactionTypes.d.cts.map +1 -0
  302. package/dist/types/transactionTypes.d.mts +64 -0
  303. package/dist/types/transactionTypes.d.mts.map +1 -0
  304. package/dist/types/transactionTypes.mjs +23 -0
  305. package/dist/types/transactionTypes.mjs.map +1 -0
  306. package/dist/utils/accountUtils.cjs +65 -0
  307. package/dist/utils/accountUtils.cjs.map +1 -0
  308. package/dist/utils/accountUtils.d.cts +26 -0
  309. package/dist/utils/accountUtils.d.cts.map +1 -0
  310. package/dist/utils/accountUtils.d.mts +26 -0
  311. package/dist/utils/accountUtils.d.mts.map +1 -0
  312. package/dist/utils/accountUtils.mjs +61 -0
  313. package/dist/utils/accountUtils.mjs.map +1 -0
  314. package/dist/utils/amountConversion.cjs +61 -0
  315. package/dist/utils/amountConversion.cjs.map +1 -0
  316. package/dist/utils/amountConversion.d.cts +16 -0
  317. package/dist/utils/amountConversion.d.cts.map +1 -0
  318. package/dist/utils/amountConversion.d.mts +16 -0
  319. package/dist/utils/amountConversion.d.mts.map +1 -0
  320. package/dist/utils/amountConversion.mjs +54 -0
  321. package/dist/utils/amountConversion.mjs.map +1 -0
  322. package/dist/utils/chartUtils.cjs +98 -0
  323. package/dist/utils/chartUtils.cjs.map +1 -0
  324. package/dist/utils/chartUtils.d.cts +14 -0
  325. package/dist/utils/chartUtils.d.cts.map +1 -0
  326. package/dist/utils/chartUtils.d.mts +14 -0
  327. package/dist/utils/chartUtils.d.mts.map +1 -0
  328. package/dist/utils/chartUtils.mjs +94 -0
  329. package/dist/utils/chartUtils.mjs.map +1 -0
  330. package/dist/utils/errorUtils.cjs +22 -0
  331. package/dist/utils/errorUtils.cjs.map +1 -0
  332. package/dist/utils/errorUtils.d.cts +13 -0
  333. package/dist/utils/errorUtils.d.cts.map +1 -0
  334. package/dist/utils/errorUtils.d.mts +13 -0
  335. package/dist/utils/errorUtils.d.mts.map +1 -0
  336. package/dist/utils/errorUtils.mjs +18 -0
  337. package/dist/utils/errorUtils.mjs.map +1 -0
  338. package/dist/utils/formatUtils.cjs +987 -0
  339. package/dist/utils/formatUtils.cjs.map +1 -0
  340. package/dist/utils/formatUtils.d.cts +387 -0
  341. package/dist/utils/formatUtils.d.cts.map +1 -0
  342. package/dist/utils/formatUtils.d.mts +387 -0
  343. package/dist/utils/formatUtils.d.mts.map +1 -0
  344. package/dist/utils/formatUtils.mjs +966 -0
  345. package/dist/utils/formatUtils.mjs.map +1 -0
  346. package/dist/utils/hyperLiquidAdapter.cjs +454 -0
  347. package/dist/utils/hyperLiquidAdapter.cjs.map +1 -0
  348. package/dist/utils/hyperLiquidAdapter.d.cts +158 -0
  349. package/dist/utils/hyperLiquidAdapter.d.cts.map +1 -0
  350. package/dist/utils/hyperLiquidAdapter.d.mts +158 -0
  351. package/dist/utils/hyperLiquidAdapter.d.mts.map +1 -0
  352. package/dist/utils/hyperLiquidAdapter.mjs +439 -0
  353. package/dist/utils/hyperLiquidAdapter.mjs.map +1 -0
  354. package/dist/utils/hyperLiquidOrderBookProcessor.cjs +89 -0
  355. package/dist/utils/hyperLiquidOrderBookProcessor.cjs.map +1 -0
  356. package/dist/utils/hyperLiquidOrderBookProcessor.d.cts +58 -0
  357. package/dist/utils/hyperLiquidOrderBookProcessor.d.cts.map +1 -0
  358. package/dist/utils/hyperLiquidOrderBookProcessor.d.mts +58 -0
  359. package/dist/utils/hyperLiquidOrderBookProcessor.d.mts.map +1 -0
  360. package/dist/utils/hyperLiquidOrderBookProcessor.mjs +84 -0
  361. package/dist/utils/hyperLiquidOrderBookProcessor.mjs.map +1 -0
  362. package/dist/utils/hyperLiquidValidation.cjs +426 -0
  363. package/dist/utils/hyperLiquidValidation.cjs.map +1 -0
  364. package/dist/utils/hyperLiquidValidation.d.cts +143 -0
  365. package/dist/utils/hyperLiquidValidation.d.cts.map +1 -0
  366. package/dist/utils/hyperLiquidValidation.d.mts +143 -0
  367. package/dist/utils/hyperLiquidValidation.d.mts.map +1 -0
  368. package/dist/utils/hyperLiquidValidation.mjs +413 -0
  369. package/dist/utils/hyperLiquidValidation.mjs.map +1 -0
  370. package/dist/utils/idUtils.cjs +50 -0
  371. package/dist/utils/idUtils.cjs.map +1 -0
  372. package/dist/utils/idUtils.d.cts +38 -0
  373. package/dist/utils/idUtils.d.cts.map +1 -0
  374. package/dist/utils/idUtils.d.mts +38 -0
  375. package/dist/utils/idUtils.d.mts.map +1 -0
  376. package/dist/utils/idUtils.mjs +42 -0
  377. package/dist/utils/idUtils.mjs.map +1 -0
  378. package/dist/utils/marginUtils.cjs +137 -0
  379. package/dist/utils/marginUtils.cjs.map +1 -0
  380. package/dist/utils/marginUtils.d.cts +64 -0
  381. package/dist/utils/marginUtils.d.cts.map +1 -0
  382. package/dist/utils/marginUtils.d.mts +64 -0
  383. package/dist/utils/marginUtils.d.mts.map +1 -0
  384. package/dist/utils/marginUtils.mjs +131 -0
  385. package/dist/utils/marginUtils.mjs.map +1 -0
  386. package/dist/utils/marketDataTransform.cjs +227 -0
  387. package/dist/utils/marketDataTransform.cjs.map +1 -0
  388. package/dist/utils/marketDataTransform.d.cts +45 -0
  389. package/dist/utils/marketDataTransform.d.cts.map +1 -0
  390. package/dist/utils/marketDataTransform.d.mts +45 -0
  391. package/dist/utils/marketDataTransform.d.mts.map +1 -0
  392. package/dist/utils/marketDataTransform.mjs +220 -0
  393. package/dist/utils/marketDataTransform.mjs.map +1 -0
  394. package/dist/utils/marketUtils.cjs +420 -0
  395. package/dist/utils/marketUtils.cjs.map +1 -0
  396. package/dist/utils/marketUtils.d.cts +227 -0
  397. package/dist/utils/marketUtils.d.cts.map +1 -0
  398. package/dist/utils/marketUtils.d.mts +227 -0
  399. package/dist/utils/marketUtils.d.mts.map +1 -0
  400. package/dist/utils/marketUtils.mjs +404 -0
  401. package/dist/utils/marketUtils.mjs.map +1 -0
  402. package/dist/utils/orderBookGrouping.cjs +151 -0
  403. package/dist/utils/orderBookGrouping.cjs.map +1 -0
  404. package/dist/utils/orderBookGrouping.d.cts +76 -0
  405. package/dist/utils/orderBookGrouping.d.cts.map +1 -0
  406. package/dist/utils/orderBookGrouping.d.mts +76 -0
  407. package/dist/utils/orderBookGrouping.d.mts.map +1 -0
  408. package/dist/utils/orderBookGrouping.mjs +143 -0
  409. package/dist/utils/orderBookGrouping.mjs.map +1 -0
  410. package/dist/utils/orderCalculations.cjs +283 -0
  411. package/dist/utils/orderCalculations.cjs.map +1 -0
  412. package/dist/utils/orderCalculations.d.cts +107 -0
  413. package/dist/utils/orderCalculations.d.cts.map +1 -0
  414. package/dist/utils/orderCalculations.d.mts +107 -0
  415. package/dist/utils/orderCalculations.d.mts.map +1 -0
  416. package/dist/utils/orderCalculations.mjs +274 -0
  417. package/dist/utils/orderCalculations.mjs.map +1 -0
  418. package/dist/utils/orderUtils.cjs +159 -0
  419. package/dist/utils/orderUtils.cjs.map +1 -0
  420. package/dist/utils/orderUtils.d.cts +66 -0
  421. package/dist/utils/orderUtils.d.cts.map +1 -0
  422. package/dist/utils/orderUtils.d.mts +66 -0
  423. package/dist/utils/orderUtils.d.mts.map +1 -0
  424. package/dist/utils/orderUtils.mjs +151 -0
  425. package/dist/utils/orderUtils.mjs.map +1 -0
  426. package/dist/utils/pnlCalculations.cjs +107 -0
  427. package/dist/utils/pnlCalculations.cjs.map +1 -0
  428. package/dist/utils/pnlCalculations.d.cts +79 -0
  429. package/dist/utils/pnlCalculations.d.cts.map +1 -0
  430. package/dist/utils/pnlCalculations.d.mts +79 -0
  431. package/dist/utils/pnlCalculations.d.mts.map +1 -0
  432. package/dist/utils/pnlCalculations.mjs +97 -0
  433. package/dist/utils/pnlCalculations.mjs.map +1 -0
  434. package/dist/utils/positionCalculations.cjs +176 -0
  435. package/dist/utils/positionCalculations.cjs.map +1 -0
  436. package/dist/utils/positionCalculations.d.cts +85 -0
  437. package/dist/utils/positionCalculations.d.cts.map +1 -0
  438. package/dist/utils/positionCalculations.d.mts +85 -0
  439. package/dist/utils/positionCalculations.d.mts.map +1 -0
  440. package/dist/utils/positionCalculations.mjs +165 -0
  441. package/dist/utils/positionCalculations.mjs.map +1 -0
  442. package/dist/utils/sortMarkets.cjs +88 -0
  443. package/dist/utils/sortMarkets.cjs.map +1 -0
  444. package/dist/utils/sortMarkets.d.cts +21 -0
  445. package/dist/utils/sortMarkets.d.cts.map +1 -0
  446. package/dist/utils/sortMarkets.d.mts +21 -0
  447. package/dist/utils/sortMarkets.d.mts.map +1 -0
  448. package/dist/utils/sortMarkets.mjs +84 -0
  449. package/dist/utils/sortMarkets.mjs.map +1 -0
  450. package/dist/utils/standaloneInfoClient.cjs +34 -0
  451. package/dist/utils/standaloneInfoClient.cjs.map +1 -0
  452. package/dist/utils/standaloneInfoClient.d.cts +31 -0
  453. package/dist/utils/standaloneInfoClient.d.cts.map +1 -0
  454. package/dist/utils/standaloneInfoClient.d.mts +31 -0
  455. package/dist/utils/standaloneInfoClient.d.mts.map +1 -0
  456. package/dist/utils/standaloneInfoClient.mjs +30 -0
  457. package/dist/utils/standaloneInfoClient.mjs.map +1 -0
  458. package/dist/utils/stringParseUtils.cjs +49 -0
  459. package/dist/utils/stringParseUtils.cjs.map +1 -0
  460. package/dist/utils/stringParseUtils.d.cts +35 -0
  461. package/dist/utils/stringParseUtils.d.cts.map +1 -0
  462. package/dist/utils/stringParseUtils.d.mts +35 -0
  463. package/dist/utils/stringParseUtils.d.mts.map +1 -0
  464. package/dist/utils/stringParseUtils.mjs +44 -0
  465. package/dist/utils/stringParseUtils.mjs.map +1 -0
  466. package/dist/utils/time.cjs +37 -0
  467. package/dist/utils/time.cjs.map +1 -0
  468. package/dist/utils/time.d.cts +17 -0
  469. package/dist/utils/time.d.cts.map +1 -0
  470. package/dist/utils/time.d.mts +17 -0
  471. package/dist/utils/time.d.mts.map +1 -0
  472. package/dist/utils/time.mjs +33 -0
  473. package/dist/utils/time.mjs.map +1 -0
  474. package/dist/utils/tpslValidation.cjs +505 -0
  475. package/dist/utils/tpslValidation.cjs.map +1 -0
  476. package/dist/utils/tpslValidation.d.cts +182 -0
  477. package/dist/utils/tpslValidation.d.cts.map +1 -0
  478. package/dist/utils/tpslValidation.d.mts +182 -0
  479. package/dist/utils/tpslValidation.d.mts.map +1 -0
  480. package/dist/utils/tpslValidation.mjs +482 -0
  481. package/dist/utils/tpslValidation.mjs.map +1 -0
  482. package/dist/utils/transactionUtils.cjs +36 -0
  483. package/dist/utils/transactionUtils.cjs.map +1 -0
  484. package/dist/utils/transactionUtils.d.cts +17 -0
  485. package/dist/utils/transactionUtils.d.cts.map +1 -0
  486. package/dist/utils/transactionUtils.d.mts +17 -0
  487. package/dist/utils/transactionUtils.d.mts.map +1 -0
  488. package/dist/utils/transactionUtils.mjs +32 -0
  489. package/dist/utils/transactionUtils.mjs.map +1 -0
  490. package/dist/utils/wait.cjs +12 -0
  491. package/dist/utils/wait.cjs.map +1 -0
  492. package/dist/utils/wait.d.cts +8 -0
  493. package/dist/utils/wait.d.cts.map +1 -0
  494. package/dist/utils/wait.d.mts +8 -0
  495. package/dist/utils/wait.d.mts.map +1 -0
  496. package/dist/utils/wait.mjs +8 -0
  497. package/dist/utils/wait.mjs.map +1 -0
  498. package/package.json +19 -4
@@ -0,0 +1,420 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAssetIconUrls = exports.getAssetIconUrl = exports.filterMarketsByQuery = exports.getMarketBadgeType = exports.calculate24hHighLow = exports.calculateFundingCountdown = exports.getPerpsDexFromSymbol = exports.getPerpsDisplaySymbol = exports.shouldIncludeMarket = exports.matchesMarketPattern = exports.compileMarketPattern = exports.validateMarketPattern = exports.escapeRegex = void 0;
4
+ const hyperLiquidConfig_1 = require("../constants/hyperLiquidConfig.cjs");
5
+ /**
6
+ * Maximum length for market filter patterns (prevents DoS attacks)
7
+ */
8
+ const MAX_MARKET_PATTERN_LENGTH = 100;
9
+ /**
10
+ * Escape special regex characters in a string
11
+ *
12
+ * @param str - String to escape
13
+ * @returns Escaped string safe for regex
14
+ */
15
+ const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
16
+ exports.escapeRegex = escapeRegex;
17
+ /**
18
+ * Validate market filter pattern for safety
19
+ * Prevents regex DoS attacks from malicious patterns
20
+ *
21
+ * @param pattern - Pattern to validate
22
+ * @returns true if pattern is safe
23
+ * @throws Error if pattern is unsafe
24
+ *
25
+ * @example Valid patterns
26
+ * validateMarketPattern("BTC") // → true
27
+ * validateMarketPattern("xyz:TSLA") // → true
28
+ * validateMarketPattern("xyz:*") // → true
29
+ *
30
+ * @example Invalid patterns
31
+ * validateMarketPattern("") // → throws Error
32
+ * validateMarketPattern("xyz:.*") // → throws Error (regex chars)
33
+ * validateMarketPattern("BTC#SCAM") // → throws Error (invalid char)
34
+ */
35
+ const validateMarketPattern = (pattern) => {
36
+ // Reject empty patterns
37
+ if (!pattern || pattern.trim().length === 0) {
38
+ throw new Error('Market pattern cannot be empty');
39
+ }
40
+ // Trim whitespace and normalize the pattern
41
+ const normalizedPattern = pattern.trim();
42
+ // Reject patterns that are too long (potential DoS)
43
+ if (normalizedPattern.length > MAX_MARKET_PATTERN_LENGTH) {
44
+ throw new Error(`Market pattern exceeds maximum length (${MAX_MARKET_PATTERN_LENGTH} chars): ${normalizedPattern}`);
45
+ }
46
+ // Reject patterns with suspicious regex control characters
47
+ // Allow only colon and asterisk for our pattern syntax
48
+ const dangerousChars = /[\\()[\]{}^$+?.|]/u;
49
+ if (dangerousChars.test(normalizedPattern)) {
50
+ throw new Error(`Market pattern contains invalid regex characters: ${normalizedPattern}`);
51
+ }
52
+ // Allow only: alphanumeric, colon, hyphen, underscore, asterisk
53
+ const validPattern = /^[a-zA-Z0-9:_\-*]+$/u;
54
+ if (!validPattern.test(normalizedPattern)) {
55
+ throw new Error(`Market pattern contains invalid characters: ${normalizedPattern}`);
56
+ }
57
+ return true;
58
+ };
59
+ exports.validateMarketPattern = validateMarketPattern;
60
+ /**
61
+ * Compile market filter pattern into optimized matcher
62
+ * Supports wildcards ("xyz:*"), DEX shorthand ("xyz"), and exact matches ("xyz:TSLA")
63
+ *
64
+ * Note: Main DEX markets (no prefix) don't need filtering - they're always included.
65
+ * Patterns without colons are treated as HIP-3 DEX shorthand.
66
+ *
67
+ * @param pattern - Pattern string (e.g., "xyz:*", "xyz:TSLA", "xyz")
68
+ * @returns Compiled matcher (RegExp for wildcards/shorthand, string for exact match)
69
+ *
70
+ * @example Wildcard - matches all markets from a DEX
71
+ * compileMarketPattern("xyz:*") // → /^xyz:/
72
+ *
73
+ * @example DEX shorthand - equivalent to wildcard
74
+ * compileMarketPattern("xyz") // → /^xyz:/ (matches all xyz markets)
75
+ *
76
+ * @example Exact match - matches specific market
77
+ * compileMarketPattern("xyz:TSLA") // → "xyz:TSLA"
78
+ */
79
+ const compileMarketPattern = (pattern) => {
80
+ // Trim and validate pattern before compilation to prevent regex DoS
81
+ const normalizedPattern = pattern.trim();
82
+ (0, exports.validateMarketPattern)(normalizedPattern);
83
+ if (normalizedPattern.endsWith(':*')) {
84
+ // Wildcard: "xyz:*" → regex /^xyz:/
85
+ const prefix = normalizedPattern.slice(0, -2);
86
+ return new RegExp(`^${(0, exports.escapeRegex)(prefix)}:`, 'u');
87
+ }
88
+ if (!normalizedPattern.includes(':')) {
89
+ // DEX shorthand: "xyz" → regex /^xyz:/
90
+ return new RegExp(`^${(0, exports.escapeRegex)(normalizedPattern)}:`, 'u');
91
+ }
92
+ // Exact match: just use string (fastest)
93
+ return normalizedPattern;
94
+ };
95
+ exports.compileMarketPattern = compileMarketPattern;
96
+ /**
97
+ * Check if a symbol matches a compiled pattern matcher
98
+ *
99
+ * @param symbol - Market symbol (e.g., "BTC", "xyz:TSLA")
100
+ * @param matcher - Compiled matcher (string or RegExp)
101
+ * @returns true if symbol matches the pattern
102
+ */
103
+ const matchesMarketPattern = (symbol, matcher) => {
104
+ if (typeof matcher === 'string') {
105
+ // Exact match - fastest
106
+ return symbol === matcher;
107
+ }
108
+ // RegExp match - still very fast
109
+ return matcher.test(symbol);
110
+ };
111
+ exports.matchesMarketPattern = matchesMarketPattern;
112
+ /**
113
+ * Check if a market should be included based on HIP-3 master switch and whitelist/blacklist patterns
114
+ * Main DEX markets (null dex) are ALWAYS included (no filtering)
115
+ *
116
+ * Logic: Check master switch → apply whitelist (if non-empty) → apply blacklist
117
+ *
118
+ * @param symbol - Market symbol (e.g., "BTC", "xyz:TSLA")
119
+ * @param dex - DEX identifier (null for main DEX, "xyz" for HIP-3 DEX)
120
+ * @param hip3Enabled - Master switch for HIP-3 markets (false = block all HIP-3)
121
+ * @param compiledEnabledPatterns - Pre-compiled whitelist patterns (empty = allow all)
122
+ * @param compiledBlockedPatterns - Pre-compiled blacklist patterns (empty = block none)
123
+ * @returns true if market should be shown to users
124
+ *
125
+ * @example Main DEX market (always included)
126
+ * shouldIncludeMarket("BTC", null, true, [...], [...]) // → true
127
+ *
128
+ * @example HIP-3 when master switch is OFF
129
+ * shouldIncludeMarket("xyz:TSLA", "xyz", false, [...], [...]) // → false (HIP-3 disabled)
130
+ *
131
+ * @example HIP-3 with empty whitelist (discovery mode)
132
+ * shouldIncludeMarket("xyz:TSLA", "xyz", true, [], []) // → true (allow all)
133
+ *
134
+ * @example HIP-3 with whitelist
135
+ * shouldIncludeMarket("xyz:TSLA", "xyz", true,
136
+ * [{pattern: "xyz:*", matcher: /^xyz:/}], []) // → true (matches whitelist)
137
+ *
138
+ * @example HIP-3 with blacklist
139
+ * shouldIncludeMarket("xyz:SCAM", "xyz", true, [],
140
+ * [{pattern: "xyz:SCAM", matcher: "xyz:SCAM"}]) // → false (blocked)
141
+ */
142
+ const shouldIncludeMarket = (symbol, dex, hip3Enabled, compiledEnabledPatterns, compiledBlockedPatterns) => {
143
+ // ALWAYS include main DEX markets (no filtering)
144
+ if (dex === null) {
145
+ return true;
146
+ }
147
+ // Enforce HIP-3 master switch: if disabled, block ALL HIP-3 markets
148
+ if (!hip3Enabled) {
149
+ return false;
150
+ }
151
+ // Step 1: Apply whitelist only if non-empty
152
+ if (compiledEnabledPatterns.length > 0) {
153
+ const whitelisted = compiledEnabledPatterns.some(({ matcher }) => (0, exports.matchesMarketPattern)(symbol, matcher));
154
+ if (!whitelisted) {
155
+ return false;
156
+ }
157
+ }
158
+ // Step 2: Apply blacklist ONLY if non-empty (early return optimization)
159
+ if (compiledBlockedPatterns.length === 0) {
160
+ return true; // No blacklist to check - accept immediately
161
+ }
162
+ // Only reach here if blacklist has values
163
+ const blacklisted = compiledBlockedPatterns.some(({ matcher }) => (0, exports.matchesMarketPattern)(symbol, matcher));
164
+ return !blacklisted;
165
+ };
166
+ exports.shouldIncludeMarket = shouldIncludeMarket;
167
+ /**
168
+ * Extract the display symbol from a full symbol string
169
+ * Strips DEX prefix for HIP-3 markets (e.g., "xyz:XYZ100" -> "XYZ100")
170
+ * Returns the symbol unchanged if no DEX prefix is present
171
+ *
172
+ * @param symbol - Full symbol (e.g., "BTC" or "xyz:XYZ100")
173
+ * @returns Display symbol without DEX prefix (e.g., "BTC" or "XYZ100")
174
+ */
175
+ const getPerpsDisplaySymbol = (symbol) => {
176
+ if (!symbol || typeof symbol !== 'string') {
177
+ return symbol;
178
+ }
179
+ // Check for DEX prefix pattern (dex:symbol)
180
+ const colonIndex = symbol.indexOf(':');
181
+ if (colonIndex > 0 && colonIndex < symbol.length - 1) {
182
+ // Return everything after the colon
183
+ return symbol.substring(colonIndex + 1);
184
+ }
185
+ // No DEX prefix found, return original symbol
186
+ return symbol;
187
+ };
188
+ exports.getPerpsDisplaySymbol = getPerpsDisplaySymbol;
189
+ /**
190
+ * Extract the DEX identifier from a full symbol string
191
+ * Returns the DEX prefix for HIP-3 markets (e.g., "xyz:XYZ100" -> "xyz")
192
+ * Returns null if no DEX prefix is present (main DEX market)
193
+ *
194
+ * @param symbol - Full symbol (e.g., "BTC" or "xyz:XYZ100")
195
+ * @returns DEX identifier or null if main DEX (e.g., "xyz" or null)
196
+ */
197
+ const getPerpsDexFromSymbol = (symbol) => {
198
+ if (!symbol || typeof symbol !== 'string') {
199
+ return null;
200
+ }
201
+ // Check for DEX prefix pattern (dex:symbol)
202
+ const colonIndex = symbol.indexOf(':');
203
+ if (colonIndex > 0 && colonIndex < symbol.length - 1) {
204
+ // Return the DEX prefix (everything before the colon)
205
+ return symbol.substring(0, colonIndex);
206
+ }
207
+ // No DEX prefix found, this is a main DEX market
208
+ return null;
209
+ };
210
+ exports.getPerpsDexFromSymbol = getPerpsDexFromSymbol;
211
+ /**
212
+ * Calculate the time until the next funding period.
213
+ * Supports market-specific funding times when provided.
214
+ * Falls back to default HyperLiquid 1-hour periods (funding paid every hour).
215
+ *
216
+ * @param params - Optional funding countdown parameters
217
+ * @returns Formatted countdown string in HH:MM:SS format
218
+ */
219
+ const calculateFundingCountdown = (params) => {
220
+ const now = new Date();
221
+ const nowMs = now.getTime();
222
+ // If we have a specific next funding time, check if it's reasonable for HyperLiquid's hourly funding
223
+ if (params?.nextFundingTime && params.nextFundingTime > nowMs) {
224
+ const msUntilFunding = params.nextFundingTime - nowMs;
225
+ const hoursUntilFunding = msUntilFunding / (1000 * 60 * 60);
226
+ // If API shows >1.1 hours, it's likely incorrect for HyperLiquid's hourly funding
227
+ // Use fallback calculation instead to show time until next hour
228
+ if (hoursUntilFunding <= 1.1) {
229
+ const totalSeconds = Math.floor(msUntilFunding / 1000);
230
+ const hours = Math.floor(totalSeconds / 3600);
231
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
232
+ const seconds = totalSeconds % 60;
233
+ // Format as HH:MM:SS
234
+ const formattedHours = String(hours).padStart(2, '0');
235
+ const formattedMinutes = String(minutes).padStart(2, '0');
236
+ const formattedSeconds = String(seconds).padStart(2, '0');
237
+ return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
238
+ }
239
+ // If >1.1 hours, fall through to use hourly calculation instead
240
+ }
241
+ // Fall back to default calculation for HyperLiquid (1-hour periods)
242
+ // HyperLiquid pays funding every hour, so next funding is at the next hour
243
+ const utcMinutes = now.getUTCMinutes();
244
+ const utcSeconds = now.getUTCSeconds();
245
+ // Calculate time remaining until next hour (next funding time)
246
+ const minutesUntilNextHour = 59 - utcMinutes;
247
+ const secondsUntilNextHour = 60 - utcSeconds;
248
+ // Handle edge case where seconds equals 60
249
+ const finalSeconds = secondsUntilNextHour === 60 ? 0 : secondsUntilNextHour;
250
+ const finalMinutes = secondsUntilNextHour === 60
251
+ ? minutesUntilNextHour + 1
252
+ : minutesUntilNextHour;
253
+ // For HyperLiquid 1-hour funding, hours should always be 0
254
+ // (countdown should never exceed 59:59 since funding happens every hour)
255
+ const finalHours = finalMinutes === 60 ? 1 : 0;
256
+ const adjustedMinutes = finalMinutes === 60 ? 0 : finalMinutes;
257
+ // Format as HH:MM:SS
258
+ const formattedHours = String(finalHours).padStart(2, '0');
259
+ const formattedMinutes = String(adjustedMinutes).padStart(2, '0');
260
+ const formattedSeconds = String(finalSeconds).padStart(2, '0');
261
+ return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
262
+ };
263
+ exports.calculateFundingCountdown = calculateFundingCountdown;
264
+ /**
265
+ * Calculate 24h high and low from candlestick data.
266
+ *
267
+ * @param candleData - Candlestick data containing price candles
268
+ * @returns Object with high and low prices for the last 24 hours
269
+ */
270
+ const calculate24hHighLow = (candleData) => {
271
+ if (!candleData?.candles || candleData.candles.length === 0) {
272
+ return { high: 0, low: 0 };
273
+ }
274
+ // Get candles from last 24 hours
275
+ const now = Date.now();
276
+ const twentyFourHoursAgo = now - 24 * 60 * 60 * 1000;
277
+ let last24hCandles = candleData.candles.filter((candle) => candle.time >= twentyFourHoursAgo);
278
+ if (last24hCandles.length === 0) {
279
+ // If no 24h data, use all available candles
280
+ last24hCandles = [...candleData.candles];
281
+ }
282
+ const highs = last24hCandles.map((candle) => parseFloat(candle.high));
283
+ const lows = last24hCandles.map((candle) => parseFloat(candle.low));
284
+ return {
285
+ high: Math.max(...highs),
286
+ low: Math.min(...lows),
287
+ };
288
+ };
289
+ exports.calculate24hHighLow = calculate24hHighLow;
290
+ /**
291
+ * Determine badge type for a market based on its metadata
292
+ * Prioritizes explicit marketType over generic experimental badge
293
+ *
294
+ * @param market - Market data object (only needs marketType and marketSource fields)
295
+ * @returns Badge type to display, or undefined for no badge (main DEX)
296
+ *
297
+ * @example Main DEX
298
+ * getMarketBadgeType({ symbol: 'BTC', marketSource: null }) // → undefined
299
+ *
300
+ * @example Mapped HIP-3 DEX
301
+ * getMarketBadgeType({ symbol: 'xyz:XYZ100', marketSource: 'xyz', marketType: 'equity' }) // → 'equity'
302
+ *
303
+ * @example Unmapped HIP-3 DEX
304
+ * getMarketBadgeType({ symbol: 'abc:ABC100', marketSource: 'abc' }) // → 'experimental'
305
+ */
306
+ const getMarketBadgeType = (market) =>
307
+ // Prioritize explicit marketType (e.g., 'equity' for xyz DEX)
308
+ // Fall back to 'experimental' for unmapped HIP-3 DEXs
309
+ // Main DEX markets without marketType show no badge
310
+ market.marketType ?? (market.marketSource ? 'experimental' : undefined);
311
+ exports.getMarketBadgeType = getMarketBadgeType;
312
+ /**
313
+ * Filter markets by search query
314
+ * Searches through both symbol and name fields (case-insensitive)
315
+ *
316
+ * @param markets - Array of markets to filter
317
+ * @param searchQuery - Search query string
318
+ * @returns Filtered array of markets matching the query
319
+ *
320
+ * @example
321
+ * filterMarketsByQuery([{ symbol: 'BTC', name: 'Bitcoin' }], 'btc') // → [{ symbol: 'BTC', name: 'Bitcoin' }]
322
+ * filterMarketsByQuery([{ symbol: 'BTC', name: 'Bitcoin' }], 'coin') // → [{ symbol: 'BTC', name: 'Bitcoin' }]
323
+ * filterMarketsByQuery([{ symbol: 'BTC', name: 'Bitcoin' }], '') // → [{ symbol: 'BTC', name: 'Bitcoin' }]
324
+ */
325
+ const filterMarketsByQuery = (markets, searchQuery) => {
326
+ // Return all markets if query is empty
327
+ if (!searchQuery?.trim()) {
328
+ return markets;
329
+ }
330
+ const lowerQuery = searchQuery.toLowerCase().trim();
331
+ return markets.filter((market) => market.symbol?.toLowerCase().includes(lowerQuery) ||
332
+ market.name?.toLowerCase().includes(lowerQuery));
333
+ };
334
+ exports.filterMarketsByQuery = filterMarketsByQuery;
335
+ /**
336
+ * Generate the appropriate icon URL for an asset symbol
337
+ * Handles both regular assets and HIP-3 assets (dex:symbol format)
338
+ *
339
+ * @param symbol - Asset symbol (e.g., "BTC" or "xyz:TSLA")
340
+ * @param kPrefixAssets - Optional set of assets that have a 'k' prefix to remove
341
+ * @returns Icon URL for the asset
342
+ *
343
+ * @example Regular asset
344
+ * getAssetIconUrl('BTC') // → 'https://app.hyperliquid.xyz/coins/BTC.svg'
345
+ *
346
+ * @example HIP-3 asset
347
+ * getAssetIconUrl('xyz:TSLA') // → 'https://raw.githubusercontent.com/.../hip3%3Axyz_TSLA.svg'
348
+ *
349
+ * @example With k-prefix handling
350
+ * getAssetIconUrl('kBONK', new Set(['KBONK'])) // → 'https://app.hyperliquid.xyz/coins/BONK.svg'
351
+ */
352
+ const getAssetIconUrl = (symbol, kPrefixAssets) => {
353
+ if (!symbol) {
354
+ return '';
355
+ }
356
+ // Check for HIP-3 asset (contains colon) BEFORE uppercasing
357
+ if (symbol.includes(':')) {
358
+ const [dex, assetSymbol] = symbol.split(':');
359
+ return `${hyperLiquidConfig_1.HYPERLIQUID_ASSET_ICONS_BASE_URL}${dex.toLowerCase()}:${assetSymbol.toUpperCase()}.svg`;
360
+ }
361
+ // For regular assets, uppercase the entire symbol
362
+ let processedSymbol = symbol.toUpperCase();
363
+ // Remove 'k' prefix only for specific assets if provided
364
+ if (kPrefixAssets?.has(processedSymbol)) {
365
+ processedSymbol = processedSymbol.substring(1);
366
+ }
367
+ // Regular asset
368
+ return `${hyperLiquidConfig_1.HYPERLIQUID_ASSET_ICONS_BASE_URL}${processedSymbol}.svg`;
369
+ };
370
+ exports.getAssetIconUrl = getAssetIconUrl;
371
+ /**
372
+ * Generate icon URLs for an asset symbol with fallback support
373
+ *
374
+ * Resolution order:
375
+ * 1. Primary: MetaMask contract-metadata repo (manually curated)
376
+ * 2. Fallback: HyperLiquid CDN (always available)
377
+ *
378
+ * @param symbol - Asset symbol (e.g., "BTC" or "xyz:TSLA")
379
+ * @param kPrefixAssets - Optional set of assets that have a 'k' prefix to remove
380
+ * @returns Object with primary and fallback URLs, or null if no symbol
381
+ *
382
+ * @example Regular asset
383
+ * getAssetIconUrls('BTC')
384
+ * // → { primary: 'https://raw.githubusercontent.com/.../BTC.svg',
385
+ * // fallback: 'https://app.hyperliquid.xyz/coins/BTC.svg' }
386
+ *
387
+ * @example HIP-3 asset
388
+ * getAssetIconUrls('xyz:TSLA')
389
+ * // → { primary: 'https://raw.githubusercontent.com/.../hip3:xyz_TSLA.svg',
390
+ * // fallback: 'https://app.hyperliquid.xyz/coins/xyz:TSLA.svg' }
391
+ */
392
+ const getAssetIconUrls = (symbol, kPrefixAssets) => {
393
+ if (!symbol) {
394
+ return null;
395
+ }
396
+ // Check for HIP-3 asset (contains colon) BEFORE uppercasing
397
+ if (symbol.includes(':')) {
398
+ const [dex, assetSymbol] = symbol.split(':');
399
+ // HyperLiquid uses dex:SYMBOL format
400
+ const hyperliquidFormat = `${dex.toLowerCase()}:${assetSymbol.toUpperCase()}`;
401
+ // MetaMask contract-metadata uses hip3:dex_SYMBOL format
402
+ const metamaskFormat = `hip3:${dex.toLowerCase()}_${assetSymbol.toUpperCase()}`;
403
+ return {
404
+ primary: `${hyperLiquidConfig_1.METAMASK_PERPS_ICONS_BASE_URL}${metamaskFormat}.svg`,
405
+ fallback: `${hyperLiquidConfig_1.HYPERLIQUID_ASSET_ICONS_BASE_URL}${hyperliquidFormat}.svg`,
406
+ };
407
+ }
408
+ // For regular assets, uppercase the entire symbol
409
+ let processedSymbol = symbol.toUpperCase();
410
+ // Remove 'k' prefix only for specific assets if provided
411
+ if (kPrefixAssets?.has(processedSymbol)) {
412
+ processedSymbol = processedSymbol.substring(1);
413
+ }
414
+ return {
415
+ primary: `${hyperLiquidConfig_1.METAMASK_PERPS_ICONS_BASE_URL}${processedSymbol}.svg`,
416
+ fallback: `${hyperLiquidConfig_1.HYPERLIQUID_ASSET_ICONS_BASE_URL}${processedSymbol}.svg`,
417
+ };
418
+ };
419
+ exports.getAssetIconUrls = getAssetIconUrls;
420
+ //# sourceMappingURL=marketUtils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketUtils.cjs","sourceRoot":"","sources":["../../src/utils/marketUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n HYPERLIQUID_ASSET_ICONS_BASE_URL,\n METAMASK_PERPS_ICONS_BASE_URL,\n} from '../constants/hyperLiquidConfig';\nimport type {\n BadgeType,\n CandleData,\n CandleStick,\n PerpsMarketData,\n} from '../types';\n\n/**\n * Maximum length for market filter patterns (prevents DoS attacks)\n */\nconst MAX_MARKET_PATTERN_LENGTH = 100;\n\n/**\n * Pattern matcher type - either string (exact match) or RegExp (wildcard)\n */\nexport type MarketPatternMatcher = RegExp | string;\n\n/**\n * Pre-compiled pattern with original pattern string and matcher\n */\nexport type CompiledMarketPattern = {\n pattern: string;\n matcher: MarketPatternMatcher;\n};\n\n/**\n * Escape special regex characters in a string\n *\n * @param str - String to escape\n * @returns Escaped string safe for regex\n */\nexport const escapeRegex = (str: string): string =>\n str.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&');\n\n/**\n * Validate market filter pattern for safety\n * Prevents regex DoS attacks from malicious patterns\n *\n * @param pattern - Pattern to validate\n * @returns true if pattern is safe\n * @throws Error if pattern is unsafe\n *\n * @example Valid patterns\n * validateMarketPattern(\"BTC\") // → true\n * validateMarketPattern(\"xyz:TSLA\") // → true\n * validateMarketPattern(\"xyz:*\") // → true\n *\n * @example Invalid patterns\n * validateMarketPattern(\"\") // → throws Error\n * validateMarketPattern(\"xyz:.*\") // → throws Error (regex chars)\n * validateMarketPattern(\"BTC#SCAM\") // → throws Error (invalid char)\n */\nexport const validateMarketPattern = (pattern: string): boolean => {\n // Reject empty patterns\n if (!pattern || pattern.trim().length === 0) {\n throw new Error('Market pattern cannot be empty');\n }\n\n // Trim whitespace and normalize the pattern\n const normalizedPattern = pattern.trim();\n\n // Reject patterns that are too long (potential DoS)\n if (normalizedPattern.length > MAX_MARKET_PATTERN_LENGTH) {\n throw new Error(\n `Market pattern exceeds maximum length (${MAX_MARKET_PATTERN_LENGTH} chars): ${normalizedPattern}`,\n );\n }\n\n // Reject patterns with suspicious regex control characters\n // Allow only colon and asterisk for our pattern syntax\n const dangerousChars = /[\\\\()[\\]{}^$+?.|]/u;\n if (dangerousChars.test(normalizedPattern)) {\n throw new Error(\n `Market pattern contains invalid regex characters: ${normalizedPattern}`,\n );\n }\n\n // Allow only: alphanumeric, colon, hyphen, underscore, asterisk\n const validPattern = /^[a-zA-Z0-9:_\\-*]+$/u;\n if (!validPattern.test(normalizedPattern)) {\n throw new Error(\n `Market pattern contains invalid characters: ${normalizedPattern}`,\n );\n }\n\n return true;\n};\n\n/**\n * Compile market filter pattern into optimized matcher\n * Supports wildcards (\"xyz:*\"), DEX shorthand (\"xyz\"), and exact matches (\"xyz:TSLA\")\n *\n * Note: Main DEX markets (no prefix) don't need filtering - they're always included.\n * Patterns without colons are treated as HIP-3 DEX shorthand.\n *\n * @param pattern - Pattern string (e.g., \"xyz:*\", \"xyz:TSLA\", \"xyz\")\n * @returns Compiled matcher (RegExp for wildcards/shorthand, string for exact match)\n *\n * @example Wildcard - matches all markets from a DEX\n * compileMarketPattern(\"xyz:*\") // → /^xyz:/\n *\n * @example DEX shorthand - equivalent to wildcard\n * compileMarketPattern(\"xyz\") // → /^xyz:/ (matches all xyz markets)\n *\n * @example Exact match - matches specific market\n * compileMarketPattern(\"xyz:TSLA\") // → \"xyz:TSLA\"\n */\nexport const compileMarketPattern = (pattern: string): MarketPatternMatcher => {\n // Trim and validate pattern before compilation to prevent regex DoS\n const normalizedPattern = pattern.trim();\n validateMarketPattern(normalizedPattern);\n\n if (normalizedPattern.endsWith(':*')) {\n // Wildcard: \"xyz:*\" → regex /^xyz:/\n const prefix = normalizedPattern.slice(0, -2);\n return new RegExp(`^${escapeRegex(prefix)}:`, 'u');\n }\n\n if (!normalizedPattern.includes(':')) {\n // DEX shorthand: \"xyz\" → regex /^xyz:/\n return new RegExp(`^${escapeRegex(normalizedPattern)}:`, 'u');\n }\n\n // Exact match: just use string (fastest)\n return normalizedPattern;\n};\n\n/**\n * Check if a symbol matches a compiled pattern matcher\n *\n * @param symbol - Market symbol (e.g., \"BTC\", \"xyz:TSLA\")\n * @param matcher - Compiled matcher (string or RegExp)\n * @returns true if symbol matches the pattern\n */\nexport const matchesMarketPattern = (\n symbol: string,\n matcher: MarketPatternMatcher,\n): boolean => {\n if (typeof matcher === 'string') {\n // Exact match - fastest\n return symbol === matcher;\n }\n\n // RegExp match - still very fast\n return matcher.test(symbol);\n};\n\n/**\n * Check if a market should be included based on HIP-3 master switch and whitelist/blacklist patterns\n * Main DEX markets (null dex) are ALWAYS included (no filtering)\n *\n * Logic: Check master switch → apply whitelist (if non-empty) → apply blacklist\n *\n * @param symbol - Market symbol (e.g., \"BTC\", \"xyz:TSLA\")\n * @param dex - DEX identifier (null for main DEX, \"xyz\" for HIP-3 DEX)\n * @param hip3Enabled - Master switch for HIP-3 markets (false = block all HIP-3)\n * @param compiledEnabledPatterns - Pre-compiled whitelist patterns (empty = allow all)\n * @param compiledBlockedPatterns - Pre-compiled blacklist patterns (empty = block none)\n * @returns true if market should be shown to users\n *\n * @example Main DEX market (always included)\n * shouldIncludeMarket(\"BTC\", null, true, [...], [...]) // → true\n *\n * @example HIP-3 when master switch is OFF\n * shouldIncludeMarket(\"xyz:TSLA\", \"xyz\", false, [...], [...]) // → false (HIP-3 disabled)\n *\n * @example HIP-3 with empty whitelist (discovery mode)\n * shouldIncludeMarket(\"xyz:TSLA\", \"xyz\", true, [], []) // → true (allow all)\n *\n * @example HIP-3 with whitelist\n * shouldIncludeMarket(\"xyz:TSLA\", \"xyz\", true,\n * [{pattern: \"xyz:*\", matcher: /^xyz:/}], []) // → true (matches whitelist)\n *\n * @example HIP-3 with blacklist\n * shouldIncludeMarket(\"xyz:SCAM\", \"xyz\", true, [],\n * [{pattern: \"xyz:SCAM\", matcher: \"xyz:SCAM\"}]) // → false (blocked)\n */\nexport const shouldIncludeMarket = (\n symbol: string,\n dex: string | null,\n hip3Enabled: boolean,\n compiledEnabledPatterns: CompiledMarketPattern[],\n compiledBlockedPatterns: CompiledMarketPattern[],\n): boolean => {\n // ALWAYS include main DEX markets (no filtering)\n if (dex === null) {\n return true;\n }\n\n // Enforce HIP-3 master switch: if disabled, block ALL HIP-3 markets\n if (!hip3Enabled) {\n return false;\n }\n\n // Step 1: Apply whitelist only if non-empty\n if (compiledEnabledPatterns.length > 0) {\n const whitelisted = compiledEnabledPatterns.some(({ matcher }) =>\n matchesMarketPattern(symbol, matcher),\n );\n if (!whitelisted) {\n return false;\n }\n }\n\n // Step 2: Apply blacklist ONLY if non-empty (early return optimization)\n if (compiledBlockedPatterns.length === 0) {\n return true; // No blacklist to check - accept immediately\n }\n\n // Only reach here if blacklist has values\n const blacklisted = compiledBlockedPatterns.some(({ matcher }) =>\n matchesMarketPattern(symbol, matcher),\n );\n\n return !blacklisted;\n};\n\n/**\n * Extract the display symbol from a full symbol string\n * Strips DEX prefix for HIP-3 markets (e.g., \"xyz:XYZ100\" -> \"XYZ100\")\n * Returns the symbol unchanged if no DEX prefix is present\n *\n * @param symbol - Full symbol (e.g., \"BTC\" or \"xyz:XYZ100\")\n * @returns Display symbol without DEX prefix (e.g., \"BTC\" or \"XYZ100\")\n */\nexport const getPerpsDisplaySymbol = (symbol: string): string => {\n if (!symbol || typeof symbol !== 'string') {\n return symbol;\n }\n\n // Check for DEX prefix pattern (dex:symbol)\n const colonIndex = symbol.indexOf(':');\n if (colonIndex > 0 && colonIndex < symbol.length - 1) {\n // Return everything after the colon\n return symbol.substring(colonIndex + 1);\n }\n\n // No DEX prefix found, return original symbol\n return symbol;\n};\n\n/**\n * Extract the DEX identifier from a full symbol string\n * Returns the DEX prefix for HIP-3 markets (e.g., \"xyz:XYZ100\" -> \"xyz\")\n * Returns null if no DEX prefix is present (main DEX market)\n *\n * @param symbol - Full symbol (e.g., \"BTC\" or \"xyz:XYZ100\")\n * @returns DEX identifier or null if main DEX (e.g., \"xyz\" or null)\n */\nexport const getPerpsDexFromSymbol = (symbol: string): string | null => {\n if (!symbol || typeof symbol !== 'string') {\n return null;\n }\n\n // Check for DEX prefix pattern (dex:symbol)\n const colonIndex = symbol.indexOf(':');\n if (colonIndex > 0 && colonIndex < symbol.length - 1) {\n // Return the DEX prefix (everything before the colon)\n return symbol.substring(0, colonIndex);\n }\n\n // No DEX prefix found, this is a main DEX market\n return null;\n};\n\ntype FundingCountdownParams = {\n /**\n * Next funding time in milliseconds since epoch (optional, market-specific)\n */\n nextFundingTime?: number;\n /**\n * Funding interval in hours (optional, market-specific)\n * Default is 1 hour for HyperLiquid (funding is paid every hour)\n */\n fundingIntervalHours?: number;\n};\n\n/**\n * Calculate the time until the next funding period.\n * Supports market-specific funding times when provided.\n * Falls back to default HyperLiquid 1-hour periods (funding paid every hour).\n *\n * @param params - Optional funding countdown parameters\n * @returns Formatted countdown string in HH:MM:SS format\n */\nexport const calculateFundingCountdown = (\n params?: FundingCountdownParams,\n): string => {\n const now = new Date();\n const nowMs = now.getTime();\n\n // If we have a specific next funding time, check if it's reasonable for HyperLiquid's hourly funding\n if (params?.nextFundingTime && params.nextFundingTime > nowMs) {\n const msUntilFunding = params.nextFundingTime - nowMs;\n const hoursUntilFunding = msUntilFunding / (1000 * 60 * 60);\n\n // If API shows >1.1 hours, it's likely incorrect for HyperLiquid's hourly funding\n // Use fallback calculation instead to show time until next hour\n if (hoursUntilFunding <= 1.1) {\n const totalSeconds = Math.floor(msUntilFunding / 1000);\n\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n // Format as HH:MM:SS\n const formattedHours = String(hours).padStart(2, '0');\n const formattedMinutes = String(minutes).padStart(2, '0');\n const formattedSeconds = String(seconds).padStart(2, '0');\n\n return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;\n }\n // If >1.1 hours, fall through to use hourly calculation instead\n }\n\n // Fall back to default calculation for HyperLiquid (1-hour periods)\n // HyperLiquid pays funding every hour, so next funding is at the next hour\n const utcMinutes = now.getUTCMinutes();\n const utcSeconds = now.getUTCSeconds();\n\n // Calculate time remaining until next hour (next funding time)\n const minutesUntilNextHour = 59 - utcMinutes;\n const secondsUntilNextHour = 60 - utcSeconds;\n\n // Handle edge case where seconds equals 60\n const finalSeconds = secondsUntilNextHour === 60 ? 0 : secondsUntilNextHour;\n const finalMinutes =\n secondsUntilNextHour === 60\n ? minutesUntilNextHour + 1\n : minutesUntilNextHour;\n\n // For HyperLiquid 1-hour funding, hours should always be 0\n // (countdown should never exceed 59:59 since funding happens every hour)\n const finalHours = finalMinutes === 60 ? 1 : 0;\n const adjustedMinutes = finalMinutes === 60 ? 0 : finalMinutes;\n\n // Format as HH:MM:SS\n const formattedHours = String(finalHours).padStart(2, '0');\n const formattedMinutes = String(adjustedMinutes).padStart(2, '0');\n const formattedSeconds = String(finalSeconds).padStart(2, '0');\n\n return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;\n};\n\n/**\n * Calculate 24h high and low from candlestick data.\n *\n * @param candleData - Candlestick data containing price candles\n * @returns Object with high and low prices for the last 24 hours\n */\nexport const calculate24hHighLow = (\n candleData: CandleData | null,\n): { high: number; low: number } => {\n if (!candleData?.candles || candleData.candles.length === 0) {\n return { high: 0, low: 0 };\n }\n\n // Get candles from last 24 hours\n const now = Date.now();\n const twentyFourHoursAgo = now - 24 * 60 * 60 * 1000;\n\n let last24hCandles = candleData.candles.filter(\n (candle: CandleStick) => candle.time >= twentyFourHoursAgo,\n );\n\n if (last24hCandles.length === 0) {\n // If no 24h data, use all available candles\n last24hCandles = [...candleData.candles];\n }\n\n const highs = last24hCandles.map((candle: CandleStick) =>\n parseFloat(candle.high),\n );\n const lows = last24hCandles.map((candle: CandleStick) =>\n parseFloat(candle.low),\n );\n\n return {\n high: Math.max(...highs),\n low: Math.min(...lows),\n };\n};\n\n/**\n * Determine badge type for a market based on its metadata\n * Prioritizes explicit marketType over generic experimental badge\n *\n * @param market - Market data object (only needs marketType and marketSource fields)\n * @returns Badge type to display, or undefined for no badge (main DEX)\n *\n * @example Main DEX\n * getMarketBadgeType({ symbol: 'BTC', marketSource: null }) // → undefined\n *\n * @example Mapped HIP-3 DEX\n * getMarketBadgeType({ symbol: 'xyz:XYZ100', marketSource: 'xyz', marketType: 'equity' }) // → 'equity'\n *\n * @example Unmapped HIP-3 DEX\n * getMarketBadgeType({ symbol: 'abc:ABC100', marketSource: 'abc' }) // → 'experimental'\n */\nexport const getMarketBadgeType = (\n market: Pick<PerpsMarketData, 'marketType' | 'marketSource'>,\n): BadgeType | undefined =>\n // Prioritize explicit marketType (e.g., 'equity' for xyz DEX)\n // Fall back to 'experimental' for unmapped HIP-3 DEXs\n // Main DEX markets without marketType show no badge\n market.marketType ?? (market.marketSource ? 'experimental' : undefined);\n\n/**\n * Filter markets by search query\n * Searches through both symbol and name fields (case-insensitive)\n *\n * @param markets - Array of markets to filter\n * @param searchQuery - Search query string\n * @returns Filtered array of markets matching the query\n *\n * @example\n * filterMarketsByQuery([{ symbol: 'BTC', name: 'Bitcoin' }], 'btc') // → [{ symbol: 'BTC', name: 'Bitcoin' }]\n * filterMarketsByQuery([{ symbol: 'BTC', name: 'Bitcoin' }], 'coin') // → [{ symbol: 'BTC', name: 'Bitcoin' }]\n * filterMarketsByQuery([{ symbol: 'BTC', name: 'Bitcoin' }], '') // → [{ symbol: 'BTC', name: 'Bitcoin' }]\n */\nexport const filterMarketsByQuery = (\n markets: PerpsMarketData[],\n searchQuery: string,\n): PerpsMarketData[] => {\n // Return all markets if query is empty\n if (!searchQuery?.trim()) {\n return markets;\n }\n\n const lowerQuery = searchQuery.toLowerCase().trim();\n\n return markets.filter(\n (market) =>\n market.symbol?.toLowerCase().includes(lowerQuery) ||\n market.name?.toLowerCase().includes(lowerQuery),\n );\n};\n\n/**\n * Generate the appropriate icon URL for an asset symbol\n * Handles both regular assets and HIP-3 assets (dex:symbol format)\n *\n * @param symbol - Asset symbol (e.g., \"BTC\" or \"xyz:TSLA\")\n * @param kPrefixAssets - Optional set of assets that have a 'k' prefix to remove\n * @returns Icon URL for the asset\n *\n * @example Regular asset\n * getAssetIconUrl('BTC') // → 'https://app.hyperliquid.xyz/coins/BTC.svg'\n *\n * @example HIP-3 asset\n * getAssetIconUrl('xyz:TSLA') // → 'https://raw.githubusercontent.com/.../hip3%3Axyz_TSLA.svg'\n *\n * @example With k-prefix handling\n * getAssetIconUrl('kBONK', new Set(['KBONK'])) // → 'https://app.hyperliquid.xyz/coins/BONK.svg'\n */\nexport const getAssetIconUrl = (\n symbol: string,\n kPrefixAssets?: Set<string>,\n): string => {\n if (!symbol) {\n return '';\n }\n\n // Check for HIP-3 asset (contains colon) BEFORE uppercasing\n if (symbol.includes(':')) {\n const [dex, assetSymbol] = symbol.split(':');\n return `${HYPERLIQUID_ASSET_ICONS_BASE_URL}${dex.toLowerCase()}:${assetSymbol.toUpperCase()}.svg`;\n }\n\n // For regular assets, uppercase the entire symbol\n let processedSymbol = symbol.toUpperCase();\n\n // Remove 'k' prefix only for specific assets if provided\n if (kPrefixAssets?.has(processedSymbol)) {\n processedSymbol = processedSymbol.substring(1);\n }\n\n // Regular asset\n return `${HYPERLIQUID_ASSET_ICONS_BASE_URL}${processedSymbol}.svg`;\n};\n\n/**\n * Icon URLs with primary (MetaMask-hosted) and fallback (HyperLiquid) sources\n */\nexport type AssetIconUrls = {\n /** MetaMask contract-metadata repo (preferred source) */\n primary: string;\n /** HyperLiquid CDN (fallback source) */\n fallback: string;\n};\n\n/**\n * Generate icon URLs for an asset symbol with fallback support\n *\n * Resolution order:\n * 1. Primary: MetaMask contract-metadata repo (manually curated)\n * 2. Fallback: HyperLiquid CDN (always available)\n *\n * @param symbol - Asset symbol (e.g., \"BTC\" or \"xyz:TSLA\")\n * @param kPrefixAssets - Optional set of assets that have a 'k' prefix to remove\n * @returns Object with primary and fallback URLs, or null if no symbol\n *\n * @example Regular asset\n * getAssetIconUrls('BTC')\n * // → { primary: 'https://raw.githubusercontent.com/.../BTC.svg',\n * // fallback: 'https://app.hyperliquid.xyz/coins/BTC.svg' }\n *\n * @example HIP-3 asset\n * getAssetIconUrls('xyz:TSLA')\n * // → { primary: 'https://raw.githubusercontent.com/.../hip3:xyz_TSLA.svg',\n * // fallback: 'https://app.hyperliquid.xyz/coins/xyz:TSLA.svg' }\n */\nexport const getAssetIconUrls = (\n symbol: string,\n kPrefixAssets?: Set<string>,\n): AssetIconUrls | null => {\n if (!symbol) {\n return null;\n }\n\n // Check for HIP-3 asset (contains colon) BEFORE uppercasing\n if (symbol.includes(':')) {\n const [dex, assetSymbol] = symbol.split(':');\n // HyperLiquid uses dex:SYMBOL format\n const hyperliquidFormat = `${dex.toLowerCase()}:${assetSymbol.toUpperCase()}`;\n // MetaMask contract-metadata uses hip3:dex_SYMBOL format\n const metamaskFormat = `hip3:${dex.toLowerCase()}_${assetSymbol.toUpperCase()}`;\n return {\n primary: `${METAMASK_PERPS_ICONS_BASE_URL}${metamaskFormat}.svg`,\n fallback: `${HYPERLIQUID_ASSET_ICONS_BASE_URL}${hyperliquidFormat}.svg`,\n };\n }\n\n // For regular assets, uppercase the entire symbol\n let processedSymbol = symbol.toUpperCase();\n\n // Remove 'k' prefix only for specific assets if provided\n if (kPrefixAssets?.has(processedSymbol)) {\n processedSymbol = processedSymbol.substring(1);\n }\n\n return {\n primary: `${METAMASK_PERPS_ICONS_BASE_URL}${processedSymbol}.svg`,\n fallback: `${HYPERLIQUID_ASSET_ICONS_BASE_URL}${processedSymbol}.svg`,\n };\n};\n"]}