@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,477 @@
1
+ import { type PopulatedTransaction, ethers, type providers } from 'ethers';
2
+ import Sinon from 'sinon';
3
+
4
+ import {
5
+ type ChainMap,
6
+ type ChainMetadata,
7
+ type ChainName,
8
+ EvmMovableCollateralAdapter,
9
+ type InterchainGasQuote,
10
+ type MultiProvider,
11
+ type Token,
12
+ type TokenAmount,
13
+ type WarpCore,
14
+ } from '@humanode-hyperlane/sdk';
15
+
16
+ import type { RebalancerConfig } from '../config/RebalancerConfig.js';
17
+ import { RebalancerStrategyOptions } from '../config/types.js';
18
+ import type {
19
+ ExecutionResult,
20
+ IRebalancer,
21
+ MovableCollateralExecutionResult,
22
+ PreparedTransaction,
23
+ RebalancerType,
24
+ } from '../interfaces/IRebalancer.js';
25
+ import type {
26
+ MovableCollateralRoute,
27
+ StrategyRoute,
28
+ } from '../interfaces/IStrategy.js';
29
+ import type { BridgeConfigWithOverride } from '../utils/bridgeUtils.js';
30
+
31
+ // === Mock Classes ===
32
+
33
+ export class MockRebalancer implements IRebalancer {
34
+ readonly rebalancerType: RebalancerType = 'movableCollateral';
35
+
36
+ rebalance(_routes: MovableCollateralRoute[]): Promise<ExecutionResult[]> {
37
+ return Promise.resolve([]);
38
+ }
39
+ }
40
+
41
+ // === Test Data Builders ===
42
+
43
+ export function buildTestRoute(
44
+ overrides: Partial<StrategyRoute> = {},
45
+ executionType: 'movableCollateral' | 'inventory' = 'movableCollateral',
46
+ ): StrategyRoute {
47
+ if (executionType === 'inventory') {
48
+ return {
49
+ origin: 'ethereum',
50
+ destination: 'arbitrum',
51
+ amount: ethers.utils.parseEther('100').toBigInt(),
52
+ executionType: 'inventory',
53
+ externalBridge: 'lifi',
54
+ ...overrides,
55
+ } as StrategyRoute;
56
+ }
57
+ return {
58
+ origin: 'ethereum',
59
+ destination: 'arbitrum',
60
+ amount: ethers.utils.parseEther('100').toBigInt(),
61
+ executionType: 'movableCollateral',
62
+ bridge: TEST_ADDRESSES.bridge,
63
+ ...overrides,
64
+ } as StrategyRoute;
65
+ }
66
+
67
+ export function buildTestMovableCollateralRoute(
68
+ overrides: Partial<MovableCollateralRoute> = {},
69
+ ): MovableCollateralRoute {
70
+ return {
71
+ origin: 'ethereum',
72
+ destination: 'arbitrum',
73
+ amount: ethers.utils.parseEther('100').toBigInt(),
74
+ executionType: 'movableCollateral',
75
+ bridge: TEST_ADDRESSES.bridge,
76
+ ...overrides,
77
+ };
78
+ }
79
+
80
+ export function buildTestResult(
81
+ overrides: Partial<MovableCollateralExecutionResult> = {},
82
+ ): MovableCollateralExecutionResult {
83
+ const route = overrides.route ?? buildTestMovableCollateralRoute();
84
+ return {
85
+ route,
86
+ success: true,
87
+ messageId:
88
+ '0x1111111111111111111111111111111111111111111111111111111111111111',
89
+ txHash:
90
+ '0x2222222222222222222222222222222222222222222222222222222222222222',
91
+ ...overrides,
92
+ };
93
+ }
94
+
95
+ export function buildTestPreparedTransaction(
96
+ overrides: Partial<PreparedTransaction> = {},
97
+ ): PreparedTransaction {
98
+ const route =
99
+ overrides.route ??
100
+ ({
101
+ ...buildTestMovableCollateralRoute(),
102
+ intentId: 'test-intent',
103
+ } as MovableCollateralRoute & { intentId: string });
104
+ return {
105
+ populatedTx: {
106
+ to: TEST_ADDRESSES.token,
107
+ data: '0x',
108
+ value: ethers.BigNumber.from(0),
109
+ } as PopulatedTransaction,
110
+ route,
111
+ originTokenAmount: createMockTokenAmount(route.amount),
112
+ ...overrides,
113
+ };
114
+ }
115
+
116
+ // === Mock Factories ===
117
+
118
+ export function createMockTokenAmount(amount: bigint): TokenAmount {
119
+ return {
120
+ amount,
121
+ token: {
122
+ name: 'TestToken',
123
+ symbol: 'TEST',
124
+ decimals: 18,
125
+ addressOrDenom: TEST_ADDRESSES.token,
126
+ },
127
+ getDecimalFormattedAmount: () => ethers.utils.formatEther(amount),
128
+ } as unknown as TokenAmount;
129
+ }
130
+
131
+ export interface MockAdapterConfig {
132
+ isRebalancer?: boolean;
133
+ allowedDestination?: string;
134
+ isBridgeAllowed?: boolean;
135
+ quotes?: InterchainGasQuote[];
136
+ populatedTx?: PopulatedTransaction;
137
+ throwOnQuotes?: Error;
138
+ throwOnPopulate?: Error;
139
+ }
140
+
141
+ export function createMockAdapter(config: MockAdapterConfig = {}) {
142
+ const {
143
+ isRebalancer = true,
144
+ allowedDestination = TEST_ADDRESSES.arbitrum,
145
+ isBridgeAllowed = true,
146
+ quotes = [{ igpQuote: { amount: BigInt(1000000) } }],
147
+ populatedTx = {
148
+ to: TEST_ADDRESSES.token,
149
+ data: '0x',
150
+ value: ethers.BigNumber.from(0),
151
+ },
152
+ throwOnQuotes,
153
+ throwOnPopulate,
154
+ } = config;
155
+
156
+ const adapter = {
157
+ isRebalancer: Sinon.stub().resolves(isRebalancer),
158
+ getAllowedDestination: Sinon.stub().resolves(allowedDestination),
159
+ isBridgeAllowed: Sinon.stub().resolves(isBridgeAllowed),
160
+ getRebalanceQuotes: throwOnQuotes
161
+ ? Sinon.stub().rejects(throwOnQuotes)
162
+ : Sinon.stub().resolves(quotes),
163
+ populateRebalanceTx: throwOnPopulate
164
+ ? Sinon.stub().rejects(throwOnPopulate)
165
+ : Sinon.stub().resolves(populatedTx),
166
+ };
167
+
168
+ Object.setPrototypeOf(adapter, EvmMovableCollateralAdapter.prototype);
169
+ return adapter;
170
+ }
171
+
172
+ export interface MockTokenConfig {
173
+ name?: string;
174
+ decimals?: number;
175
+ addressOrDenom?: string;
176
+ adapter?: ReturnType<typeof createMockAdapter>;
177
+ }
178
+
179
+ export function createMockToken(config: MockTokenConfig = {}) {
180
+ const {
181
+ name = 'TestToken',
182
+ decimals = 18,
183
+ addressOrDenom = TEST_ADDRESSES.token,
184
+ adapter = createMockAdapter(),
185
+ } = config;
186
+
187
+ const token = {
188
+ name,
189
+ decimals,
190
+ addressOrDenom,
191
+ amount: (amt: bigint) => createMockTokenAmount(amt),
192
+ getHypAdapter: Sinon.stub().returns(adapter),
193
+ };
194
+
195
+ return { token, adapter };
196
+ }
197
+
198
+ export interface MockMultiProviderConfig {
199
+ chainMetadata?: ChainMap<Partial<ChainMetadata>>;
200
+ signerAddress?: string;
201
+ sendTransactionReceipt?: providers.TransactionReceipt;
202
+ throwOnSendTransaction?: Error;
203
+ throwOnEstimateGas?: Error;
204
+ providerWaitForTransaction?: providers.TransactionReceipt;
205
+ providerGetBlock?: providers.Block | null;
206
+ providerGetTransactionReceipt?: providers.TransactionReceipt | null;
207
+ }
208
+
209
+ export function createMockMultiProvider(config: MockMultiProviderConfig = {}) {
210
+ const {
211
+ chainMetadata = {},
212
+ signerAddress = TEST_ADDRESSES.signer,
213
+ sendTransactionReceipt = {
214
+ transactionHash:
215
+ '0x1111111111111111111111111111111111111111111111111111111111111111',
216
+ blockNumber: 100,
217
+ status: 1,
218
+ } as providers.TransactionReceipt,
219
+ throwOnSendTransaction,
220
+ throwOnEstimateGas,
221
+ providerWaitForTransaction = sendTransactionReceipt,
222
+ providerGetBlock = { number: 150 } as providers.Block,
223
+ providerGetTransactionReceipt = sendTransactionReceipt,
224
+ } = config;
225
+
226
+ const mockProvider = {
227
+ waitForTransaction: Sinon.stub().resolves(providerWaitForTransaction),
228
+ getBlock: Sinon.stub().resolves(providerGetBlock),
229
+ getTransactionReceipt: Sinon.stub().resolves(providerGetTransactionReceipt),
230
+ };
231
+
232
+ const mockSigner = {
233
+ getAddress: Sinon.stub().resolves(signerAddress),
234
+ sendTransaction: throwOnSendTransaction
235
+ ? Sinon.stub().rejects(throwOnSendTransaction)
236
+ : Sinon.stub().resolves({
237
+ hash: sendTransactionReceipt.transactionHash,
238
+ wait: Sinon.stub().resolves(sendTransactionReceipt),
239
+ }),
240
+ };
241
+
242
+ const defaultChainMetadata: ChainMap<Partial<ChainMetadata>> = {
243
+ ethereum: { domainId: 1, blocks: { confirmations: 32, reorgPeriod: 32 } },
244
+ arbitrum: {
245
+ domainId: 42161,
246
+ blocks: { confirmations: 0, reorgPeriod: 0, estimateBlockTime: 1 },
247
+ },
248
+ };
249
+
250
+ const mergedMetadata = { ...defaultChainMetadata, ...chainMetadata };
251
+
252
+ return {
253
+ getChainMetadata: Sinon.stub().callsFake(
254
+ (chain: ChainName) => mergedMetadata[chain] ?? {},
255
+ ),
256
+ getProvider: Sinon.stub().returns(mockProvider),
257
+ getSigner: Sinon.stub().returns(mockSigner),
258
+ estimateGas: throwOnEstimateGas
259
+ ? Sinon.stub().rejects(throwOnEstimateGas)
260
+ : Sinon.stub().resolves(ethers.BigNumber.from(100000)),
261
+ sendTransaction: throwOnSendTransaction
262
+ ? Sinon.stub().rejects(throwOnSendTransaction)
263
+ : Sinon.stub().resolves(sendTransactionReceipt),
264
+ getDomainId: Sinon.stub().callsFake(
265
+ (chain: ChainName) => mergedMetadata[chain]?.domainId ?? 0,
266
+ ),
267
+ _mockProvider: mockProvider,
268
+ _mockSigner: mockSigner,
269
+ } as unknown as MultiProvider & {
270
+ _mockProvider: typeof mockProvider;
271
+ _mockSigner: typeof mockSigner;
272
+ };
273
+ }
274
+
275
+ export function createMockWarpCore(multiProvider: MultiProvider) {
276
+ return {
277
+ multiProvider,
278
+ } as unknown as WarpCore;
279
+ }
280
+
281
+ // Valid EVM test addresses (40 hex chars after 0x)
282
+ export const TEST_ADDRESSES: Record<string, string> = {
283
+ ethereum: '0x1111111111111111111111111111111111111111',
284
+ arbitrum: '0x2222222222222222222222222222222222222222',
285
+ optimism: '0x3333333333333333333333333333333333333333',
286
+ polygon: '0x4444444444444444444444444444444444444444',
287
+ bridge: '0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
288
+ signer: '0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
289
+ token: '0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
290
+ };
291
+
292
+ export function getTestAddress(key: string): string {
293
+ return TEST_ADDRESSES[key] ?? `0x${key.padStart(40, '0').slice(-40)}`;
294
+ }
295
+
296
+ export function buildTestBridges(
297
+ chains: ChainName[] = ['ethereum', 'arbitrum'],
298
+ ): ChainMap<BridgeConfigWithOverride> {
299
+ return chains.reduce((acc, chain) => {
300
+ acc[chain] = {
301
+ executionType: 'movableCollateral',
302
+ bridge: TEST_ADDRESSES.bridge,
303
+ bridgeMinAcceptedAmount: 0,
304
+ };
305
+ return acc;
306
+ }, {} as ChainMap<BridgeConfigWithOverride>);
307
+ }
308
+
309
+ /**
310
+ * Convert a chain config map (with bridge addresses) to a BridgeConfigWithOverride map.
311
+ * Useful for tests that define bridge addresses in the strategy config.
312
+ */
313
+ export function extractBridgeConfigs(
314
+ chainConfig: Record<
315
+ string,
316
+ { bridge: string; bridgeMinAcceptedAmount?: number | string }
317
+ >,
318
+ ): ChainMap<BridgeConfigWithOverride> {
319
+ return Object.entries(chainConfig).reduce((acc, [chain, config]) => {
320
+ acc[chain] = {
321
+ executionType: 'movableCollateral',
322
+ bridge: config.bridge,
323
+ bridgeMinAcceptedAmount: config.bridgeMinAcceptedAmount ?? 0,
324
+ };
325
+ return acc;
326
+ }, {} as ChainMap<BridgeConfigWithOverride>);
327
+ }
328
+
329
+ export function buildTestChainMetadata(
330
+ chains: ChainName[] = ['ethereum', 'arbitrum'],
331
+ ): ChainMap<ChainMetadata> {
332
+ const domainIds: Record<string, number> = {
333
+ ethereum: 1,
334
+ arbitrum: 42161,
335
+ optimism: 10,
336
+ polygon: 137,
337
+ };
338
+
339
+ return chains.reduce((acc, chain) => {
340
+ acc[chain] = {
341
+ name: chain,
342
+ chainId: domainIds[chain] ?? 1,
343
+ domainId: domainIds[chain] ?? 1,
344
+ protocol: 'ethereum' as any,
345
+ rpcUrls: [{ http: 'http://localhost:8545' }],
346
+ blocks: { reorgPeriod: chain === 'polygon' ? 'finalized' : 32 },
347
+ } as ChainMetadata;
348
+ return acc;
349
+ }, {} as ChainMap<ChainMetadata>);
350
+ }
351
+
352
+ export interface RebalancerTestContext {
353
+ multiProvider: ReturnType<typeof createMockMultiProvider>;
354
+ warpCore: WarpCore;
355
+ bridges: ChainMap<BridgeConfigWithOverride>;
356
+ chainMetadata: ChainMap<ChainMetadata>;
357
+ tokensByChainName: ChainMap<Token>;
358
+ adapters: ChainMap<ReturnType<typeof createMockAdapter>>;
359
+ }
360
+
361
+ export function createRebalancerTestContext(
362
+ chains: ChainName[] = ['ethereum', 'arbitrum'],
363
+ adapterConfigs: ChainMap<MockAdapterConfig> = {},
364
+ ): RebalancerTestContext {
365
+ const multiProvider = createMockMultiProvider();
366
+ const warpCore = createMockWarpCore(
367
+ multiProvider as unknown as MultiProvider,
368
+ );
369
+ const bridges = buildTestBridges(chains);
370
+ const chainMetadata = buildTestChainMetadata(chains);
371
+
372
+ const adapters: ChainMap<ReturnType<typeof createMockAdapter>> = {};
373
+ const tokensByChainName: ChainMap<Token> = {};
374
+
375
+ for (const chain of chains) {
376
+ const adapterConfig = adapterConfigs[chain] ?? {};
377
+ const tokenAddress = getTestAddress(chain);
378
+ const { token, adapter } = createMockToken({
379
+ name: `${chain}Token`,
380
+ addressOrDenom: tokenAddress,
381
+ adapter: createMockAdapter(adapterConfig),
382
+ });
383
+ adapters[chain] = adapter;
384
+ tokensByChainName[chain] = token as unknown as Token;
385
+ }
386
+
387
+ for (const originChain of chains) {
388
+ const adapterConfig = adapterConfigs[originChain] ?? {};
389
+ if (adapterConfig.allowedDestination === undefined) {
390
+ const destAddressMap: Record<number, string> = {};
391
+ for (const destChain of chains) {
392
+ if (originChain !== destChain) {
393
+ destAddressMap[chainMetadata[destChain].domainId] =
394
+ getTestAddress(destChain);
395
+ }
396
+ }
397
+ adapters[originChain].getAllowedDestination.callsFake(
398
+ (domainId: number) => {
399
+ return Promise.resolve(
400
+ destAddressMap[domainId] ??
401
+ '0x0000000000000000000000000000000000000000',
402
+ );
403
+ },
404
+ );
405
+ }
406
+ }
407
+
408
+ return {
409
+ multiProvider,
410
+ warpCore,
411
+ bridges,
412
+ chainMetadata,
413
+ tokensByChainName,
414
+ adapters,
415
+ };
416
+ }
417
+
418
+ // === Config Builders ===
419
+
420
+ export function buildTestConfig(
421
+ overrides: Partial<RebalancerConfig> = {},
422
+ chains: string[] = ['chain1'],
423
+ ): RebalancerConfig {
424
+ const baseChains = chains.reduce(
425
+ (acc, chain) => {
426
+ (acc as any)[chain] = {
427
+ bridgeLockTime: 60 * 1000,
428
+ bridge: ethers.constants.AddressZero,
429
+ weighted: {
430
+ weight: BigInt(1),
431
+ tolerance: BigInt(0),
432
+ },
433
+ };
434
+ return acc;
435
+ },
436
+ {} as Record<string, any>,
437
+ );
438
+
439
+ // Build the default strategy config
440
+ const defaultStrategyConfig = {
441
+ rebalanceStrategy: RebalancerStrategyOptions.Weighted,
442
+ chains: baseChains,
443
+ };
444
+
445
+ // If overrides has strategyConfig as an array, use it directly
446
+ // Otherwise, wrap single strategy in an array
447
+ let strategyConfig;
448
+ if (overrides.strategyConfig) {
449
+ if (Array.isArray(overrides.strategyConfig)) {
450
+ strategyConfig = overrides.strategyConfig;
451
+ } else {
452
+ // Single strategy override - use it directly wrapped in array
453
+ // If chains is explicitly provided, use it (don't merge with baseChains)
454
+ const singleConfig = overrides.strategyConfig as any;
455
+ strategyConfig = [
456
+ {
457
+ ...singleConfig,
458
+ chains:
459
+ singleConfig.chains !== undefined
460
+ ? singleConfig.chains
461
+ : baseChains,
462
+ },
463
+ ];
464
+ }
465
+ } else {
466
+ strategyConfig = [defaultStrategyConfig];
467
+ }
468
+
469
+ // Destructure to exclude strategyConfig from overrides spread
470
+ const { strategyConfig: _, ...restOverrides } = overrides;
471
+
472
+ return {
473
+ warpRouteId: 'test-route',
474
+ ...restOverrides,
475
+ strategyConfig,
476
+ } as any as RebalancerConfig;
477
+ }
@@ -0,0 +1,211 @@
1
+ import Sinon, { type SinonStub } from 'sinon';
2
+
3
+ import type {
4
+ BridgeQuote,
5
+ BridgeQuoteParams,
6
+ BridgeTransferStatus,
7
+ } from '../interfaces/IExternalBridge.js';
8
+
9
+ /**
10
+ * Create mock functions for LiFi SDK.
11
+ */
12
+ export function createLiFiSdkMocks() {
13
+ return {
14
+ createConfig: Sinon.stub(),
15
+ getQuote: Sinon.stub(),
16
+ executeRoute: Sinon.stub(),
17
+ getStatus: Sinon.stub(),
18
+ convertQuoteToRoute: Sinon.stub().callsFake((quote: unknown) => {
19
+ const q = quote as Record<string, unknown> & {
20
+ action?: { fromChainId?: number; toChainId?: number };
21
+ };
22
+ return {
23
+ ...q,
24
+ fromChainId: q.action?.fromChainId ?? 42161,
25
+ toChainId: q.action?.toChainId ?? 1151111081099710,
26
+ steps: [],
27
+ };
28
+ }),
29
+ };
30
+ }
31
+
32
+ /**
33
+ * Configure a mock getQuote to return a successful quote.
34
+ */
35
+ export function mockSuccessfulQuote(
36
+ stub: SinonStub,
37
+ overrides?: Partial<{
38
+ id: string;
39
+ tool: string;
40
+ fromAmount: string;
41
+ toAmount: string;
42
+ toAmountMin: string;
43
+ executionDuration: number;
44
+ fromChainId: number;
45
+ toChainId: number;
46
+ }>,
47
+ ) {
48
+ const fromChainId = overrides?.fromChainId ?? 42161;
49
+ const toChainId = overrides?.toChainId ?? 1151111081099710;
50
+ const fromAmount = overrides?.fromAmount ?? '10000000000';
51
+ const toAmount = overrides?.toAmount ?? '9950000000';
52
+ const toAmountMin = overrides?.toAmountMin ?? '9900000000';
53
+
54
+ stub.resolves({
55
+ id: overrides?.id ?? 'quote-123',
56
+ tool: overrides?.tool ?? 'across',
57
+ action: {
58
+ fromAmount,
59
+ fromChainId,
60
+ toChainId,
61
+ },
62
+ estimate: {
63
+ toAmount,
64
+ toAmountMin,
65
+ executionDuration: overrides?.executionDuration ?? 300,
66
+ },
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Configure a mock executeRoute to return a successful execution.
72
+ */
73
+ export function mockSuccessfulExecution(stub: SinonStub, txHash: string) {
74
+ stub.resolves({
75
+ steps: [
76
+ {
77
+ execution: {
78
+ process: [{ txHash }],
79
+ },
80
+ },
81
+ ],
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Configure a mock getStatus to return a specific status.
87
+ */
88
+ export function mockLiFiStatus(
89
+ stub: SinonStub,
90
+ status: 'DONE' | 'PENDING' | 'FAILED' | 'NOT_FOUND',
91
+ overrides?: Partial<{
92
+ receivingTxHash: string;
93
+ amount: string;
94
+ substatus: string;
95
+ }>,
96
+ ) {
97
+ const responses: Record<string, unknown> = {
98
+ DONE: {
99
+ status: 'DONE',
100
+ receiving: {
101
+ txHash: overrides?.receivingTxHash ?? '0xReceivingTxHash',
102
+ amount: overrides?.amount ?? '9950000000',
103
+ },
104
+ },
105
+ PENDING: {
106
+ status: 'PENDING',
107
+ substatus: overrides?.substatus ?? 'WAIT_SOURCE_CONFIRMATIONS',
108
+ },
109
+ FAILED: {
110
+ status: 'FAILED',
111
+ substatus: overrides?.substatus ?? 'BRIDGE_CALL_FAILED',
112
+ },
113
+ NOT_FOUND: {
114
+ status: 'NOT_FOUND',
115
+ },
116
+ };
117
+
118
+ stub.resolves(responses[status]);
119
+ }
120
+
121
+ /**
122
+ * Create a mock BridgeQuote for testing.
123
+ * The route structure includes all fields read by validateRouteAgainstRequest.
124
+ */
125
+ export function createMockBridgeQuote(
126
+ overrides?: Partial<BridgeQuote>,
127
+ ): BridgeQuote {
128
+ const route = overrides?.route as
129
+ | { action?: { fromChainId?: number; toChainId?: number } }
130
+ | undefined;
131
+
132
+ const defaultRequestParams: BridgeQuoteParams = {
133
+ fromChain: 42161,
134
+ toChain: 1399811149,
135
+ fromToken: '0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
136
+ toToken: '0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
137
+ fromAddress: '0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
138
+ toAddress: '0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
139
+ fromAmount: 10000000000n,
140
+ };
141
+ const requestParams: BridgeQuoteParams = {
142
+ ...defaultRequestParams,
143
+ ...overrides?.requestParams,
144
+ };
145
+
146
+ const fromChainId = route?.action?.fromChainId ?? requestParams.fromChain;
147
+ const toChainId = route?.action?.toChainId ?? requestParams.toChain;
148
+ const fromAmount =
149
+ overrides?.fromAmount ?? requestParams.fromAmount ?? 10000000000n;
150
+ const toAmount = overrides?.toAmount ?? 9950000000n;
151
+ const toAmountMin = overrides?.toAmountMin ?? 9900000000n;
152
+
153
+ return {
154
+ id: 'quote-123',
155
+ tool: 'across',
156
+ fromAmount,
157
+ toAmount,
158
+ toAmountMin,
159
+ executionDuration: 300,
160
+ gasCosts: 50000000n,
161
+ feeCosts: 0n,
162
+ // Route includes all fields read by validateRouteAgainstRequest for validation compatibility
163
+ route: {
164
+ action: { fromChainId, toChainId },
165
+ fromChainId,
166
+ toChainId,
167
+ fromToken: { address: requestParams.fromToken },
168
+ toToken: { address: requestParams.toToken },
169
+ fromAddress: requestParams.fromAddress,
170
+ toAddress: requestParams.toAddress ?? requestParams.fromAddress,
171
+ fromAmount: fromAmount.toString(),
172
+ toAmount: toAmount.toString(),
173
+ },
174
+ requestParams,
175
+ ...overrides,
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Create a mock BridgeTransferStatus for testing.
181
+ */
182
+ export function createMockBridgeStatus(
183
+ status: 'pending' | 'complete' | 'failed' | 'not_found',
184
+ overrides?: Partial<{
185
+ substatus: string;
186
+ receivingTxHash: string;
187
+ receivedAmount: bigint;
188
+ error: string;
189
+ }>,
190
+ ): BridgeTransferStatus {
191
+ switch (status) {
192
+ case 'pending':
193
+ return {
194
+ status: 'pending',
195
+ substatus: overrides?.substatus,
196
+ };
197
+ case 'complete':
198
+ return {
199
+ status: 'complete',
200
+ receivingTxHash: overrides?.receivingTxHash ?? '0xReceivingTxHash',
201
+ receivedAmount: overrides?.receivedAmount ?? 9950000000n,
202
+ };
203
+ case 'failed':
204
+ return {
205
+ status: 'failed',
206
+ error: overrides?.error,
207
+ };
208
+ case 'not_found':
209
+ return { status: 'not_found' };
210
+ }
211
+ }