@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,678 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { assert, parseWarpRouteMessage } from '@humanode-hyperlane/utils';
3
+ import { DEFAULT_MOVEMENT_STALENESS_MS } from '../config/types.js';
4
+ import { getConfirmedBlockTag } from '../utils/blockTag.js';
5
+ /**
6
+ * ActionTracker implementation managing the lifecycle of tracked entities.
7
+ */
8
+ export class ActionTracker {
9
+ transferStore;
10
+ rebalanceIntentStore;
11
+ rebalanceActionStore;
12
+ explorerClient;
13
+ core;
14
+ config;
15
+ logger;
16
+ constructor(transferStore, rebalanceIntentStore, rebalanceActionStore, explorerClient, core, config, logger) {
17
+ this.transferStore = transferStore;
18
+ this.rebalanceIntentStore = rebalanceIntentStore;
19
+ this.rebalanceActionStore = rebalanceActionStore;
20
+ this.explorerClient = explorerClient;
21
+ this.core = core;
22
+ this.config = config;
23
+ this.logger = logger;
24
+ }
25
+ // === Lifecycle ===
26
+ async initialize() {
27
+ this.logger.info('ActionTracker initializing');
28
+ // Log config for debugging
29
+ this.logger.debug({
30
+ routersByDomain: this.config.routersByDomain,
31
+ bridges: this.config.bridges,
32
+ rebalancerAddress: this.config.rebalancerAddress,
33
+ }, 'ActionTracker config');
34
+ // 1. Startup recovery: query Explorer for inflight rebalance messages
35
+ const inflightMessages = await this.explorerClient.getInflightRebalanceActions({
36
+ bridges: this.config.bridges,
37
+ routersByDomain: this.config.routersByDomain,
38
+ rebalancerAddress: this.config.rebalancerAddress,
39
+ inventorySignerAddresses: this.config.inventorySignerAddresses,
40
+ }, this.logger);
41
+ this.logger.info({ count: inflightMessages.length }, 'Found inflight rebalance messages during startup');
42
+ // 2. For each message, create synthetic intent + action
43
+ for (const msg of inflightMessages) {
44
+ await this.recoverAction(msg);
45
+ }
46
+ // 3. Sync all stores
47
+ await this.syncTransfers();
48
+ await this.syncRebalanceIntents();
49
+ await this.syncRebalanceActions();
50
+ // Log store contents for debugging
51
+ await this.logStoreContents();
52
+ this.logger.info('ActionTracker initialized');
53
+ }
54
+ // === Sync Operations ===
55
+ async syncTransfers(confirmedBlockTags) {
56
+ this.logger.debug('Syncing transfers');
57
+ // Build list of addresses to exclude (rebalancer + optional inventory signer)
58
+ const excludeTxSenders = [this.config.rebalancerAddress];
59
+ if (this.config.inventorySignerAddresses) {
60
+ excludeTxSenders.push(...this.config.inventorySignerAddresses);
61
+ }
62
+ const inflightMessages = await this.explorerClient.getInflightUserTransfers({
63
+ routersByDomain: this.config.routersByDomain,
64
+ excludeTxSenders,
65
+ }, this.logger);
66
+ this.logger.debug({ count: inflightMessages.length }, 'Received inflight user transfers from Explorer');
67
+ let newTransfers = 0;
68
+ let completedTransfers = 0;
69
+ for (const msg of inflightMessages) {
70
+ const transfer = await this.transferStore.get(msg.msg_id);
71
+ if (!transfer) {
72
+ this.logger.debug({
73
+ msgId: msg.msg_id,
74
+ origin: msg.origin_domain_id,
75
+ destination: msg.destination_domain_id,
76
+ sender: msg.sender,
77
+ recipient: msg.recipient,
78
+ messageBodyLength: msg.message_body?.length,
79
+ messageBodyPreview: msg.message_body?.substring(0, 66),
80
+ }, 'Processing new transfer message');
81
+ try {
82
+ const { amount } = parseWarpRouteMessage(msg.message_body);
83
+ const newTransfer = {
84
+ id: msg.msg_id,
85
+ status: 'in_progress',
86
+ messageId: msg.msg_id,
87
+ origin: msg.origin_domain_id,
88
+ destination: msg.destination_domain_id,
89
+ sender: msg.sender,
90
+ recipient: msg.recipient,
91
+ amount,
92
+ createdAt: Date.now(),
93
+ updatedAt: Date.now(),
94
+ };
95
+ await this.transferStore.save(newTransfer);
96
+ newTransfers++;
97
+ this.logger.debug({ id: newTransfer.id, amount: amount.toString() }, 'Created new transfer');
98
+ }
99
+ catch (error) {
100
+ this.logger.warn({
101
+ msgId: msg.msg_id,
102
+ messageBody: msg.message_body,
103
+ messageBodyLength: msg.message_body?.length,
104
+ origin: msg.origin_domain_id,
105
+ destination: msg.destination_domain_id,
106
+ error: error instanceof Error ? error.message : String(error),
107
+ }, 'Failed to parse message body, skipping transfer');
108
+ }
109
+ }
110
+ }
111
+ const existingTransfers = await this.getInProgressTransfers();
112
+ for (const transfer of existingTransfers) {
113
+ const blockTag = await this.getConfirmedBlockTag(transfer.destination, confirmedBlockTags);
114
+ const delivered = await this.isMessageDelivered(transfer.messageId, transfer.destination, blockTag);
115
+ if (delivered) {
116
+ await this.transferStore.update(transfer.id, { status: 'complete' });
117
+ completedTransfers++;
118
+ this.logger.debug({ id: transfer.id }, 'Transfer completed');
119
+ }
120
+ }
121
+ const inProgressCount = (await this.getInProgressTransfers()).length;
122
+ this.logger.info({
123
+ newTransfers,
124
+ completed: completedTransfers,
125
+ inProgress: inProgressCount,
126
+ }, 'Transfers synced');
127
+ }
128
+ async syncRebalanceIntents() {
129
+ this.logger.debug('Syncing rebalance intents');
130
+ // Check in_progress intents for completion or TTL expiry
131
+ const inProgressIntents = await this.rebalanceIntentStore.getByStatus('in_progress');
132
+ const allInProgressActions = await this.rebalanceActionStore.getByStatus('in_progress');
133
+ const now = Date.now();
134
+ for (const intent of inProgressIntents) {
135
+ const completedAmount = await this.getCompletedAmountForIntent(intent.id);
136
+ if (completedAmount >= intent.amount) {
137
+ await this.rebalanceIntentStore.update(intent.id, {
138
+ status: 'complete',
139
+ });
140
+ this.logger.debug({ id: intent.id }, 'RebalanceIntent completed');
141
+ }
142
+ else if (now - intent.createdAt > this.config.intentTTL) {
143
+ await this.rebalanceIntentStore.update(intent.id, {
144
+ status: 'failed',
145
+ });
146
+ // Fail any in-progress actions associated with the expired intent
147
+ for (const action of allInProgressActions) {
148
+ if (action.intentId === intent.id) {
149
+ await this.rebalanceActionStore.update(action.id, {
150
+ status: 'failed',
151
+ });
152
+ this.logger.warn({ actionId: action.id, intentId: intent.id }, 'RebalanceAction failed due to parent intent TTL expiry');
153
+ }
154
+ }
155
+ this.logger.debug({
156
+ id: intent.id,
157
+ origin: intent.origin,
158
+ destination: intent.destination,
159
+ amount: intent.amount.toString(),
160
+ ageMs: now - intent.createdAt,
161
+ ttlMs: this.config.intentTTL,
162
+ }, 'RebalanceIntent TTL expiry details');
163
+ this.logger.warn({ id: intent.id }, 'RebalanceIntent expired due to TTL');
164
+ }
165
+ }
166
+ this.logger.debug('Rebalance intents synced');
167
+ }
168
+ async syncRebalanceActions(confirmedBlockTags) {
169
+ this.logger.debug('Syncing rebalance actions');
170
+ let discoveredActions = 0;
171
+ let completedActions = 0;
172
+ const inflightMessages = await this.explorerClient.getInflightRebalanceActions({
173
+ bridges: this.config.bridges,
174
+ routersByDomain: this.config.routersByDomain,
175
+ rebalancerAddress: this.config.rebalancerAddress,
176
+ inventorySignerAddresses: this.config.inventorySignerAddresses,
177
+ }, this.logger);
178
+ this.logger.debug({ count: inflightMessages.length }, 'Found inflight rebalance actions from Explorer');
179
+ const allActions = await this.rebalanceActionStore.getAll();
180
+ for (const msg of inflightMessages) {
181
+ const existingAction = allActions.find((a) => a.messageId === msg.msg_id);
182
+ if (!existingAction) {
183
+ this.logger.info({
184
+ msgId: msg.msg_id,
185
+ origin: msg.origin_domain_id,
186
+ destination: msg.destination_domain_id,
187
+ }, 'Discovered new rebalance action, recovering...');
188
+ await this.recoverAction(msg);
189
+ discoveredActions++;
190
+ }
191
+ }
192
+ // Check delivery status for all in-progress actions in our store
193
+ // Only check delivery for actions that have a messageId (rebalance_message, inventory_deposit)
194
+ // inventory_movement actions are synced separately via LiFi status API
195
+ const inProgressActions = await this.rebalanceActionStore.getByStatus('in_progress');
196
+ for (const action of inProgressActions) {
197
+ // Skip actions without messageId (e.g., inventory_movement)
198
+ if (!action.messageId) {
199
+ continue;
200
+ }
201
+ const blockTag = await this.getConfirmedBlockTag(action.destination, confirmedBlockTags);
202
+ const delivered = await this.isMessageDelivered(action.messageId, action.destination, blockTag);
203
+ if (delivered) {
204
+ await this.completeRebalanceAction(action.id);
205
+ completedActions++;
206
+ this.logger.debug({ id: action.id }, 'RebalanceAction completed');
207
+ }
208
+ }
209
+ const inProgressCount = (await this.rebalanceActionStore.getByStatus('in_progress')).length;
210
+ this.logger.info({
211
+ discovered: discoveredActions,
212
+ completed: completedActions,
213
+ inProgress: inProgressCount,
214
+ }, 'Actions synced');
215
+ }
216
+ // === Transfer Queries ===
217
+ async getTransfer(id) {
218
+ return this.transferStore.get(id);
219
+ }
220
+ async getInProgressTransfers() {
221
+ return this.transferStore.getByStatus('in_progress');
222
+ }
223
+ async getTransfersByDestination(destination) {
224
+ return this.transferStore.getByDestination(destination);
225
+ }
226
+ // === RebalanceIntent Queries ===
227
+ async getRebalanceIntent(id) {
228
+ return this.rebalanceIntentStore.get(id);
229
+ }
230
+ async getActiveRebalanceIntents() {
231
+ // Only return in_progress intents - their origin tx is confirmed
232
+ // so simulation only needs to add to destination (origin already deducted on-chain)
233
+ return this.rebalanceIntentStore.getByStatus('in_progress');
234
+ }
235
+ async getRebalanceIntentsByDestination(destination) {
236
+ return this.rebalanceIntentStore.getByDestination(destination);
237
+ }
238
+ // === RebalanceIntent Management ===
239
+ async createRebalanceIntent(params) {
240
+ const intent = {
241
+ id: uuidv4(),
242
+ status: 'not_started',
243
+ origin: params.origin,
244
+ destination: params.destination,
245
+ amount: params.amount,
246
+ bridge: params.bridge,
247
+ priority: params.priority,
248
+ strategyType: params.strategyType,
249
+ executionMethod: params.executionMethod,
250
+ externalBridge: params.externalBridge,
251
+ createdAt: Date.now(),
252
+ updatedAt: Date.now(),
253
+ };
254
+ await this.rebalanceIntentStore.save(intent);
255
+ this.logger.debug({
256
+ id: intent.id,
257
+ origin: intent.origin,
258
+ destination: intent.destination,
259
+ executionMethod: intent.executionMethod,
260
+ }, 'Created RebalanceIntent');
261
+ return intent;
262
+ }
263
+ async completeRebalanceIntent(id) {
264
+ await this.rebalanceIntentStore.update(id, { status: 'complete' });
265
+ this.logger.info({ id }, 'Intent completed');
266
+ }
267
+ async cancelRebalanceIntent(id) {
268
+ await this.rebalanceIntentStore.update(id, { status: 'cancelled' });
269
+ this.logger.debug({ id }, 'Cancelled RebalanceIntent');
270
+ }
271
+ async failRebalanceIntent(id) {
272
+ await this.rebalanceIntentStore.update(id, { status: 'failed' });
273
+ this.logger.info({ id }, 'Intent failed');
274
+ }
275
+ // === RebalanceAction Queries ===
276
+ async getRebalanceAction(id) {
277
+ return this.rebalanceActionStore.get(id);
278
+ }
279
+ async getInProgressActions() {
280
+ return this.rebalanceActionStore.getByStatus('in_progress');
281
+ }
282
+ // === RebalanceAction Management ===
283
+ async createRebalanceAction(params) {
284
+ const action = {
285
+ id: uuidv4(),
286
+ status: 'in_progress',
287
+ type: params.type,
288
+ intentId: params.intentId,
289
+ messageId: params.messageId,
290
+ txHash: params.txHash,
291
+ externalBridgeTransferId: params.externalBridgeTransferId,
292
+ externalBridgeId: params.externalBridgeId,
293
+ origin: params.origin,
294
+ destination: params.destination,
295
+ amount: params.amount,
296
+ createdAt: Date.now(),
297
+ updatedAt: Date.now(),
298
+ };
299
+ await this.rebalanceActionStore.save(action);
300
+ // Transition parent intent from not_started to in_progress
301
+ const intent = await this.rebalanceIntentStore.get(params.intentId);
302
+ if (intent && intent.status === 'not_started') {
303
+ await this.rebalanceIntentStore.update(intent.id, {
304
+ status: 'in_progress',
305
+ });
306
+ this.logger.debug({ intentId: intent.id }, 'Transitioned RebalanceIntent to in_progress');
307
+ }
308
+ this.logger.debug({ id: action.id, intentId: action.intentId, type: action.type }, 'Created RebalanceAction');
309
+ return action;
310
+ }
311
+ async completeRebalanceAction(id) {
312
+ const action = await this.rebalanceActionStore.get(id);
313
+ if (!action) {
314
+ throw new Error(`RebalanceAction ${id} not found`);
315
+ }
316
+ await this.rebalanceActionStore.update(id, { status: 'complete' });
317
+ // Check if parent intent is now complete (derive from action states)
318
+ await this.checkAndCompleteIntent(action.intentId);
319
+ this.logger.info({ id, intentId: action.intentId, type: action.type }, 'Action completed');
320
+ }
321
+ /**
322
+ * Check if an intent is fully fulfilled based on completed action amounts.
323
+ * Only `inventory_deposit` and `rebalance_message` actions count toward fulfillment.
324
+ */
325
+ async checkAndCompleteIntent(intentId) {
326
+ const intent = await this.rebalanceIntentStore.get(intentId);
327
+ if (!intent || intent.status === 'complete')
328
+ return;
329
+ const completedAmount = await this.getCompletedAmountForIntent(intentId);
330
+ if (completedAmount >= intent.amount) {
331
+ await this.rebalanceIntentStore.update(intentId, { status: 'complete' });
332
+ this.logger.debug({ intentId, completedAmount: completedAmount.toString() }, 'RebalanceIntent fully fulfilled');
333
+ }
334
+ }
335
+ /**
336
+ * Get the total completed amount for an intent from its actions.
337
+ * Only `inventory_deposit` and `rebalance_message` actions count.
338
+ */
339
+ async getCompletedAmountForIntent(intentId) {
340
+ const actions = await this.getActionsForIntent(intentId);
341
+ return actions
342
+ .filter((a) => a.status === 'complete' &&
343
+ (a.type === 'inventory_deposit' || a.type === 'rebalance_message'))
344
+ .reduce((sum, a) => sum + a.amount, 0n);
345
+ }
346
+ async failRebalanceAction(id) {
347
+ await this.rebalanceActionStore.update(id, { status: 'failed' });
348
+ this.logger.info({ id }, 'Action failed');
349
+ }
350
+ // === RebalanceAction Queries ===
351
+ async getActionsByType(type) {
352
+ const allActions = await this.rebalanceActionStore.getAll();
353
+ return allActions.filter((action) => action.type === type);
354
+ }
355
+ async getInflightInventoryMovements(origin) {
356
+ const allActions = await this.rebalanceActionStore.getAll();
357
+ const inflightMovements = allActions.filter((action) => action.type === 'inventory_movement' &&
358
+ action.status === 'in_progress' &&
359
+ action.origin === origin);
360
+ return inflightMovements.reduce((sum, action) => sum + action.amount, BigInt(0));
361
+ }
362
+ /**
363
+ * Get inventory intents that are in_progress or not_started but not fully settled.
364
+ * Intents with in-flight deposits are included but flagged via hasInflightDeposit.
365
+ * Returns enriched data with computed values derived from action states.
366
+ *
367
+ * NOTE: We include 'not_started' intents because they may have been created
368
+ * but failed to execute (e.g., all bridges failed viability check). Without
369
+ * checking for these, we would create duplicate intents every polling cycle.
370
+ */
371
+ async getPartiallyFulfilledInventoryIntents() {
372
+ // Query both in_progress AND not_started intents
373
+ // not_started intents may exist if execution failed before any action was created
374
+ const [inProgressIntents, notStartedIntents] = await Promise.all([
375
+ this.rebalanceIntentStore.getByStatus('in_progress'),
376
+ this.rebalanceIntentStore.getByStatus('not_started'),
377
+ ]);
378
+ const allActiveIntents = [...inProgressIntents, ...notStartedIntents];
379
+ const partialIntents = [];
380
+ for (const intent of allActiveIntents) {
381
+ // Only inventory execution method
382
+ if (intent.executionMethod !== 'inventory')
383
+ continue;
384
+ const actions = await this.getActionsForIntent(intent.id);
385
+ // Check for in-flight inventory_movement actions
386
+ // Skip intents with active bridge movement(s). Movements still `pending` on
387
+ // the bridge are kept alive regardless of age. Non-pending movements are only
388
+ // failed after they've been in a non-pending state for the staleness window
389
+ // (nonPendingSince), preventing premature failure from transient not_found polls.
390
+ // `undefined` status (pre-deploy data) falls back to createdAt for staleness.
391
+ const inflightMovements = actions.filter((a) => a.status === 'in_progress' && a.type === 'inventory_movement');
392
+ const now = Date.now();
393
+ const staleMovements = inflightMovements.filter((a) => {
394
+ if (a.lastBridgeStatus === 'pending')
395
+ return false;
396
+ // Use nonPendingSince when available; fall back to createdAt for
397
+ // pre-deploy data that lacks the field.
398
+ const nonPendingStart = a.nonPendingSince ?? a.createdAt;
399
+ return now - nonPendingStart >= DEFAULT_MOVEMENT_STALENESS_MS;
400
+ });
401
+ const staleMovementIds = new Set(staleMovements.map((a) => a.id));
402
+ const hasBlockingInflightMovement = inflightMovements.some((a) => !staleMovementIds.has(a.id));
403
+ if (hasBlockingInflightMovement) {
404
+ this.logger.debug({ intentId: intent.id }, 'Skipping partial intent - has in-flight inventory movement');
405
+ continue;
406
+ }
407
+ // Fail stale movements so the intent can proceed
408
+ for (const movement of staleMovements) {
409
+ await this.failRebalanceAction(movement.id);
410
+ this.logger.warn({
411
+ actionId: movement.id,
412
+ age: now - movement.createdAt,
413
+ nonPendingDuration: now - (movement.nonPendingSince ?? movement.createdAt),
414
+ intentId: intent.id,
415
+ lastBridgeStatus: movement.lastBridgeStatus,
416
+ }, 'Failing stale inventory movement to unblock intent');
417
+ }
418
+ // Compute amounts from action states
419
+ const completedAmount = actions
420
+ .filter((a) => a.status === 'complete' && a.type === 'inventory_deposit')
421
+ .reduce((sum, a) => sum + a.amount, 0n);
422
+ const inflightAmount = actions
423
+ .filter((a) => a.status === 'in_progress' && a.type === 'inventory_deposit')
424
+ .reduce((sum, a) => sum + a.amount, 0n);
425
+ const remaining = intent.amount - completedAmount - inflightAmount;
426
+ if (remaining > 0n || inflightAmount > 0n) {
427
+ partialIntents.push({
428
+ intent,
429
+ completedAmount,
430
+ remaining,
431
+ hasInflightDeposit: inflightAmount > 0n,
432
+ });
433
+ }
434
+ }
435
+ return partialIntents;
436
+ }
437
+ /**
438
+ * Get all actions associated with a specific intent.
439
+ */
440
+ async getActionsForIntent(intentId) {
441
+ const allActions = await this.rebalanceActionStore.getAll();
442
+ return allActions.filter((a) => a.intentId === intentId);
443
+ }
444
+ async syncInventoryMovementActions(externalBridgeRegistry) {
445
+ this.logger.debug('Syncing inventory movement actions');
446
+ let completed = 0;
447
+ let failed = 0;
448
+ // Get all in-progress inventory_movement actions
449
+ const inProgressActions = await this.rebalanceActionStore.getByStatus('in_progress');
450
+ const inventoryMovements = inProgressActions.filter((a) => a.type === 'inventory_movement');
451
+ this.logger.debug({ count: inventoryMovements.length }, 'Found in-progress inventory movements');
452
+ for (const action of inventoryMovements) {
453
+ // Skip if no txHash (shouldn't happen but be safe)
454
+ if (!action.txHash) {
455
+ this.logger.warn({ actionId: action.id }, 'Inventory movement action has no txHash');
456
+ continue;
457
+ }
458
+ // Skip if no externalBridgeId (shouldn't happen but be safe)
459
+ if (!action.externalBridgeId) {
460
+ this.logger.warn({ actionId: action.id }, 'Inventory movement action has no externalBridgeId');
461
+ continue;
462
+ }
463
+ const externalBridge = externalBridgeRegistry[action.externalBridgeId];
464
+ if (!externalBridge) {
465
+ this.logger.warn({ actionId: action.id, bridgeId: action.externalBridgeId }, 'Bridge not found in registry');
466
+ continue;
467
+ }
468
+ try {
469
+ const status = await externalBridge.getStatus(action.txHash, action.origin, action.destination);
470
+ if (status.status === 'complete') {
471
+ await this.completeRebalanceAction(action.id);
472
+ completed++;
473
+ this.logger.info({
474
+ actionId: action.id,
475
+ txHash: action.txHash,
476
+ receivedAmount: status.receivedAmount?.toString(),
477
+ }, 'Inventory movement completed');
478
+ }
479
+ else if (status.status === 'failed') {
480
+ await this.failRebalanceAction(action.id);
481
+ failed++;
482
+ this.logger.warn({
483
+ actionId: action.id,
484
+ txHash: action.txHash,
485
+ error: status.error,
486
+ }, 'Inventory movement failed');
487
+ }
488
+ else if (status.status === 'pending') {
489
+ await this.rebalanceActionStore.update(action.id, {
490
+ lastBridgeStatus: 'pending',
491
+ nonPendingSince: undefined,
492
+ });
493
+ this.logger.debug({
494
+ actionId: action.id,
495
+ txHash: action.txHash,
496
+ substatus: status.substatus,
497
+ }, 'Inventory movement still pending');
498
+ }
499
+ else if (status.status === 'not_found') {
500
+ await this.rebalanceActionStore.update(action.id, {
501
+ lastBridgeStatus: 'not_found',
502
+ nonPendingSince: action.nonPendingSince ?? Date.now(),
503
+ });
504
+ this.logger.debug({
505
+ actionId: action.id,
506
+ txHash: action.txHash,
507
+ }, 'Inventory movement not found');
508
+ }
509
+ }
510
+ catch (error) {
511
+ this.logger.debug({
512
+ actionId: action.id,
513
+ txHash: action.txHash,
514
+ error: error.message,
515
+ }, 'Failed to get inventory movement status');
516
+ }
517
+ }
518
+ if (inventoryMovements.length > 0) {
519
+ this.logger.info({
520
+ completed,
521
+ failed,
522
+ pending: inventoryMovements.length - completed - failed,
523
+ }, 'Inventory movements synced');
524
+ }
525
+ return { completed, failed };
526
+ }
527
+ // === Debug Helpers ===
528
+ /**
529
+ * Log the contents of all stores.
530
+ * Logs each item separately for full visibility (avoids [Object] truncation).
531
+ */
532
+ async logStoreContents() {
533
+ const transfers = await this.transferStore.getAll();
534
+ const intents = await this.rebalanceIntentStore.getAll();
535
+ const actions = await this.rebalanceActionStore.getAll();
536
+ const activeIntents = intents.filter((i) => ['not_started', 'in_progress'].includes(i.status));
537
+ const inProgressTransfers = transfers.filter((t) => t.status === 'in_progress');
538
+ const inProgressActions = actions.filter((a) => a.status === 'in_progress');
539
+ // Log summary
540
+ this.logger.info({
541
+ transfers: inProgressTransfers.length,
542
+ intents: activeIntents.length,
543
+ actions: inProgressActions.length,
544
+ }, 'Store summary');
545
+ // Log each transfer separately
546
+ for (const t of inProgressTransfers) {
547
+ this.logger.info({
548
+ type: 'transfer',
549
+ origin: t.origin,
550
+ destination: t.destination,
551
+ amount: t.amount.toString(),
552
+ messageId: t.messageId,
553
+ }, 'In-progress transfer');
554
+ }
555
+ // Log each intent separately
556
+ for (const i of activeIntents) {
557
+ this.logger.info({
558
+ type: 'intent',
559
+ id: i.id,
560
+ origin: i.origin,
561
+ destination: i.destination,
562
+ amount: i.amount.toString(),
563
+ status: i.status,
564
+ bridge: i.bridge,
565
+ }, 'Active intent');
566
+ }
567
+ // Log each action separately
568
+ for (const a of inProgressActions) {
569
+ this.logger.info({
570
+ type: 'action',
571
+ id: a.id,
572
+ origin: a.origin,
573
+ destination: a.destination,
574
+ amount: a.amount.toString(),
575
+ messageId: a.messageId,
576
+ intentId: a.intentId,
577
+ }, 'In-progress action');
578
+ }
579
+ }
580
+ // === Private Helpers ===
581
+ /**
582
+ * Get the confirmed block tag for delivery checks.
583
+ * Uses cached value from Monitor event if available, otherwise computes on-demand.
584
+ */
585
+ async getConfirmedBlockTag(destination, confirmedBlockTags) {
586
+ const chainName = this.core.multiProvider.getChainName(destination);
587
+ // If tags provided (from Monitor event), use cached value
588
+ if (confirmedBlockTags) {
589
+ return confirmedBlockTags[chainName];
590
+ }
591
+ // Otherwise compute on-demand (e.g., during initialize())
592
+ return getConfirmedBlockTag(this.core.multiProvider, chainName, this.logger);
593
+ }
594
+ async isMessageDelivered(messageId, destination, blockTag) {
595
+ try {
596
+ const chainName = this.core.multiProvider.getChainName(destination);
597
+ const delivered = await this.core
598
+ .adapter(chainName)
599
+ .isDelivered(messageId, blockTag);
600
+ this.logger.debug({ messageId, destination: chainName, delivered, blockTag }, 'Checked message delivery');
601
+ return delivered;
602
+ }
603
+ catch (error) {
604
+ this.logger.warn({ messageId, destination, error }, 'Failed to check message delivery status');
605
+ return false;
606
+ }
607
+ }
608
+ async recoverAction(msg) {
609
+ // Check if action already exists
610
+ const existing = await this.rebalanceActionStore.get(msg.msg_id);
611
+ if (existing) {
612
+ this.logger.debug({ id: msg.msg_id }, 'Action already exists, skipping');
613
+ return;
614
+ }
615
+ this.logger.debug({
616
+ msgId: msg.msg_id,
617
+ origin: msg.origin_domain_id,
618
+ destination: msg.destination_domain_id,
619
+ sender: msg.sender,
620
+ recipient: msg.recipient,
621
+ txHash: msg.origin_tx_hash,
622
+ messageBodyLength: msg.message_body?.length,
623
+ messageBodyPreview: msg.message_body?.substring(0, 66),
624
+ }, 'Recovering rebalance action');
625
+ try {
626
+ // Create synthetic intent
627
+ const { amount } = parseWarpRouteMessage(msg.message_body);
628
+ // Hasura returns block timestamps as UTC without 'Z' suffix (e.g. "2024-01-15T12:30:45").
629
+ // Null when the scraper hasn't indexed the origin block yet, so fall back to now.
630
+ // Note: when null, TTL effectively extends by scraper lag since recoverAction won't update createdAt later.
631
+ const createdAt = msg.send_occurred_at
632
+ ? new Date(msg.send_occurred_at + 'Z').getTime()
633
+ : Date.now();
634
+ assert(!isNaN(createdAt), `Invalid send_occurred_at timestamp: ${msg.send_occurred_at}`);
635
+ const intent = {
636
+ id: uuidv4(),
637
+ status: 'in_progress',
638
+ origin: msg.origin_domain_id,
639
+ destination: msg.destination_domain_id,
640
+ amount,
641
+ priority: undefined,
642
+ strategyType: undefined,
643
+ createdAt,
644
+ updatedAt: Date.now(),
645
+ };
646
+ await this.rebalanceIntentStore.save(intent);
647
+ this.logger.debug({ id: intent.id, amount: amount.toString(), createdAt }, 'Created synthetic RebalanceIntent');
648
+ // Create action (recovered actions are always rebalance_message type)
649
+ const action = {
650
+ id: msg.msg_id,
651
+ status: 'in_progress',
652
+ type: 'rebalance_message',
653
+ intentId: intent.id,
654
+ messageId: msg.msg_id,
655
+ txHash: msg.origin_tx_hash,
656
+ origin: msg.origin_domain_id,
657
+ destination: msg.destination_domain_id,
658
+ amount,
659
+ createdAt,
660
+ updatedAt: Date.now(),
661
+ };
662
+ await this.rebalanceActionStore.save(action);
663
+ this.logger.debug({ id: action.id, intentId: action.intentId, amount: amount.toString() }, 'Recovered RebalanceAction');
664
+ }
665
+ catch (error) {
666
+ this.logger.warn({
667
+ msgId: msg.msg_id,
668
+ messageBody: msg.message_body,
669
+ messageBodyLength: msg.message_body?.length,
670
+ origin: msg.origin_domain_id,
671
+ destination: msg.destination_domain_id,
672
+ txHash: msg.origin_tx_hash,
673
+ error: error instanceof Error ? error.message : String(error),
674
+ }, 'Failed to parse message body during recovery, skipping action');
675
+ }
676
+ }
677
+ }
678
+ //# sourceMappingURL=ActionTracker.js.map