@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,728 @@
1
+ import { expect } from 'chai';
2
+ import { pino } from 'pino';
3
+
4
+ import {
5
+ type ChainMap,
6
+ type ChainName,
7
+ Token,
8
+ TokenStandard,
9
+ } from '@humanode-hyperlane/sdk';
10
+ import type { Address } from '@humanode-hyperlane/utils';
11
+
12
+ import { ExternalBridgeType } from '../config/types.js';
13
+ import type {
14
+ InventoryRoute,
15
+ RawBalances,
16
+ Route,
17
+ StrategyRoute,
18
+ } from '../interfaces/IStrategy.js';
19
+ import { extractBridgeConfigs } from '../test/helpers.js';
20
+ import type { BridgeConfigWithOverride } from '../utils/bridgeUtils.js';
21
+
22
+ import { CollateralDeficitStrategy } from './CollateralDeficitStrategy.js';
23
+
24
+ const testLogger = pino({ level: 'silent' });
25
+
26
+ const BRIDGE1 = '0x1234567890123456789012345678901234567890' as Address;
27
+ const BRIDGE2 = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd' as Address;
28
+ const OTHER_BRIDGE = '0x9876543210987654321098765432109876543210' as Address;
29
+
30
+ describe('CollateralDeficitStrategy', () => {
31
+ let chain1: ChainName;
32
+ let chain2: ChainName;
33
+ let chain3: ChainName;
34
+ const tokensByChainName: ChainMap<Token> = {};
35
+ const tokenArgs = {
36
+ name: 'USDC',
37
+ decimals: 6, // USDC has 6 decimals
38
+ symbol: 'USDC',
39
+ standard: TokenStandard.ERC20,
40
+ addressOrDenom: '',
41
+ };
42
+
43
+ beforeEach(() => {
44
+ chain1 = 'chain1';
45
+ chain2 = 'chain2';
46
+ chain3 = 'chain3';
47
+ tokensByChainName[chain1] = new Token({ ...tokenArgs, chainName: chain1 });
48
+ tokensByChainName[chain2] = new Token({ ...tokenArgs, chainName: chain2 });
49
+ tokensByChainName[chain3] = new Token({ ...tokenArgs, chainName: chain3 });
50
+ });
51
+
52
+ describe('constructor', () => {
53
+ it('should throw an error when less than two chains are configured', () => {
54
+ expect(
55
+ () =>
56
+ new CollateralDeficitStrategy(
57
+ {
58
+ [chain1]: {
59
+ bridge: BRIDGE1,
60
+ buffer: '1000',
61
+ },
62
+ },
63
+ tokensByChainName,
64
+ testLogger,
65
+ {},
66
+ ),
67
+ ).to.throw('At least two chains must be configured');
68
+ });
69
+
70
+ it('should create a strategy with valid config', () => {
71
+ const strategy = new CollateralDeficitStrategy(
72
+ {
73
+ [chain1]: {
74
+ bridge: BRIDGE1,
75
+ buffer: '1000',
76
+ },
77
+ [chain2]: {
78
+ bridge: BRIDGE2,
79
+ buffer: '500',
80
+ },
81
+ },
82
+ tokensByChainName,
83
+ testLogger,
84
+ {},
85
+ );
86
+ expect(strategy).to.be.instanceOf(CollateralDeficitStrategy);
87
+ });
88
+ });
89
+
90
+ describe('getCategorizedBalances', () => {
91
+ it('should detect deficit when balance is negative and add buffer', () => {
92
+ const strategy = new CollateralDeficitStrategy(
93
+ {
94
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
95
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
96
+ },
97
+ tokensByChainName,
98
+ testLogger,
99
+ {},
100
+ );
101
+
102
+ const rawBalances: RawBalances = {
103
+ [chain1]: -5_000_000n, // -5 USDC (6 decimals)
104
+ [chain2]: 10_000_000n, // 10 USDC
105
+ };
106
+
107
+ const result = strategy['getCategorizedBalances'](rawBalances);
108
+
109
+ // chain1: deficit = |-5 USDC| + 1000 USDC = 1005 USDC = 1005000000 (wei)
110
+ expect(result.deficits).to.have.lengthOf(1);
111
+ expect(result.deficits[0].chain).to.equal(chain1);
112
+ expect(result.deficits[0].amount).to.equal(1_005_000_000n);
113
+
114
+ // chain2: surplus = 10 USDC
115
+ expect(result.surpluses).to.have.lengthOf(1);
116
+ expect(result.surpluses[0].chain).to.equal(chain2);
117
+ expect(result.surpluses[0].amount).to.equal(10_000_000n);
118
+ });
119
+
120
+ it('should treat zero balance as neither surplus nor deficit', () => {
121
+ const strategy = new CollateralDeficitStrategy(
122
+ {
123
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
124
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
125
+ },
126
+ tokensByChainName,
127
+ testLogger,
128
+ {},
129
+ );
130
+
131
+ const rawBalances: RawBalances = {
132
+ [chain1]: 0n,
133
+ [chain2]: 10_000_000n,
134
+ };
135
+
136
+ const result = strategy['getCategorizedBalances'](rawBalances);
137
+
138
+ expect(result.deficits).to.have.lengthOf(0);
139
+ expect(result.surpluses).to.have.lengthOf(1);
140
+ expect(result.surpluses[0].chain).to.equal(chain2);
141
+ });
142
+
143
+ it('should treat positive balance as surplus', () => {
144
+ const strategy = new CollateralDeficitStrategy(
145
+ {
146
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
147
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
148
+ },
149
+ tokensByChainName,
150
+ testLogger,
151
+ {},
152
+ );
153
+
154
+ const rawBalances: RawBalances = {
155
+ [chain1]: 5_000_000n, // 5 USDC
156
+ [chain2]: 10_000_000n, // 10 USDC
157
+ };
158
+
159
+ const result = strategy['getCategorizedBalances'](rawBalances);
160
+
161
+ expect(result.deficits).to.have.lengthOf(0);
162
+ expect(result.surpluses).to.have.lengthOf(2);
163
+ });
164
+
165
+ it('should filter pending rebalances by configured bridges and simulate', () => {
166
+ const config = {
167
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
168
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
169
+ };
170
+ const bridgeConfigs = extractBridgeConfigs(config);
171
+
172
+ const strategy = new CollateralDeficitStrategy(
173
+ config,
174
+ tokensByChainName,
175
+ testLogger,
176
+ bridgeConfigs,
177
+ );
178
+
179
+ const rawBalances: RawBalances = {
180
+ [chain1]: -10_000_000n, // -10 USDC before simulation
181
+ [chain2]: 20_000_000n, // 20 USDC
182
+ };
183
+
184
+ const pendingRebalances: StrategyRoute[] = [
185
+ {
186
+ origin: chain2,
187
+ destination: chain1,
188
+ amount: 5_000_000n, // 5 USDC pending to chain1
189
+ executionType: 'movableCollateral',
190
+ bridge: BRIDGE2, // Matches chain2's bridge for chain2->chain1 route
191
+ },
192
+ ];
193
+
194
+ const result = strategy['getCategorizedBalances'](
195
+ rawBalances,
196
+ pendingRebalances,
197
+ );
198
+
199
+ // After simulation: chain1 = -10 + 5 = -5 USDC (destination increase)
200
+ // Deficit = |-5| + 1000 = 1005 USDC
201
+ expect(result.deficits).to.have.lengthOf(1);
202
+ expect(result.deficits[0].chain).to.equal(chain1);
203
+ expect(result.deficits[0].amount).to.equal(1_005_000_000n);
204
+
205
+ // chain2 after simulation: 20 USDC (no change - origin already deducted on-chain)
206
+ // Simulation only adds to destination, doesn't subtract from origin
207
+ expect(result.surpluses).to.have.lengthOf(1);
208
+ expect(result.surpluses[0].chain).to.equal(chain2);
209
+ expect(result.surpluses[0].amount).to.equal(20_000_000n);
210
+ });
211
+
212
+ it('should filter out pending rebalances with different bridge', () => {
213
+ const config = {
214
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
215
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
216
+ };
217
+ const bridgeConfigs = extractBridgeConfigs(config);
218
+
219
+ const strategy = new CollateralDeficitStrategy(
220
+ config,
221
+ tokensByChainName,
222
+ testLogger,
223
+ bridgeConfigs,
224
+ );
225
+
226
+ const rawBalances: RawBalances = {
227
+ [chain1]: -10_000_000n,
228
+ [chain2]: 20_000_000n,
229
+ };
230
+
231
+ const pendingRebalances: StrategyRoute[] = [
232
+ {
233
+ origin: chain2,
234
+ destination: chain1,
235
+ amount: 5_000_000n,
236
+ executionType: 'movableCollateral',
237
+ bridge: OTHER_BRIDGE, // Does NOT match chain2's configured bridge for chain2->chain1
238
+ },
239
+ ];
240
+
241
+ const result = strategy['getCategorizedBalances'](
242
+ rawBalances,
243
+ pendingRebalances,
244
+ );
245
+
246
+ // Pending rebalance should be filtered out, so no simulation
247
+ // Deficit = |-10| + 1000 = 1010 USDC
248
+ expect(result.deficits).to.have.lengthOf(1);
249
+ expect(result.deficits[0].amount).to.equal(1_010_000_000n);
250
+
251
+ // chain2: no subtraction, stays at 20 USDC
252
+ expect(result.surpluses[0].amount).to.equal(20_000_000n);
253
+ });
254
+
255
+ it('should handle pending rebalance that fully covers deficit', () => {
256
+ const config = {
257
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
258
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
259
+ };
260
+ const bridgeConfigs = extractBridgeConfigs(config);
261
+
262
+ const strategy = new CollateralDeficitStrategy(
263
+ config,
264
+ tokensByChainName,
265
+ testLogger,
266
+ bridgeConfigs,
267
+ );
268
+
269
+ const rawBalances: RawBalances = {
270
+ [chain1]: -5_000_000n, // -5 USDC
271
+ [chain2]: 20_000_000n,
272
+ };
273
+
274
+ const pendingRebalances: StrategyRoute[] = [
275
+ {
276
+ origin: chain2,
277
+ destination: chain1,
278
+ amount: 10_000_000n, // 10 USDC pending - more than enough
279
+ executionType: 'movableCollateral',
280
+ bridge: BRIDGE2, // Matches chain2's configured bridge for chain2->chain1
281
+ },
282
+ ];
283
+
284
+ const result = strategy['getCategorizedBalances'](
285
+ rawBalances,
286
+ pendingRebalances,
287
+ );
288
+
289
+ // After simulation: chain1 = -5 + 10 = 5 USDC (positive, no deficit)
290
+ expect(result.deficits).to.have.lengthOf(0);
291
+ expect(result.surpluses).to.have.lengthOf(2); // Both chains have surplus
292
+ });
293
+
294
+ it('should handle multiple chains with mixed balances', () => {
295
+ const strategy = new CollateralDeficitStrategy(
296
+ {
297
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
298
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
299
+ [chain3]: { bridge: BRIDGE1, buffer: '2000' },
300
+ },
301
+ tokensByChainName,
302
+ testLogger,
303
+ {},
304
+ );
305
+
306
+ const rawBalances: RawBalances = {
307
+ [chain1]: -5_000_000n, // -5 USDC -> deficit
308
+ [chain2]: 10_000_000n, // 10 USDC -> surplus
309
+ [chain3]: -3_000_000n, // -3 USDC -> deficit
310
+ };
311
+
312
+ const result = strategy['getCategorizedBalances'](rawBalances);
313
+
314
+ expect(result.deficits).to.have.lengthOf(2);
315
+ expect(result.surpluses).to.have.lengthOf(1);
316
+
317
+ // chain1: deficit = 5 + 1000 = 1005 USDC
318
+ const chain1Deficit = result.deficits.find((d) => d.chain === chain1);
319
+ expect(chain1Deficit?.amount).to.equal(1_005_000_000n);
320
+
321
+ // chain3: deficit = 3 + 2000 = 2003 USDC
322
+ const chain3Deficit = result.deficits.find((d) => d.chain === chain3);
323
+ expect(chain3Deficit?.amount).to.equal(2_003_000_000n);
324
+ });
325
+
326
+ it('should handle empty pending rebalances array', () => {
327
+ const strategy = new CollateralDeficitStrategy(
328
+ {
329
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
330
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
331
+ },
332
+ tokensByChainName,
333
+ testLogger,
334
+ {},
335
+ );
336
+
337
+ const rawBalances: RawBalances = {
338
+ [chain1]: -5_000_000n,
339
+ [chain2]: 10_000_000n,
340
+ };
341
+
342
+ const result = strategy['getCategorizedBalances'](rawBalances, []);
343
+
344
+ // No simulation should occur
345
+ expect(result.deficits).to.have.lengthOf(1);
346
+ expect(result.deficits[0].amount).to.equal(1_005_000_000n);
347
+ });
348
+ });
349
+
350
+ describe('getRebalancingRoutes', () => {
351
+ it('should set bridge field on output routes', () => {
352
+ const config = {
353
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
354
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
355
+ };
356
+ const bridgeConfigs = extractBridgeConfigs(config);
357
+
358
+ const strategy = new CollateralDeficitStrategy(
359
+ config,
360
+ tokensByChainName,
361
+ testLogger,
362
+ bridgeConfigs,
363
+ );
364
+
365
+ // Start with positive balances
366
+ const rawBalances: RawBalances = {
367
+ [chain1]: 2_000_000n, // 2 USDC
368
+ [chain2]: 20_000_000n, // 20 USDC
369
+ };
370
+
371
+ // Pending transfer will drain chain1 to create deficit
372
+ const inflightContext = {
373
+ pendingTransfers: [
374
+ {
375
+ origin: chain2,
376
+ destination: chain1,
377
+ amount: 7_000_000n, // 7 USDC pending to chain1
378
+ },
379
+ ],
380
+ pendingRebalances: [] as StrategyRoute[],
381
+ };
382
+
383
+ // After reserveCollateral: chain1 = 2 - 7 = -5 USDC (deficit)
384
+ const routes = strategy.getRebalancingRoutes(
385
+ rawBalances,
386
+ inflightContext,
387
+ );
388
+
389
+ expect(routes).to.have.lengthOf(1);
390
+ expect(routes[0].origin).to.equal(chain2);
391
+ expect(routes[0].destination).to.equal(chain1);
392
+ if (routes[0].executionType === 'movableCollateral') {
393
+ expect(routes[0].bridge).to.equal(BRIDGE2); // Uses chain2's (origin) bridge
394
+ }
395
+ });
396
+
397
+ it('should generate routes from surplus to deficit chains', () => {
398
+ const config = {
399
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
400
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
401
+ [chain3]: { bridge: BRIDGE1, buffer: '100' },
402
+ };
403
+ const bridgeConfigs = extractBridgeConfigs(config);
404
+
405
+ const strategy = new CollateralDeficitStrategy(
406
+ config,
407
+ tokensByChainName,
408
+ testLogger,
409
+ bridgeConfigs,
410
+ );
411
+
412
+ // Start with positive balances
413
+ const rawBalances: RawBalances = {
414
+ [chain1]: 5_000_000n, // 5 USDC
415
+ [chain2]: 20_000_000n, // 20 USDC
416
+ [chain3]: 5_000_000n, // 5 USDC
417
+ };
418
+
419
+ // Pending transfer will create deficit on chain1
420
+ const inflightContext = {
421
+ pendingTransfers: [
422
+ {
423
+ origin: chain2,
424
+ destination: chain1,
425
+ amount: 15_000_000n, // 15 USDC pending to chain1
426
+ },
427
+ ],
428
+ pendingRebalances: [] as StrategyRoute[],
429
+ };
430
+
431
+ // After reserveCollateral: chain1 = 5 - 15 = -10 USDC (deficit)
432
+ const routes = strategy.getRebalancingRoutes(
433
+ rawBalances,
434
+ inflightContext,
435
+ );
436
+
437
+ // Should have route(s) from surplus chains (chain2, chain3) to deficit chain (chain1)
438
+ expect(routes.length).to.be.greaterThan(0);
439
+ routes.forEach((route) => {
440
+ expect([chain2, chain3]).to.include(route.origin);
441
+ expect(route.destination).to.equal(chain1);
442
+ });
443
+ });
444
+ });
445
+
446
+ describe('filterByConfiguredBridges', () => {
447
+ it('should filter rebalances by configured bridge for route', () => {
448
+ const config = {
449
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
450
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
451
+ };
452
+ const bridgeConfigs = extractBridgeConfigs(config);
453
+
454
+ const strategy = new CollateralDeficitStrategy(
455
+ config,
456
+ tokensByChainName,
457
+ testLogger,
458
+ bridgeConfigs,
459
+ );
460
+
461
+ const pendingRebalances: Array<Route & { bridge?: Address }> = [
462
+ {
463
+ origin: chain2,
464
+ destination: chain1,
465
+ amount: 5_000_000n,
466
+ bridge: BRIDGE2,
467
+ },
468
+ {
469
+ origin: chain1,
470
+ destination: chain2,
471
+ amount: 3_000_000n,
472
+ bridge: OTHER_BRIDGE,
473
+ },
474
+ {
475
+ origin: chain2,
476
+ destination: chain1,
477
+ amount: 2_000_000n,
478
+ },
479
+ ];
480
+
481
+ const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
482
+
483
+ expect(filtered).to.have.lengthOf(2);
484
+ expect((filtered[0] as Route & { bridge?: Address }).bridge).to.equal(
485
+ BRIDGE2,
486
+ );
487
+ expect((filtered[1] as Route & { bridge?: Address }).bridge).to.be
488
+ .undefined;
489
+ });
490
+
491
+ it('should include rebalance when bridge matches configured bridge for the route', () => {
492
+ const config = {
493
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
494
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
495
+ };
496
+ const bridgeConfigs = extractBridgeConfigs(config);
497
+
498
+ const strategy = new CollateralDeficitStrategy(
499
+ config,
500
+ tokensByChainName,
501
+ testLogger,
502
+ bridgeConfigs,
503
+ );
504
+
505
+ const pendingRebalances: Array<Route & { bridge?: Address }> = [
506
+ {
507
+ origin: chain2,
508
+ destination: chain1,
509
+ amount: 5_000_000n,
510
+ bridge: BRIDGE2,
511
+ },
512
+ ];
513
+
514
+ const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
515
+ expect(filtered).to.have.lengthOf(1);
516
+ expect((filtered[0] as Route & { bridge?: Address }).bridge).to.equal(
517
+ BRIDGE2,
518
+ );
519
+ });
520
+
521
+ it('should exclude rebalance when bridge does not match configured bridge for the route', () => {
522
+ const config = {
523
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
524
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
525
+ };
526
+ const bridgeConfigs = extractBridgeConfigs(config);
527
+
528
+ const strategy = new CollateralDeficitStrategy(
529
+ config,
530
+ tokensByChainName,
531
+ testLogger,
532
+ bridgeConfigs,
533
+ );
534
+
535
+ // Route from chain2 → chain1 with a different bridge
536
+ const pendingRebalances: StrategyRoute[] = [
537
+ {
538
+ origin: chain2,
539
+ destination: chain1,
540
+ amount: 5_000_000n,
541
+ executionType: 'movableCollateral',
542
+ bridge: BRIDGE1, // Does NOT match configured bridge for chain2->chain1 (should be BRIDGE2)
543
+ },
544
+ ];
545
+
546
+ const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
547
+ expect(filtered).to.have.lengthOf(0);
548
+ });
549
+
550
+ it('should return empty array for undefined pending rebalances', () => {
551
+ const strategy = new CollateralDeficitStrategy(
552
+ {
553
+ [chain1]: { bridge: BRIDGE1, buffer: '1000' },
554
+ [chain2]: { bridge: BRIDGE2, buffer: '500' },
555
+ },
556
+ tokensByChainName,
557
+ testLogger,
558
+ {},
559
+ );
560
+
561
+ const filtered = strategy['filterByConfiguredBridges'](undefined);
562
+ expect(filtered).to.have.lengthOf(0);
563
+ });
564
+ });
565
+
566
+ describe('inventory execution type', () => {
567
+ it('should create inventory route when config is inventory type', () => {
568
+ const config = {
569
+ [chain1]: {
570
+ executionType: 'inventory',
571
+ externalBridge: ExternalBridgeType.LiFi,
572
+ buffer: '1000',
573
+ },
574
+ [chain2]: {
575
+ executionType: 'inventory',
576
+ externalBridge: ExternalBridgeType.LiFi,
577
+ buffer: '500',
578
+ },
579
+ };
580
+ const bridgeConfigs: ChainMap<BridgeConfigWithOverride> = {
581
+ [chain1]: {
582
+ executionType: 'inventory',
583
+ externalBridge: ExternalBridgeType.LiFi,
584
+ },
585
+ [chain2]: {
586
+ executionType: 'inventory',
587
+ externalBridge: ExternalBridgeType.LiFi,
588
+ },
589
+ };
590
+
591
+ const strategy = new CollateralDeficitStrategy(
592
+ config as any,
593
+ tokensByChainName,
594
+ testLogger,
595
+ bridgeConfigs,
596
+ );
597
+
598
+ // Start with positive balances
599
+ const rawBalances: RawBalances = {
600
+ [chain1]: 2_000_000n, // 2 USDC
601
+ [chain2]: 20_000_000n, // 20 USDC
602
+ };
603
+
604
+ // Pending transfer will drain chain1 to create deficit
605
+ const inflightContext = {
606
+ pendingTransfers: [
607
+ {
608
+ origin: chain2,
609
+ destination: chain1,
610
+ amount: 7_000_000n, // 7 USDC pending to chain1
611
+ },
612
+ ],
613
+ pendingRebalances: [] as StrategyRoute[],
614
+ };
615
+
616
+ // After reserveCollateral: chain1 = 2 - 7 = -5 USDC (deficit)
617
+ const routes = strategy.getRebalancingRoutes(
618
+ rawBalances,
619
+ inflightContext,
620
+ );
621
+
622
+ expect(routes).to.have.lengthOf(1);
623
+ expect(routes[0].origin).to.equal(chain2);
624
+ expect(routes[0].destination).to.equal(chain1);
625
+ expect(routes[0].executionType).to.equal('inventory');
626
+ expect((routes[0] as InventoryRoute).externalBridge).to.equal(
627
+ ExternalBridgeType.LiFi,
628
+ );
629
+ });
630
+
631
+ it('should include pending inventory rebalances with matching externalBridge in filter', () => {
632
+ const bridgeConfigs: ChainMap<BridgeConfigWithOverride> = {
633
+ [chain1]: {
634
+ executionType: 'inventory',
635
+ externalBridge: ExternalBridgeType.LiFi,
636
+ },
637
+ [chain2]: {
638
+ executionType: 'inventory',
639
+ externalBridge: ExternalBridgeType.LiFi,
640
+ },
641
+ };
642
+
643
+ const config = {
644
+ [chain1]: {
645
+ executionType: 'inventory',
646
+ externalBridge: ExternalBridgeType.LiFi,
647
+ buffer: '1000',
648
+ },
649
+ [chain2]: {
650
+ executionType: 'inventory',
651
+ externalBridge: ExternalBridgeType.LiFi,
652
+ buffer: '500',
653
+ },
654
+ };
655
+
656
+ const strategy = new CollateralDeficitStrategy(
657
+ config as any,
658
+ tokensByChainName,
659
+ testLogger,
660
+ bridgeConfigs,
661
+ );
662
+
663
+ const pendingRebalances: InventoryRoute[] = [
664
+ {
665
+ origin: chain2,
666
+ destination: chain1,
667
+ amount: 5_000_000n,
668
+ executionType: 'inventory',
669
+ externalBridge: ExternalBridgeType.LiFi,
670
+ },
671
+ ];
672
+
673
+ const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
674
+ expect(filtered).to.have.lengthOf(1);
675
+ expect((filtered[0] as InventoryRoute).externalBridge).to.equal(
676
+ ExternalBridgeType.LiFi,
677
+ );
678
+ });
679
+
680
+ it('should exclude pending inventory rebalances with non-matching externalBridge', () => {
681
+ const bridgeConfigs: ChainMap<BridgeConfigWithOverride> = {
682
+ [chain1]: {
683
+ executionType: 'inventory',
684
+ externalBridge: ExternalBridgeType.LiFi,
685
+ },
686
+ [chain2]: {
687
+ executionType: 'inventory',
688
+ externalBridge: ExternalBridgeType.LiFi,
689
+ },
690
+ };
691
+
692
+ const config = {
693
+ [chain1]: {
694
+ executionType: 'inventory',
695
+ externalBridge: ExternalBridgeType.LiFi,
696
+ buffer: '1000',
697
+ },
698
+ [chain2]: {
699
+ executionType: 'inventory',
700
+ externalBridge: ExternalBridgeType.LiFi,
701
+ buffer: '500',
702
+ },
703
+ };
704
+
705
+ const strategy = new CollateralDeficitStrategy(
706
+ config as any,
707
+ tokensByChainName,
708
+ testLogger,
709
+ bridgeConfigs,
710
+ );
711
+
712
+ // Create a route with a different externalBridge value to test mismatch
713
+ // Using type assertion since we're testing the filtering logic
714
+ const pendingRebalances = [
715
+ {
716
+ origin: chain2,
717
+ destination: chain1,
718
+ amount: 5_000_000n,
719
+ executionType: 'inventory' as const,
720
+ externalBridge: 'nonexistent_bridge' as ExternalBridgeType, // Different bridge
721
+ },
722
+ ];
723
+
724
+ const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
725
+ expect(filtered).to.have.lengthOf(0);
726
+ });
727
+ });
728
+ });