@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,193 @@
1
+ import assert from 'node:assert';
2
+
3
+ import { expect } from 'chai';
4
+
5
+ import { type ChainMap } from '@humanode-hyperlane/sdk';
6
+
7
+ import { ExecutionType, ExternalBridgeType } from '../config/types.js';
8
+ import {
9
+ type BridgeConfigWithOverride,
10
+ getBridgeConfig,
11
+ isInventoryConfig,
12
+ isMovableCollateralConfig,
13
+ } from './bridgeUtils.js';
14
+
15
+ describe('bridgeConfig', () => {
16
+ it('should return the base bridge config when no overrides exist', () => {
17
+ const bridges: ChainMap<BridgeConfigWithOverride> = {
18
+ chain1: {
19
+ executionType: 'movableCollateral',
20
+ bridge: '0x1234567890123456789012345678901234567890',
21
+ bridgeMinAcceptedAmount: 1000,
22
+ },
23
+ chain2: {
24
+ executionType: 'movableCollateral',
25
+ bridge: '0x0987654321098765432109876543210987654321',
26
+ bridgeMinAcceptedAmount: 2000,
27
+ },
28
+ };
29
+
30
+ const result = getBridgeConfig(bridges, 'chain1', 'chain2');
31
+
32
+ expect(result).to.deep.equal({
33
+ executionType: 'movableCollateral',
34
+ bridge: '0x1234567890123456789012345678901234567890',
35
+ bridgeMinAcceptedAmount: 1000,
36
+ });
37
+ });
38
+
39
+ it('should merge base config with overrides when they exist', () => {
40
+ const bridges: ChainMap<BridgeConfigWithOverride> = {
41
+ chain1: {
42
+ executionType: 'movableCollateral',
43
+ bridge: '0x1234567890123456789012345678901234567890',
44
+ bridgeMinAcceptedAmount: 1000,
45
+ override: {
46
+ chain2: {
47
+ bridgeMinAcceptedAmount: 5000,
48
+ },
49
+ },
50
+ },
51
+ chain2: {
52
+ executionType: 'movableCollateral',
53
+ bridge: '0x0987654321098765432109876543210987654321',
54
+ bridgeMinAcceptedAmount: 2000,
55
+ },
56
+ };
57
+
58
+ const result = getBridgeConfig(bridges, 'chain1', 'chain2');
59
+
60
+ expect(result).to.deep.equal({
61
+ executionType: 'movableCollateral',
62
+ bridge: '0x1234567890123456789012345678901234567890',
63
+ bridgeMinAcceptedAmount: 5000,
64
+ });
65
+ });
66
+
67
+ it('should handle overrides that change the bridge address', () => {
68
+ const bridges: ChainMap<BridgeConfigWithOverride> = {
69
+ chain1: {
70
+ executionType: 'movableCollateral',
71
+ bridge: '0x1234567890123456789012345678901234567890',
72
+ bridgeMinAcceptedAmount: 1000,
73
+ override: {
74
+ chain2: {
75
+ bridge: '0xABCDEF0123456789ABCDEF0123456789ABCDEF01',
76
+ },
77
+ },
78
+ },
79
+ chain2: {
80
+ executionType: 'movableCollateral',
81
+ bridge: '0x0987654321098765432109876543210987654321',
82
+ bridgeMinAcceptedAmount: 2000,
83
+ },
84
+ };
85
+
86
+ const result = getBridgeConfig(bridges, 'chain1', 'chain2');
87
+
88
+ expect(result).to.deep.equal({
89
+ executionType: 'movableCollateral',
90
+ bridge: '0xABCDEF0123456789ABCDEF0123456789ABCDEF01',
91
+ bridgeMinAcceptedAmount: 1000,
92
+ });
93
+ });
94
+
95
+ it('should apply override with executionType: inventory', () => {
96
+ const bridges: ChainMap<BridgeConfigWithOverride> = {
97
+ chain1: {
98
+ executionType: ExecutionType.MovableCollateral,
99
+ bridge: '0x1234567890123456789012345678901234567890',
100
+ bridgeMinAcceptedAmount: 1000,
101
+ override: {
102
+ chain2: {
103
+ executionType: ExecutionType.Inventory,
104
+ externalBridge: ExternalBridgeType.LiFi,
105
+ },
106
+ },
107
+ },
108
+ chain2: {
109
+ executionType: ExecutionType.MovableCollateral,
110
+ bridge: '0x0987654321098765432109876543210987654321',
111
+ bridgeMinAcceptedAmount: 2000,
112
+ },
113
+ };
114
+
115
+ const result = getBridgeConfig(bridges, 'chain1', 'chain2');
116
+
117
+ expect(result.executionType).to.equal(ExecutionType.Inventory);
118
+ assert(isInventoryConfig(result));
119
+ expect(result.externalBridge).to.equal(ExternalBridgeType.LiFi);
120
+ expect(result.bridgeMinAcceptedAmount).to.equal(1000);
121
+ });
122
+ it('should apply override with executionType: inventory and externalBridge', () => {
123
+ const bridges: ChainMap<BridgeConfigWithOverride> = {
124
+ chain1: {
125
+ executionType: ExecutionType.MovableCollateral,
126
+ bridge: '0x1234567890123456789012345678901234567890',
127
+ override: {
128
+ chain2: {
129
+ executionType: ExecutionType.Inventory,
130
+ externalBridge: ExternalBridgeType.LiFi,
131
+ },
132
+ },
133
+ },
134
+ chain2: {
135
+ executionType: ExecutionType.MovableCollateral,
136
+ bridge: '0x0987654321098765432109876543210987654321',
137
+ },
138
+ };
139
+
140
+ const result = getBridgeConfig(bridges, 'chain1', 'chain2');
141
+
142
+ expect(result.executionType).to.equal(ExecutionType.Inventory);
143
+ assert(isInventoryConfig(result));
144
+ expect(result.externalBridge).to.equal(ExternalBridgeType.LiFi);
145
+ });
146
+
147
+ it('should allow override to change executionType from movableCollateral to inventory', () => {
148
+ const bridges: ChainMap<BridgeConfigWithOverride> = {
149
+ chain1: {
150
+ executionType: ExecutionType.MovableCollateral,
151
+ bridge: '0x1234567890123456789012345678901234567890',
152
+ override: {
153
+ chain2: {
154
+ executionType: ExecutionType.Inventory,
155
+ externalBridge: ExternalBridgeType.LiFi,
156
+ },
157
+ },
158
+ },
159
+ chain2: {
160
+ executionType: ExecutionType.MovableCollateral,
161
+ bridge: '0x0987654321098765432109876543210987654321',
162
+ },
163
+ };
164
+
165
+ const result = getBridgeConfig(bridges, 'chain1', 'chain2');
166
+
167
+ // Override should win: executionType should be inventory, not movableCollateral
168
+ expect(result.executionType).to.equal(ExecutionType.Inventory);
169
+ assert(isInventoryConfig(result));
170
+ expect(result.externalBridge).to.equal(ExternalBridgeType.LiFi);
171
+ });
172
+
173
+ it('should preserve base chain executionType when no override exists', () => {
174
+ const bridges: ChainMap<BridgeConfigWithOverride> = {
175
+ chain1: {
176
+ executionType: ExecutionType.MovableCollateral,
177
+ bridge: '0x1234567890123456789012345678901234567890',
178
+ },
179
+ chain2: {
180
+ executionType: ExecutionType.MovableCollateral,
181
+ bridge: '0x0987654321098765432109876543210987654321',
182
+ },
183
+ };
184
+
185
+ const result = getBridgeConfig(bridges, 'chain1', 'chain2');
186
+
187
+ expect(result.executionType).to.equal(ExecutionType.MovableCollateral);
188
+ assert(isMovableCollateralConfig(result));
189
+ expect(result.bridge).to.equal(
190
+ '0x1234567890123456789012345678901234567890',
191
+ );
192
+ });
193
+ });
@@ -0,0 +1,101 @@
1
+ import type { ChainMap, ChainName } from '@humanode-hyperlane/sdk';
2
+ import type { Address } from '@humanode-hyperlane/utils';
3
+
4
+ import type { ExternalBridgeType } from '../config/types.js';
5
+ import type { StrategyRoute } from '../interfaces/IStrategy.js';
6
+
7
+ type BaseBridgeConfig = {
8
+ bridgeMinAcceptedAmount?: string | number;
9
+ };
10
+
11
+ export type MovableCollateralBridgeConfig = BaseBridgeConfig & {
12
+ executionType: 'movableCollateral';
13
+ bridge: Address;
14
+ };
15
+
16
+ export type InventoryBridgeConfig = BaseBridgeConfig & {
17
+ executionType: 'inventory';
18
+ externalBridge: ExternalBridgeType;
19
+ };
20
+
21
+ export type BridgeConfig =
22
+ | MovableCollateralBridgeConfig
23
+ | InventoryBridgeConfig;
24
+
25
+ export function isMovableCollateralConfig(
26
+ config: BridgeConfig,
27
+ ): config is MovableCollateralBridgeConfig {
28
+ return config.executionType === 'movableCollateral';
29
+ }
30
+
31
+ export function isInventoryConfig(
32
+ config: BridgeConfig,
33
+ ): config is InventoryBridgeConfig {
34
+ return config.executionType === 'inventory';
35
+ }
36
+
37
+ export type BridgeConfigWithOverride = BridgeConfig & {
38
+ override?: ChainMap<Partial<BridgeConfig>>;
39
+ };
40
+
41
+ /**
42
+ * Gets the bridge configuration for a specific chain pair, applying any overrides
43
+ * @param bridges The map of bridge configurations by chain
44
+ * @param fromChain The source chain
45
+ * @param toChain The destination chain
46
+ * @returns The bridge configuration with any overrides applied
47
+ */
48
+ export function getBridgeConfig(
49
+ bridges: ChainMap<BridgeConfigWithOverride>,
50
+ fromChain: ChainName,
51
+ toChain: ChainName,
52
+ ): BridgeConfig {
53
+ const fromConfig = bridges[fromChain];
54
+ const routeSpecificOverrides = fromConfig.override?.[toChain];
55
+
56
+ // Create a new object with the properties from bridgeConfig, excluding the overrides property
57
+ const { override: _, ...baseConfig } = fromConfig;
58
+
59
+ // Return a new object with the base config and any overrides
60
+ return { ...baseConfig, ...routeSpecificOverrides } as BridgeConfig;
61
+ }
62
+
63
+ /**
64
+ * Creates a StrategyRoute from a BridgeConfig with exhaustive type checking
65
+ * @param bridgeConfig The bridge configuration
66
+ * @param origin The origin chain
67
+ * @param destination The destination chain
68
+ * @param amount The amount to transfer
69
+ * @returns A StrategyRoute with the appropriate execution type
70
+ */
71
+ export function createStrategyRoute(
72
+ bridgeConfig: BridgeConfig,
73
+ origin: ChainName,
74
+ destination: ChainName,
75
+ amount: bigint,
76
+ ): StrategyRoute {
77
+ switch (bridgeConfig.executionType) {
78
+ case 'inventory':
79
+ return {
80
+ origin,
81
+ destination,
82
+ amount,
83
+ executionType: 'inventory',
84
+ externalBridge: bridgeConfig.externalBridge,
85
+ };
86
+ case 'movableCollateral':
87
+ return {
88
+ origin,
89
+ destination,
90
+ amount,
91
+ executionType: 'movableCollateral',
92
+ bridge: bridgeConfig.bridge,
93
+ };
94
+ default: {
95
+ const _exhaustive: never = bridgeConfig;
96
+ throw new Error(
97
+ `Unknown execution type: ${(_exhaustive as BridgeConfig).executionType}`,
98
+ );
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,5 @@
1
+ export class WrappedError extends Error {
2
+ constructor(message: string, cause?: Error) {
3
+ super(message, cause ? { cause } : undefined);
4
+ }
5
+ }
@@ -0,0 +1,306 @@
1
+ import { BigNumber } from 'ethers';
2
+ import type { Logger } from 'pino';
3
+
4
+ import {
5
+ type AnnotatedEV5Transaction,
6
+ type ChainName,
7
+ type InterchainGasQuote,
8
+ type MultiProvider,
9
+ type Token,
10
+ TokenStandard,
11
+ } from '@humanode-hyperlane/sdk';
12
+ import {
13
+ addBufferToGasLimit,
14
+ isZeroishAddress,
15
+ ProtocolType,
16
+ } from '@humanode-hyperlane/utils';
17
+
18
+ /**
19
+ * Fallback gas limit for transferRemote when eth_estimateGas fails.
20
+ * Conservative estimate for cross-chain token transfers.
21
+ */
22
+ export const FALLBACK_TRANSFER_REMOTE_GAS_LIMIT = 300_000n;
23
+
24
+ /**
25
+ * Cost multiplier for minimum viable transfer.
26
+ * A transfer must be worth at least this multiple of its cost to be worthwhile.
27
+ */
28
+ export const MIN_VIABLE_COST_MULTIPLIER = 2n;
29
+
30
+ /**
31
+ * Transfer cost estimate for native token transfers.
32
+ * Contains all cost components needed for transfer decisions.
33
+ */
34
+ export interface TransferCostEstimate {
35
+ /** IGP cost for the Hyperlane message */
36
+ igpCost: bigint;
37
+ /** Estimated gas cost for the transferRemote transaction (with buffer) */
38
+ gasCost: bigint;
39
+ /** Token fee cost (native denom only) */
40
+ tokenFeeCost: bigint;
41
+ /** Total cost = igpCost + gasCost + tokenFeeCost */
42
+ totalCost: bigint;
43
+ /** Maximum transferable amount after reserving costs (availableInventory - totalCost) */
44
+ maxTransferable: bigint;
45
+ /** Minimum viable transfer (totalCost * MIN_VIABLE_COST_MULTIPLIER) */
46
+ minViableTransfer: bigint;
47
+ /** Gas quote from adapter (for passing to executeTransferRemote) */
48
+ gasQuote?: InterchainGasQuote;
49
+ }
50
+
51
+ /**
52
+ * Estimate gas for a transferRemote transaction using eth_estimateGas.
53
+ * Falls back to conservative estimate if estimation fails.
54
+ *
55
+ * @param originChain - Chain where transferRemote will be called
56
+ * @param destinationChain - Chain where the Hyperlane message goes
57
+ * @param amount - Amount to transfer
58
+ * @param multiProvider - MultiProvider for chain access
59
+ * @param warpCoreMultiProvider - MultiProvider from WarpCore for adapter access
60
+ * @param getTokenForChain - Function to get token for a chain
61
+ * @param inventorySigner - Address of the inventory signer
62
+ * @param logger - Logger instance
63
+ * @returns Estimated gas limit for the transaction
64
+ */
65
+ export async function estimateTransferRemoteGas(
66
+ originChain: ChainName,
67
+ destinationChain: ChainName,
68
+ amount: bigint,
69
+ multiProvider: MultiProvider,
70
+ warpCoreMultiProvider: any,
71
+ getTokenForChain: (chain: ChainName) => Token | undefined,
72
+ inventorySigner: string,
73
+ logger: Logger,
74
+ ): Promise<bigint> {
75
+ const originToken = getTokenForChain(originChain);
76
+ if (!originToken) {
77
+ logger.warn(
78
+ { originChain },
79
+ 'No token found for origin chain, using fallback gas limit',
80
+ );
81
+ return FALLBACK_TRANSFER_REMOTE_GAS_LIMIT;
82
+ }
83
+
84
+ try {
85
+ const destinationDomain = multiProvider.getDomainId(destinationChain);
86
+ const adapter = originToken.getHypAdapter(warpCoreMultiProvider);
87
+
88
+ // Quote the IGP gas first (needed for the full transaction)
89
+ const gasQuote = await adapter.quoteTransferRemoteGas({
90
+ destination: destinationDomain,
91
+ sender: inventorySigner,
92
+ recipient: inventorySigner,
93
+ amount,
94
+ });
95
+
96
+ // Populate with minimal amount for gas estimation
97
+ // Gas cost is independent of transfer size (just a require check in _transferFromSender),
98
+ // and using minimal amount prevents eth_estimateGas from failing when account balance < requested amount
99
+ // Note: getHypAdapter returns IHypTokenAdapter<unknown> for protocol-agnostic support.
100
+ // For EVM chains (which inventory rebalancing uses), the actual type is AnnotatedEV5Transaction.
101
+ const populatedTx = (await adapter.populateTransferRemoteTx({
102
+ destination: destinationDomain,
103
+ recipient: inventorySigner,
104
+ weiAmountOrId: 1n,
105
+ interchainGas: gasQuote,
106
+ })) as AnnotatedEV5Transaction;
107
+
108
+ // Estimate gas using the provider
109
+ const provider = multiProvider.getProvider(originChain);
110
+ const gasEstimate = await provider.estimateGas({
111
+ to: populatedTx.to,
112
+ data: populatedTx.data,
113
+ value: populatedTx.value,
114
+ from: inventorySigner,
115
+ });
116
+
117
+ const estimatedGas = BigInt(gasEstimate.toString());
118
+
119
+ logger.debug(
120
+ {
121
+ originChain,
122
+ destinationChain,
123
+ amount: amount.toString(),
124
+ estimatedGas: estimatedGas.toString(),
125
+ },
126
+ 'Estimated transferRemote gas via eth_estimateGas',
127
+ );
128
+
129
+ return estimatedGas;
130
+ } catch (error) {
131
+ logger.warn(
132
+ {
133
+ originChain,
134
+ destinationChain,
135
+ error: (error as Error).message,
136
+ fallbackGas: FALLBACK_TRANSFER_REMOTE_GAS_LIMIT.toString(),
137
+ },
138
+ 'Gas estimation failed, using fallback gas limit',
139
+ );
140
+ return FALLBACK_TRANSFER_REMOTE_GAS_LIMIT;
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Calculate all transfer costs for a transferRemote operation.
146
+ * Consolidates IGP costs, gas costs, and derived values (max transferable, min viable).
147
+ *
148
+ * @param originChain - Chain to transfer from (where transferRemote is called)
149
+ * @param destinationChain - Chain to transfer to (Hyperlane message destination)
150
+ * @param availableInventory - Available token balance on origin chain
151
+ * @param requestedAmount - Requested transfer amount
152
+ * @param multiProvider - MultiProvider for chain access
153
+ * @param warpCoreMultiProvider - MultiProvider from WarpCore for adapter access
154
+ * @param getTokenForChain - Function to get token for a chain
155
+ * @param inventorySigner - Address of the inventory signer
156
+ * @param isNativeTokenStandard - Function to check if token standard is native
157
+ * @param logger - Logger instance
158
+ * @returns Cost estimate with all components and derived values
159
+ */
160
+ export async function calculateTransferCosts(
161
+ originChain: ChainName,
162
+ destinationChain: ChainName,
163
+ availableInventory: bigint,
164
+ requestedAmount: bigint,
165
+ multiProvider: MultiProvider,
166
+ warpCoreMultiProvider: any,
167
+ getTokenForChain: (chain: ChainName) => Token | undefined,
168
+ inventorySigner: string,
169
+ isNativeTokenStandard: (standard: TokenStandard) => boolean,
170
+ logger: Logger,
171
+ ): Promise<TransferCostEstimate> {
172
+ const originToken = getTokenForChain(originChain);
173
+ if (!originToken) {
174
+ throw new Error(`No token found for origin chain: ${originChain}`);
175
+ }
176
+
177
+ const destinationDomain = multiProvider.getDomainId(destinationChain);
178
+ const adapter = originToken.getHypAdapter(warpCoreMultiProvider);
179
+
180
+ // Always quote IGP for the gas quote (needed for populateTransferRemoteTx)
181
+ const gasQuote = await adapter.quoteTransferRemoteGas({
182
+ destination: destinationDomain,
183
+ sender: inventorySigner,
184
+ recipient: inventorySigner,
185
+ amount: requestedAmount,
186
+ });
187
+
188
+ // For non-native tokens, no cost reservation needed from token balance
189
+ if (!isNativeTokenStandard(originToken.standard)) {
190
+ return {
191
+ igpCost: 0n,
192
+ gasCost: 0n,
193
+ tokenFeeCost: 0n,
194
+ totalCost: 0n,
195
+ maxTransferable:
196
+ availableInventory < requestedAmount
197
+ ? availableInventory
198
+ : requestedAmount,
199
+ minViableTransfer: 0n,
200
+ gasQuote,
201
+ };
202
+ }
203
+
204
+ // For native tokens, calculate costs
205
+ const igpCost = gasQuote.igpQuote.amount;
206
+
207
+ // Extract token fee cost (native denom only)
208
+ const tokenFeeCost =
209
+ !gasQuote.tokenFeeQuote?.addressOrDenom ||
210
+ isZeroishAddress(gasQuote.tokenFeeQuote.addressOrDenom)
211
+ ? (gasQuote.tokenFeeQuote?.amount ?? 0n)
212
+ : 0n;
213
+
214
+ // Skip gas estimation for non-EVM chains (e.g., Solana).
215
+ // Non-EVM chains have negligible base fees (~5000 lamports ~$0.0001 on Solana)
216
+ // compared to EVM gas costs ($0.50-$50/tx). The IGP (Interchain Gas Paymaster)
217
+ // reservation dominates the cost, not chain-specific gas. Thus gasCost=0 is a
218
+ // safe approximation for non-EVM origin chains.
219
+ const originProtocol = multiProvider.getProtocol(originChain);
220
+ if (originProtocol !== ProtocolType.Ethereum) {
221
+ const totalCost = igpCost + tokenFeeCost;
222
+ let maxTransferable: bigint;
223
+ if (availableInventory <= totalCost) {
224
+ maxTransferable = 0n;
225
+ } else {
226
+ const maxAfterReservation = availableInventory - totalCost;
227
+ maxTransferable =
228
+ maxAfterReservation < requestedAmount
229
+ ? maxAfterReservation
230
+ : requestedAmount;
231
+ }
232
+ const minViableTransfer = totalCost * MIN_VIABLE_COST_MULTIPLIER;
233
+ return {
234
+ igpCost,
235
+ gasCost: 0n,
236
+ tokenFeeCost,
237
+ totalCost,
238
+ maxTransferable,
239
+ minViableTransfer,
240
+ gasQuote,
241
+ };
242
+ }
243
+
244
+ // Estimate gas with buffer
245
+ const estimatedGasLimit = await estimateTransferRemoteGas(
246
+ originChain,
247
+ destinationChain,
248
+ requestedAmount,
249
+ multiProvider,
250
+ warpCoreMultiProvider,
251
+ getTokenForChain,
252
+ inventorySigner,
253
+ logger,
254
+ );
255
+ const bufferedGasLimit = addBufferToGasLimit(
256
+ BigNumber.from(estimatedGasLimit.toString()),
257
+ );
258
+
259
+ // Get gas price and calculate cost
260
+ const provider = multiProvider.getProvider(originChain);
261
+ const feeData = await provider.getFeeData();
262
+ const gasPrice = feeData.maxFeePerGas ?? feeData.gasPrice ?? 0n;
263
+ const gasCost = bufferedGasLimit.toBigInt() * BigInt(gasPrice.toString());
264
+
265
+ const totalCost = igpCost + gasCost + tokenFeeCost;
266
+
267
+ // Calculate derived values
268
+ let maxTransferable: bigint;
269
+ if (availableInventory <= totalCost) {
270
+ maxTransferable = 0n;
271
+ } else {
272
+ const maxAfterReservation = availableInventory - totalCost;
273
+ maxTransferable =
274
+ maxAfterReservation < requestedAmount
275
+ ? maxAfterReservation
276
+ : requestedAmount;
277
+ }
278
+
279
+ const minViableTransfer = totalCost * MIN_VIABLE_COST_MULTIPLIER;
280
+
281
+ logger.debug(
282
+ {
283
+ originChain,
284
+ destinationChain,
285
+ availableInventory: availableInventory.toString(),
286
+ requestedAmount: requestedAmount.toString(),
287
+ igpCost: igpCost.toString(),
288
+ gasCost: gasCost.toString(),
289
+ tokenFeeCost: tokenFeeCost.toString(),
290
+ totalCost: totalCost.toString(),
291
+ maxTransferable: maxTransferable.toString(),
292
+ minViableTransfer: minViableTransfer.toString(),
293
+ },
294
+ 'Calculated transfer costs for native token',
295
+ );
296
+
297
+ return {
298
+ igpCost,
299
+ gasCost,
300
+ tokenFeeCost,
301
+ totalCost,
302
+ maxTransferable,
303
+ minViableTransfer,
304
+ gasQuote,
305
+ };
306
+ }