@humanode-hyperlane/rebalancer 0.0.0-stage → 27.2.2

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,758 @@
1
+ import { BigNumber, ethers } from 'ethers';
2
+ import { type Logger, pino } from 'pino';
3
+
4
+ import { ERC20Test__factory } from '@humanode-hyperlane/core';
5
+ import {
6
+ HyperlaneCore,
7
+ MultiProtocolProvider,
8
+ type MultiProvider,
9
+ type WarpCoreConfig,
10
+ } from '@humanode-hyperlane/sdk';
11
+ import {
12
+ ProtocolType,
13
+ addressToBytes32,
14
+ assert,
15
+ } from '@humanode-hyperlane/utils';
16
+
17
+ import { RebalancerConfig } from '../../config/RebalancerConfig.js';
18
+ import {
19
+ DEFAULT_INTENT_TTL_MS,
20
+ ExternalBridgeType,
21
+ type StrategyConfig,
22
+ getStrategyChainNames,
23
+ } from '../../config/types.js';
24
+ import {
25
+ RebalancerOrchestrator,
26
+ type RebalancerOrchestratorDeps,
27
+ } from '../../core/RebalancerOrchestrator.js';
28
+ import { RebalancerContextFactory } from '../../factories/RebalancerContextFactory.js';
29
+ import type { ExternalBridgeRegistry } from '../../interfaces/IExternalBridge.js';
30
+ import type { ConfirmedBlockTags } from '../../interfaces/IMonitor.js';
31
+ import type { IStrategy } from '../../interfaces/IStrategy.js';
32
+ import type { InventoryMonitorConfig, Monitor } from '../../monitor/Monitor.js';
33
+ import type { IActionTracker } from '../../tracking/IActionTracker.js';
34
+ import type { ExplorerMessage } from '../../utils/ExplorerClient.js';
35
+ import {
36
+ ANVIL_TEST_PRIVATE_KEY,
37
+ BALANCE_PRESETS,
38
+ DOMAIN_IDS,
39
+ type DeployedAddresses,
40
+ ERC20_INVENTORY_MONITORED_ROUTE_ID,
41
+ type Erc20InventoryDeployedAddresses,
42
+ INVENTORY_SIGNER_PRESETS,
43
+ MONITORED_ROUTE_ID,
44
+ NATIVE_MONITORED_ROUTE_ID,
45
+ type NativeDeployedAddresses,
46
+ TEST_CHAINS,
47
+ type TestChain,
48
+ buildErc20InventoryWarpRouteConfig,
49
+ buildNativeWarpRouteConfig,
50
+ buildWarpRouteConfig,
51
+ } from '../fixtures/routes.js';
52
+
53
+ import { setupCollateralBalances } from './BridgeSetup.js';
54
+ import { BaseLocalDeploymentManager } from './BaseLocalDeploymentManager.js';
55
+ import { ForkIndexer } from './ForkIndexer.js';
56
+ import {
57
+ MockExplorerClient,
58
+ type MockExplorerConfig,
59
+ } from './MockExplorerClient.js';
60
+ import { MockExternalBridge } from './MockExternalBridge.js';
61
+
62
+ function encodeWarpRouteMessageBody(
63
+ recipient: string,
64
+ amount: BigNumber,
65
+ ): string {
66
+ const recipientBytes32 = addressToBytes32(recipient);
67
+ const amountHex = ethers.utils.hexZeroPad(amount.toHexString(), 32);
68
+ return recipientBytes32 + amountHex.slice(2);
69
+ }
70
+
71
+ export interface PendingTransferParams {
72
+ from: TestChain;
73
+ to: TestChain;
74
+ amount: BigNumber;
75
+ warpRecipient?: string;
76
+ }
77
+
78
+ export interface TestRebalancerContext {
79
+ orchestrator: RebalancerOrchestrator;
80
+ strategy: IStrategy;
81
+ tracker: IActionTracker;
82
+ mockExplorer: MockExplorerClient;
83
+ forkIndexer: ForkIndexer;
84
+ multiProvider: MultiProvider;
85
+ rebalancerConfig: RebalancerConfig;
86
+ contextFactory: RebalancerContextFactory;
87
+ inventoryConfig?: InventoryMonitorConfig;
88
+ createMonitor(checkFrequency: number): Monitor;
89
+ getConfirmedBlockTags(): Promise<ConfirmedBlockTags>;
90
+ }
91
+
92
+ type BalancePreset = keyof typeof BALANCE_PRESETS;
93
+ type BalanceConfig = BalancePreset | Record<string, BigNumber>;
94
+ type ExecutionMode = 'propose' | 'execute';
95
+ type InventorySignerPreset = keyof typeof INVENTORY_SIGNER_PRESETS;
96
+ type InventorySignerBalanceConfig =
97
+ | InventorySignerPreset
98
+ | Partial<Record<string, BigNumber>>;
99
+
100
+ type TestInventoryConfig = {
101
+ inventorySignerKey: string;
102
+ nativeDeployedAddresses: NativeDeployedAddresses;
103
+ };
104
+
105
+ type TestErc20InventoryConfig = {
106
+ inventorySignerKey: string;
107
+ erc20DeployedAddresses: Erc20InventoryDeployedAddresses;
108
+ };
109
+
110
+ export class TestRebalancerBuilder {
111
+ private strategyConfig: StrategyConfig[] | undefined;
112
+ private balanceConfig: BalanceConfig = 'BALANCED';
113
+ private pendingTransfers: PendingTransferParams[] = [];
114
+ private mockTransfers: ExplorerMessage[] = [];
115
+ private executionMode: ExecutionMode = 'propose';
116
+ private inventoryConfig: TestInventoryConfig | undefined;
117
+ private erc20InventoryConfig: TestErc20InventoryConfig | undefined;
118
+ private mockExternalBridge: MockExternalBridge | undefined;
119
+ private readonly logger: Logger;
120
+ private inventorySignerBalanceConfig:
121
+ | InventorySignerBalanceConfig
122
+ | undefined;
123
+
124
+ constructor(
125
+ private readonly deploymentManager: BaseLocalDeploymentManager<
126
+ DeployedAddresses | NativeDeployedAddresses
127
+ >,
128
+ private readonly multiProvider: MultiProvider,
129
+ ) {
130
+ this.logger = pino({ level: 'debug' }).child({ module: 'TestRebalancer' });
131
+ }
132
+
133
+ withStrategy(config: StrategyConfig[]): this {
134
+ this.strategyConfig = config;
135
+ return this;
136
+ }
137
+
138
+ withBalances(preset: BalancePreset | Record<string, BigNumber>): this {
139
+ this.balanceConfig = preset;
140
+ return this;
141
+ }
142
+
143
+ withPendingTransfer(params: PendingTransferParams): this {
144
+ this.pendingTransfers.push(params);
145
+ return this;
146
+ }
147
+
148
+ withMockTransfer(message: ExplorerMessage): this {
149
+ this.mockTransfers.push(message);
150
+ return this;
151
+ }
152
+
153
+ withExecutionMode(mode: ExecutionMode): this {
154
+ this.executionMode = mode;
155
+ return this;
156
+ }
157
+
158
+ withInventoryConfig(config: {
159
+ inventorySignerKey: string;
160
+ nativeDeployedAddresses: NativeDeployedAddresses;
161
+ }): this {
162
+ this.inventoryConfig = config;
163
+ return this;
164
+ }
165
+
166
+ withErc20InventoryConfig(config: TestErc20InventoryConfig): this {
167
+ this.erc20InventoryConfig = config;
168
+ return this;
169
+ }
170
+
171
+ withMockExternalBridge(bridge: MockExternalBridge): this {
172
+ this.mockExternalBridge = bridge;
173
+ return this;
174
+ }
175
+
176
+ withInventorySignerBalances(config: InventorySignerBalanceConfig): this {
177
+ this.inventorySignerBalanceConfig = config;
178
+ return this;
179
+ }
180
+
181
+ private async computeConfirmedBlockTags(): Promise<ConfirmedBlockTags> {
182
+ const blockTags: ConfirmedBlockTags = {};
183
+ const localProviders = this.deploymentManager.getContext().providers;
184
+
185
+ for (const [chain, provider] of localProviders) {
186
+ try {
187
+ const blockNumber = await provider.send('eth_blockNumber', []);
188
+ blockTags[chain] = parseInt(blockNumber, 16);
189
+ this.logger.debug(
190
+ { chain, blockNumber: blockTags[chain] },
191
+ 'Computed confirmed block tag',
192
+ );
193
+ } catch (error: unknown) {
194
+ this.logger.warn(
195
+ {
196
+ chain,
197
+ error: error instanceof Error ? error.message : String(error),
198
+ },
199
+ 'Failed to get block number, using undefined',
200
+ );
201
+ blockTags[chain] = undefined;
202
+ }
203
+ }
204
+
205
+ return blockTags;
206
+ }
207
+
208
+ async build(): Promise<TestRebalancerContext> {
209
+ if (!this.strategyConfig || this.strategyConfig.length === 0) {
210
+ throw new Error(
211
+ 'Strategy config is required. Call withStrategy() before build().',
212
+ );
213
+ }
214
+
215
+ const strategyChains = getStrategyChainNames(this.strategyConfig);
216
+ const balanceChains = this.getBalanceChains();
217
+ const missingChains = strategyChains.filter(
218
+ (chain) => !balanceChains.includes(chain),
219
+ );
220
+ if (missingChains.length > 0) {
221
+ throw new Error(
222
+ `Balance config missing chains required by strategy: ${missingChains.join(', ')}. ` +
223
+ `Strategy chains: ${strategyChains.join(', ')}, Balance chains: ${balanceChains.join(', ')}`,
224
+ );
225
+ }
226
+
227
+ assert(
228
+ !(this.inventoryConfig && this.erc20InventoryConfig),
229
+ 'Cannot set both inventoryConfig and erc20InventoryConfig — use one or the other',
230
+ );
231
+
232
+ if (this.inventoryConfig && !this.mockExternalBridge) {
233
+ throw new Error(
234
+ 'Inventory mode requires .withMockExternalBridge() to prevent hitting real external bridges in tests',
235
+ );
236
+ }
237
+
238
+ await this.setupBalances();
239
+
240
+ const inventoryModeConfig = this.inventoryConfig;
241
+ const erc20InventoryModeConfig = this.erc20InventoryConfig;
242
+ const isInventoryMode = inventoryModeConfig !== undefined;
243
+ const isErc20InventoryMode = erc20InventoryModeConfig !== undefined;
244
+ const ctx = this.deploymentManager.getContext();
245
+ const { providers: localProviders } = ctx;
246
+ const deployedAddresses = ctx.deployedAddresses;
247
+ if (!isInventoryMode && !('tokens' in deployedAddresses)) {
248
+ throw new Error('Expected ERC20 deployed addresses with tokens field');
249
+ }
250
+
251
+ const coreAddresses: Record<string, Record<string, string>> = {};
252
+ for (const chain of TEST_CHAINS) {
253
+ const chainAddresses = isErc20InventoryMode
254
+ ? erc20InventoryModeConfig.erc20DeployedAddresses.chains[chain]
255
+ : isInventoryMode
256
+ ? inventoryModeConfig.nativeDeployedAddresses.chains[chain]
257
+ : deployedAddresses.chains[chain];
258
+ if (!chainAddresses) {
259
+ throw new Error(`Missing chain addresses for ${chain}`);
260
+ }
261
+ coreAddresses[chain] = {
262
+ mailbox: chainAddresses.mailbox,
263
+ interchainSecurityModule: chainAddresses.ism,
264
+ };
265
+ }
266
+ const hyperlaneCore = HyperlaneCore.fromAddressesMap(
267
+ coreAddresses,
268
+ this.multiProvider,
269
+ );
270
+
271
+ const deployerWallet = new ethers.Wallet(ANVIL_TEST_PRIVATE_KEY);
272
+ const rebalancerAddresses = [deployerWallet.address];
273
+
274
+ const workingMultiProvider = await this.getWorkingMultiProvider();
275
+
276
+ const forkIndexer = new ForkIndexer(
277
+ localProviders,
278
+ hyperlaneCore,
279
+ rebalancerAddresses,
280
+ this.logger,
281
+ );
282
+
283
+ const confirmedBlockTags = await this.computeConfirmedBlockTags();
284
+ await forkIndexer.initialize(confirmedBlockTags);
285
+
286
+ const mockExplorer = new MockExplorerClient(
287
+ this.buildMockExplorerConfig(),
288
+ forkIndexer,
289
+ () => this.computeConfirmedBlockTags(),
290
+ );
291
+
292
+ const registry = this.deploymentManager.getRegistry();
293
+ const mpp = MultiProtocolProvider.fromMultiProvider(workingMultiProvider);
294
+
295
+ let rebalancerConfig: RebalancerConfig;
296
+ let warpCoreConfig: WarpCoreConfig;
297
+ if (isErc20InventoryMode) {
298
+ const inventorySignerAddress = new ethers.Wallet(
299
+ erc20InventoryModeConfig.inventorySignerKey,
300
+ ).address;
301
+ rebalancerAddresses.push(inventorySignerAddress);
302
+ rebalancerConfig = new RebalancerConfig(
303
+ ERC20_INVENTORY_MONITORED_ROUTE_ID,
304
+ this.strategyConfig,
305
+ DEFAULT_INTENT_TTL_MS,
306
+ {
307
+ [ProtocolType.Ethereum]: {
308
+ address: inventorySignerAddress,
309
+ key: erc20InventoryModeConfig.inventorySignerKey,
310
+ },
311
+ },
312
+ { lifi: { integrator: 'test' } },
313
+ );
314
+ warpCoreConfig = buildErc20InventoryWarpRouteConfig(
315
+ erc20InventoryModeConfig.erc20DeployedAddresses,
316
+ );
317
+ } else if (isInventoryMode) {
318
+ const inventorySignerAddress = new ethers.Wallet(
319
+ inventoryModeConfig.inventorySignerKey,
320
+ ).address;
321
+ rebalancerAddresses.push(inventorySignerAddress);
322
+ rebalancerConfig = new RebalancerConfig(
323
+ NATIVE_MONITORED_ROUTE_ID,
324
+ this.strategyConfig,
325
+ DEFAULT_INTENT_TTL_MS,
326
+ {
327
+ [ProtocolType.Ethereum]: {
328
+ address: inventorySignerAddress,
329
+ key: inventoryModeConfig.inventorySignerKey,
330
+ },
331
+ },
332
+ { lifi: { integrator: 'test' } },
333
+ );
334
+ warpCoreConfig = buildNativeWarpRouteConfig(
335
+ inventoryModeConfig.nativeDeployedAddresses,
336
+ );
337
+ } else {
338
+ if (!('tokens' in deployedAddresses)) {
339
+ throw new Error('Expected ERC20 deployed addresses with tokens field');
340
+ }
341
+ rebalancerConfig = new RebalancerConfig(
342
+ MONITORED_ROUTE_ID,
343
+ this.strategyConfig,
344
+ DEFAULT_INTENT_TTL_MS,
345
+ );
346
+ warpCoreConfig = buildWarpRouteConfig(deployedAddresses);
347
+ }
348
+
349
+ const contextFactory = await RebalancerContextFactory.create(
350
+ rebalancerConfig,
351
+ workingMultiProvider,
352
+ mpp,
353
+ registry,
354
+ this.logger,
355
+ undefined,
356
+ warpCoreConfig,
357
+ );
358
+
359
+ const strategy = await contextFactory.createStrategy();
360
+ const { tracker, adapter } =
361
+ await contextFactory.createActionTracker(mockExplorer);
362
+
363
+ await tracker.initialize();
364
+ this.logger.info('ActionTracker initialized with mock explorer');
365
+
366
+ const isAnyInventoryMode = isInventoryMode || isErc20InventoryMode;
367
+ const externalBridgeRegistryOverride =
368
+ isAnyInventoryMode && this.mockExternalBridge
369
+ ? ({
370
+ [ExternalBridgeType.LiFi]: this.mockExternalBridge,
371
+ } as Partial<ExternalBridgeRegistry>)
372
+ : undefined;
373
+ const rebalancerComponents =
374
+ this.executionMode === 'execute' || isAnyInventoryMode
375
+ ? await contextFactory.createRebalancers(
376
+ tracker,
377
+ undefined,
378
+ externalBridgeRegistryOverride,
379
+ )
380
+ : undefined;
381
+ const rebalancers =
382
+ this.executionMode === 'execute'
383
+ ? (rebalancerComponents?.rebalancers ?? [])
384
+ : [];
385
+ const inventoryConfig = rebalancerComponents?.inventoryConfig;
386
+ const externalBridgeRegistry = rebalancerComponents?.externalBridgeRegistry;
387
+
388
+ const orchestratorDeps: RebalancerOrchestratorDeps = {
389
+ strategy,
390
+ rebalancers,
391
+ actionTracker: tracker,
392
+ inflightContextAdapter: adapter,
393
+ rebalancerConfig,
394
+ externalBridgeRegistry,
395
+ logger: this.logger,
396
+ };
397
+ const orchestrator = new RebalancerOrchestrator(orchestratorDeps);
398
+
399
+ return {
400
+ orchestrator,
401
+ strategy,
402
+ tracker,
403
+ mockExplorer,
404
+ forkIndexer,
405
+ multiProvider: workingMultiProvider,
406
+ rebalancerConfig,
407
+ contextFactory,
408
+ inventoryConfig,
409
+ createMonitor: (checkFrequency: number) =>
410
+ contextFactory.createMonitor(checkFrequency, inventoryConfig),
411
+ getConfirmedBlockTags: () => this.computeConfirmedBlockTags(),
412
+ };
413
+ }
414
+
415
+ private getBalanceChains(): string[] {
416
+ if (typeof this.balanceConfig === 'string') {
417
+ return Object.keys(BALANCE_PRESETS[this.balanceConfig]);
418
+ }
419
+ return Object.keys(this.balanceConfig);
420
+ }
421
+
422
+ private getBalances(): Record<string, BigNumber> {
423
+ if (typeof this.balanceConfig === 'string') {
424
+ const preset = BALANCE_PRESETS[this.balanceConfig];
425
+ return Object.fromEntries(
426
+ Object.entries(preset).map(([chain, value]) => [
427
+ chain,
428
+ BigNumber.from(value),
429
+ ]),
430
+ ) as Record<string, BigNumber>;
431
+ }
432
+ return this.balanceConfig;
433
+ }
434
+
435
+ private async setupBalances(): Promise<void> {
436
+ const balances = this.getBalances();
437
+ const ctx = this.deploymentManager.getContext();
438
+ const { providers: localProviders } = ctx;
439
+
440
+ if (this.inventoryConfig) {
441
+ for (const [chain, balance] of Object.entries(balances)) {
442
+ const provider = localProviders.get(chain);
443
+ const monitoredRouteAddress =
444
+ this.inventoryConfig.nativeDeployedAddresses.monitoredRoute[
445
+ chain as TestChain
446
+ ];
447
+ if (!provider) {
448
+ throw new Error(
449
+ `Missing local provider for inventory chain ${chain}`,
450
+ );
451
+ }
452
+ if (!monitoredRouteAddress) {
453
+ throw new Error(
454
+ `Missing monitored route address for inventory chain ${chain}`,
455
+ );
456
+ }
457
+
458
+ await provider.send('anvil_setBalance', [
459
+ monitoredRouteAddress,
460
+ ethers.utils.hexValue(balance),
461
+ ]);
462
+ }
463
+
464
+ this.logger.info(
465
+ {
466
+ balances: Object.fromEntries(
467
+ Object.entries(balances).map(([chain, balance]) => [
468
+ chain,
469
+ balance.toString(),
470
+ ]),
471
+ ),
472
+ },
473
+ 'Inventory balances configured on monitored routes',
474
+ );
475
+ await this.setupInventorySignerBalances(localProviders);
476
+ return;
477
+ }
478
+
479
+ if (this.erc20InventoryConfig) {
480
+ for (const [chain, balance] of Object.entries(balances)) {
481
+ const provider = localProviders.get(chain);
482
+ const tokenAddress: string | undefined =
483
+ this.erc20InventoryConfig.erc20DeployedAddresses.tokens[
484
+ chain as TestChain
485
+ ];
486
+ const monitoredRouteAddress: string | undefined =
487
+ this.erc20InventoryConfig.erc20DeployedAddresses.monitoredRoute[
488
+ chain as TestChain
489
+ ];
490
+ assert(provider, `setupBalances: missing provider for chain ${chain}`);
491
+ assert(
492
+ tokenAddress,
493
+ `setupBalances: missing token address for chain ${chain}`,
494
+ );
495
+ assert(
496
+ monitoredRouteAddress,
497
+ `setupBalances: missing monitored route address for chain ${chain}`,
498
+ );
499
+
500
+ const deployerSigner = new ethers.Wallet(
501
+ ANVIL_TEST_PRIVATE_KEY,
502
+ provider,
503
+ );
504
+ const token = ERC20Test__factory.connect(tokenAddress, deployerSigner);
505
+ const tx = await token.transfer(monitoredRouteAddress, balance);
506
+ await tx.wait();
507
+ }
508
+
509
+ this.logger.info(
510
+ {
511
+ balances: Object.fromEntries(
512
+ Object.entries(balances).map(([chain, balance]) => [
513
+ chain,
514
+ balance.toString(),
515
+ ]),
516
+ ),
517
+ },
518
+ 'ERC20 inventory balances configured on monitored routes',
519
+ );
520
+ await this.setupInventorySignerBalances(localProviders);
521
+ return;
522
+ }
523
+
524
+ const deployedAddresses = ctx.deployedAddresses;
525
+ if (!('tokens' in deployedAddresses)) {
526
+ throw new Error('Expected ERC20 deployed addresses with tokens field');
527
+ }
528
+
529
+ await setupCollateralBalances(
530
+ localProviders,
531
+ balances,
532
+ deployedAddresses.monitoredRoute,
533
+ deployedAddresses.tokens,
534
+ ANVIL_TEST_PRIVATE_KEY,
535
+ );
536
+
537
+ this.logger.info(
538
+ {
539
+ balances: Object.fromEntries(
540
+ Object.entries(balances).map(([chain, balance]) => [
541
+ chain,
542
+ balance.toString(),
543
+ ]),
544
+ ),
545
+ },
546
+ 'Collateral balances configured',
547
+ );
548
+ }
549
+
550
+ private getInventorySignerAddress(): string {
551
+ const config = this.inventoryConfig ?? this.erc20InventoryConfig;
552
+ assert(config, 'Expected inventoryConfig or erc20InventoryConfig');
553
+ return new ethers.Wallet(config.inventorySignerKey).address;
554
+ }
555
+
556
+ private async setupInventorySignerBalances(
557
+ localProviders: Map<string, ethers.providers.JsonRpcProvider>,
558
+ ): Promise<void> {
559
+ if (
560
+ !this.inventorySignerBalanceConfig ||
561
+ (!this.inventoryConfig && !this.erc20InventoryConfig)
562
+ ) {
563
+ return;
564
+ }
565
+
566
+ const signerAddress = this.getInventorySignerAddress();
567
+
568
+ let balances: Partial<Record<string, string>>;
569
+ if (typeof this.inventorySignerBalanceConfig === 'string') {
570
+ balances = INVENTORY_SIGNER_PRESETS[this.inventorySignerBalanceConfig];
571
+ } else {
572
+ balances = Object.fromEntries(
573
+ Object.entries(this.inventorySignerBalanceConfig)
574
+ .filter(
575
+ (entry): entry is [string, BigNumber] => entry[1] !== undefined,
576
+ )
577
+ .map(([chain, val]) => [chain, val.toString()]),
578
+ );
579
+ }
580
+
581
+ if (this.erc20InventoryConfig) {
582
+ const signerWallet = new ethers.Wallet(
583
+ this.erc20InventoryConfig.inventorySignerKey,
584
+ );
585
+ const deployerKey = ANVIL_TEST_PRIVATE_KEY;
586
+ const tokens = this.erc20InventoryConfig.erc20DeployedAddresses.tokens;
587
+
588
+ for (const [chain, balance] of Object.entries(balances)) {
589
+ const provider = localProviders.get(chain);
590
+ assert(
591
+ balance !== undefined,
592
+ `setupInventorySignerBalances: missing balance for chain ${chain}`,
593
+ );
594
+ assert(
595
+ provider,
596
+ `setupInventorySignerBalances: missing provider for chain ${chain}`,
597
+ );
598
+
599
+ const tokenAddress = tokens[chain as TestChain];
600
+ assert(
601
+ tokenAddress,
602
+ `setupInventorySignerBalances: missing token address for chain ${chain}`,
603
+ );
604
+
605
+ const connectedSigner = signerWallet.connect(provider);
606
+ const deployerSigner = new ethers.Wallet(deployerKey, provider);
607
+ const tokenAsSigner = ERC20Test__factory.connect(
608
+ tokenAddress,
609
+ connectedSigner,
610
+ );
611
+ const tokenAsDeployer = ERC20Test__factory.connect(
612
+ tokenAddress,
613
+ deployerSigner,
614
+ );
615
+
616
+ const current = await tokenAsSigner.balanceOf(signerAddress);
617
+ if (current.gt(0)) {
618
+ const tx1 = await tokenAsSigner.transfer(
619
+ deployerSigner.address,
620
+ current,
621
+ );
622
+ await tx1.wait();
623
+ }
624
+
625
+ if (BigNumber.from(balance).gt(0)) {
626
+ const tx2 = await tokenAsDeployer.transfer(
627
+ signerAddress,
628
+ BigNumber.from(balance),
629
+ );
630
+ await tx2.wait();
631
+ }
632
+ }
633
+
634
+ this.logger.info(
635
+ { balances, signer: signerWallet.address },
636
+ 'ERC20 inventory signer balances configured',
637
+ );
638
+ return;
639
+ }
640
+
641
+ for (const [chain, balance] of Object.entries(balances)) {
642
+ const provider = localProviders.get(chain);
643
+ if (balance === undefined) {
644
+ continue;
645
+ }
646
+ if (!provider) {
647
+ throw new Error(
648
+ `Missing local provider for inventory signer chain ${chain}`,
649
+ );
650
+ }
651
+
652
+ await provider.send('anvil_setBalance', [
653
+ signerAddress,
654
+ ethers.utils.hexValue(BigNumber.from(balance)),
655
+ ]);
656
+ }
657
+
658
+ this.logger.info(
659
+ { balances, signer: signerAddress },
660
+ 'Inventory signer balances configured',
661
+ );
662
+ }
663
+
664
+ private buildMockExplorerConfig(): MockExplorerConfig {
665
+ const monitoredRoute = this.getMonitoredRouteAddresses();
666
+ const userTransfers: ExplorerMessage[] = [...this.mockTransfers];
667
+
668
+ for (let i = 0; i < this.pendingTransfers.length; i++) {
669
+ const params = this.pendingTransfers[i];
670
+ const warpRecipient = params.warpRecipient ?? monitoredRoute[params.to];
671
+
672
+ const mockTransfer: ExplorerMessage = {
673
+ msg_id: `0x${(1000 + i).toString(16).padStart(64, '0')}`,
674
+ origin_domain_id: DOMAIN_IDS[params.from],
675
+ destination_domain_id: DOMAIN_IDS[params.to],
676
+ sender: monitoredRoute[params.from],
677
+ recipient: monitoredRoute[params.to],
678
+ origin_tx_hash: `0x${(2000 + i).toString(16).padStart(64, '0')}`,
679
+ origin_tx_sender: `0x${(3000 + i).toString(16).padStart(40, '0')}`,
680
+ origin_tx_recipient: monitoredRoute[params.from],
681
+ is_delivered: false,
682
+ message_body: encodeWarpRouteMessageBody(warpRecipient, params.amount),
683
+ send_occurred_at: null,
684
+ };
685
+
686
+ userTransfers.push(mockTransfer);
687
+
688
+ this.logger.debug(
689
+ {
690
+ transfer: {
691
+ from: params.from,
692
+ to: params.to,
693
+ origin: mockTransfer.origin_domain_id,
694
+ destination: mockTransfer.destination_domain_id,
695
+ amount: params.amount.toString(),
696
+ },
697
+ },
698
+ 'Created mock pending transfer',
699
+ );
700
+ }
701
+
702
+ return {
703
+ userTransfers,
704
+ rebalanceActions: [],
705
+ };
706
+ }
707
+
708
+ private getMonitoredRouteAddresses(): Record<TestChain, string> {
709
+ if (this.erc20InventoryConfig) {
710
+ return this.erc20InventoryConfig.erc20DeployedAddresses.monitoredRoute;
711
+ }
712
+
713
+ if (this.inventoryConfig) {
714
+ return this.inventoryConfig.nativeDeployedAddresses.monitoredRoute;
715
+ }
716
+
717
+ const deployedAddresses =
718
+ this.deploymentManager.getContext().deployedAddresses;
719
+ if (!('tokens' in deployedAddresses)) {
720
+ throw new Error('Expected ERC20 deployed addresses with tokens field');
721
+ }
722
+ return deployedAddresses.monitoredRoute;
723
+ }
724
+
725
+ private async getWorkingMultiProvider(): Promise<MultiProvider> {
726
+ if (this.executionMode === 'propose') {
727
+ return this.multiProvider;
728
+ }
729
+
730
+ const ctx = this.deploymentManager.getContext();
731
+ const rebalancerMultiProvider = this.multiProvider.extendChainMetadata({});
732
+
733
+ const wallet = new ethers.Wallet(ANVIL_TEST_PRIVATE_KEY);
734
+ for (const chain of TEST_CHAINS) {
735
+ const provider = ctx.providers.get(chain);
736
+ if (provider) {
737
+ rebalancerMultiProvider.setSigner(chain, wallet.connect(provider));
738
+ }
739
+ }
740
+
741
+ this.logger.info(
742
+ 'Created MultiProvider with deployer as rebalancer for execute mode',
743
+ );
744
+
745
+ return rebalancerMultiProvider;
746
+ }
747
+ }
748
+
749
+ export class TestRebalancer {
750
+ static builder(
751
+ deploymentManager: BaseLocalDeploymentManager<
752
+ DeployedAddresses | NativeDeployedAddresses
753
+ >,
754
+ multiProvider: MultiProvider,
755
+ ): TestRebalancerBuilder {
756
+ return new TestRebalancerBuilder(deploymentManager, multiProvider);
757
+ }
758
+ }