@humanode-hyperlane/rebalancer 0.0.0-stage → 27.2.2-humanode.1

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 (439) hide show
  1. package/LICENSE.md +193 -0
  2. package/README.md +297 -2
  3. package/dist/bridges/LiFiBridge.d.ts +93 -0
  4. package/dist/bridges/LiFiBridge.d.ts.map +1 -0
  5. package/dist/bridges/LiFiBridge.js +527 -0
  6. package/dist/bridges/LiFiBridge.js.map +1 -0
  7. package/dist/bridges/LiFiBridge.test.d.ts +2 -0
  8. package/dist/bridges/LiFiBridge.test.d.ts.map +1 -0
  9. package/dist/bridges/LiFiBridge.test.js +504 -0
  10. package/dist/bridges/LiFiBridge.test.js.map +1 -0
  11. package/dist/config/RebalancerConfig.d.ts +20 -0
  12. package/dist/config/RebalancerConfig.d.ts.map +1 -0
  13. package/dist/config/RebalancerConfig.js +35 -0
  14. package/dist/config/RebalancerConfig.js.map +1 -0
  15. package/dist/config/RebalancerConfig.test.d.ts +2 -0
  16. package/dist/config/RebalancerConfig.test.d.ts.map +1 -0
  17. package/dist/config/RebalancerConfig.test.js +798 -0
  18. package/dist/config/RebalancerConfig.test.js.map +1 -0
  19. package/dist/config/types.d.ts +3008 -0
  20. package/dist/config/types.d.ts.map +1 -0
  21. package/dist/config/types.js +451 -0
  22. package/dist/config/types.js.map +1 -0
  23. package/dist/core/InventoryRebalancer.d.ts +201 -0
  24. package/dist/core/InventoryRebalancer.d.ts.map +1 -0
  25. package/dist/core/InventoryRebalancer.js +994 -0
  26. package/dist/core/InventoryRebalancer.js.map +1 -0
  27. package/dist/core/InventoryRebalancer.test.d.ts +2 -0
  28. package/dist/core/InventoryRebalancer.test.d.ts.map +1 -0
  29. package/dist/core/InventoryRebalancer.test.js +1511 -0
  30. package/dist/core/InventoryRebalancer.test.js.map +1 -0
  31. package/dist/core/Rebalancer.d.ts +37 -0
  32. package/dist/core/Rebalancer.d.ts.map +1 -0
  33. package/dist/core/Rebalancer.js +433 -0
  34. package/dist/core/Rebalancer.js.map +1 -0
  35. package/dist/core/Rebalancer.test.d.ts +2 -0
  36. package/dist/core/Rebalancer.test.d.ts.map +1 -0
  37. package/dist/core/Rebalancer.test.js +424 -0
  38. package/dist/core/Rebalancer.test.js.map +1 -0
  39. package/dist/core/RebalancerOrchestrator.d.ts +56 -0
  40. package/dist/core/RebalancerOrchestrator.d.ts.map +1 -0
  41. package/dist/core/RebalancerOrchestrator.js +154 -0
  42. package/dist/core/RebalancerOrchestrator.js.map +1 -0
  43. package/dist/core/RebalancerOrchestrator.test.d.ts +2 -0
  44. package/dist/core/RebalancerOrchestrator.test.d.ts.map +1 -0
  45. package/dist/core/RebalancerOrchestrator.test.js +721 -0
  46. package/dist/core/RebalancerOrchestrator.test.js.map +1 -0
  47. package/dist/core/RebalancerService.d.ts +127 -0
  48. package/dist/core/RebalancerService.d.ts.map +1 -0
  49. package/dist/core/RebalancerService.js +270 -0
  50. package/dist/core/RebalancerService.js.map +1 -0
  51. package/dist/core/RebalancerService.test.d.ts +2 -0
  52. package/dist/core/RebalancerService.test.d.ts.map +1 -0
  53. package/dist/core/RebalancerService.test.js +777 -0
  54. package/dist/core/RebalancerService.test.js.map +1 -0
  55. package/dist/e2e/collateral-deficit.e2e-test.d.ts +2 -0
  56. package/dist/e2e/collateral-deficit.e2e-test.d.ts.map +1 -0
  57. package/dist/e2e/collateral-deficit.e2e-test.js +227 -0
  58. package/dist/e2e/collateral-deficit.e2e-test.js.map +1 -0
  59. package/dist/e2e/composite.e2e-test.d.ts +2 -0
  60. package/dist/e2e/composite.e2e-test.d.ts.map +1 -0
  61. package/dist/e2e/composite.e2e-test.js +666 -0
  62. package/dist/e2e/composite.e2e-test.js.map +1 -0
  63. package/dist/e2e/fixtures/routes.d.ts +89 -0
  64. package/dist/e2e/fixtures/routes.d.ts.map +1 -0
  65. package/dist/e2e/fixtures/routes.js +420 -0
  66. package/dist/e2e/fixtures/routes.js.map +1 -0
  67. package/dist/e2e/harness/BaseLocalDeploymentManager.d.ts +38 -0
  68. package/dist/e2e/harness/BaseLocalDeploymentManager.d.ts.map +1 -0
  69. package/dist/e2e/harness/BaseLocalDeploymentManager.js +144 -0
  70. package/dist/e2e/harness/BaseLocalDeploymentManager.js.map +1 -0
  71. package/dist/e2e/harness/BridgeSetup.d.ts +11 -0
  72. package/dist/e2e/harness/BridgeSetup.d.ts.map +1 -0
  73. package/dist/e2e/harness/BridgeSetup.js +50 -0
  74. package/dist/e2e/harness/BridgeSetup.js.map +1 -0
  75. package/dist/e2e/harness/Erc20InventoryLocalDeploymentManager.d.ts +13 -0
  76. package/dist/e2e/harness/Erc20InventoryLocalDeploymentManager.d.ts.map +1 -0
  77. package/dist/e2e/harness/Erc20InventoryLocalDeploymentManager.js +105 -0
  78. package/dist/e2e/harness/Erc20InventoryLocalDeploymentManager.js.map +1 -0
  79. package/dist/e2e/harness/Erc20LocalDeploymentManager.d.ts +11 -0
  80. package/dist/e2e/harness/Erc20LocalDeploymentManager.d.ts.map +1 -0
  81. package/dist/e2e/harness/Erc20LocalDeploymentManager.js +105 -0
  82. package/dist/e2e/harness/Erc20LocalDeploymentManager.js.map +1 -0
  83. package/dist/e2e/harness/ForkIndexer.d.ts +23 -0
  84. package/dist/e2e/harness/ForkIndexer.d.ts.map +1 -0
  85. package/dist/e2e/harness/ForkIndexer.js +127 -0
  86. package/dist/e2e/harness/ForkIndexer.js.map +1 -0
  87. package/dist/e2e/harness/ForkIndexer.test.d.ts +2 -0
  88. package/dist/e2e/harness/ForkIndexer.test.d.ts.map +1 -0
  89. package/dist/e2e/harness/ForkIndexer.test.js +257 -0
  90. package/dist/e2e/harness/ForkIndexer.test.js.map +1 -0
  91. package/dist/e2e/harness/MixedLocalDeploymentManager.d.ts +21 -0
  92. package/dist/e2e/harness/MixedLocalDeploymentManager.d.ts.map +1 -0
  93. package/dist/e2e/harness/MixedLocalDeploymentManager.js +115 -0
  94. package/dist/e2e/harness/MixedLocalDeploymentManager.js.map +1 -0
  95. package/dist/e2e/harness/MockExplorerClient.d.ts +23 -0
  96. package/dist/e2e/harness/MockExplorerClient.d.ts.map +1 -0
  97. package/dist/e2e/harness/MockExplorerClient.js +57 -0
  98. package/dist/e2e/harness/MockExplorerClient.js.map +1 -0
  99. package/dist/e2e/harness/MockExternalBridge.d.ts +32 -0
  100. package/dist/e2e/harness/MockExternalBridge.d.ts.map +1 -0
  101. package/dist/e2e/harness/MockExternalBridge.js +247 -0
  102. package/dist/e2e/harness/MockExternalBridge.js.map +1 -0
  103. package/dist/e2e/harness/NativeLocalDeploymentManager.d.ts +13 -0
  104. package/dist/e2e/harness/NativeLocalDeploymentManager.d.ts.map +1 -0
  105. package/dist/e2e/harness/NativeLocalDeploymentManager.js +91 -0
  106. package/dist/e2e/harness/NativeLocalDeploymentManager.js.map +1 -0
  107. package/dist/e2e/harness/SnapshotHelper.d.ts +13 -0
  108. package/dist/e2e/harness/SnapshotHelper.d.ts.map +1 -0
  109. package/dist/e2e/harness/SnapshotHelper.js +36 -0
  110. package/dist/e2e/harness/SnapshotHelper.js.map +1 -0
  111. package/dist/e2e/harness/TestHelpers.d.ts +25 -0
  112. package/dist/e2e/harness/TestHelpers.d.ts.map +1 -0
  113. package/dist/e2e/harness/TestHelpers.js +103 -0
  114. package/dist/e2e/harness/TestHelpers.js.map +1 -0
  115. package/dist/e2e/harness/TestRebalancer.d.ts +85 -0
  116. package/dist/e2e/harness/TestRebalancer.d.ts.map +1 -0
  117. package/dist/e2e/harness/TestRebalancer.js +427 -0
  118. package/dist/e2e/harness/TestRebalancer.js.map +1 -0
  119. package/dist/e2e/harness/TransferHelper.d.ts +34 -0
  120. package/dist/e2e/harness/TransferHelper.d.ts.map +1 -0
  121. package/dist/e2e/harness/TransferHelper.js +93 -0
  122. package/dist/e2e/harness/TransferHelper.js.map +1 -0
  123. package/dist/e2e/inventory-erc20-minAmount.e2e-test.d.ts +2 -0
  124. package/dist/e2e/inventory-erc20-minAmount.e2e-test.d.ts.map +1 -0
  125. package/dist/e2e/inventory-erc20-minAmount.e2e-test.js +411 -0
  126. package/dist/e2e/inventory-erc20-minAmount.e2e-test.js.map +1 -0
  127. package/dist/e2e/inventory-erc20-weighted.e2e-test.d.ts +2 -0
  128. package/dist/e2e/inventory-erc20-weighted.e2e-test.d.ts.map +1 -0
  129. package/dist/e2e/inventory-erc20-weighted.e2e-test.js +408 -0
  130. package/dist/e2e/inventory-erc20-weighted.e2e-test.js.map +1 -0
  131. package/dist/e2e/inventory-minAmount.e2e-test.d.ts +2 -0
  132. package/dist/e2e/inventory-minAmount.e2e-test.d.ts.map +1 -0
  133. package/dist/e2e/inventory-minAmount.e2e-test.js +411 -0
  134. package/dist/e2e/inventory-minAmount.e2e-test.js.map +1 -0
  135. package/dist/e2e/inventory-weighted.e2e-test.d.ts +2 -0
  136. package/dist/e2e/inventory-weighted.e2e-test.d.ts.map +1 -0
  137. package/dist/e2e/inventory-weighted.e2e-test.js +409 -0
  138. package/dist/e2e/inventory-weighted.e2e-test.js.map +1 -0
  139. package/dist/e2e/minAmount.e2e-test.d.ts +2 -0
  140. package/dist/e2e/minAmount.e2e-test.d.ts.map +1 -0
  141. package/dist/e2e/minAmount.e2e-test.js +203 -0
  142. package/dist/e2e/minAmount.e2e-test.js.map +1 -0
  143. package/dist/e2e/mixed-weighted.e2e-test.d.ts +2 -0
  144. package/dist/e2e/mixed-weighted.e2e-test.d.ts.map +1 -0
  145. package/dist/e2e/mixed-weighted.e2e-test.js +189 -0
  146. package/dist/e2e/mixed-weighted.e2e-test.js.map +1 -0
  147. package/dist/e2e/weighted.e2e-test.d.ts +2 -0
  148. package/dist/e2e/weighted.e2e-test.d.ts.map +1 -0
  149. package/dist/e2e/weighted.e2e-test.js +198 -0
  150. package/dist/e2e/weighted.e2e-test.js.map +1 -0
  151. package/dist/factories/RebalancerContextFactory.d.ts +89 -0
  152. package/dist/factories/RebalancerContextFactory.d.ts.map +1 -0
  153. package/dist/factories/RebalancerContextFactory.js +420 -0
  154. package/dist/factories/RebalancerContextFactory.js.map +1 -0
  155. package/dist/factories/RebalancerContextFactory.test.d.ts +2 -0
  156. package/dist/factories/RebalancerContextFactory.test.d.ts.map +1 -0
  157. package/dist/factories/RebalancerContextFactory.test.js +270 -0
  158. package/dist/factories/RebalancerContextFactory.test.js.map +1 -0
  159. package/dist/index.d.ts +37 -0
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +37 -0
  162. package/dist/index.js.map +1 -0
  163. package/dist/interfaces/IExternalBridge.d.ts +103 -0
  164. package/dist/interfaces/IExternalBridge.d.ts.map +1 -0
  165. package/dist/interfaces/IExternalBridge.js +2 -0
  166. package/dist/interfaces/IExternalBridge.js.map +1 -0
  167. package/dist/interfaces/IMetrics.d.ts +5 -0
  168. package/dist/interfaces/IMetrics.d.ts.map +1 -0
  169. package/dist/interfaces/IMetrics.js +2 -0
  170. package/dist/interfaces/IMetrics.js.map +1 -0
  171. package/dist/interfaces/IMonitor.d.ts +50 -0
  172. package/dist/interfaces/IMonitor.d.ts.map +1 -0
  173. package/dist/interfaces/IMonitor.js +14 -0
  174. package/dist/interfaces/IMonitor.js.map +1 -0
  175. package/dist/interfaces/IRebalancer.d.ts +31 -0
  176. package/dist/interfaces/IRebalancer.d.ts.map +1 -0
  177. package/dist/interfaces/IRebalancer.js +2 -0
  178. package/dist/interfaces/IRebalancer.js.map +1 -0
  179. package/dist/interfaces/IStrategy.d.ts +60 -0
  180. package/dist/interfaces/IStrategy.d.ts.map +1 -0
  181. package/dist/interfaces/IStrategy.js +13 -0
  182. package/dist/interfaces/IStrategy.js.map +1 -0
  183. package/dist/metrics/Metrics.d.ts +25 -0
  184. package/dist/metrics/Metrics.d.ts.map +1 -0
  185. package/dist/metrics/Metrics.js +164 -0
  186. package/dist/metrics/Metrics.js.map +1 -0
  187. package/dist/metrics/PriceGetter.d.ts +10 -0
  188. package/dist/metrics/PriceGetter.d.ts.map +1 -0
  189. package/dist/metrics/PriceGetter.js +41 -0
  190. package/dist/metrics/PriceGetter.js.map +1 -0
  191. package/dist/metrics/scripts/metrics.d.ts +28 -0
  192. package/dist/metrics/scripts/metrics.d.ts.map +1 -0
  193. package/dist/metrics/scripts/metrics.js +61 -0
  194. package/dist/metrics/scripts/metrics.js.map +1 -0
  195. package/dist/monitor/Monitor.d.ts +40 -0
  196. package/dist/monitor/Monitor.d.ts.map +1 -0
  197. package/dist/monitor/Monitor.js +211 -0
  198. package/dist/monitor/Monitor.js.map +1 -0
  199. package/dist/service.d.ts +3 -0
  200. package/dist/service.d.ts.map +1 -0
  201. package/dist/service.js +205 -0
  202. package/dist/service.js.map +1 -0
  203. package/dist/strategy/BaseStrategy.d.ts +86 -0
  204. package/dist/strategy/BaseStrategy.d.ts.map +1 -0
  205. package/dist/strategy/BaseStrategy.js +342 -0
  206. package/dist/strategy/BaseStrategy.js.map +1 -0
  207. package/dist/strategy/CollateralDeficitStrategy.d.ts +65 -0
  208. package/dist/strategy/CollateralDeficitStrategy.d.ts.map +1 -0
  209. package/dist/strategy/CollateralDeficitStrategy.js +253 -0
  210. package/dist/strategy/CollateralDeficitStrategy.js.map +1 -0
  211. package/dist/strategy/CollateralDeficitStrategy.test.d.ts +2 -0
  212. package/dist/strategy/CollateralDeficitStrategy.test.d.ts.map +1 -0
  213. package/dist/strategy/CollateralDeficitStrategy.test.js +497 -0
  214. package/dist/strategy/CollateralDeficitStrategy.test.js.map +1 -0
  215. package/dist/strategy/CompositeStrategy.d.ts +18 -0
  216. package/dist/strategy/CompositeStrategy.d.ts.map +1 -0
  217. package/dist/strategy/CompositeStrategy.js +63 -0
  218. package/dist/strategy/CompositeStrategy.js.map +1 -0
  219. package/dist/strategy/CompositeStrategy.test.d.ts +2 -0
  220. package/dist/strategy/CompositeStrategy.test.d.ts.map +1 -0
  221. package/dist/strategy/CompositeStrategy.test.js +278 -0
  222. package/dist/strategy/CompositeStrategy.test.js.map +1 -0
  223. package/dist/strategy/MinAmountStrategy.d.ts +35 -0
  224. package/dist/strategy/MinAmountStrategy.d.ts.map +1 -0
  225. package/dist/strategy/MinAmountStrategy.js +112 -0
  226. package/dist/strategy/MinAmountStrategy.js.map +1 -0
  227. package/dist/strategy/MinAmountStrategy.test.d.ts +2 -0
  228. package/dist/strategy/MinAmountStrategy.test.d.ts.map +1 -0
  229. package/dist/strategy/MinAmountStrategy.test.js +547 -0
  230. package/dist/strategy/MinAmountStrategy.test.js.map +1 -0
  231. package/dist/strategy/StrategyFactory.d.ts +27 -0
  232. package/dist/strategy/StrategyFactory.d.ts.map +1 -0
  233. package/dist/strategy/StrategyFactory.js +79 -0
  234. package/dist/strategy/StrategyFactory.js.map +1 -0
  235. package/dist/strategy/StrategyFactory.test.d.ts +2 -0
  236. package/dist/strategy/StrategyFactory.test.d.ts.map +1 -0
  237. package/dist/strategy/StrategyFactory.test.js +81 -0
  238. package/dist/strategy/StrategyFactory.test.js.map +1 -0
  239. package/dist/strategy/WeightedStrategy.d.ts +32 -0
  240. package/dist/strategy/WeightedStrategy.d.ts.map +1 -0
  241. package/dist/strategy/WeightedStrategy.js +73 -0
  242. package/dist/strategy/WeightedStrategy.js.map +1 -0
  243. package/dist/strategy/WeightedStrategy.test.d.ts +2 -0
  244. package/dist/strategy/WeightedStrategy.test.d.ts.map +1 -0
  245. package/dist/strategy/WeightedStrategy.test.js +403 -0
  246. package/dist/strategy/WeightedStrategy.test.js.map +1 -0
  247. package/dist/strategy/index.d.ts +7 -0
  248. package/dist/strategy/index.d.ts.map +1 -0
  249. package/dist/strategy/index.js +7 -0
  250. package/dist/strategy/index.js.map +1 -0
  251. package/dist/test/helpers.d.ts +99 -0
  252. package/dist/test/helpers.d.ts.map +1 -0
  253. package/dist/test/helpers.js +311 -0
  254. package/dist/test/helpers.js.map +1 -0
  255. package/dist/test/lifiMocks.d.ts +52 -0
  256. package/dist/test/lifiMocks.d.ts.map +1 -0
  257. package/dist/test/lifiMocks.js +160 -0
  258. package/dist/test/lifiMocks.js.map +1 -0
  259. package/dist/tracking/ActionTracker.d.ts +90 -0
  260. package/dist/tracking/ActionTracker.d.ts.map +1 -0
  261. package/dist/tracking/ActionTracker.js +678 -0
  262. package/dist/tracking/ActionTracker.js.map +1 -0
  263. package/dist/tracking/ActionTracker.test.d.ts +2 -0
  264. package/dist/tracking/ActionTracker.test.d.ts.map +1 -0
  265. package/dist/tracking/ActionTracker.test.js +1351 -0
  266. package/dist/tracking/ActionTracker.test.js.map +1 -0
  267. package/dist/tracking/IActionTracker.d.ts +157 -0
  268. package/dist/tracking/IActionTracker.d.ts.map +1 -0
  269. package/dist/tracking/IActionTracker.js +2 -0
  270. package/dist/tracking/IActionTracker.js.map +1 -0
  271. package/dist/tracking/InflightContextAdapter.d.ts +18 -0
  272. package/dist/tracking/InflightContextAdapter.d.ts.map +1 -0
  273. package/dist/tracking/InflightContextAdapter.js +52 -0
  274. package/dist/tracking/InflightContextAdapter.js.map +1 -0
  275. package/dist/tracking/InflightContextAdapter.test.d.ts +2 -0
  276. package/dist/tracking/InflightContextAdapter.test.d.ts.map +1 -0
  277. package/dist/tracking/InflightContextAdapter.test.js +175 -0
  278. package/dist/tracking/InflightContextAdapter.test.js.map +1 -0
  279. package/dist/tracking/store/IStore.d.ts +41 -0
  280. package/dist/tracking/store/IStore.d.ts.map +1 -0
  281. package/dist/tracking/store/IStore.js +2 -0
  282. package/dist/tracking/store/IStore.js.map +1 -0
  283. package/dist/tracking/store/InMemoryStore.d.ts +21 -0
  284. package/dist/tracking/store/InMemoryStore.d.ts.map +1 -0
  285. package/dist/tracking/store/InMemoryStore.js +40 -0
  286. package/dist/tracking/store/InMemoryStore.js.map +1 -0
  287. package/dist/tracking/store/InMemoryStore.test.d.ts +2 -0
  288. package/dist/tracking/store/InMemoryStore.test.d.ts.map +1 -0
  289. package/dist/tracking/store/InMemoryStore.test.js +290 -0
  290. package/dist/tracking/store/InMemoryStore.test.js.map +1 -0
  291. package/dist/tracking/store/index.d.ts +3 -0
  292. package/dist/tracking/store/index.d.ts.map +1 -0
  293. package/dist/tracking/store/index.js +2 -0
  294. package/dist/tracking/store/index.js.map +1 -0
  295. package/dist/tracking/types.d.ts +77 -0
  296. package/dist/tracking/types.d.ts.map +1 -0
  297. package/dist/tracking/types.js +2 -0
  298. package/dist/tracking/types.js.map +1 -0
  299. package/dist/utils/ExplorerClient.d.ts +68 -0
  300. package/dist/utils/ExplorerClient.d.ts.map +1 -0
  301. package/dist/utils/ExplorerClient.js +324 -0
  302. package/dist/utils/ExplorerClient.js.map +1 -0
  303. package/dist/utils/ExplorerClient.test.d.ts +2 -0
  304. package/dist/utils/ExplorerClient.test.d.ts.map +1 -0
  305. package/dist/utils/ExplorerClient.test.js +261 -0
  306. package/dist/utils/ExplorerClient.test.js.map +1 -0
  307. package/dist/utils/balanceUtils.d.ts +12 -0
  308. package/dist/utils/balanceUtils.d.ts.map +1 -0
  309. package/dist/utils/balanceUtils.js +40 -0
  310. package/dist/utils/balanceUtils.js.map +1 -0
  311. package/dist/utils/balanceUtils.test.d.ts +2 -0
  312. package/dist/utils/balanceUtils.test.d.ts.map +1 -0
  313. package/dist/utils/balanceUtils.test.js +55 -0
  314. package/dist/utils/balanceUtils.test.js.map +1 -0
  315. package/dist/utils/blockTag.d.ts +14 -0
  316. package/dist/utils/blockTag.d.ts.map +1 -0
  317. package/dist/utils/blockTag.js +46 -0
  318. package/dist/utils/blockTag.js.map +1 -0
  319. package/dist/utils/bridgeUtils.d.ts +40 -0
  320. package/dist/utils/bridgeUtils.d.ts.map +1 -0
  321. package/dist/utils/bridgeUtils.js +54 -0
  322. package/dist/utils/bridgeUtils.js.map +1 -0
  323. package/dist/utils/bridgeUtils.test.d.ts +2 -0
  324. package/dist/utils/bridgeUtils.test.d.ts.map +1 -0
  325. package/dist/utils/bridgeUtils.test.js +163 -0
  326. package/dist/utils/bridgeUtils.test.js.map +1 -0
  327. package/dist/utils/errors.d.ts +4 -0
  328. package/dist/utils/errors.d.ts.map +1 -0
  329. package/dist/utils/errors.js +6 -0
  330. package/dist/utils/errors.js.map +1 -0
  331. package/dist/utils/gasEstimation.d.ts +65 -0
  332. package/dist/utils/gasEstimation.d.ts.map +1 -0
  333. package/dist/utils/gasEstimation.js +206 -0
  334. package/dist/utils/gasEstimation.js.map +1 -0
  335. package/dist/utils/solanaKeyParser.d.ts +10 -0
  336. package/dist/utils/solanaKeyParser.d.ts.map +1 -0
  337. package/dist/utils/solanaKeyParser.js +87 -0
  338. package/dist/utils/solanaKeyParser.js.map +1 -0
  339. package/dist/utils/solanaKeyParser.test.d.ts +2 -0
  340. package/dist/utils/solanaKeyParser.test.d.ts.map +1 -0
  341. package/dist/utils/solanaKeyParser.test.js +71 -0
  342. package/dist/utils/solanaKeyParser.test.js.map +1 -0
  343. package/dist/utils/tokenUtils.d.ts +38 -0
  344. package/dist/utils/tokenUtils.d.ts.map +1 -0
  345. package/dist/utils/tokenUtils.js +65 -0
  346. package/dist/utils/tokenUtils.js.map +1 -0
  347. package/dist/utils/transactionUtils.d.ts +22 -0
  348. package/dist/utils/transactionUtils.d.ts.map +1 -0
  349. package/dist/utils/transactionUtils.js +26 -0
  350. package/dist/utils/transactionUtils.js.map +1 -0
  351. package/package.json +87 -3
  352. package/src/bridges/LiFiBridge.test.ts +615 -0
  353. package/src/bridges/LiFiBridge.ts +731 -0
  354. package/src/config/RebalancerConfig.test.ts +921 -0
  355. package/src/config/RebalancerConfig.ts +63 -0
  356. package/src/config/types.ts +613 -0
  357. package/src/core/InventoryRebalancer.test.ts +1858 -0
  358. package/src/core/InventoryRebalancer.ts +1455 -0
  359. package/src/core/Rebalancer.test.ts +686 -0
  360. package/src/core/Rebalancer.ts +686 -0
  361. package/src/core/RebalancerOrchestrator.test.ts +871 -0
  362. package/src/core/RebalancerOrchestrator.ts +273 -0
  363. package/src/core/RebalancerService.test.ts +1094 -0
  364. package/src/core/RebalancerService.ts +412 -0
  365. package/src/e2e/E2E_TEST_CONVENTIONS.md +222 -0
  366. package/src/e2e/collateral-deficit.e2e-test.ts +403 -0
  367. package/src/e2e/composite.e2e-test.ts +1008 -0
  368. package/src/e2e/fixtures/routes.ts +532 -0
  369. package/src/e2e/harness/BaseLocalDeploymentManager.ts +246 -0
  370. package/src/e2e/harness/BridgeSetup.ts +95 -0
  371. package/src/e2e/harness/Erc20InventoryLocalDeploymentManager.ts +183 -0
  372. package/src/e2e/harness/Erc20LocalDeploymentManager.ts +190 -0
  373. package/src/e2e/harness/ForkIndexer.test.ts +448 -0
  374. package/src/e2e/harness/ForkIndexer.ts +183 -0
  375. package/src/e2e/harness/MixedLocalDeploymentManager.ts +196 -0
  376. package/src/e2e/harness/MockExplorerClient.ts +94 -0
  377. package/src/e2e/harness/MockExternalBridge.ts +411 -0
  378. package/src/e2e/harness/NativeLocalDeploymentManager.ts +138 -0
  379. package/src/e2e/harness/SnapshotHelper.ts +56 -0
  380. package/src/e2e/harness/TestHelpers.ts +169 -0
  381. package/src/e2e/harness/TestRebalancer.ts +758 -0
  382. package/src/e2e/harness/TransferHelper.ts +188 -0
  383. package/src/e2e/inventory-erc20-minAmount.e2e-test.ts +735 -0
  384. package/src/e2e/inventory-erc20-weighted.e2e-test.ts +733 -0
  385. package/src/e2e/inventory-minAmount.e2e-test.ts +734 -0
  386. package/src/e2e/inventory-weighted.e2e-test.ts +734 -0
  387. package/src/e2e/minAmount.e2e-test.ts +313 -0
  388. package/src/e2e/mixed-weighted.e2e-test.ts +267 -0
  389. package/src/e2e/weighted.e2e-test.ts +304 -0
  390. package/src/factories/RebalancerContextFactory.test.ts +394 -0
  391. package/src/factories/RebalancerContextFactory.ts +771 -0
  392. package/src/index.ts +125 -0
  393. package/src/interfaces/IExternalBridge.ts +117 -0
  394. package/src/interfaces/IMetrics.ts +5 -0
  395. package/src/interfaces/IMonitor.ts +71 -0
  396. package/src/interfaces/IRebalancer.ts +57 -0
  397. package/src/interfaces/IStrategy.ts +81 -0
  398. package/src/metrics/Metrics.ts +335 -0
  399. package/src/metrics/PriceGetter.ts +74 -0
  400. package/src/metrics/scripts/metrics.ts +139 -0
  401. package/src/monitor/Monitor.ts +324 -0
  402. package/src/service.ts +285 -0
  403. package/src/strategy/BaseStrategy.ts +553 -0
  404. package/src/strategy/CollateralDeficitStrategy.test.ts +728 -0
  405. package/src/strategy/CollateralDeficitStrategy.ts +421 -0
  406. package/src/strategy/CompositeStrategy.test.ts +418 -0
  407. package/src/strategy/CompositeStrategy.ts +102 -0
  408. package/src/strategy/MinAmountStrategy.test.ts +732 -0
  409. package/src/strategy/MinAmountStrategy.ts +200 -0
  410. package/src/strategy/StrategyFactory.test.ts +108 -0
  411. package/src/strategy/StrategyFactory.ts +157 -0
  412. package/src/strategy/WeightedStrategy.test.ts +529 -0
  413. package/src/strategy/WeightedStrategy.ts +126 -0
  414. package/src/strategy/index.ts +6 -0
  415. package/src/test/helpers.ts +477 -0
  416. package/src/test/lifiMocks.ts +211 -0
  417. package/src/tracking/ActionTracker.test.ts +1625 -0
  418. package/src/tracking/ActionTracker.ts +1019 -0
  419. package/src/tracking/IActionTracker.ts +213 -0
  420. package/src/tracking/InflightContextAdapter.test.ts +206 -0
  421. package/src/tracking/InflightContextAdapter.ts +75 -0
  422. package/src/tracking/store/IStore.ts +48 -0
  423. package/src/tracking/store/InMemoryStore.test.ts +338 -0
  424. package/src/tracking/store/InMemoryStore.ts +59 -0
  425. package/src/tracking/store/index.ts +2 -0
  426. package/src/tracking/types.ts +118 -0
  427. package/src/utils/ExplorerClient.test.ts +386 -0
  428. package/src/utils/ExplorerClient.ts +439 -0
  429. package/src/utils/balanceUtils.test.ts +79 -0
  430. package/src/utils/balanceUtils.ts +65 -0
  431. package/src/utils/blockTag.ts +68 -0
  432. package/src/utils/bridgeUtils.test.ts +193 -0
  433. package/src/utils/bridgeUtils.ts +101 -0
  434. package/src/utils/errors.ts +5 -0
  435. package/src/utils/gasEstimation.ts +306 -0
  436. package/src/utils/solanaKeyParser.test.ts +103 -0
  437. package/src/utils/solanaKeyParser.ts +117 -0
  438. package/src/utils/tokenUtils.ts +89 -0
  439. package/src/utils/transactionUtils.ts +41 -0
@@ -0,0 +1,448 @@
1
+ import { expect } from 'chai';
2
+ import { pino } from 'pino';
3
+ import sinon from 'sinon';
4
+
5
+ import { formatMessage, messageId } from '@humanode-hyperlane/utils';
6
+
7
+ import { ForkIndexer } from './ForkIndexer.js';
8
+
9
+ const testLogger = pino({ level: 'silent' });
10
+
11
+ // Test addresses
12
+ const ROUTER_ADDRESS_1 = '0x1111111111111111111111111111111111111111';
13
+ const ROUTER_ADDRESS_2 = '0x2222222222222222222222222222222222222222';
14
+ const REBALANCER_ADDRESS = '0xReBA1ancer000000000000000000000000000000';
15
+ const USER_ADDRESS = '0xUser000000000000000000000000000000000000';
16
+
17
+ // Domain IDs
18
+ const DOMAIN_1 = 1;
19
+ const DOMAIN_2 = 2;
20
+
21
+ /**
22
+ * Creates a properly formatted Hyperlane message for testing
23
+ */
24
+ function createTestMessage(
25
+ origin: number,
26
+ destination: number,
27
+ sender: string,
28
+ recipient: string,
29
+ body = '0x',
30
+ nonce = 0,
31
+ ): string {
32
+ return formatMessage(3, nonce, origin, sender, destination, recipient, body);
33
+ }
34
+
35
+ /**
36
+ * Creates a mock Dispatch event matching ethers event structure
37
+ */
38
+ function createMockDispatchEvent(
39
+ sender: string,
40
+ message: string,
41
+ txFrom: string,
42
+ txHash = '0xtxhash123',
43
+ ): any {
44
+ return {
45
+ args: {
46
+ sender,
47
+ message,
48
+ },
49
+ getTransactionReceipt: sinon.stub().resolves({
50
+ transactionHash: txHash,
51
+ from: txFrom,
52
+ }),
53
+ };
54
+ }
55
+
56
+ describe('ForkIndexer', () => {
57
+ let provider1Stub: any;
58
+ let provider2Stub: any;
59
+ let providers: Map<string, any>;
60
+ let coreStub: any;
61
+ let mailboxStub1: any;
62
+ let mailboxStub2: any;
63
+ let indexer: ForkIndexer;
64
+
65
+ beforeEach(() => {
66
+ provider1Stub = {
67
+ getBlockNumber: sinon.stub(),
68
+ };
69
+ provider2Stub = {
70
+ getBlockNumber: sinon.stub(),
71
+ };
72
+
73
+ providers = new Map([
74
+ ['chain1', provider1Stub],
75
+ ['chain2', provider2Stub],
76
+ ]);
77
+
78
+ mailboxStub1 = {
79
+ queryFilter: sinon.stub().resolves([]),
80
+ filters: {
81
+ Dispatch: sinon.stub().returns('DispatchFilter'),
82
+ },
83
+ };
84
+ mailboxStub2 = {
85
+ queryFilter: sinon.stub().resolves([]),
86
+ filters: {
87
+ Dispatch: sinon.stub().returns('DispatchFilter'),
88
+ },
89
+ };
90
+
91
+ coreStub = {
92
+ getContracts: sinon.stub().callsFake((chain: string) => {
93
+ if (chain === 'chain1') return { mailbox: mailboxStub1 };
94
+ if (chain === 'chain2') return { mailbox: mailboxStub2 };
95
+ throw new Error(`Unknown chain: ${chain}`);
96
+ }),
97
+ multiProvider: {
98
+ tryGetChainName: sinon.stub().callsFake((domain: number) => {
99
+ if (domain === DOMAIN_1) return 'chain1';
100
+ if (domain === DOMAIN_2) return 'chain2';
101
+ return null;
102
+ }),
103
+ },
104
+ };
105
+
106
+ indexer = new ForkIndexer(
107
+ providers,
108
+ coreStub,
109
+ [REBALANCER_ADDRESS],
110
+ testLogger,
111
+ );
112
+ });
113
+
114
+ afterEach(() => {
115
+ sinon.restore();
116
+ });
117
+
118
+ describe('initialize', () => {
119
+ it('should set lastScannedBlock to current block for each chain', async () => {
120
+ await indexer.initialize({ chain1: 100, chain2: 200 });
121
+
122
+ // Verify by calling sync - should not query any events since lastScanned == currentBlock
123
+ await indexer.sync({ chain1: 100, chain2: 200 });
124
+
125
+ // queryFilter should not be called since lastScannedBlock >= currentBlock
126
+ expect(mailboxStub1.queryFilter.called).to.be.false;
127
+ expect(mailboxStub2.queryFilter.called).to.be.false;
128
+ });
129
+ });
130
+
131
+ describe('sync - uninitialized behavior', () => {
132
+ it('should be a no-op if called before initialize()', async () => {
133
+ await indexer.sync({ chain1: 100, chain2: 100 });
134
+
135
+ expect(mailboxStub1.queryFilter.called).to.be.false;
136
+ expect(mailboxStub2.queryFilter.called).to.be.false;
137
+ expect(indexer.getUserTransfers()).to.have.lengthOf(0);
138
+ expect(indexer.getRebalanceActions()).to.have.lengthOf(0);
139
+ });
140
+ });
141
+
142
+ describe('sync - block range queries', () => {
143
+ it('should query events from lastScannedBlock+1 to currentBlock', async () => {
144
+ // Initialize at block 100
145
+ await indexer.initialize({ chain1: 100, chain2: 100 });
146
+
147
+ // Advance to block 150 for chain1
148
+ await indexer.sync({ chain1: 150, chain2: 100 });
149
+
150
+ // Verify queryFilter was called with correct block range
151
+ expect(mailboxStub1.queryFilter.calledOnce).to.be.true;
152
+ const [filter, fromBlock, toBlock] =
153
+ mailboxStub1.queryFilter.firstCall.args;
154
+ expect(filter).to.equal('DispatchFilter');
155
+ expect(fromBlock).to.equal(101); // lastScannedBlock + 1
156
+ expect(toBlock).to.equal(150);
157
+
158
+ // chain2 should not query since block didn't change
159
+ expect(mailboxStub2.queryFilter.called).to.be.false;
160
+ });
161
+ });
162
+
163
+ describe('sync - message conversion', () => {
164
+ it('should convert Dispatch events to ExplorerMessage format correctly', async () => {
165
+ await indexer.initialize({ chain1: 100, chain2: 100 });
166
+
167
+ // Create a test message
168
+ const testMsg = createTestMessage(
169
+ DOMAIN_1,
170
+ DOMAIN_2,
171
+ ROUTER_ADDRESS_1,
172
+ ROUTER_ADDRESS_2,
173
+ '0xdeadbeef',
174
+ );
175
+ const msgId = messageId(testMsg);
176
+ const txHash = '0xabc123';
177
+
178
+ const mockEvent = createMockDispatchEvent(
179
+ ROUTER_ADDRESS_1,
180
+ testMsg,
181
+ USER_ADDRESS,
182
+ txHash,
183
+ );
184
+
185
+ mailboxStub1.queryFilter.resolves([mockEvent]);
186
+
187
+ // Advance block and sync
188
+ await indexer.sync({ chain1: 110, chain2: 100 });
189
+
190
+ const userTransfers = indexer.getUserTransfers();
191
+
192
+ expect(userTransfers).to.have.lengthOf(1);
193
+ const transfer = userTransfers[0];
194
+ expect(transfer.msg_id).to.equal(msgId);
195
+ expect(transfer.origin_domain_id).to.equal(DOMAIN_1);
196
+ expect(transfer.destination_domain_id).to.equal(DOMAIN_2);
197
+ expect(transfer.origin_tx_hash).to.equal(txHash);
198
+ expect(transfer.origin_tx_sender).to.equal(USER_ADDRESS);
199
+ expect(transfer.origin_tx_recipient).to.equal(ROUTER_ADDRESS_1);
200
+ expect(transfer.is_delivered).to.be.false;
201
+ });
202
+ });
203
+
204
+ describe('sync - deduplication', () => {
205
+ it('should deduplicate messages by msg_id (same message not added twice)', async () => {
206
+ await indexer.initialize({ chain1: 100, chain2: 100 });
207
+
208
+ // Create a test message
209
+ const testMsg = createTestMessage(
210
+ DOMAIN_1,
211
+ DOMAIN_2,
212
+ ROUTER_ADDRESS_1,
213
+ ROUTER_ADDRESS_2,
214
+ );
215
+
216
+ const mockEvent = createMockDispatchEvent(
217
+ ROUTER_ADDRESS_1,
218
+ testMsg,
219
+ USER_ADDRESS,
220
+ );
221
+
222
+ // First sync with one event
223
+ mailboxStub1.queryFilter.resolves([mockEvent]);
224
+ await indexer.sync({ chain1: 110, chain2: 100 });
225
+
226
+ // Second sync returns the same event (simulating event requery overlap)
227
+ mailboxStub1.queryFilter.resolves([mockEvent]);
228
+ await indexer.sync({ chain1: 120, chain2: 100 });
229
+
230
+ const userTransfers = indexer.getUserTransfers();
231
+ expect(userTransfers).to.have.lengthOf(1);
232
+ });
233
+ });
234
+
235
+ describe('sync - no-op conditions', () => {
236
+ it('should be a no-op when lastScannedBlock >= currentBlock', async () => {
237
+ await indexer.initialize({ chain1: 100, chain2: 100 });
238
+
239
+ // Keep blocks the same
240
+ await indexer.sync({ chain1: 100, chain2: 100 });
241
+
242
+ expect(mailboxStub1.queryFilter.called).to.be.false;
243
+ expect(mailboxStub2.queryFilter.called).to.be.false;
244
+
245
+ // Even with block numbers less than last scanned (shouldn't happen but test edge case)
246
+ await indexer.sync({ chain1: 90, chain2: 100 });
247
+
248
+ expect(mailboxStub1.queryFilter.called).to.be.false;
249
+ });
250
+ });
251
+
252
+ describe('sync - incremental indexing', () => {
253
+ it('should only index new events on multiple sync() calls (incremental)', async () => {
254
+ await indexer.initialize({ chain1: 100, chain2: 100 });
255
+
256
+ // First message at block 110
257
+ const msg1 = createTestMessage(
258
+ DOMAIN_1,
259
+ DOMAIN_2,
260
+ ROUTER_ADDRESS_1,
261
+ ROUTER_ADDRESS_2,
262
+ '0x01',
263
+ 1,
264
+ );
265
+ const event1 = createMockDispatchEvent(
266
+ ROUTER_ADDRESS_1,
267
+ msg1,
268
+ USER_ADDRESS,
269
+ '0xtx1',
270
+ );
271
+
272
+ mailboxStub1.queryFilter.resolves([event1]);
273
+ await indexer.sync({ chain1: 110, chain2: 100 });
274
+
275
+ // Verify first query range
276
+ expect(mailboxStub1.queryFilter.firstCall.args[1]).to.equal(101);
277
+ expect(mailboxStub1.queryFilter.firstCall.args[2]).to.equal(110);
278
+
279
+ // Second message at block 120
280
+ const msg2 = createTestMessage(
281
+ DOMAIN_1,
282
+ DOMAIN_2,
283
+ ROUTER_ADDRESS_1,
284
+ ROUTER_ADDRESS_2,
285
+ '0x02',
286
+ 2,
287
+ );
288
+ const event2 = createMockDispatchEvent(
289
+ ROUTER_ADDRESS_1,
290
+ msg2,
291
+ USER_ADDRESS,
292
+ '0xtx2',
293
+ );
294
+
295
+ mailboxStub1.queryFilter.resolves([event2]);
296
+ await indexer.sync({ chain1: 120, chain2: 100 });
297
+
298
+ // Verify second query starts from where first left off
299
+ expect(mailboxStub1.queryFilter.secondCall.args[1]).to.equal(111);
300
+ expect(mailboxStub1.queryFilter.secondCall.args[2]).to.equal(120);
301
+
302
+ const userTransfers = indexer.getUserTransfers();
303
+ expect(userTransfers).to.have.lengthOf(2);
304
+ });
305
+ });
306
+
307
+ describe('sync - message classification', () => {
308
+ it('should classify rebalancer txs as addRebalanceAction', async () => {
309
+ await indexer.initialize({ chain1: 100, chain2: 100 });
310
+
311
+ // Create a message where tx sender is the rebalancer
312
+ const testMsg = createTestMessage(
313
+ DOMAIN_1,
314
+ DOMAIN_2,
315
+ ROUTER_ADDRESS_1,
316
+ ROUTER_ADDRESS_2,
317
+ );
318
+
319
+ const mockEvent = createMockDispatchEvent(
320
+ ROUTER_ADDRESS_1,
321
+ testMsg,
322
+ REBALANCER_ADDRESS, // tx sender is rebalancer
323
+ );
324
+
325
+ mailboxStub1.queryFilter.resolves([mockEvent]);
326
+ await indexer.sync({ chain1: 110, chain2: 100 });
327
+
328
+ expect(indexer.getUserTransfers()).to.have.lengthOf(0);
329
+ expect(indexer.getRebalanceActions()).to.have.lengthOf(1);
330
+ });
331
+
332
+ it('should classify non-rebalancer txs as addUserTransfer', async () => {
333
+ await indexer.initialize({ chain1: 100, chain2: 100 });
334
+
335
+ // Create a message where tx sender is a regular user
336
+ const testMsg = createTestMessage(
337
+ DOMAIN_1,
338
+ DOMAIN_2,
339
+ ROUTER_ADDRESS_1,
340
+ ROUTER_ADDRESS_2,
341
+ );
342
+
343
+ const mockEvent = createMockDispatchEvent(
344
+ ROUTER_ADDRESS_1,
345
+ testMsg,
346
+ USER_ADDRESS, // tx sender is regular user
347
+ );
348
+
349
+ mailboxStub1.queryFilter.resolves([mockEvent]);
350
+ await indexer.sync({ chain1: 110, chain2: 100 });
351
+
352
+ expect(indexer.getUserTransfers()).to.have.lengthOf(1);
353
+ expect(indexer.getRebalanceActions()).to.have.lengthOf(0);
354
+ });
355
+
356
+ it('should classify correctly with case-insensitive address comparison', async () => {
357
+ await indexer.initialize({ chain1: 100, chain2: 100 });
358
+
359
+ // Create a message where tx sender is rebalancer with different case
360
+ const testMsg = createTestMessage(
361
+ DOMAIN_1,
362
+ DOMAIN_2,
363
+ ROUTER_ADDRESS_1,
364
+ ROUTER_ADDRESS_2,
365
+ );
366
+
367
+ const mockEvent = createMockDispatchEvent(
368
+ ROUTER_ADDRESS_1,
369
+ testMsg,
370
+ REBALANCER_ADDRESS.toLowerCase(), // lowercase
371
+ );
372
+
373
+ mailboxStub1.queryFilter.resolves([mockEvent]);
374
+ await indexer.sync({ chain1: 110, chain2: 100 });
375
+
376
+ expect(indexer.getRebalanceActions()).to.have.lengthOf(1);
377
+ });
378
+ });
379
+
380
+ describe('sync - unknown destination chain', () => {
381
+ it('should skip messages with unknown destination domain', async () => {
382
+ await indexer.initialize({ chain1: 100, chain2: 100 });
383
+
384
+ // Create a message to an unknown domain (999)
385
+ const testMsg = createTestMessage(
386
+ DOMAIN_1,
387
+ 999, // unknown domain
388
+ ROUTER_ADDRESS_1,
389
+ ROUTER_ADDRESS_2,
390
+ );
391
+
392
+ const mockEvent = createMockDispatchEvent(
393
+ ROUTER_ADDRESS_1,
394
+ testMsg,
395
+ USER_ADDRESS,
396
+ );
397
+
398
+ mailboxStub1.queryFilter.resolves([mockEvent]);
399
+ await indexer.sync({ chain1: 110, chain2: 100 });
400
+
401
+ expect(indexer.getUserTransfers()).to.have.lengthOf(0);
402
+ });
403
+ });
404
+
405
+ describe('sync - multiple chains', () => {
406
+ it('should index events from all chains', async () => {
407
+ await indexer.initialize({ chain1: 100, chain2: 100 });
408
+
409
+ // Create events for both chains
410
+ const msg1 = createTestMessage(
411
+ DOMAIN_1,
412
+ DOMAIN_2,
413
+ ROUTER_ADDRESS_1,
414
+ ROUTER_ADDRESS_2,
415
+ '0x01',
416
+ 1,
417
+ );
418
+ const event1 = createMockDispatchEvent(
419
+ ROUTER_ADDRESS_1,
420
+ msg1,
421
+ USER_ADDRESS,
422
+ '0xtx1',
423
+ );
424
+
425
+ const msg2 = createTestMessage(
426
+ DOMAIN_2,
427
+ DOMAIN_1,
428
+ ROUTER_ADDRESS_2,
429
+ ROUTER_ADDRESS_1,
430
+ '0x02',
431
+ 2,
432
+ );
433
+ const event2 = createMockDispatchEvent(
434
+ ROUTER_ADDRESS_2,
435
+ msg2,
436
+ USER_ADDRESS,
437
+ '0xtx2',
438
+ );
439
+
440
+ mailboxStub1.queryFilter.resolves([event1]);
441
+ mailboxStub2.queryFilter.resolves([event2]);
442
+
443
+ await indexer.sync({ chain1: 110, chain2: 110 });
444
+
445
+ expect(indexer.getUserTransfers()).to.have.lengthOf(2);
446
+ });
447
+ });
448
+ });
@@ -0,0 +1,183 @@
1
+ import { providers } from 'ethers';
2
+ import type { Logger } from 'pino';
3
+
4
+ import { HyperlaneCore } from '@humanode-hyperlane/sdk';
5
+ import {
6
+ bytes32ToAddress,
7
+ messageId,
8
+ parseMessage,
9
+ } from '@humanode-hyperlane/utils';
10
+
11
+ import type { ConfirmedBlockTags } from '../../interfaces/IMonitor.js';
12
+ import type { ExplorerMessage } from '../../utils/ExplorerClient.js';
13
+
14
+ export class ForkIndexer {
15
+ private lastScannedBlock: Map<string, number> = new Map();
16
+ private seenMessageIds: Set<string> = new Set();
17
+ private initialized: boolean = false;
18
+ private userTransfers: ExplorerMessage[] = [];
19
+ private rebalanceActions: ExplorerMessage[] = [];
20
+
21
+ constructor(
22
+ private readonly providers: Map<string, providers.JsonRpcProvider>,
23
+ private readonly core: HyperlaneCore,
24
+ private readonly rebalancerAddresses: string[],
25
+ private readonly logger: Logger,
26
+ ) {}
27
+
28
+ getUserTransfers(): ExplorerMessage[] {
29
+ return this.userTransfers;
30
+ }
31
+
32
+ getRebalanceActions(): ExplorerMessage[] {
33
+ return this.rebalanceActions;
34
+ }
35
+
36
+ async initialize(confirmedBlockTags: ConfirmedBlockTags): Promise<void> {
37
+ for (const [chain] of this.providers) {
38
+ const blockNumber = confirmedBlockTags[chain];
39
+ if (blockNumber === undefined) {
40
+ throw new Error(`Missing confirmed block tag for chain ${chain}`);
41
+ }
42
+ this.lastScannedBlock.set(chain, blockNumber as number);
43
+ this.logger.debug(
44
+ { chain, blockNumber },
45
+ 'ForkIndexer initialized lastScannedBlock',
46
+ );
47
+ }
48
+ this.initialized = true;
49
+ }
50
+
51
+ async sync(confirmedBlockTags: ConfirmedBlockTags): Promise<void> {
52
+ if (!this.initialized) {
53
+ return; // No-op: nothing to scan yet
54
+ }
55
+
56
+ // Check delivery status for previously discovered messages
57
+ await this.updateDeliveryStatus(confirmedBlockTags);
58
+
59
+ for (const [chain] of this.providers) {
60
+ const currentBlock = confirmedBlockTags[chain];
61
+ if (currentBlock === undefined) {
62
+ throw new Error(`Missing confirmed block tag for chain ${chain}`);
63
+ }
64
+ const lastBlock = this.lastScannedBlock.get(chain) ?? 0;
65
+ const currentBlockNumber = currentBlock as number;
66
+
67
+ this.logger.debug(
68
+ {
69
+ chain,
70
+ lastBlock,
71
+ currentBlock: currentBlockNumber,
72
+ skip: lastBlock >= currentBlockNumber,
73
+ },
74
+ 'ForkIndexer sync check',
75
+ );
76
+
77
+ if (lastBlock >= currentBlockNumber) {
78
+ continue;
79
+ }
80
+
81
+ const mailbox = this.core.getContracts(chain).mailbox;
82
+ const events = await mailbox.queryFilter(
83
+ mailbox.filters.Dispatch(),
84
+ lastBlock + 1,
85
+ currentBlockNumber,
86
+ );
87
+
88
+ this.logger.debug(
89
+ {
90
+ chain,
91
+ eventCount: events.length,
92
+ fromBlock: lastBlock + 1,
93
+ toBlock: currentBlockNumber,
94
+ },
95
+ 'Scanned Dispatch events',
96
+ );
97
+
98
+ for (const event of events) {
99
+ const parsed = parseMessage(event.args.message);
100
+
101
+ const destChain = this.core.multiProvider.tryGetChainName(
102
+ parsed.destination,
103
+ );
104
+ if (!destChain) {
105
+ continue;
106
+ }
107
+
108
+ const receipt = await event.getTransactionReceipt();
109
+ const msgId = messageId(event.args.message);
110
+
111
+ if (this.seenMessageIds.has(msgId)) {
112
+ continue;
113
+ }
114
+
115
+ const msg: ExplorerMessage = {
116
+ msg_id: msgId,
117
+ origin_domain_id: parsed.origin,
118
+ destination_domain_id: parsed.destination,
119
+ sender: bytes32ToAddress(parsed.sender),
120
+ recipient: bytes32ToAddress(parsed.recipient),
121
+ origin_tx_hash: receipt.transactionHash,
122
+ origin_tx_sender: receipt.from,
123
+ origin_tx_recipient: event.args.sender,
124
+ is_delivered: false,
125
+ message_body: parsed.body,
126
+ send_occurred_at: null,
127
+ };
128
+
129
+ if (
130
+ this.rebalancerAddresses.some(
131
+ (addr) => receipt.from.toLowerCase() === addr.toLowerCase(),
132
+ )
133
+ ) {
134
+ this.rebalanceActions.push(msg);
135
+ } else {
136
+ this.userTransfers.push(msg);
137
+ }
138
+
139
+ this.seenMessageIds.add(msgId);
140
+ }
141
+
142
+ this.lastScannedBlock.set(chain, currentBlockNumber);
143
+ }
144
+ }
145
+
146
+ private async updateDeliveryStatus(
147
+ confirmedBlockTags: ConfirmedBlockTags,
148
+ ): Promise<void> {
149
+ const allMessages = [...this.rebalanceActions, ...this.userTransfers];
150
+ await Promise.all(
151
+ allMessages.map(async (msg) => {
152
+ if (msg.is_delivered) return;
153
+
154
+ const destChain = this.core.multiProvider.tryGetChainName(
155
+ msg.destination_domain_id,
156
+ );
157
+ if (!destChain) return;
158
+
159
+ const blockTag = confirmedBlockTags[destChain];
160
+ if (blockTag === undefined) return;
161
+
162
+ try {
163
+ const mailbox = this.core.getContracts(destChain).mailbox;
164
+ const delivered = await mailbox.delivered(msg.msg_id, {
165
+ blockTag,
166
+ });
167
+ if (delivered) {
168
+ msg.is_delivered = true;
169
+ this.logger.debug(
170
+ { msgId: msg.msg_id, destChain },
171
+ 'ForkIndexer marked message as delivered',
172
+ );
173
+ }
174
+ } catch (error) {
175
+ this.logger.debug(
176
+ { msgId: msg.msg_id, destChain, error },
177
+ 'Failed to check delivery status',
178
+ );
179
+ }
180
+ }),
181
+ );
182
+ }
183
+ }