@metamask-previews/perps-controller 0.0.0-preview-e4aa1532 → 0.0.0-preview-6dfa4aeba

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 +1 -11
  2. package/dist/PerpsController.cjs +66 -2224
  3. package/dist/PerpsController.cjs.map +1 -1
  4. package/dist/PerpsController.d.cts +79 -933
  5. package/dist/PerpsController.d.cts.map +1 -1
  6. package/dist/PerpsController.d.mts +79 -933
  7. package/dist/PerpsController.d.mts.map +1 -1
  8. package/dist/PerpsController.mjs +64 -2221
  9. package/dist/PerpsController.mjs.map +1 -1
  10. package/dist/index.cjs +1 -32
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +2 -6
  13. package/dist/index.d.cts.map +1 -1
  14. package/dist/index.d.mts +2 -6
  15. package/dist/index.d.mts.map +1 -1
  16. package/dist/index.mjs +1 -9
  17. package/dist/index.mjs.map +1 -1
  18. package/package.json +4 -19
  19. package/dist/__mocks__/hyperliquidMock.cjs +0 -68
  20. package/dist/__mocks__/hyperliquidMock.cjs.map +0 -1
  21. package/dist/__mocks__/hyperliquidMock.d.cts +0 -15
  22. package/dist/__mocks__/hyperliquidMock.d.cts.map +0 -1
  23. package/dist/__mocks__/hyperliquidMock.d.mts +0 -15
  24. package/dist/__mocks__/hyperliquidMock.d.mts.map +0 -1
  25. package/dist/__mocks__/hyperliquidMock.mjs +0 -65
  26. package/dist/__mocks__/hyperliquidMock.mjs.map +0 -1
  27. package/dist/__mocks__/providerMocks.cjs +0 -144
  28. package/dist/__mocks__/providerMocks.cjs.map +0 -1
  29. package/dist/__mocks__/providerMocks.d.cts +0 -44
  30. package/dist/__mocks__/providerMocks.d.cts.map +0 -1
  31. package/dist/__mocks__/providerMocks.d.mts +0 -44
  32. package/dist/__mocks__/providerMocks.d.mts.map +0 -1
  33. package/dist/__mocks__/providerMocks.mjs +0 -136
  34. package/dist/__mocks__/providerMocks.mjs.map +0 -1
  35. package/dist/__mocks__/serviceMocks.cjs +0 -187
  36. package/dist/__mocks__/serviceMocks.cjs.map +0 -1
  37. package/dist/__mocks__/serviceMocks.d.cts +0 -58
  38. package/dist/__mocks__/serviceMocks.d.cts.map +0 -1
  39. package/dist/__mocks__/serviceMocks.d.mts +0 -58
  40. package/dist/__mocks__/serviceMocks.d.mts.map +0 -1
  41. package/dist/__mocks__/serviceMocks.mjs +0 -180
  42. package/dist/__mocks__/serviceMocks.mjs.map +0 -1
  43. package/dist/aggregation/SubscriptionMultiplexer.cjs +0 -459
  44. package/dist/aggregation/SubscriptionMultiplexer.cjs.map +0 -1
  45. package/dist/aggregation/SubscriptionMultiplexer.d.cts +0 -222
  46. package/dist/aggregation/SubscriptionMultiplexer.d.cts.map +0 -1
  47. package/dist/aggregation/SubscriptionMultiplexer.d.mts +0 -222
  48. package/dist/aggregation/SubscriptionMultiplexer.d.mts.map +0 -1
  49. package/dist/aggregation/SubscriptionMultiplexer.mjs +0 -455
  50. package/dist/aggregation/SubscriptionMultiplexer.mjs.map +0 -1
  51. package/dist/aggregation/index.cjs +0 -9
  52. package/dist/aggregation/index.cjs.map +0 -1
  53. package/dist/aggregation/index.d.cts +0 -6
  54. package/dist/aggregation/index.d.cts.map +0 -1
  55. package/dist/aggregation/index.d.mts +0 -6
  56. package/dist/aggregation/index.d.mts.map +0 -1
  57. package/dist/aggregation/index.mjs +0 -5
  58. package/dist/aggregation/index.mjs.map +0 -1
  59. package/dist/constants/eventNames.cjs +0 -117
  60. package/dist/constants/eventNames.cjs.map +0 -1
  61. package/dist/constants/eventNames.d.cts +0 -106
  62. package/dist/constants/eventNames.d.cts.map +0 -1
  63. package/dist/constants/eventNames.d.mts +0 -106
  64. package/dist/constants/eventNames.d.mts.map +0 -1
  65. package/dist/constants/eventNames.mjs +0 -114
  66. package/dist/constants/eventNames.mjs.map +0 -1
  67. package/dist/constants/hyperLiquidConfig.cjs +0 -366
  68. package/dist/constants/hyperLiquidConfig.cjs.map +0 -1
  69. package/dist/constants/hyperLiquidConfig.d.cts +0 -276
  70. package/dist/constants/hyperLiquidConfig.d.cts.map +0 -1
  71. package/dist/constants/hyperLiquidConfig.d.mts +0 -276
  72. package/dist/constants/hyperLiquidConfig.d.mts.map +0 -1
  73. package/dist/constants/hyperLiquidConfig.mjs +0 -357
  74. package/dist/constants/hyperLiquidConfig.mjs.map +0 -1
  75. package/dist/constants/index.cjs +0 -23
  76. package/dist/constants/index.cjs.map +0 -1
  77. package/dist/constants/index.d.cts +0 -7
  78. package/dist/constants/index.d.cts.map +0 -1
  79. package/dist/constants/index.d.mts +0 -7
  80. package/dist/constants/index.d.mts.map +0 -1
  81. package/dist/constants/index.mjs +0 -7
  82. package/dist/constants/index.mjs.map +0 -1
  83. package/dist/constants/orderTypes.cjs +0 -31
  84. package/dist/constants/orderTypes.cjs.map +0 -1
  85. package/dist/constants/orderTypes.d.cts +0 -19
  86. package/dist/constants/orderTypes.d.cts.map +0 -1
  87. package/dist/constants/orderTypes.d.mts +0 -19
  88. package/dist/constants/orderTypes.d.mts.map +0 -1
  89. package/dist/constants/orderTypes.mjs +0 -27
  90. package/dist/constants/orderTypes.mjs.map +0 -1
  91. package/dist/constants/performanceMetrics.cjs +0 -61
  92. package/dist/constants/performanceMetrics.cjs.map +0 -1
  93. package/dist/constants/performanceMetrics.d.cts +0 -44
  94. package/dist/constants/performanceMetrics.d.cts.map +0 -1
  95. package/dist/constants/performanceMetrics.d.mts +0 -44
  96. package/dist/constants/performanceMetrics.d.mts.map +0 -1
  97. package/dist/constants/performanceMetrics.mjs +0 -58
  98. package/dist/constants/performanceMetrics.mjs.map +0 -1
  99. package/dist/constants/perpsConfig.cjs +0 -461
  100. package/dist/constants/perpsConfig.cjs.map +0 -1
  101. package/dist/constants/perpsConfig.d.cts +0 -343
  102. package/dist/constants/perpsConfig.d.cts.map +0 -1
  103. package/dist/constants/perpsConfig.d.mts +0 -343
  104. package/dist/constants/perpsConfig.d.mts.map +0 -1
  105. package/dist/constants/perpsConfig.mjs +0 -458
  106. package/dist/constants/perpsConfig.mjs.map +0 -1
  107. package/dist/constants/perpsErrorCodes.cjs +0 -79
  108. package/dist/constants/perpsErrorCodes.cjs.map +0 -1
  109. package/dist/constants/perpsErrorCodes.d.cts +0 -64
  110. package/dist/constants/perpsErrorCodes.d.cts.map +0 -1
  111. package/dist/constants/perpsErrorCodes.d.mts +0 -64
  112. package/dist/constants/perpsErrorCodes.d.mts.map +0 -1
  113. package/dist/constants/perpsErrorCodes.mjs +0 -76
  114. package/dist/constants/perpsErrorCodes.mjs.map +0 -1
  115. package/dist/platform-services/HyperLiquidClientService.cjs +0 -857
  116. package/dist/platform-services/HyperLiquidClientService.cjs.map +0 -1
  117. package/dist/platform-services/HyperLiquidClientService.d.cts +0 -263
  118. package/dist/platform-services/HyperLiquidClientService.d.cts.map +0 -1
  119. package/dist/platform-services/HyperLiquidClientService.d.mts +0 -263
  120. package/dist/platform-services/HyperLiquidClientService.d.mts.map +0 -1
  121. package/dist/platform-services/HyperLiquidClientService.mjs +0 -853
  122. package/dist/platform-services/HyperLiquidClientService.mjs.map +0 -1
  123. package/dist/platform-services/HyperLiquidSubscriptionService.cjs +0 -2170
  124. package/dist/platform-services/HyperLiquidSubscriptionService.cjs.map +0 -1
  125. package/dist/platform-services/HyperLiquidSubscriptionService.d.cts +0 -424
  126. package/dist/platform-services/HyperLiquidSubscriptionService.d.cts.map +0 -1
  127. package/dist/platform-services/HyperLiquidSubscriptionService.d.mts +0 -424
  128. package/dist/platform-services/HyperLiquidSubscriptionService.d.mts.map +0 -1
  129. package/dist/platform-services/HyperLiquidSubscriptionService.mjs +0 -2166
  130. package/dist/platform-services/HyperLiquidSubscriptionService.mjs.map +0 -1
  131. package/dist/platform-services/HyperLiquidWalletService.cjs +0 -140
  132. package/dist/platform-services/HyperLiquidWalletService.cjs.map +0 -1
  133. package/dist/platform-services/HyperLiquidWalletService.d.cts +0 -78
  134. package/dist/platform-services/HyperLiquidWalletService.d.cts.map +0 -1
  135. package/dist/platform-services/HyperLiquidWalletService.d.mts +0 -78
  136. package/dist/platform-services/HyperLiquidWalletService.d.mts.map +0 -1
  137. package/dist/platform-services/HyperLiquidWalletService.mjs +0 -136
  138. package/dist/platform-services/HyperLiquidWalletService.mjs.map +0 -1
  139. package/dist/providers/AggregatedPerpsProvider.cjs +0 -777
  140. package/dist/providers/AggregatedPerpsProvider.cjs.map +0 -1
  141. package/dist/providers/AggregatedPerpsProvider.d.cts +0 -466
  142. package/dist/providers/AggregatedPerpsProvider.d.cts.map +0 -1
  143. package/dist/providers/AggregatedPerpsProvider.d.mts +0 -466
  144. package/dist/providers/AggregatedPerpsProvider.d.mts.map +0 -1
  145. package/dist/providers/AggregatedPerpsProvider.mjs +0 -773
  146. package/dist/providers/AggregatedPerpsProvider.mjs.map +0 -1
  147. package/dist/providers/HyperLiquidProvider.cjs +0 -5172
  148. package/dist/providers/HyperLiquidProvider.cjs.map +0 -1
  149. package/dist/providers/HyperLiquidProvider.d.cts +0 -881
  150. package/dist/providers/HyperLiquidProvider.d.cts.map +0 -1
  151. package/dist/providers/HyperLiquidProvider.d.mts +0 -881
  152. package/dist/providers/HyperLiquidProvider.d.mts.map +0 -1
  153. package/dist/providers/HyperLiquidProvider.mjs +0 -5168
  154. package/dist/providers/HyperLiquidProvider.mjs.map +0 -1
  155. package/dist/providers/index.cjs +0 -11
  156. package/dist/providers/index.cjs.map +0 -1
  157. package/dist/providers/index.d.cts +0 -6
  158. package/dist/providers/index.d.cts.map +0 -1
  159. package/dist/providers/index.d.mts +0 -6
  160. package/dist/providers/index.d.mts.map +0 -1
  161. package/dist/providers/index.mjs +0 -6
  162. package/dist/providers/index.mjs.map +0 -1
  163. package/dist/routing/ProviderRouter.cjs +0 -148
  164. package/dist/routing/ProviderRouter.cjs.map +0 -1
  165. package/dist/routing/ProviderRouter.d.cts +0 -124
  166. package/dist/routing/ProviderRouter.d.cts.map +0 -1
  167. package/dist/routing/ProviderRouter.d.mts +0 -124
  168. package/dist/routing/ProviderRouter.d.mts.map +0 -1
  169. package/dist/routing/ProviderRouter.mjs +0 -144
  170. package/dist/routing/ProviderRouter.mjs.map +0 -1
  171. package/dist/routing/index.cjs +0 -9
  172. package/dist/routing/index.cjs.map +0 -1
  173. package/dist/routing/index.d.cts +0 -6
  174. package/dist/routing/index.d.cts.map +0 -1
  175. package/dist/routing/index.d.mts +0 -6
  176. package/dist/routing/index.d.mts.map +0 -1
  177. package/dist/routing/index.mjs +0 -5
  178. package/dist/routing/index.mjs.map +0 -1
  179. package/dist/selectors.cjs +0 -161
  180. package/dist/selectors.cjs.map +0 -1
  181. package/dist/selectors.d.cts +0 -345
  182. package/dist/selectors.d.cts.map +0 -1
  183. package/dist/selectors.d.mts +0 -345
  184. package/dist/selectors.d.mts.map +0 -1
  185. package/dist/selectors.mjs +0 -153
  186. package/dist/selectors.mjs.map +0 -1
  187. package/dist/services/AccountService.cjs +0 -313
  188. package/dist/services/AccountService.cjs.map +0 -1
  189. package/dist/services/AccountService.d.cts +0 -53
  190. package/dist/services/AccountService.d.cts.map +0 -1
  191. package/dist/services/AccountService.d.mts +0 -53
  192. package/dist/services/AccountService.d.mts.map +0 -1
  193. package/dist/services/AccountService.mjs +0 -309
  194. package/dist/services/AccountService.mjs.map +0 -1
  195. package/dist/services/DataLakeService.cjs +0 -219
  196. package/dist/services/DataLakeService.cjs.map +0 -1
  197. package/dist/services/DataLakeService.d.cts +0 -49
  198. package/dist/services/DataLakeService.d.cts.map +0 -1
  199. package/dist/services/DataLakeService.d.mts +0 -49
  200. package/dist/services/DataLakeService.d.mts.map +0 -1
  201. package/dist/services/DataLakeService.mjs +0 -215
  202. package/dist/services/DataLakeService.mjs.map +0 -1
  203. package/dist/services/DepositService.cjs +0 -96
  204. package/dist/services/DepositService.cjs.map +0 -1
  205. package/dist/services/DepositService.d.cts +0 -37
  206. package/dist/services/DepositService.d.cts.map +0 -1
  207. package/dist/services/DepositService.d.mts +0 -37
  208. package/dist/services/DepositService.d.mts.map +0 -1
  209. package/dist/services/DepositService.mjs +0 -92
  210. package/dist/services/DepositService.mjs.map +0 -1
  211. package/dist/services/EligibilityService.cjs +0 -156
  212. package/dist/services/EligibilityService.cjs.map +0 -1
  213. package/dist/services/EligibilityService.d.cts +0 -48
  214. package/dist/services/EligibilityService.d.cts.map +0 -1
  215. package/dist/services/EligibilityService.d.mts +0 -48
  216. package/dist/services/EligibilityService.d.mts.map +0 -1
  217. package/dist/services/EligibilityService.mjs +0 -152
  218. package/dist/services/EligibilityService.mjs.map +0 -1
  219. package/dist/services/FeatureFlagConfigurationService.cjs +0 -258
  220. package/dist/services/FeatureFlagConfigurationService.cjs.map +0 -1
  221. package/dist/services/FeatureFlagConfigurationService.d.cts +0 -100
  222. package/dist/services/FeatureFlagConfigurationService.d.cts.map +0 -1
  223. package/dist/services/FeatureFlagConfigurationService.d.mts +0 -100
  224. package/dist/services/FeatureFlagConfigurationService.d.mts.map +0 -1
  225. package/dist/services/FeatureFlagConfigurationService.mjs +0 -254
  226. package/dist/services/FeatureFlagConfigurationService.mjs.map +0 -1
  227. package/dist/services/MarketDataService.cjs +0 -875
  228. package/dist/services/MarketDataService.cjs.map +0 -1
  229. package/dist/services/MarketDataService.d.cts +0 -289
  230. package/dist/services/MarketDataService.d.cts.map +0 -1
  231. package/dist/services/MarketDataService.d.mts +0 -289
  232. package/dist/services/MarketDataService.d.mts.map +0 -1
  233. package/dist/services/MarketDataService.mjs +0 -871
  234. package/dist/services/MarketDataService.mjs.map +0 -1
  235. package/dist/services/RewardsIntegrationService.cjs +0 -94
  236. package/dist/services/RewardsIntegrationService.cjs.map +0 -1
  237. package/dist/services/RewardsIntegrationService.d.cts +0 -30
  238. package/dist/services/RewardsIntegrationService.d.cts.map +0 -1
  239. package/dist/services/RewardsIntegrationService.d.mts +0 -30
  240. package/dist/services/RewardsIntegrationService.d.mts.map +0 -1
  241. package/dist/services/RewardsIntegrationService.mjs +0 -90
  242. package/dist/services/RewardsIntegrationService.mjs.map +0 -1
  243. package/dist/services/ServiceContext.cjs +0 -3
  244. package/dist/services/ServiceContext.cjs.map +0 -1
  245. package/dist/services/ServiceContext.d.cts +0 -110
  246. package/dist/services/ServiceContext.d.cts.map +0 -1
  247. package/dist/services/ServiceContext.d.mts +0 -110
  248. package/dist/services/ServiceContext.d.mts.map +0 -1
  249. package/dist/services/ServiceContext.mjs +0 -2
  250. package/dist/services/ServiceContext.mjs.map +0 -1
  251. package/dist/services/TradingService.cjs +0 -1481
  252. package/dist/services/TradingService.cjs.map +0 -1
  253. package/dist/services/TradingService.d.cts +0 -308
  254. package/dist/services/TradingService.d.cts.map +0 -1
  255. package/dist/services/TradingService.d.mts +0 -308
  256. package/dist/services/TradingService.d.mts.map +0 -1
  257. package/dist/services/TradingService.mjs +0 -1477
  258. package/dist/services/TradingService.mjs.map +0 -1
  259. package/dist/services/index.cjs +0 -26
  260. package/dist/services/index.cjs.map +0 -1
  261. package/dist/services/index.d.cts +0 -11
  262. package/dist/services/index.d.cts.map +0 -1
  263. package/dist/services/index.d.mts +0 -11
  264. package/dist/services/index.d.mts.map +0 -1
  265. package/dist/services/index.mjs +0 -10
  266. package/dist/services/index.mjs.map +0 -1
  267. package/dist/services/utils.cjs +0 -16
  268. package/dist/services/utils.cjs.map +0 -1
  269. package/dist/services/utils.d.cts +0 -8
  270. package/dist/services/utils.d.cts.map +0 -1
  271. package/dist/services/utils.d.mts +0 -8
  272. package/dist/services/utils.d.mts.map +0 -1
  273. package/dist/services/utils.mjs +0 -12
  274. package/dist/services/utils.mjs.map +0 -1
  275. package/dist/types/chart.cjs +0 -42
  276. package/dist/types/chart.cjs.map +0 -1
  277. package/dist/types/chart.d.cts +0 -62
  278. package/dist/types/chart.d.cts.map +0 -1
  279. package/dist/types/chart.d.mts +0 -62
  280. package/dist/types/chart.d.mts.map +0 -1
  281. package/dist/types/chart.mjs +0 -39
  282. package/dist/types/chart.mjs.map +0 -1
  283. package/dist/types/hyperliquid-types.cjs +0 -3
  284. package/dist/types/hyperliquid-types.cjs.map +0 -1
  285. package/dist/types/hyperliquid-types.d.cts +0 -52
  286. package/dist/types/hyperliquid-types.d.cts.map +0 -1
  287. package/dist/types/hyperliquid-types.d.mts +0 -52
  288. package/dist/types/hyperliquid-types.d.mts.map +0 -1
  289. package/dist/types/hyperliquid-types.mjs +0 -2
  290. package/dist/types/hyperliquid-types.mjs.map +0 -1
  291. package/dist/types/index.cjs +0 -96
  292. package/dist/types/index.cjs.map +0 -1
  293. package/dist/types/index.d.cts +0 -1153
  294. package/dist/types/index.d.cts.map +0 -1
  295. package/dist/types/index.d.mts +0 -1153
  296. package/dist/types/index.d.mts.map +0 -1
  297. package/dist/types/index.mjs +0 -79
  298. package/dist/types/index.mjs.map +0 -1
  299. package/dist/types/transactionTypes.cjs +0 -28
  300. package/dist/types/transactionTypes.cjs.map +0 -1
  301. package/dist/types/transactionTypes.d.cts +0 -64
  302. package/dist/types/transactionTypes.d.cts.map +0 -1
  303. package/dist/types/transactionTypes.d.mts +0 -64
  304. package/dist/types/transactionTypes.d.mts.map +0 -1
  305. package/dist/types/transactionTypes.mjs +0 -23
  306. package/dist/types/transactionTypes.mjs.map +0 -1
  307. package/dist/utils/accountUtils.cjs +0 -65
  308. package/dist/utils/accountUtils.cjs.map +0 -1
  309. package/dist/utils/accountUtils.d.cts +0 -26
  310. package/dist/utils/accountUtils.d.cts.map +0 -1
  311. package/dist/utils/accountUtils.d.mts +0 -26
  312. package/dist/utils/accountUtils.d.mts.map +0 -1
  313. package/dist/utils/accountUtils.mjs +0 -61
  314. package/dist/utils/accountUtils.mjs.map +0 -1
  315. package/dist/utils/amountConversion.cjs +0 -61
  316. package/dist/utils/amountConversion.cjs.map +0 -1
  317. package/dist/utils/amountConversion.d.cts +0 -16
  318. package/dist/utils/amountConversion.d.cts.map +0 -1
  319. package/dist/utils/amountConversion.d.mts +0 -16
  320. package/dist/utils/amountConversion.d.mts.map +0 -1
  321. package/dist/utils/amountConversion.mjs +0 -54
  322. package/dist/utils/amountConversion.mjs.map +0 -1
  323. package/dist/utils/chartUtils.cjs +0 -98
  324. package/dist/utils/chartUtils.cjs.map +0 -1
  325. package/dist/utils/chartUtils.d.cts +0 -14
  326. package/dist/utils/chartUtils.d.cts.map +0 -1
  327. package/dist/utils/chartUtils.d.mts +0 -14
  328. package/dist/utils/chartUtils.d.mts.map +0 -1
  329. package/dist/utils/chartUtils.mjs +0 -94
  330. package/dist/utils/chartUtils.mjs.map +0 -1
  331. package/dist/utils/errorUtils.cjs +0 -22
  332. package/dist/utils/errorUtils.cjs.map +0 -1
  333. package/dist/utils/errorUtils.d.cts +0 -13
  334. package/dist/utils/errorUtils.d.cts.map +0 -1
  335. package/dist/utils/errorUtils.d.mts +0 -13
  336. package/dist/utils/errorUtils.d.mts.map +0 -1
  337. package/dist/utils/errorUtils.mjs +0 -18
  338. package/dist/utils/errorUtils.mjs.map +0 -1
  339. package/dist/utils/formatUtils.cjs +0 -987
  340. package/dist/utils/formatUtils.cjs.map +0 -1
  341. package/dist/utils/formatUtils.d.cts +0 -387
  342. package/dist/utils/formatUtils.d.cts.map +0 -1
  343. package/dist/utils/formatUtils.d.mts +0 -387
  344. package/dist/utils/formatUtils.d.mts.map +0 -1
  345. package/dist/utils/formatUtils.mjs +0 -966
  346. package/dist/utils/formatUtils.mjs.map +0 -1
  347. package/dist/utils/hyperLiquidAdapter.cjs +0 -454
  348. package/dist/utils/hyperLiquidAdapter.cjs.map +0 -1
  349. package/dist/utils/hyperLiquidAdapter.d.cts +0 -158
  350. package/dist/utils/hyperLiquidAdapter.d.cts.map +0 -1
  351. package/dist/utils/hyperLiquidAdapter.d.mts +0 -158
  352. package/dist/utils/hyperLiquidAdapter.d.mts.map +0 -1
  353. package/dist/utils/hyperLiquidAdapter.mjs +0 -439
  354. package/dist/utils/hyperLiquidAdapter.mjs.map +0 -1
  355. package/dist/utils/hyperLiquidOrderBookProcessor.cjs +0 -89
  356. package/dist/utils/hyperLiquidOrderBookProcessor.cjs.map +0 -1
  357. package/dist/utils/hyperLiquidOrderBookProcessor.d.cts +0 -58
  358. package/dist/utils/hyperLiquidOrderBookProcessor.d.cts.map +0 -1
  359. package/dist/utils/hyperLiquidOrderBookProcessor.d.mts +0 -58
  360. package/dist/utils/hyperLiquidOrderBookProcessor.d.mts.map +0 -1
  361. package/dist/utils/hyperLiquidOrderBookProcessor.mjs +0 -84
  362. package/dist/utils/hyperLiquidOrderBookProcessor.mjs.map +0 -1
  363. package/dist/utils/hyperLiquidValidation.cjs +0 -426
  364. package/dist/utils/hyperLiquidValidation.cjs.map +0 -1
  365. package/dist/utils/hyperLiquidValidation.d.cts +0 -143
  366. package/dist/utils/hyperLiquidValidation.d.cts.map +0 -1
  367. package/dist/utils/hyperLiquidValidation.d.mts +0 -143
  368. package/dist/utils/hyperLiquidValidation.d.mts.map +0 -1
  369. package/dist/utils/hyperLiquidValidation.mjs +0 -413
  370. package/dist/utils/hyperLiquidValidation.mjs.map +0 -1
  371. package/dist/utils/idUtils.cjs +0 -50
  372. package/dist/utils/idUtils.cjs.map +0 -1
  373. package/dist/utils/idUtils.d.cts +0 -38
  374. package/dist/utils/idUtils.d.cts.map +0 -1
  375. package/dist/utils/idUtils.d.mts +0 -38
  376. package/dist/utils/idUtils.d.mts.map +0 -1
  377. package/dist/utils/idUtils.mjs +0 -42
  378. package/dist/utils/idUtils.mjs.map +0 -1
  379. package/dist/utils/marginUtils.cjs +0 -137
  380. package/dist/utils/marginUtils.cjs.map +0 -1
  381. package/dist/utils/marginUtils.d.cts +0 -64
  382. package/dist/utils/marginUtils.d.cts.map +0 -1
  383. package/dist/utils/marginUtils.d.mts +0 -64
  384. package/dist/utils/marginUtils.d.mts.map +0 -1
  385. package/dist/utils/marginUtils.mjs +0 -131
  386. package/dist/utils/marginUtils.mjs.map +0 -1
  387. package/dist/utils/marketDataTransform.cjs +0 -227
  388. package/dist/utils/marketDataTransform.cjs.map +0 -1
  389. package/dist/utils/marketDataTransform.d.cts +0 -45
  390. package/dist/utils/marketDataTransform.d.cts.map +0 -1
  391. package/dist/utils/marketDataTransform.d.mts +0 -45
  392. package/dist/utils/marketDataTransform.d.mts.map +0 -1
  393. package/dist/utils/marketDataTransform.mjs +0 -220
  394. package/dist/utils/marketDataTransform.mjs.map +0 -1
  395. package/dist/utils/marketUtils.cjs +0 -420
  396. package/dist/utils/marketUtils.cjs.map +0 -1
  397. package/dist/utils/marketUtils.d.cts +0 -227
  398. package/dist/utils/marketUtils.d.cts.map +0 -1
  399. package/dist/utils/marketUtils.d.mts +0 -227
  400. package/dist/utils/marketUtils.d.mts.map +0 -1
  401. package/dist/utils/marketUtils.mjs +0 -404
  402. package/dist/utils/marketUtils.mjs.map +0 -1
  403. package/dist/utils/orderBookGrouping.cjs +0 -151
  404. package/dist/utils/orderBookGrouping.cjs.map +0 -1
  405. package/dist/utils/orderBookGrouping.d.cts +0 -76
  406. package/dist/utils/orderBookGrouping.d.cts.map +0 -1
  407. package/dist/utils/orderBookGrouping.d.mts +0 -76
  408. package/dist/utils/orderBookGrouping.d.mts.map +0 -1
  409. package/dist/utils/orderBookGrouping.mjs +0 -143
  410. package/dist/utils/orderBookGrouping.mjs.map +0 -1
  411. package/dist/utils/orderCalculations.cjs +0 -283
  412. package/dist/utils/orderCalculations.cjs.map +0 -1
  413. package/dist/utils/orderCalculations.d.cts +0 -107
  414. package/dist/utils/orderCalculations.d.cts.map +0 -1
  415. package/dist/utils/orderCalculations.d.mts +0 -107
  416. package/dist/utils/orderCalculations.d.mts.map +0 -1
  417. package/dist/utils/orderCalculations.mjs +0 -274
  418. package/dist/utils/orderCalculations.mjs.map +0 -1
  419. package/dist/utils/orderUtils.cjs +0 -159
  420. package/dist/utils/orderUtils.cjs.map +0 -1
  421. package/dist/utils/orderUtils.d.cts +0 -66
  422. package/dist/utils/orderUtils.d.cts.map +0 -1
  423. package/dist/utils/orderUtils.d.mts +0 -66
  424. package/dist/utils/orderUtils.d.mts.map +0 -1
  425. package/dist/utils/orderUtils.mjs +0 -151
  426. package/dist/utils/orderUtils.mjs.map +0 -1
  427. package/dist/utils/pnlCalculations.cjs +0 -107
  428. package/dist/utils/pnlCalculations.cjs.map +0 -1
  429. package/dist/utils/pnlCalculations.d.cts +0 -79
  430. package/dist/utils/pnlCalculations.d.cts.map +0 -1
  431. package/dist/utils/pnlCalculations.d.mts +0 -79
  432. package/dist/utils/pnlCalculations.d.mts.map +0 -1
  433. package/dist/utils/pnlCalculations.mjs +0 -97
  434. package/dist/utils/pnlCalculations.mjs.map +0 -1
  435. package/dist/utils/positionCalculations.cjs +0 -176
  436. package/dist/utils/positionCalculations.cjs.map +0 -1
  437. package/dist/utils/positionCalculations.d.cts +0 -85
  438. package/dist/utils/positionCalculations.d.cts.map +0 -1
  439. package/dist/utils/positionCalculations.d.mts +0 -85
  440. package/dist/utils/positionCalculations.d.mts.map +0 -1
  441. package/dist/utils/positionCalculations.mjs +0 -165
  442. package/dist/utils/positionCalculations.mjs.map +0 -1
  443. package/dist/utils/sortMarkets.cjs +0 -88
  444. package/dist/utils/sortMarkets.cjs.map +0 -1
  445. package/dist/utils/sortMarkets.d.cts +0 -21
  446. package/dist/utils/sortMarkets.d.cts.map +0 -1
  447. package/dist/utils/sortMarkets.d.mts +0 -21
  448. package/dist/utils/sortMarkets.d.mts.map +0 -1
  449. package/dist/utils/sortMarkets.mjs +0 -84
  450. package/dist/utils/sortMarkets.mjs.map +0 -1
  451. package/dist/utils/standaloneInfoClient.cjs +0 -34
  452. package/dist/utils/standaloneInfoClient.cjs.map +0 -1
  453. package/dist/utils/standaloneInfoClient.d.cts +0 -31
  454. package/dist/utils/standaloneInfoClient.d.cts.map +0 -1
  455. package/dist/utils/standaloneInfoClient.d.mts +0 -31
  456. package/dist/utils/standaloneInfoClient.d.mts.map +0 -1
  457. package/dist/utils/standaloneInfoClient.mjs +0 -30
  458. package/dist/utils/standaloneInfoClient.mjs.map +0 -1
  459. package/dist/utils/stringParseUtils.cjs +0 -49
  460. package/dist/utils/stringParseUtils.cjs.map +0 -1
  461. package/dist/utils/stringParseUtils.d.cts +0 -35
  462. package/dist/utils/stringParseUtils.d.cts.map +0 -1
  463. package/dist/utils/stringParseUtils.d.mts +0 -35
  464. package/dist/utils/stringParseUtils.d.mts.map +0 -1
  465. package/dist/utils/stringParseUtils.mjs +0 -44
  466. package/dist/utils/stringParseUtils.mjs.map +0 -1
  467. package/dist/utils/time.cjs +0 -37
  468. package/dist/utils/time.cjs.map +0 -1
  469. package/dist/utils/time.d.cts +0 -17
  470. package/dist/utils/time.d.cts.map +0 -1
  471. package/dist/utils/time.d.mts +0 -17
  472. package/dist/utils/time.d.mts.map +0 -1
  473. package/dist/utils/time.mjs +0 -33
  474. package/dist/utils/time.mjs.map +0 -1
  475. package/dist/utils/tpslValidation.cjs +0 -505
  476. package/dist/utils/tpslValidation.cjs.map +0 -1
  477. package/dist/utils/tpslValidation.d.cts +0 -182
  478. package/dist/utils/tpslValidation.d.cts.map +0 -1
  479. package/dist/utils/tpslValidation.d.mts +0 -182
  480. package/dist/utils/tpslValidation.d.mts.map +0 -1
  481. package/dist/utils/tpslValidation.mjs +0 -482
  482. package/dist/utils/tpslValidation.mjs.map +0 -1
  483. package/dist/utils/transactionUtils.cjs +0 -36
  484. package/dist/utils/transactionUtils.cjs.map +0 -1
  485. package/dist/utils/transactionUtils.d.cts +0 -17
  486. package/dist/utils/transactionUtils.d.cts.map +0 -1
  487. package/dist/utils/transactionUtils.d.mts +0 -17
  488. package/dist/utils/transactionUtils.d.mts.map +0 -1
  489. package/dist/utils/transactionUtils.mjs +0 -32
  490. package/dist/utils/transactionUtils.mjs.map +0 -1
  491. package/dist/utils/wait.cjs +0 -12
  492. package/dist/utils/wait.cjs.map +0 -1
  493. package/dist/utils/wait.d.cts +0 -8
  494. package/dist/utils/wait.d.cts.map +0 -1
  495. package/dist/utils/wait.d.mts +0 -8
  496. package/dist/utils/wait.d.mts.map +0 -1
  497. package/dist/utils/wait.mjs +0 -8
  498. package/dist/utils/wait.mjs.map +0 -1
@@ -1,1477 +0,0 @@
1
- /* eslint-disable id-denylist, jsdoc/require-param-description, @typescript-eslint/prefer-nullish-coalescing, no-restricted-syntax, @typescript-eslint/naming-convention, @typescript-eslint/unbound-method, no-eq-null, jsdoc/check-param-names */
2
- // TODO: Fix ESLint errors in this file - tracked for Phase 5 cleanup
3
- import { v4 as uuidv4 } from "uuid";
4
- import { PerpsEventProperties, PerpsEventValues } from "../constants/eventNames.mjs";
5
- import { isTPSLOrder } from "../constants/orderTypes.mjs";
6
- import { PerpsMeasurementName } from "../constants/performanceMetrics.mjs";
7
- import { PerpsAnalyticsEvent, PerpsTraceNames, PerpsTraceOperations } from "../types/index.mjs";
8
- /**
9
- * TradingService
10
- *
11
- * Handles trading operations with fee discount management.
12
- * Controller is responsible for analytics, state management, and tracing.
13
- *
14
- * Instance-based service with constructor injection of platform dependencies.
15
- * Controller-level dependencies (RewardsController, NetworkController, etc.)
16
- * are injected via setControllerDependencies() after construction.
17
- */
18
- export class TradingService {
19
- /**
20
- * Create a new TradingService instance.
21
- *
22
- * @param deps - Platform dependencies for logging, metrics, etc.
23
- */
24
- constructor(deps) {
25
- /**
26
- * Controller-level dependencies for fee discount calculation.
27
- * Set via setControllerDependencies() after construction.
28
- */
29
- this.controllerDeps = null;
30
- this.deps = deps;
31
- }
32
- /**
33
- * Set controller-level dependencies for fee discount calculation.
34
- * Called by PerpsController after construction to inject singleton dependencies.
35
- *
36
- * @param controllerDeps - Controller-level dependencies (RewardsController, etc.)
37
- */
38
- setControllerDependencies(controllerDeps) {
39
- this.controllerDeps = controllerDeps;
40
- }
41
- /**
42
- * Error context helper for consistent logging.
43
- *
44
- * @param method - Method name
45
- * @param additionalContext - Additional context data
46
- * @returns Error context object
47
- */
48
- getErrorContext(method, additionalContext) {
49
- return {
50
- controller: 'TradingService',
51
- method,
52
- ...additionalContext,
53
- };
54
- }
55
- /**
56
- * Track order result analytics event (success or failure).
57
- *
58
- * @param options - Tracking options
59
- * @param options.result
60
- * @param options.error
61
- * @param options.params
62
- * @param options.context
63
- * @param options.duration
64
- */
65
- trackOrderResult(options) {
66
- const { result, error, params, duration } = options;
67
- const status = result?.success === true
68
- ? PerpsEventValues.STATUS.EXECUTED
69
- : PerpsEventValues.STATUS.FAILED;
70
- // Build base properties
71
- const properties = {
72
- [PerpsEventProperties.STATUS]: status,
73
- [PerpsEventProperties.ASSET]: params.symbol,
74
- [PerpsEventProperties.DIRECTION]: params.isBuy
75
- ? PerpsEventValues.DIRECTION.LONG
76
- : PerpsEventValues.DIRECTION.SHORT,
77
- [PerpsEventProperties.ORDER_TYPE]: params.orderType,
78
- [PerpsEventProperties.LEVERAGE]: parseFloat(String(params.leverage || 1)),
79
- [PerpsEventProperties.ORDER_SIZE]: parseFloat(result?.filledSize || params.size),
80
- [PerpsEventProperties.COMPLETION_DURATION]: duration,
81
- };
82
- // Add optional properties
83
- if (params.trackingData?.marginUsed != null) {
84
- properties[PerpsEventProperties.MARGIN_USED] =
85
- params.trackingData.marginUsed;
86
- }
87
- if (params.trackingData?.totalFee != null) {
88
- properties[PerpsEventProperties.FEES] = params.trackingData.totalFee;
89
- }
90
- if (result?.averagePrice || params.trackingData?.marketPrice) {
91
- properties[PerpsEventProperties.ASSET_PRICE] = result?.averagePrice
92
- ? parseFloat(result.averagePrice)
93
- : params.trackingData?.marketPrice;
94
- }
95
- if (params.orderType === 'limit' && params.price) {
96
- properties[PerpsEventProperties.LIMIT_PRICE] = parseFloat(params.price);
97
- }
98
- if (params.trackingData?.source) {
99
- properties[PerpsEventProperties.SOURCE] = params.trackingData.source;
100
- }
101
- if (params.trackingData?.tradeAction) {
102
- properties[PerpsEventProperties.ACTION] = params.trackingData.tradeAction;
103
- }
104
- // Add success-specific properties
105
- if (status === PerpsEventValues.STATUS.EXECUTED) {
106
- if (params.trackingData?.metamaskFee != null) {
107
- properties[PerpsEventProperties.METAMASK_FEE] =
108
- params.trackingData.metamaskFee;
109
- }
110
- if (params.trackingData?.metamaskFeeRate != null) {
111
- properties[PerpsEventProperties.METAMASK_FEE_RATE] =
112
- params.trackingData.metamaskFeeRate;
113
- }
114
- if (params.trackingData?.feeDiscountPercentage != null) {
115
- properties[PerpsEventProperties.DISCOUNT_PERCENTAGE] =
116
- params.trackingData.feeDiscountPercentage;
117
- }
118
- if (params.trackingData?.estimatedPoints != null) {
119
- properties[PerpsEventProperties.ESTIMATED_REWARDS] =
120
- params.trackingData.estimatedPoints;
121
- }
122
- if (params.takeProfitPrice) {
123
- properties[PerpsEventProperties.TAKE_PROFIT_PRICE] = parseFloat(params.takeProfitPrice);
124
- }
125
- if (params.stopLossPrice) {
126
- properties[PerpsEventProperties.STOP_LOSS_PRICE] = parseFloat(params.stopLossPrice);
127
- }
128
- }
129
- else {
130
- // Add failure-specific properties
131
- properties[PerpsEventProperties.ERROR_MESSAGE] =
132
- error?.message || result?.error || 'Unknown error';
133
- }
134
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.TradeTransaction, properties);
135
- }
136
- /**
137
- * Handle successful order placement (state updates, analytics, data lake reporting).
138
- *
139
- * @param options - Options for handling order success
140
- * @param options.params
141
- * @param options.context
142
- * @param options.reportOrderToDataLake
143
- */
144
- async handleOrderSuccess(options) {
145
- const { params, context, reportOrderToDataLake } = options;
146
- // Update state on success
147
- if (context.stateManager) {
148
- context.stateManager.update((state) => {
149
- state.lastUpdateTimestamp = Date.now();
150
- });
151
- }
152
- // Save executed trade configuration for this market
153
- if (params.leverage && context.saveTradeConfiguration) {
154
- context.saveTradeConfiguration(params.symbol, params.leverage);
155
- }
156
- // Report to data lake (fire-and-forget with retry)
157
- reportOrderToDataLake({
158
- action: 'open',
159
- symbol: params.symbol,
160
- sl_price: params.stopLossPrice
161
- ? parseFloat(params.stopLossPrice)
162
- : undefined,
163
- tp_price: params.takeProfitPrice
164
- ? parseFloat(params.takeProfitPrice)
165
- : undefined,
166
- }).catch((caughtError) => {
167
- const errorObj = caughtError instanceof Error
168
- ? caughtError
169
- : new Error(String(caughtError));
170
- this.deps.logger.error(errorObj, {
171
- tags: {
172
- feature: 'perps',
173
- provider: context.tracingContext.provider,
174
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
175
- },
176
- context: {
177
- name: context.errorContext.controller,
178
- data: {
179
- method: context.errorContext.method,
180
- operation: 'reportOrderToDataLake',
181
- symbol: params.symbol,
182
- },
183
- },
184
- });
185
- });
186
- }
187
- /**
188
- * Execute a trading operation with fee discount context.
189
- * Ensures fee discount is always cleared after operation (success or failure).
190
- *
191
- * @param options - Options for fee discount context
192
- * @param options.provider
193
- * @param options.feeDiscountBips
194
- * @param options.operation
195
- * @returns The operation result
196
- */
197
- async withFeeDiscount(options) {
198
- const { provider, feeDiscountBips, operation } = options;
199
- try {
200
- // Set discount context in provider for this operation
201
- if (feeDiscountBips !== undefined && provider.setUserFeeDiscount) {
202
- provider.setUserFeeDiscount(feeDiscountBips);
203
- this.deps.debugLogger.log('TradingService: Fee discount set in provider', {
204
- feeDiscountBips,
205
- });
206
- }
207
- // Execute the operation
208
- return await operation();
209
- }
210
- finally {
211
- // Always clear discount context, even on exception
212
- if (provider.setUserFeeDiscount) {
213
- provider.setUserFeeDiscount(undefined);
214
- this.deps.debugLogger.log('TradingService: Fee discount cleared from provider');
215
- }
216
- }
217
- }
218
- /**
219
- * Place a new order with full orchestration.
220
- * Handles tracing, fee discounts, state management, analytics, and data lake reporting.
221
- *
222
- * @param options - Options for placing order
223
- * @param options.provider
224
- * @param options.params
225
- * @param options.context
226
- * @param options.reportOrderToDataLake
227
- * @returns Order result
228
- */
229
- async placeOrder(options) {
230
- const { provider, params, context, reportOrderToDataLake } = options;
231
- const traceId = uuidv4();
232
- const startTime = this.deps.performance.now();
233
- let traceData;
234
- try {
235
- // Start trace for the entire operation
236
- this.deps.tracer.trace({
237
- name: PerpsTraceNames.PlaceOrder,
238
- id: traceId,
239
- op: PerpsTraceOperations.OrderSubmission,
240
- tags: {
241
- provider: context.tracingContext.provider,
242
- orderType: params.orderType,
243
- market: params.symbol,
244
- leverage: String(params.leverage || 1),
245
- isTestnet: String(context.tracingContext.isTestnet),
246
- },
247
- data: {
248
- isBuy: params.isBuy,
249
- orderPrice: params.price || '',
250
- },
251
- });
252
- // Calculate fee discount at execution time (fresh, secure)
253
- const feeDiscountBips = await this.calculateFeeDiscountWithMeasurement();
254
- this.deps.debugLogger.log('TradingService: Fee discount calculated', {
255
- feeDiscountBips,
256
- hasDiscount: feeDiscountBips !== undefined,
257
- });
258
- this.deps.debugLogger.log('TradingService: Submitting order to provider', {
259
- symbol: params.symbol,
260
- orderType: params.orderType,
261
- isBuy: params.isBuy,
262
- size: params.size,
263
- leverage: params.leverage,
264
- hasTP: Boolean(params.takeProfitPrice),
265
- hasSL: Boolean(params.stopLossPrice),
266
- });
267
- // Execute order with fee discount management
268
- const result = await this.withFeeDiscount({
269
- provider,
270
- feeDiscountBips,
271
- operation: () => provider.placeOrder(params),
272
- });
273
- this.deps.debugLogger.log('TradingService: Provider response received', {
274
- success: result.success,
275
- orderId: result.orderId,
276
- error: result.error,
277
- });
278
- // Update state and handle success/failure
279
- const completionDuration = this.deps.performance.now() - startTime;
280
- if (result.success) {
281
- // Handle success: state updates, data lake reporting
282
- await this.handleOrderSuccess({
283
- params,
284
- context,
285
- reportOrderToDataLake,
286
- });
287
- traceData = { success: true, orderId: result.orderId || '' };
288
- }
289
- else {
290
- traceData = { success: false, error: result.error || 'Unknown error' };
291
- }
292
- // Track analytics (success or failure)
293
- this.trackOrderResult({
294
- result,
295
- params,
296
- context,
297
- duration: completionDuration,
298
- });
299
- return result;
300
- }
301
- catch (err) {
302
- const completionDuration = this.deps.performance.now() - startTime;
303
- const error = err instanceof Error ? err : new Error(String(err));
304
- // Track analytics for exception
305
- this.trackOrderResult({
306
- result: null,
307
- error,
308
- params,
309
- context,
310
- duration: completionDuration,
311
- });
312
- this.deps.logger.error(error, {
313
- tags: {
314
- feature: 'perps',
315
- provider: context.tracingContext.provider,
316
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
317
- },
318
- context: {
319
- name: context.errorContext.controller,
320
- data: {
321
- method: context.errorContext.method,
322
- symbol: params.symbol,
323
- orderType: params.orderType,
324
- },
325
- },
326
- });
327
- traceData = {
328
- success: false,
329
- error: error.message,
330
- };
331
- throw err;
332
- }
333
- finally {
334
- // Always end trace on exit (success or failure)
335
- this.deps.tracer.endTrace({
336
- name: PerpsTraceNames.PlaceOrder,
337
- id: traceId,
338
- data: traceData,
339
- });
340
- }
341
- }
342
- /**
343
- * Load position data with performance measurement.
344
- *
345
- * @param options - Options for loading position data
346
- * @param options.symbol
347
- * @param options.context
348
- * @returns The position or undefined
349
- */
350
- async loadPositionData(options) {
351
- const { symbol, context } = options;
352
- const positionLoadStart = this.deps.performance.now();
353
- try {
354
- const positions = context.getPositions
355
- ? await context.getPositions()
356
- : [];
357
- const position = positions.find((pos) => pos.symbol === symbol);
358
- this.deps.tracer.setMeasurement(PerpsMeasurementName.PerpsGetPositionsOperation, this.deps.performance.now() - positionLoadStart, 'millisecond');
359
- return position;
360
- }
361
- catch (err) {
362
- this.deps.debugLogger.log('TradingService: Could not get position data for tracking', err instanceof Error ? err.message : String(err));
363
- return undefined;
364
- }
365
- }
366
- /**
367
- * Calculate close position metrics.
368
- *
369
- * @param position - The position being closed
370
- * @param params - Close position parameters
371
- * @param result - Order result
372
- * @returns Calculated metrics
373
- */
374
- calculateCloseMetrics(position, params, result) {
375
- const direction = parseFloat(position.size) > 0
376
- ? PerpsEventValues.DIRECTION.LONG
377
- : PerpsEventValues.DIRECTION.SHORT;
378
- const filledSize = result.filledSize ? parseFloat(result.filledSize) : 0;
379
- const requestedSize = params.size
380
- ? parseFloat(params.size)
381
- : Math.abs(parseFloat(position.size));
382
- const isPartiallyFilled = filledSize > 0 && filledSize < requestedSize;
383
- const orderType = params.orderType || PerpsEventValues.ORDER_TYPE.MARKET;
384
- const closePercentage = params.size
385
- ? (parseFloat(params.size) / Math.abs(parseFloat(position.size))) * 100
386
- : 100;
387
- const closeType = closePercentage === 100
388
- ? PerpsEventValues.CLOSE_TYPE.FULL
389
- : PerpsEventValues.CLOSE_TYPE.PARTIAL;
390
- return {
391
- direction,
392
- closePercentage,
393
- closeType,
394
- orderType,
395
- filledSize,
396
- requestedSize,
397
- isPartiallyFilled,
398
- };
399
- }
400
- /**
401
- * Build event properties for position close analytics.
402
- *
403
- * @param position - The position being closed
404
- * @param params - Close position parameters
405
- * @param metrics - Calculated metrics
406
- * @param metrics.direction
407
- * @param result - Order result
408
- * @param metrics.closePercentage
409
- * @param status - Event status
410
- * @param metrics.closeType
411
- * @param error - Error message if any
412
- * @param metrics.orderType
413
- * @param metrics.requestedSize
414
- * @returns Event properties
415
- */
416
- buildCloseEventProperties(position, params, metrics, result, status, error) {
417
- const baseProperties = {
418
- [PerpsEventProperties.STATUS]: status,
419
- [PerpsEventProperties.ASSET]: position.symbol,
420
- [PerpsEventProperties.DIRECTION]: metrics.direction,
421
- [PerpsEventProperties.ORDER_TYPE]: metrics.orderType,
422
- [PerpsEventProperties.ORDER_SIZE]: metrics.requestedSize,
423
- [PerpsEventProperties.OPEN_POSITION_SIZE]: Math.abs(parseFloat(position.size)),
424
- [PerpsEventProperties.PERCENTAGE_CLOSED]: metrics.closePercentage,
425
- ...(position.unrealizedPnl && {
426
- [PerpsEventProperties.PNL_DOLLAR]: parseFloat(position.unrealizedPnl),
427
- }),
428
- ...(position.returnOnEquity && {
429
- [PerpsEventProperties.PNL_PERCENT]: parseFloat(position.returnOnEquity) * 100,
430
- }),
431
- ...(params.trackingData?.totalFee != null && {
432
- [PerpsEventProperties.FEE]: params.trackingData.totalFee,
433
- }),
434
- ...(params.trackingData?.metamaskFee != null && {
435
- [PerpsEventProperties.METAMASK_FEE]: params.trackingData.metamaskFee,
436
- }),
437
- ...(params.trackingData?.metamaskFeeRate != null && {
438
- [PerpsEventProperties.METAMASK_FEE_RATE]: params.trackingData.metamaskFeeRate,
439
- }),
440
- ...(params.trackingData?.feeDiscountPercentage != null && {
441
- [PerpsEventProperties.DISCOUNT_PERCENTAGE]: params.trackingData.feeDiscountPercentage,
442
- }),
443
- ...(params.trackingData?.estimatedPoints != null && {
444
- [PerpsEventProperties.ESTIMATED_REWARDS]: params.trackingData.estimatedPoints,
445
- }),
446
- ...((params.trackingData?.marketPrice || result?.averagePrice) && {
447
- [PerpsEventProperties.ASSET_PRICE]: result?.averagePrice
448
- ? parseFloat(result.averagePrice)
449
- : params.trackingData?.marketPrice,
450
- }),
451
- ...(params.orderType === 'limit' &&
452
- params.price && {
453
- [PerpsEventProperties.LIMIT_PRICE]: parseFloat(params.price),
454
- }),
455
- ...(params.trackingData?.receivedAmount != null && {
456
- [PerpsEventProperties.RECEIVED_AMOUNT]: params.trackingData.receivedAmount,
457
- }),
458
- };
459
- // Add success-specific properties
460
- if (status === PerpsEventValues.STATUS.EXECUTED) {
461
- return {
462
- ...baseProperties,
463
- [PerpsEventProperties.CLOSE_TYPE]: metrics.closeType,
464
- };
465
- }
466
- // Add error for failures
467
- return {
468
- ...baseProperties,
469
- ...(error && { [PerpsEventProperties.ERROR_MESSAGE]: error }),
470
- };
471
- }
472
- /**
473
- * Track position close result analytics (consolidates all tracking logic).
474
- *
475
- * @param options - Tracking options
476
- * @param options.position
477
- * @param options.result
478
- * @param options.error
479
- * @param options.params
480
- * @param options.context
481
- * @param options.duration
482
- */
483
- trackPositionCloseResult(options) {
484
- const { position, result, error, params, duration } = options;
485
- if (!position) {
486
- return;
487
- }
488
- const metrics = result
489
- ? this.calculateCloseMetrics(position, params, result)
490
- : {
491
- direction: parseFloat(position.size) > 0
492
- ? PerpsEventValues.DIRECTION.LONG
493
- : PerpsEventValues.DIRECTION.SHORT,
494
- closePercentage: params.size
495
- ? (parseFloat(params.size) / Math.abs(parseFloat(position.size))) *
496
- 100
497
- : 100,
498
- closeType: PerpsEventValues.CLOSE_TYPE.FULL,
499
- orderType: params.orderType || PerpsEventValues.ORDER_TYPE.MARKET,
500
- requestedSize: params.size
501
- ? parseFloat(params.size)
502
- : Math.abs(parseFloat(position.size)),
503
- filledSize: 0,
504
- isPartiallyFilled: false,
505
- };
506
- // Track partially filled event if applicable
507
- if (result?.success && metrics.isPartiallyFilled) {
508
- const partialProperties = this.buildCloseEventProperties(position, params, metrics, result, PerpsEventValues.STATUS.PARTIALLY_FILLED);
509
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.PositionCloseTransaction, {
510
- ...partialProperties,
511
- [PerpsEventProperties.AMOUNT_FILLED]: metrics.filledSize,
512
- [PerpsEventProperties.REMAINING_AMOUNT]: metrics.requestedSize - metrics.filledSize,
513
- [PerpsEventProperties.COMPLETION_DURATION]: duration,
514
- });
515
- }
516
- // Determine status
517
- const status = result?.success === true
518
- ? PerpsEventValues.STATUS.EXECUTED
519
- : PerpsEventValues.STATUS.FAILED;
520
- const errorMessage = error?.message || result?.error;
521
- // Track main close event
522
- const eventProperties = this.buildCloseEventProperties(position, params, metrics, result, status, errorMessage);
523
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.PositionCloseTransaction, {
524
- ...eventProperties,
525
- [PerpsEventProperties.COMPLETION_DURATION]: duration,
526
- });
527
- }
528
- /**
529
- * Handle data lake reporting (fire-and-forget).
530
- *
531
- * @param reportOrderToDataLake - Data lake reporting function
532
- * @param symbol - Asset symbol
533
- * @param context - Service context
534
- */
535
- handleDataLakeReporting(reportOrderToDataLake, symbol, context) {
536
- reportOrderToDataLake({
537
- action: 'close',
538
- symbol,
539
- }).catch((caughtError) => {
540
- const errorObj = caughtError instanceof Error
541
- ? caughtError
542
- : new Error(String(caughtError));
543
- this.deps.logger.error(errorObj, {
544
- tags: {
545
- feature: 'perps',
546
- provider: context.tracingContext.provider,
547
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
548
- },
549
- context: {
550
- name: context.errorContext.controller,
551
- data: {
552
- method: context.errorContext.method,
553
- operation: 'reportOrderToDataLake',
554
- symbol,
555
- },
556
- },
557
- });
558
- });
559
- }
560
- /**
561
- * Calculate fee discount with performance measurement.
562
- * Uses controller dependencies injected via setControllerDependencies().
563
- * Helper method for placeOrder orchestration.
564
- *
565
- * @returns Fee discount in basis points or undefined
566
- */
567
- async calculateFeeDiscountWithMeasurement() {
568
- // Check if controller dependencies are available
569
- if (!this.controllerDeps) {
570
- this.deps.debugLogger.log('TradingService: Controller dependencies not set, skipping fee discount');
571
- return undefined;
572
- }
573
- const { controllers, rewardsIntegrationService } = this.controllerDeps;
574
- const orderExecutionFeeDiscountStartTime = this.deps.performance.now();
575
- // Calculate fee discount using injected controllers
576
- const discountBips = await rewardsIntegrationService.calculateUserFeeDiscount({
577
- controllers,
578
- });
579
- const orderExecutionFeeDiscountDuration = this.deps.performance.now() - orderExecutionFeeDiscountStartTime;
580
- // Record measurement
581
- this.deps.tracer.setMeasurement(PerpsMeasurementName.PerpsRewardsOrderExecutionFeeDiscountApiCall, orderExecutionFeeDiscountDuration, 'millisecond');
582
- this.deps.debugLogger.log('TradingService: Fee discount API call completed', {
583
- discountBips,
584
- duration: `${orderExecutionFeeDiscountDuration.toFixed(0)}ms`,
585
- });
586
- return discountBips;
587
- }
588
- /**
589
- * Edit an existing order with full orchestration.
590
- * Handles tracing, fee discounts, state management, and analytics.
591
- *
592
- * @param options - Options for editing order
593
- * @param options.provider
594
- * @param options.params
595
- * @param options.context
596
- * @returns Order result
597
- */
598
- async editOrder(options) {
599
- const { provider, params, context } = options;
600
- const traceId = uuidv4();
601
- const startTime = this.deps.performance.now();
602
- let traceData;
603
- try {
604
- this.deps.tracer.trace({
605
- name: PerpsTraceNames.EditOrder,
606
- id: traceId,
607
- op: PerpsTraceOperations.OrderSubmission,
608
- tags: {
609
- provider: context.tracingContext.provider,
610
- orderType: params.newOrder.orderType,
611
- market: params.newOrder.symbol,
612
- leverage: String(params.newOrder.leverage || 1),
613
- isTestnet: String(context.tracingContext.isTestnet),
614
- },
615
- data: {
616
- isBuy: params.newOrder.isBuy,
617
- orderPrice: params.newOrder.price || '',
618
- },
619
- });
620
- // Calculate fee discount only if required dependencies are available
621
- const feeDiscountBips = await this.calculateFeeDiscountWithMeasurement();
622
- // Execute order edit with fee discount management
623
- const result = await this.withFeeDiscount({
624
- provider,
625
- feeDiscountBips,
626
- operation: () => provider.editOrder(params),
627
- });
628
- const completionDuration = this.deps.performance.now() - startTime;
629
- if (result.success) {
630
- // Update state on success
631
- if (context.stateManager) {
632
- context.stateManager.update((state) => {
633
- state.lastUpdateTimestamp = Date.now();
634
- });
635
- }
636
- // Track order edit executed
637
- const editExecutedProps = {
638
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.EXECUTED,
639
- [PerpsEventProperties.ASSET]: params.newOrder.symbol,
640
- [PerpsEventProperties.DIRECTION]: params.newOrder.isBuy
641
- ? PerpsEventValues.DIRECTION.LONG
642
- : PerpsEventValues.DIRECTION.SHORT,
643
- [PerpsEventProperties.ORDER_TYPE]: params.newOrder.orderType,
644
- [PerpsEventProperties.LEVERAGE]: params.newOrder.leverage || 1,
645
- [PerpsEventProperties.ORDER_SIZE]: params.newOrder.size,
646
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
647
- };
648
- if (params.newOrder.price) {
649
- editExecutedProps[PerpsEventProperties.LIMIT_PRICE] = parseFloat(params.newOrder.price);
650
- }
651
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.TradeTransaction, editExecutedProps);
652
- traceData = { success: true, orderId: result.orderId || '' };
653
- }
654
- else {
655
- // Track order edit failed
656
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.TradeTransaction, {
657
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.FAILED,
658
- [PerpsEventProperties.ASSET]: params.newOrder.symbol,
659
- [PerpsEventProperties.DIRECTION]: params.newOrder.isBuy
660
- ? PerpsEventValues.DIRECTION.LONG
661
- : PerpsEventValues.DIRECTION.SHORT,
662
- [PerpsEventProperties.ORDER_TYPE]: params.newOrder.orderType,
663
- [PerpsEventProperties.LEVERAGE]: params.newOrder.leverage || 1,
664
- [PerpsEventProperties.ORDER_SIZE]: params.newOrder.size,
665
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
666
- [PerpsEventProperties.ERROR_MESSAGE]: result.error || 'Unknown error',
667
- });
668
- traceData = { success: false, error: result.error || 'Unknown error' };
669
- }
670
- return result;
671
- }
672
- catch (err) {
673
- const completionDuration = this.deps.performance.now() - startTime;
674
- const error = err instanceof Error ? err : new Error(String(err));
675
- // Track order edit exception
676
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.TradeTransaction, {
677
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.FAILED,
678
- [PerpsEventProperties.ASSET]: params.newOrder.symbol,
679
- [PerpsEventProperties.DIRECTION]: params.newOrder.isBuy
680
- ? PerpsEventValues.DIRECTION.LONG
681
- : PerpsEventValues.DIRECTION.SHORT,
682
- [PerpsEventProperties.ORDER_TYPE]: params.newOrder.orderType,
683
- [PerpsEventProperties.LEVERAGE]: params.newOrder.leverage || 1,
684
- [PerpsEventProperties.ORDER_SIZE]: params.newOrder.size,
685
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
686
- [PerpsEventProperties.ERROR_MESSAGE]: error.message,
687
- });
688
- this.deps.logger.error(error, {
689
- tags: {
690
- feature: 'perps',
691
- provider: context.tracingContext.provider,
692
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
693
- },
694
- context: {
695
- name: context.errorContext.controller,
696
- data: {
697
- method: context.errorContext.method,
698
- orderId: params.orderId,
699
- },
700
- },
701
- });
702
- traceData = {
703
- success: false,
704
- error: error.message,
705
- };
706
- throw err;
707
- }
708
- finally {
709
- this.deps.tracer.endTrace({
710
- name: PerpsTraceNames.EditOrder,
711
- id: traceId,
712
- data: traceData,
713
- });
714
- }
715
- }
716
- /**
717
- * Cancel a single order with full orchestration.
718
- * Handles tracing, state management, and analytics.
719
- *
720
- * @param options - Options for canceling order
721
- * @param options.provider
722
- * @param options.params
723
- * @param options.context
724
- * @returns Cancel order result
725
- */
726
- async cancelOrder(options) {
727
- const { provider, params, context } = options;
728
- const traceId = uuidv4();
729
- const startTime = this.deps.performance.now();
730
- let traceData;
731
- try {
732
- // Start trace for the entire operation
733
- this.deps.tracer.trace({
734
- name: PerpsTraceNames.CancelOrder,
735
- id: traceId,
736
- op: PerpsTraceOperations.OrderSubmission,
737
- tags: {
738
- provider: context.tracingContext.provider,
739
- market: params.symbol,
740
- isTestnet: String(context.tracingContext.isTestnet),
741
- },
742
- data: {
743
- orderId: params.orderId,
744
- },
745
- });
746
- // Execute order cancellation
747
- const result = await provider.cancelOrder(params);
748
- const completionDuration = this.deps.performance.now() - startTime;
749
- if (result.success) {
750
- // Update state on success
751
- if (context.stateManager) {
752
- context.stateManager.update((state) => {
753
- state.lastUpdateTimestamp = Date.now();
754
- });
755
- }
756
- // Track order cancel executed
757
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.OrderCancelTransaction, {
758
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.EXECUTED,
759
- [PerpsEventProperties.ASSET]: params.symbol,
760
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
761
- });
762
- traceData = { success: true, orderId: params.orderId };
763
- }
764
- else {
765
- // Track order cancel failed
766
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.OrderCancelTransaction, {
767
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.FAILED,
768
- [PerpsEventProperties.ASSET]: params.symbol,
769
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
770
- [PerpsEventProperties.ERROR_MESSAGE]: result.error || 'Unknown error',
771
- });
772
- traceData = { success: false, error: result.error || 'Unknown error' };
773
- }
774
- return result;
775
- }
776
- catch (err) {
777
- const completionDuration = this.deps.performance.now() - startTime;
778
- const error = err instanceof Error ? err : new Error(String(err));
779
- // Track order cancel exception
780
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.OrderCancelTransaction, {
781
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.FAILED,
782
- [PerpsEventProperties.ASSET]: params.symbol,
783
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
784
- [PerpsEventProperties.ERROR_MESSAGE]: error.message,
785
- });
786
- this.deps.logger.error(error, this.getErrorContext('cancelOrder', { symbol: params.symbol }));
787
- traceData = {
788
- success: false,
789
- error: error.message,
790
- };
791
- throw err;
792
- }
793
- finally {
794
- this.deps.tracer.endTrace({
795
- name: PerpsTraceNames.CancelOrder,
796
- id: traceId,
797
- data: traceData,
798
- });
799
- }
800
- }
801
- /**
802
- * Cancel multiple orders with full orchestration.
803
- * Handles tracing, stream pausing, filtering, batch operations, and analytics.
804
- *
805
- * @param options - Options for canceling multiple orders
806
- * @param options.provider
807
- * @param options.params
808
- * @param options.context
809
- * @param options.withStreamPause
810
- * @returns Cancel orders result
811
- */
812
- async cancelOrders(options) {
813
- const { provider, params, context, withStreamPause } = options;
814
- const traceId = uuidv4();
815
- const startTime = this.deps.performance.now();
816
- let operationResult = null;
817
- let operationError = null;
818
- try {
819
- // Start trace for batch operation
820
- this.deps.tracer.trace({
821
- name: PerpsTraceNames.CancelOrder,
822
- id: traceId,
823
- op: PerpsTraceOperations.OrderSubmission,
824
- tags: {
825
- provider: context.tracingContext.provider,
826
- isBatch: 'true',
827
- isTestnet: String(context.tracingContext.isTestnet),
828
- },
829
- data: {
830
- cancelAll: params.cancelAll ? 'true' : 'false',
831
- symbolCount: params.symbols?.length || 0,
832
- orderIdCount: params.orderIds?.length || 0,
833
- },
834
- });
835
- // Pause orders stream to prevent WebSocket updates during cancellation
836
- operationResult = await withStreamPause(async () => {
837
- // Get all open orders
838
- if (!context.getOpenOrders) {
839
- throw new Error('getOpenOrders callback not provided in context');
840
- }
841
- const orders = await context.getOpenOrders();
842
- // Filter orders based on params
843
- let ordersToCancel = orders;
844
- if (params.cancelAll || (!params.symbols && !params.orderIds)) {
845
- // Cancel all orders (excluding TP/SL orders for positions)
846
- ordersToCancel = orders.filter((order) => !isTPSLOrder(order.detailedOrderType));
847
- }
848
- else if (params.orderIds && params.orderIds.length > 0) {
849
- // Cancel specific order IDs
850
- ordersToCancel = orders.filter((order) => params.orderIds?.includes(order.orderId));
851
- }
852
- else if (params.symbols && params.symbols.length > 0) {
853
- // Cancel orders for specific symbols
854
- ordersToCancel = orders.filter((order) => params.symbols?.includes(order.symbol));
855
- }
856
- if (ordersToCancel.length === 0) {
857
- return {
858
- success: false,
859
- successCount: 0,
860
- failureCount: 0,
861
- results: [],
862
- };
863
- }
864
- // Use batch cancel if provider supports it
865
- if (provider.cancelOrders) {
866
- return await provider.cancelOrders(ordersToCancel.map((order) => ({
867
- symbol: order.symbol,
868
- orderId: order.orderId,
869
- })));
870
- }
871
- // Fallback: Cancel orders in parallel (for providers without batch support)
872
- const results = await Promise.allSettled(ordersToCancel.map((order) => this.cancelOrder({
873
- provider,
874
- params: { symbol: order.symbol, orderId: order.orderId },
875
- context,
876
- })));
877
- // Aggregate results
878
- const successCount = results.filter((resItem) => resItem.status === 'fulfilled' && resItem.value.success).length;
879
- const failureCount = results.length - successCount;
880
- return {
881
- success: successCount > 0,
882
- successCount,
883
- failureCount,
884
- results: results.map((resItem, index) => {
885
- let errorMsg;
886
- if (resItem.status === 'rejected') {
887
- errorMsg =
888
- resItem.reason instanceof Error
889
- ? resItem.reason.message
890
- : 'Unknown error';
891
- }
892
- else if (resItem.status === 'fulfilled' &&
893
- !resItem.value.success) {
894
- errorMsg = resItem.value.error;
895
- }
896
- return {
897
- orderId: ordersToCancel[index].orderId,
898
- symbol: ordersToCancel[index].symbol,
899
- success: Boolean(resItem.status === 'fulfilled' && resItem.value.success),
900
- error: errorMsg,
901
- };
902
- }),
903
- };
904
- }, ['orders']); // Disconnect orders stream during operation
905
- return operationResult;
906
- }
907
- catch (err) {
908
- operationError = err instanceof Error ? err : new Error(String(err));
909
- this.deps.logger.error(operationError, this.getErrorContext('cancelOrders'));
910
- throw err;
911
- }
912
- finally {
913
- const completionDuration = this.deps.performance.now() - startTime;
914
- // Track batch cancel event (success or failure)
915
- const batchCancelProps = {
916
- [PerpsEventProperties.STATUS]: operationResult?.success && operationResult.successCount > 0
917
- ? PerpsEventValues.STATUS.EXECUTED
918
- : PerpsEventValues.STATUS.FAILED,
919
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
920
- };
921
- if (operationError) {
922
- batchCancelProps[PerpsEventProperties.ERROR_MESSAGE] =
923
- operationError.message;
924
- }
925
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.OrderCancelTransaction, batchCancelProps);
926
- this.deps.tracer.endTrace({
927
- name: PerpsTraceNames.CancelOrder,
928
- id: traceId,
929
- });
930
- }
931
- }
932
- /**
933
- * Close a single position with full orchestration.
934
- * Handles tracing, fee discounts, state management, analytics, and data lake reporting.
935
- *
936
- * @param options - Options for closing position
937
- * @param options.provider
938
- * @param options.params
939
- * @param options.context
940
- * @param options.reportOrderToDataLake
941
- * @returns Order result
942
- */
943
- async closePosition(options) {
944
- const { provider, params, context, reportOrderToDataLake } = options;
945
- const traceId = uuidv4();
946
- const startTime = this.deps.performance.now();
947
- let position;
948
- let result;
949
- let traceData;
950
- try {
951
- this.deps.tracer.trace({
952
- name: PerpsTraceNames.ClosePosition,
953
- id: traceId,
954
- op: PerpsTraceOperations.PositionManagement,
955
- tags: {
956
- provider: context.tracingContext.provider,
957
- symbol: params.symbol,
958
- closeSize: params.size || 'full',
959
- isTestnet: String(context.tracingContext.isTestnet),
960
- },
961
- });
962
- // Load position data with measurement
963
- position = await this.loadPositionData({
964
- symbol: params.symbol,
965
- context,
966
- });
967
- // Calculate fee discount with measurement
968
- const feeDiscountBips = await this.calculateFeeDiscountWithMeasurement();
969
- // Execute position close with fee discount management
970
- result = await this.withFeeDiscount({
971
- provider,
972
- feeDiscountBips,
973
- operation: () => provider.closePosition(params),
974
- });
975
- const completionDuration = this.deps.performance.now() - startTime;
976
- if (result.success) {
977
- // Update state on success
978
- if (context.stateManager) {
979
- context.stateManager.update((state) => {
980
- state.lastUpdateTimestamp = Date.now();
981
- });
982
- }
983
- // Report to data lake (fire-and-forget)
984
- this.handleDataLakeReporting(reportOrderToDataLake, params.symbol, context);
985
- traceData = { success: true, filledSize: result.filledSize || '' };
986
- }
987
- else {
988
- traceData = { success: false, error: result.error || 'Unknown error' };
989
- }
990
- // Track analytics (success or failure, includes partial fills)
991
- this.trackPositionCloseResult({
992
- position,
993
- result,
994
- params,
995
- context,
996
- duration: completionDuration,
997
- });
998
- return result;
999
- }
1000
- catch (err) {
1001
- const completionDuration = this.deps.performance.now() - startTime;
1002
- const error = err instanceof Error ? err : new Error(String(err));
1003
- traceData = {
1004
- success: false,
1005
- error: error.message,
1006
- };
1007
- // Track analytics for exception
1008
- this.trackPositionCloseResult({
1009
- position,
1010
- result: null,
1011
- error,
1012
- params,
1013
- context,
1014
- duration: completionDuration,
1015
- });
1016
- this.deps.logger.error(error, {
1017
- tags: {
1018
- feature: 'perps',
1019
- provider: context.tracingContext.provider,
1020
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
1021
- },
1022
- context: {
1023
- name: context.errorContext.controller,
1024
- data: {
1025
- method: context.errorContext.method,
1026
- symbol: params.symbol,
1027
- },
1028
- },
1029
- });
1030
- throw err;
1031
- }
1032
- finally {
1033
- // Always end trace on exit (success or failure)
1034
- this.deps.tracer.endTrace({
1035
- name: PerpsTraceNames.ClosePosition,
1036
- id: traceId,
1037
- data: traceData,
1038
- });
1039
- }
1040
- }
1041
- /**
1042
- * Close multiple positions with full orchestration.
1043
- * Handles tracing, fee discounts, batch operations, and analytics.
1044
- *
1045
- * @param options - Options for closing multiple positions
1046
- * @param options.provider
1047
- * @param options.params
1048
- * @param options.context
1049
- * @returns Close positions result
1050
- */
1051
- async closePositions(options) {
1052
- const { provider, params, context } = options;
1053
- const traceId = uuidv4();
1054
- const startTime = this.deps.performance.now();
1055
- let operationResult = null;
1056
- let operationError = null;
1057
- try {
1058
- // Start trace for batch operation
1059
- this.deps.tracer.trace({
1060
- name: PerpsTraceNames.ClosePosition,
1061
- id: traceId,
1062
- op: PerpsTraceOperations.PositionManagement,
1063
- tags: {
1064
- provider: context.tracingContext.provider,
1065
- isBatch: 'true',
1066
- isTestnet: String(context.tracingContext.isTestnet),
1067
- },
1068
- data: {
1069
- closeAll: params.closeAll ? 'true' : 'false',
1070
- symbolCount: params.symbols?.length || 0,
1071
- },
1072
- });
1073
- this.deps.debugLogger.log('[closePositions] Batch method check', {
1074
- providerType: provider.protocolId,
1075
- hasBatchMethod: Boolean(provider.closePositions),
1076
- methodType: typeof provider.closePositions,
1077
- providerKeys: Object.keys(provider).filter((key) => key.includes('close')),
1078
- });
1079
- // Use batch close if provider supports it (provider handles filtering)
1080
- if (provider.closePositions) {
1081
- const feeDiscountBips = await this.calculateFeeDiscountWithMeasurement();
1082
- operationResult = await this.withFeeDiscount({
1083
- provider,
1084
- feeDiscountBips,
1085
- operation: async () => {
1086
- if (!provider.closePositions) {
1087
- throw new Error('closePositions method not available');
1088
- }
1089
- return provider.closePositions(params);
1090
- },
1091
- });
1092
- }
1093
- else {
1094
- // Fallback: Get positions, filter, and close in parallel
1095
- if (!context.getPositions) {
1096
- throw new Error('getPositions callback not provided in context');
1097
- }
1098
- const positions = await context.getPositions();
1099
- const positionsToClose = params.closeAll || !params.symbols || params.symbols.length === 0
1100
- ? positions
1101
- : positions.filter((pos) => params.symbols?.includes(pos.symbol));
1102
- if (positionsToClose.length === 0) {
1103
- operationResult = {
1104
- success: false,
1105
- successCount: 0,
1106
- failureCount: 0,
1107
- results: [],
1108
- };
1109
- return operationResult;
1110
- }
1111
- const results = await Promise.allSettled(positionsToClose.map((pos) => this.closePosition({
1112
- provider,
1113
- params: { symbol: pos.symbol },
1114
- context,
1115
- reportOrderToDataLake: () => Promise.resolve({ success: true }), // No-op for batch fallback
1116
- })));
1117
- // Aggregate results
1118
- const successCount = results.filter((resItem) => resItem.status === 'fulfilled' && resItem.value.success).length;
1119
- const failureCount = results.length - successCount;
1120
- operationResult = {
1121
- success: successCount > 0,
1122
- successCount,
1123
- failureCount,
1124
- results: results.map((resItem, index) => {
1125
- let errorMsg;
1126
- if (resItem.status === 'rejected') {
1127
- errorMsg =
1128
- resItem.reason instanceof Error
1129
- ? resItem.reason.message
1130
- : 'Unknown error';
1131
- }
1132
- else if (resItem.status === 'fulfilled' &&
1133
- !resItem.value.success) {
1134
- errorMsg = resItem.value.error;
1135
- }
1136
- return {
1137
- symbol: positionsToClose[index].symbol,
1138
- success: Boolean(resItem.status === 'fulfilled' && resItem.value.success),
1139
- error: errorMsg,
1140
- };
1141
- }),
1142
- };
1143
- }
1144
- return operationResult;
1145
- }
1146
- catch (err) {
1147
- operationError = err instanceof Error ? err : new Error(String(err));
1148
- this.deps.logger.error(operationError, this.getErrorContext('closePositions', {
1149
- symbols: params.symbols?.length || 0,
1150
- closeAll: params.closeAll,
1151
- }));
1152
- throw err;
1153
- }
1154
- finally {
1155
- const completionDuration = this.deps.performance.now() - startTime;
1156
- // Track batch close event (success or failure)
1157
- const batchCloseProps = {
1158
- [PerpsEventProperties.STATUS]: operationResult?.success && operationResult.successCount > 0
1159
- ? PerpsEventValues.STATUS.EXECUTED
1160
- : PerpsEventValues.STATUS.FAILED,
1161
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
1162
- };
1163
- if (operationError) {
1164
- batchCloseProps[PerpsEventProperties.ERROR_MESSAGE] =
1165
- operationError.message;
1166
- }
1167
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.PositionCloseTransaction, batchCloseProps);
1168
- this.deps.tracer.endTrace({
1169
- name: PerpsTraceNames.ClosePosition,
1170
- id: traceId,
1171
- });
1172
- }
1173
- }
1174
- /**
1175
- * Update TP/SL for an existing position with full orchestration.
1176
- * Handles tracing, fee discounts, state management, and analytics.
1177
- *
1178
- * @param options - Options for updating TP/SL
1179
- * @param options.provider
1180
- * @param options.params
1181
- * @param options.context
1182
- * @returns Order result
1183
- */
1184
- async updatePositionTPSL(options) {
1185
- const { provider, params, context } = options;
1186
- const traceId = uuidv4();
1187
- const startTime = this.deps.performance.now();
1188
- let traceData;
1189
- let result;
1190
- let errorMessage;
1191
- // Extract tracking data with defaults
1192
- const direction = params.trackingData?.direction;
1193
- const positionSize = params.trackingData?.positionSize;
1194
- const source = params.trackingData?.source || PerpsEventValues.SOURCE.TP_SL_VIEW;
1195
- const takeProfitPercentage = params.trackingData?.takeProfitPercentage;
1196
- const stopLossPercentage = params.trackingData?.stopLossPercentage;
1197
- const isEditingExistingPosition = params.trackingData?.isEditingExistingPosition ?? false;
1198
- try {
1199
- this.deps.tracer.trace({
1200
- name: PerpsTraceNames.UpdateTpsl,
1201
- id: traceId,
1202
- op: PerpsTraceOperations.PositionManagement,
1203
- tags: {
1204
- provider: context.tracingContext.provider,
1205
- market: params.symbol,
1206
- isTestnet: String(context.tracingContext.isTestnet),
1207
- },
1208
- data: {
1209
- takeProfitPrice: params.takeProfitPrice || '',
1210
- stopLossPrice: params.stopLossPrice || '',
1211
- },
1212
- });
1213
- // Get fee discount from rewards
1214
- const feeDiscountBips = await this.calculateFeeDiscountWithMeasurement();
1215
- // Execute with fee discount management
1216
- result = await this.withFeeDiscount({
1217
- provider,
1218
- feeDiscountBips,
1219
- operation: () => provider.updatePositionTPSL(params),
1220
- });
1221
- if (result.success) {
1222
- // Update state on success
1223
- if (context.stateManager) {
1224
- context.stateManager.update((state) => {
1225
- state.lastUpdateTimestamp = Date.now();
1226
- });
1227
- }
1228
- traceData = { success: true };
1229
- }
1230
- else {
1231
- errorMessage = result.error || 'Unknown error';
1232
- traceData = { success: false, error: errorMessage };
1233
- }
1234
- return result;
1235
- }
1236
- catch (err) {
1237
- errorMessage = err instanceof Error ? err.message : 'Unknown error';
1238
- traceData = { success: false, error: errorMessage };
1239
- throw err;
1240
- }
1241
- finally {
1242
- const completionDuration = this.deps.performance.now() - startTime;
1243
- // Determine screen type based on whether editing existing position
1244
- const screenType = isEditingExistingPosition
1245
- ? PerpsEventValues.SCREEN_TYPE.EDIT_TPSL
1246
- : PerpsEventValues.SCREEN_TYPE.CREATE_TPSL;
1247
- // Determine if TP/SL are set
1248
- const hasTakeProfit = Boolean(params.takeProfitPrice);
1249
- const hasStopLoss = Boolean(params.stopLossPrice);
1250
- // Build comprehensive event properties
1251
- const eventProperties = {
1252
- [PerpsEventProperties.STATUS]: result?.success
1253
- ? PerpsEventValues.STATUS.EXECUTED
1254
- : PerpsEventValues.STATUS.FAILED,
1255
- [PerpsEventProperties.ASSET]: params.symbol,
1256
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
1257
- [PerpsEventProperties.SOURCE]: source,
1258
- [PerpsEventProperties.SCREEN_TYPE]: screenType,
1259
- [PerpsEventProperties.HAS_TAKE_PROFIT]: hasTakeProfit,
1260
- [PerpsEventProperties.HAS_STOP_LOSS]: hasStopLoss,
1261
- ...(direction && {
1262
- [PerpsEventProperties.DIRECTION]: direction === 'long'
1263
- ? PerpsEventValues.DIRECTION.LONG
1264
- : PerpsEventValues.DIRECTION.SHORT,
1265
- }),
1266
- ...(positionSize !== undefined && {
1267
- [PerpsEventProperties.POSITION_SIZE]: positionSize,
1268
- }),
1269
- ...(params.takeProfitPrice && {
1270
- [PerpsEventProperties.TAKE_PROFIT_PRICE]: parseFloat(params.takeProfitPrice),
1271
- }),
1272
- ...(params.stopLossPrice && {
1273
- [PerpsEventProperties.STOP_LOSS_PRICE]: parseFloat(params.stopLossPrice),
1274
- }),
1275
- ...(takeProfitPercentage !== undefined && {
1276
- [PerpsEventProperties.TAKE_PROFIT_PERCENTAGE]: takeProfitPercentage,
1277
- }),
1278
- ...(stopLossPercentage !== undefined && {
1279
- [PerpsEventProperties.STOP_LOSS_PERCENTAGE]: stopLossPercentage,
1280
- }),
1281
- ...(errorMessage && {
1282
- [PerpsEventProperties.ERROR_MESSAGE]: errorMessage,
1283
- }),
1284
- };
1285
- // Track event once with all properties
1286
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.RiskManagement, eventProperties);
1287
- this.deps.tracer.endTrace({
1288
- name: PerpsTraceNames.UpdateTpsl,
1289
- id: traceId,
1290
- data: traceData,
1291
- });
1292
- }
1293
- }
1294
- /**
1295
- * Update margin for an existing position (add or remove).
1296
- *
1297
- * @param options - Options for updating margin
1298
- * @param options.provider
1299
- * @param options.symbol
1300
- * @param options.amount
1301
- * @param options.context
1302
- * @returns Margin update result
1303
- */
1304
- async updateMargin(options) {
1305
- const { provider, symbol, amount, context } = options;
1306
- const traceId = uuidv4();
1307
- const startTime = this.deps.performance.now();
1308
- try {
1309
- this.deps.tracer.trace({
1310
- name: PerpsTraceNames.UpdateMargin,
1311
- id: traceId,
1312
- op: PerpsTraceOperations.PositionManagement,
1313
- tags: {
1314
- provider: context.tracingContext.provider,
1315
- symbol,
1316
- isAdd: String(parseFloat(amount) > 0),
1317
- isTestnet: String(context.tracingContext.isTestnet),
1318
- },
1319
- });
1320
- // Call provider method
1321
- const result = await provider.updateMargin?.({ symbol, amount });
1322
- if (!result) {
1323
- throw new Error('Provider does not support margin adjustment');
1324
- }
1325
- const completionDuration = this.deps.performance.now() - startTime;
1326
- if (result.success) {
1327
- // Update state on success
1328
- if (context.stateManager) {
1329
- context.stateManager.update((state) => {
1330
- state.lastUpdateTimestamp = Date.now();
1331
- });
1332
- }
1333
- // Track success analytics
1334
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.RiskManagement, {
1335
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.EXECUTED,
1336
- [PerpsEventProperties.ASSET]: symbol,
1337
- [PerpsEventProperties.ACTION]: parseFloat(amount) > 0 ? 'add_margin' : 'remove_margin',
1338
- [PerpsEventProperties.MARGIN_USED]: Math.abs(parseFloat(amount)),
1339
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
1340
- });
1341
- }
1342
- this.deps.tracer.endTrace({
1343
- name: PerpsTraceNames.UpdateMargin,
1344
- id: traceId,
1345
- data: { success: result.success, error: result.error || '' },
1346
- });
1347
- return result;
1348
- }
1349
- catch (err) {
1350
- const completionDuration = this.deps.performance.now() - startTime;
1351
- const errorMessage = err instanceof Error ? err.message : 'Unknown error';
1352
- const error = err instanceof Error ? err : new Error(String(err));
1353
- this.deps.logger.error(error, this.getErrorContext('updateMargin', { symbol, amount }));
1354
- // Track failure analytics
1355
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.RiskManagement, {
1356
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.FAILED,
1357
- [PerpsEventProperties.ASSET]: symbol,
1358
- [PerpsEventProperties.ACTION]: parseFloat(amount) > 0 ? 'add_margin' : 'remove_margin',
1359
- [PerpsEventProperties.MARGIN_USED]: Math.abs(parseFloat(amount)),
1360
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
1361
- [PerpsEventProperties.ERROR_MESSAGE]: errorMessage,
1362
- });
1363
- this.deps.tracer.endTrace({
1364
- name: PerpsTraceNames.UpdateMargin,
1365
- id: traceId,
1366
- data: { success: false, error: errorMessage },
1367
- });
1368
- throw err;
1369
- }
1370
- }
1371
- /**
1372
- * Flip position (reverse direction while keeping size and leverage).
1373
- *
1374
- * @param options - Options for flipping position
1375
- * @param options.provider
1376
- * @param options.position
1377
- * @param options.context
1378
- * @returns Order result
1379
- */
1380
- async flipPosition(options) {
1381
- const { provider, position, context } = options;
1382
- const traceId = uuidv4();
1383
- const startTime = this.deps.performance.now();
1384
- try {
1385
- this.deps.tracer.trace({
1386
- name: PerpsTraceNames.FlipPosition,
1387
- id: traceId,
1388
- op: PerpsTraceOperations.PositionManagement,
1389
- tags: {
1390
- provider: context.tracingContext.provider,
1391
- symbol: position.symbol,
1392
- isTestnet: String(context.tracingContext.isTestnet),
1393
- },
1394
- });
1395
- // Calculate flip parameters
1396
- const positionSize = Math.abs(parseFloat(position.size));
1397
- const isCurrentlyLong = parseFloat(position.size) > 0;
1398
- const oppositeDirection = !isCurrentlyLong;
1399
- // Validate available balance for fees
1400
- const accountState = await provider.getAccountState?.();
1401
- if (!accountState) {
1402
- throw new Error('Failed to get account state');
1403
- }
1404
- const availableBalance = parseFloat(accountState.availableBalance);
1405
- // Estimate fees (close + open, approximately 0.09% of notional)
1406
- // Flip requires 2x position size (1x to close, 1x to open opposite)
1407
- const entryPrice = parseFloat(position.entryPrice);
1408
- const flipSize = positionSize * 2;
1409
- const notionalValue = flipSize * entryPrice;
1410
- const estimatedFees = notionalValue * 0.0009;
1411
- if (estimatedFees > availableBalance) {
1412
- throw new Error(`Insufficient balance for flip fees. Need $${estimatedFees.toFixed(2)}, have $${availableBalance.toFixed(2)}`);
1413
- }
1414
- // Create order params for flip
1415
- // Use 2x position size: 1x to close current position + 1x to open opposite position
1416
- const orderParams = {
1417
- symbol: position.symbol,
1418
- isBuy: oppositeDirection,
1419
- size: flipSize.toString(),
1420
- orderType: 'market',
1421
- leverage: position.leverage?.value,
1422
- currentPrice: entryPrice,
1423
- };
1424
- // Place flip order (HyperLiquid handles margin transfer automatically)
1425
- const result = await provider.placeOrder(orderParams);
1426
- const completionDuration = this.deps.performance.now() - startTime;
1427
- if (result.success) {
1428
- // Update state on success
1429
- if (context.stateManager) {
1430
- context.stateManager.update((state) => {
1431
- state.lastUpdateTimestamp = Date.now();
1432
- });
1433
- }
1434
- // Track success analytics
1435
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.TradeTransaction, {
1436
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.EXECUTED,
1437
- [PerpsEventProperties.ASSET]: position.symbol,
1438
- [PerpsEventProperties.DIRECTION]: oppositeDirection
1439
- ? PerpsEventValues.DIRECTION.LONG
1440
- : PerpsEventValues.DIRECTION.SHORT,
1441
- [PerpsEventProperties.ORDER_TYPE]: 'market',
1442
- [PerpsEventProperties.LEVERAGE]: position.leverage?.value || 1,
1443
- [PerpsEventProperties.ORDER_SIZE]: positionSize,
1444
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
1445
- [PerpsEventProperties.ACTION]: 'flip_position',
1446
- });
1447
- }
1448
- this.deps.tracer.endTrace({
1449
- name: PerpsTraceNames.FlipPosition,
1450
- id: traceId,
1451
- data: { success: result.success ?? false, error: result.error || '' },
1452
- });
1453
- return result;
1454
- }
1455
- catch (err) {
1456
- const completionDuration = this.deps.performance.now() - startTime;
1457
- const errorMessage = err instanceof Error ? err.message : 'Unknown error';
1458
- const error = err instanceof Error ? err : new Error(String(err));
1459
- this.deps.logger.error(error, this.getErrorContext('flipPosition', { symbol: position.symbol }));
1460
- // Track failure analytics
1461
- this.deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.TradeTransaction, {
1462
- [PerpsEventProperties.STATUS]: PerpsEventValues.STATUS.FAILED,
1463
- [PerpsEventProperties.ASSET]: position.symbol,
1464
- [PerpsEventProperties.ACTION]: 'flip_position',
1465
- [PerpsEventProperties.COMPLETION_DURATION]: completionDuration,
1466
- [PerpsEventProperties.ERROR_MESSAGE]: errorMessage,
1467
- });
1468
- this.deps.tracer.endTrace({
1469
- name: PerpsTraceNames.FlipPosition,
1470
- id: traceId,
1471
- data: { success: false, error: errorMessage },
1472
- });
1473
- throw err;
1474
- }
1475
- }
1476
- }
1477
- //# sourceMappingURL=TradingService.mjs.map