@hyperlane-xyz/rebalancer 0.1.0-beta.5a8bd28ab

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 (202) hide show
  1. package/README.md +178 -0
  2. package/dist/config/RebalancerConfig.d.ts +12 -0
  3. package/dist/config/RebalancerConfig.d.ts.map +1 -0
  4. package/dist/config/RebalancerConfig.js +29 -0
  5. package/dist/config/RebalancerConfig.js.map +1 -0
  6. package/dist/config/RebalancerConfig.test.d.ts +2 -0
  7. package/dist/config/RebalancerConfig.test.d.ts.map +1 -0
  8. package/dist/config/RebalancerConfig.test.js +325 -0
  9. package/dist/config/RebalancerConfig.test.js.map +1 -0
  10. package/dist/core/Rebalancer.d.ts +23 -0
  11. package/dist/core/Rebalancer.d.ts.map +1 -0
  12. package/dist/core/Rebalancer.js +290 -0
  13. package/dist/core/Rebalancer.js.map +1 -0
  14. package/dist/core/RebalancerService.d.ts +115 -0
  15. package/dist/core/RebalancerService.d.ts.map +1 -0
  16. package/dist/core/RebalancerService.js +227 -0
  17. package/dist/core/RebalancerService.js.map +1 -0
  18. package/dist/core/WithInflightGuard.d.ts +20 -0
  19. package/dist/core/WithInflightGuard.d.ts.map +1 -0
  20. package/dist/core/WithInflightGuard.js +47 -0
  21. package/dist/core/WithInflightGuard.js.map +1 -0
  22. package/dist/core/WithInflightGuard.test.d.ts +2 -0
  23. package/dist/core/WithInflightGuard.test.d.ts.map +1 -0
  24. package/dist/core/WithInflightGuard.test.js +64 -0
  25. package/dist/core/WithInflightGuard.test.js.map +1 -0
  26. package/dist/core/WithSemaphore.d.ts +22 -0
  27. package/dist/core/WithSemaphore.d.ts.map +1 -0
  28. package/dist/core/WithSemaphore.js +67 -0
  29. package/dist/core/WithSemaphore.js.map +1 -0
  30. package/dist/core/WithSemaphore.test.d.ts +2 -0
  31. package/dist/core/WithSemaphore.test.d.ts.map +1 -0
  32. package/dist/core/WithSemaphore.test.js +83 -0
  33. package/dist/core/WithSemaphore.test.js.map +1 -0
  34. package/dist/factories/RebalancerContextFactory.d.ts +41 -0
  35. package/dist/factories/RebalancerContextFactory.d.ts.map +1 -0
  36. package/dist/factories/RebalancerContextFactory.js +115 -0
  37. package/dist/factories/RebalancerContextFactory.js.map +1 -0
  38. package/dist/index.d.ts +33 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +35 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/interfaces/IMetrics.d.ts +5 -0
  43. package/dist/interfaces/IMetrics.d.ts.map +1 -0
  44. package/dist/interfaces/IMetrics.js +2 -0
  45. package/dist/interfaces/IMetrics.js.map +1 -0
  46. package/dist/interfaces/IMonitor.d.ts +51 -0
  47. package/dist/interfaces/IMonitor.d.ts.map +1 -0
  48. package/dist/interfaces/IMonitor.js +14 -0
  49. package/dist/interfaces/IMonitor.js.map +1 -0
  50. package/dist/interfaces/IRebalancer.d.ts +15 -0
  51. package/dist/interfaces/IRebalancer.d.ts.map +1 -0
  52. package/dist/interfaces/IRebalancer.js +2 -0
  53. package/dist/interfaces/IRebalancer.js.map +1 -0
  54. package/dist/interfaces/IStrategy.d.ts +11 -0
  55. package/dist/interfaces/IStrategy.d.ts.map +1 -0
  56. package/dist/interfaces/IStrategy.js +2 -0
  57. package/dist/interfaces/IStrategy.js.map +1 -0
  58. package/dist/metrics/Metrics.d.ts +31 -0
  59. package/dist/metrics/Metrics.d.ts.map +1 -0
  60. package/dist/metrics/Metrics.js +302 -0
  61. package/dist/metrics/Metrics.js.map +1 -0
  62. package/dist/metrics/PriceGetter.d.ts +10 -0
  63. package/dist/metrics/PriceGetter.d.ts.map +1 -0
  64. package/dist/metrics/PriceGetter.js +41 -0
  65. package/dist/metrics/PriceGetter.js.map +1 -0
  66. package/dist/metrics/scripts/metrics.d.ts +14 -0
  67. package/dist/metrics/scripts/metrics.d.ts.map +1 -0
  68. package/dist/metrics/scripts/metrics.js +198 -0
  69. package/dist/metrics/scripts/metrics.js.map +1 -0
  70. package/dist/metrics/types.d.ts +24 -0
  71. package/dist/metrics/types.d.ts.map +1 -0
  72. package/dist/metrics/types.js +2 -0
  73. package/dist/metrics/types.js.map +1 -0
  74. package/dist/metrics/utils/metrics.d.ts +12 -0
  75. package/dist/metrics/utils/metrics.d.ts.map +1 -0
  76. package/dist/metrics/utils/metrics.js +28 -0
  77. package/dist/metrics/utils/metrics.js.map +1 -0
  78. package/dist/monitor/Monitor.d.ts +26 -0
  79. package/dist/monitor/Monitor.d.ts.map +1 -0
  80. package/dist/monitor/Monitor.js +116 -0
  81. package/dist/monitor/Monitor.js.map +1 -0
  82. package/dist/service.d.ts +3 -0
  83. package/dist/service.d.ts.map +1 -0
  84. package/dist/service.js +125 -0
  85. package/dist/service.js.map +1 -0
  86. package/dist/strategy/BaseStrategy.d.ts +34 -0
  87. package/dist/strategy/BaseStrategy.d.ts.map +1 -0
  88. package/dist/strategy/BaseStrategy.js +127 -0
  89. package/dist/strategy/BaseStrategy.js.map +1 -0
  90. package/dist/strategy/MinAmountStrategy.d.ts +27 -0
  91. package/dist/strategy/MinAmountStrategy.d.ts.map +1 -0
  92. package/dist/strategy/MinAmountStrategy.js +103 -0
  93. package/dist/strategy/MinAmountStrategy.js.map +1 -0
  94. package/dist/strategy/MinAmountStrategy.test.d.ts +2 -0
  95. package/dist/strategy/MinAmountStrategy.test.d.ts.map +1 -0
  96. package/dist/strategy/MinAmountStrategy.test.js +472 -0
  97. package/dist/strategy/MinAmountStrategy.test.js.map +1 -0
  98. package/dist/strategy/StrategyFactory.d.ts +16 -0
  99. package/dist/strategy/StrategyFactory.d.ts.map +1 -0
  100. package/dist/strategy/StrategyFactory.js +25 -0
  101. package/dist/strategy/StrategyFactory.js.map +1 -0
  102. package/dist/strategy/StrategyFactory.test.d.ts +2 -0
  103. package/dist/strategy/StrategyFactory.test.d.ts.map +1 -0
  104. package/dist/strategy/StrategyFactory.test.js +80 -0
  105. package/dist/strategy/StrategyFactory.test.js.map +1 -0
  106. package/dist/strategy/WeightedStrategy.d.ts +23 -0
  107. package/dist/strategy/WeightedStrategy.d.ts.map +1 -0
  108. package/dist/strategy/WeightedStrategy.js +61 -0
  109. package/dist/strategy/WeightedStrategy.js.map +1 -0
  110. package/dist/strategy/WeightedStrategy.test.d.ts +2 -0
  111. package/dist/strategy/WeightedStrategy.test.d.ts.map +1 -0
  112. package/dist/strategy/WeightedStrategy.test.js +307 -0
  113. package/dist/strategy/WeightedStrategy.test.js.map +1 -0
  114. package/dist/strategy/index.d.ts +5 -0
  115. package/dist/strategy/index.d.ts.map +1 -0
  116. package/dist/strategy/index.js +5 -0
  117. package/dist/strategy/index.js.map +1 -0
  118. package/dist/test/helpers.d.ts +8 -0
  119. package/dist/test/helpers.d.ts.map +1 -0
  120. package/dist/test/helpers.js +33 -0
  121. package/dist/test/helpers.js.map +1 -0
  122. package/dist/utils/ExplorerClient.d.ts +14 -0
  123. package/dist/utils/ExplorerClient.d.ts.map +1 -0
  124. package/dist/utils/ExplorerClient.js +82 -0
  125. package/dist/utils/ExplorerClient.js.map +1 -0
  126. package/dist/utils/balanceUtils.d.ts +13 -0
  127. package/dist/utils/balanceUtils.d.ts.map +1 -0
  128. package/dist/utils/balanceUtils.js +43 -0
  129. package/dist/utils/balanceUtils.js.map +1 -0
  130. package/dist/utils/balanceUtils.test.d.ts +2 -0
  131. package/dist/utils/balanceUtils.test.d.ts.map +1 -0
  132. package/dist/utils/balanceUtils.test.js +54 -0
  133. package/dist/utils/balanceUtils.test.js.map +1 -0
  134. package/dist/utils/bridgeUtils.d.ts +19 -0
  135. package/dist/utils/bridgeUtils.d.ts.map +1 -0
  136. package/dist/utils/bridgeUtils.js +20 -0
  137. package/dist/utils/bridgeUtils.js.map +1 -0
  138. package/dist/utils/bridgeUtils.test.d.ts +2 -0
  139. package/dist/utils/bridgeUtils.test.d.ts.map +1 -0
  140. package/dist/utils/bridgeUtils.test.js +77 -0
  141. package/dist/utils/bridgeUtils.test.js.map +1 -0
  142. package/dist/utils/errors.d.ts +4 -0
  143. package/dist/utils/errors.d.ts.map +1 -0
  144. package/dist/utils/errors.js +6 -0
  145. package/dist/utils/errors.js.map +1 -0
  146. package/dist/utils/files.d.ts +35 -0
  147. package/dist/utils/files.d.ts.map +1 -0
  148. package/dist/utils/files.js +190 -0
  149. package/dist/utils/files.js.map +1 -0
  150. package/dist/utils/generalUtils.d.ts +3 -0
  151. package/dist/utils/generalUtils.d.ts.map +1 -0
  152. package/dist/utils/generalUtils.js +9 -0
  153. package/dist/utils/generalUtils.js.map +1 -0
  154. package/dist/utils/index.d.ts +5 -0
  155. package/dist/utils/index.d.ts.map +1 -0
  156. package/dist/utils/index.js +5 -0
  157. package/dist/utils/index.js.map +1 -0
  158. package/dist/utils/tokenUtils.d.ts +14 -0
  159. package/dist/utils/tokenUtils.d.ts.map +1 -0
  160. package/dist/utils/tokenUtils.js +21 -0
  161. package/dist/utils/tokenUtils.js.map +1 -0
  162. package/package.json +70 -0
  163. package/src/config/RebalancerConfig.test.ts +388 -0
  164. package/src/config/RebalancerConfig.ts +39 -0
  165. package/src/core/Rebalancer.ts +471 -0
  166. package/src/core/RebalancerService.ts +333 -0
  167. package/src/core/WithInflightGuard.test.ts +131 -0
  168. package/src/core/WithInflightGuard.ts +67 -0
  169. package/src/core/WithSemaphore.test.ts +112 -0
  170. package/src/core/WithSemaphore.ts +92 -0
  171. package/src/factories/RebalancerContextFactory.ts +210 -0
  172. package/src/index.ts +68 -0
  173. package/src/interfaces/IMetrics.ts +5 -0
  174. package/src/interfaces/IMonitor.ts +63 -0
  175. package/src/interfaces/IRebalancer.ts +20 -0
  176. package/src/interfaces/IStrategy.ts +13 -0
  177. package/src/metrics/Metrics.ts +558 -0
  178. package/src/metrics/PriceGetter.ts +74 -0
  179. package/src/metrics/scripts/metrics.ts +298 -0
  180. package/src/metrics/types.ts +27 -0
  181. package/src/metrics/utils/metrics.ts +33 -0
  182. package/src/monitor/Monitor.ts +174 -0
  183. package/src/service.ts +154 -0
  184. package/src/strategy/BaseStrategy.ts +210 -0
  185. package/src/strategy/MinAmountStrategy.test.ts +625 -0
  186. package/src/strategy/MinAmountStrategy.ts +170 -0
  187. package/src/strategy/StrategyFactory.test.ts +109 -0
  188. package/src/strategy/StrategyFactory.ts +48 -0
  189. package/src/strategy/WeightedStrategy.test.ts +408 -0
  190. package/src/strategy/WeightedStrategy.ts +93 -0
  191. package/src/strategy/index.ts +4 -0
  192. package/src/test/helpers.ts +46 -0
  193. package/src/utils/ExplorerClient.ts +99 -0
  194. package/src/utils/balanceUtils.test.ts +74 -0
  195. package/src/utils/balanceUtils.ts +69 -0
  196. package/src/utils/bridgeUtils.test.ts +92 -0
  197. package/src/utils/bridgeUtils.ts +42 -0
  198. package/src/utils/errors.ts +5 -0
  199. package/src/utils/files.ts +276 -0
  200. package/src/utils/generalUtils.ts +13 -0
  201. package/src/utils/index.ts +4 -0
  202. package/src/utils/tokenUtils.ts +26 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WeightedStrategy.d.ts","sourceRoot":"","sources":["../../src/strategy/WeightedStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE7D;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAGhC,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO;IAkCnB;;OAEG;IACH,SAAS,CAAC,sBAAsB,CAAC,WAAW,EAAE,WAAW,GAAG;QAC1D,SAAS,EAAE,KAAK,EAAE,CAAC;QACnB,QAAQ,EAAE,KAAK,EAAE,CAAC;KACnB;CA+BF"}
@@ -0,0 +1,61 @@
1
+ import { BaseStrategy } from './BaseStrategy.js';
2
+ /**
3
+ * Strategy implementation that rebalance based on weights
4
+ * It distributes funds across chains based on their weights
5
+ */
6
+ export class WeightedStrategy extends BaseStrategy {
7
+ config;
8
+ totalWeight;
9
+ logger;
10
+ constructor(config, logger, metrics) {
11
+ const chains = Object.keys(config);
12
+ const log = logger.child({ class: WeightedStrategy.name });
13
+ super(chains, log, metrics);
14
+ this.logger = log;
15
+ let totalWeight = 0n;
16
+ for (const chain of chains) {
17
+ const { weight, tolerance } = config[chain].weighted;
18
+ if (weight < 0n) {
19
+ throw new Error(`Weight (${weight}) must not be negative for ${chain}`);
20
+ }
21
+ if (tolerance < 0n || tolerance > 100n) {
22
+ throw new Error(`Tolerance (${tolerance}) must be between 0 and 100 for ${chain}`);
23
+ }
24
+ totalWeight += weight;
25
+ }
26
+ if (totalWeight <= 0n) {
27
+ throw new Error('The total weight for all chains must be greater than 0');
28
+ }
29
+ this.config = config;
30
+ this.totalWeight = totalWeight;
31
+ this.logger.info('WeightedStrategy created');
32
+ }
33
+ /**
34
+ * Gets balances categorized by surplus and deficit based on weights
35
+ */
36
+ getCategorizedBalances(rawBalances) {
37
+ // Get the total balance from all chains
38
+ const total = this.chains.reduce((sum, chain) => sum + rawBalances[chain], 0n);
39
+ return this.chains.reduce((acc, chain) => {
40
+ const { weight, tolerance } = this.config[chain].weighted;
41
+ const target = (total * weight) / this.totalWeight;
42
+ const toleranceAmount = (target * tolerance) / 100n;
43
+ const balance = rawBalances[chain];
44
+ // Apply the tolerance to deficits to prevent small imbalances
45
+ if (balance < target - toleranceAmount) {
46
+ acc.deficits.push({ chain, amount: target - balance });
47
+ }
48
+ else if (balance > target) {
49
+ acc.surpluses.push({ chain, amount: balance - target });
50
+ }
51
+ else {
52
+ // Do nothing as the balance is already on target
53
+ }
54
+ return acc;
55
+ }, {
56
+ surpluses: [],
57
+ deficits: [],
58
+ });
59
+ }
60
+ }
61
+ //# sourceMappingURL=WeightedStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WeightedStrategy.js","sourceRoot":"","sources":["../../src/strategy/WeightedStrategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=WeightedStrategy.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WeightedStrategy.test.d.ts","sourceRoot":"","sources":["../../src/strategy/WeightedStrategy.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,307 @@
1
+ import { expect } from 'chai';
2
+ import { ethers } from 'ethers';
3
+ import { pino } from 'pino';
4
+ import { WeightedStrategy } from './WeightedStrategy.js';
5
+ const testLogger = pino({ level: 'silent' });
6
+ describe('WeightedStrategy', () => {
7
+ let chain1;
8
+ let chain2;
9
+ let chain3;
10
+ beforeEach(() => {
11
+ chain1 = 'chain1';
12
+ chain2 = 'chain2';
13
+ chain3 = 'chain3';
14
+ });
15
+ describe('constructor', () => {
16
+ it('should throw an error when less than two chains are configured', () => {
17
+ expect(() => new WeightedStrategy({
18
+ [chain1]: {
19
+ weighted: { weight: 100n, tolerance: 0n },
20
+ bridge: ethers.constants.AddressZero,
21
+ bridgeLockTime: 1,
22
+ },
23
+ }, testLogger)).to.throw('At least two chains must be configured');
24
+ });
25
+ it('should throw an error when weight is negative', () => {
26
+ expect(() => new WeightedStrategy({
27
+ [chain1]: {
28
+ weighted: { weight: 100n, tolerance: 0n },
29
+ bridge: ethers.constants.AddressZero,
30
+ bridgeLockTime: 1,
31
+ },
32
+ [chain2]: {
33
+ weighted: { weight: -1n, tolerance: 0n },
34
+ bridge: ethers.constants.AddressZero,
35
+ bridgeLockTime: 1,
36
+ },
37
+ }, testLogger)).to.throw('Weight (-1) must not be negative for chain2');
38
+ });
39
+ it('should throw an error when the total weight is 0', () => {
40
+ expect(() => new WeightedStrategy({
41
+ [chain1]: {
42
+ weighted: { weight: 0n, tolerance: 0n },
43
+ bridge: ethers.constants.AddressZero,
44
+ bridgeLockTime: 1,
45
+ },
46
+ [chain2]: {
47
+ weighted: { weight: 0n, tolerance: 0n },
48
+ bridge: ethers.constants.AddressZero,
49
+ bridgeLockTime: 1,
50
+ },
51
+ }, testLogger)).to.throw('The total weight for all chains must be greater than 0');
52
+ });
53
+ it('should throw an error when tolerance is less than 0 or greater than 100', () => {
54
+ expect(() => new WeightedStrategy({
55
+ [chain1]: {
56
+ weighted: { weight: 100n, tolerance: 0n },
57
+ bridge: ethers.constants.AddressZero,
58
+ bridgeLockTime: 1,
59
+ },
60
+ [chain2]: {
61
+ weighted: { weight: 100n, tolerance: -1n },
62
+ bridge: ethers.constants.AddressZero,
63
+ bridgeLockTime: 1,
64
+ },
65
+ }, testLogger)).to.throw('Tolerance (-1) must be between 0 and 100 for chain2');
66
+ expect(() => new WeightedStrategy({
67
+ [chain1]: {
68
+ weighted: { weight: 100n, tolerance: 100n },
69
+ bridge: ethers.constants.AddressZero,
70
+ bridgeLockTime: 1,
71
+ },
72
+ [chain2]: {
73
+ weighted: { weight: 100n, tolerance: 101n },
74
+ bridge: ethers.constants.AddressZero,
75
+ bridgeLockTime: 1,
76
+ },
77
+ }, testLogger)).to.throw('Tolerance (101) must be between 0 and 100 for chain2');
78
+ });
79
+ });
80
+ describe('getRebalancingRoutes', () => {
81
+ it('should throw an error when raw balances chains length does not match configured chains length', () => {
82
+ expect(() => new WeightedStrategy({
83
+ [chain1]: {
84
+ weighted: { weight: 100n, tolerance: 0n },
85
+ bridge: ethers.constants.AddressZero,
86
+ bridgeLockTime: 1,
87
+ },
88
+ [chain2]: {
89
+ weighted: { weight: 100n, tolerance: 0n },
90
+ bridge: ethers.constants.AddressZero,
91
+ bridgeLockTime: 1,
92
+ },
93
+ }, testLogger).getRebalancingRoutes({
94
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
95
+ [chain2]: ethers.utils.parseEther('200').toBigInt(),
96
+ [chain3]: ethers.utils.parseEther('300').toBigInt(),
97
+ })).to.throw('Config chains do not match raw balances chains length');
98
+ });
99
+ it('should throw an error when a raw balance is missing', () => {
100
+ expect(() => new WeightedStrategy({
101
+ [chain1]: {
102
+ weighted: { weight: 100n, tolerance: 0n },
103
+ bridge: ethers.constants.AddressZero,
104
+ bridgeLockTime: 1,
105
+ },
106
+ [chain2]: {
107
+ weighted: { weight: 100n, tolerance: 0n },
108
+ bridge: ethers.constants.AddressZero,
109
+ bridgeLockTime: 1,
110
+ },
111
+ }, testLogger).getRebalancingRoutes({
112
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
113
+ [chain3]: ethers.utils.parseEther('300').toBigInt(),
114
+ })).to.throw('Raw balance for chain chain2 not found');
115
+ });
116
+ it('should throw an error when a raw balance is negative', () => {
117
+ expect(() => new WeightedStrategy({
118
+ [chain1]: {
119
+ weighted: { weight: 100n, tolerance: 0n },
120
+ bridge: ethers.constants.AddressZero,
121
+ bridgeLockTime: 1,
122
+ },
123
+ [chain2]: {
124
+ weighted: { weight: 100n, tolerance: 0n },
125
+ bridge: ethers.constants.AddressZero,
126
+ bridgeLockTime: 1,
127
+ },
128
+ }, testLogger).getRebalancingRoutes({
129
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
130
+ [chain2]: ethers.utils.parseEther('-200').toBigInt(),
131
+ })).to.throw('Raw balance for chain chain2 is negative');
132
+ });
133
+ it('should return an empty array when all chains are balanced', () => {
134
+ const strategy = new WeightedStrategy({
135
+ [chain1]: {
136
+ weighted: { weight: 100n, tolerance: 0n },
137
+ bridge: ethers.constants.AddressZero,
138
+ bridgeLockTime: 1,
139
+ },
140
+ [chain2]: {
141
+ weighted: { weight: 100n, tolerance: 0n },
142
+ bridge: ethers.constants.AddressZero,
143
+ bridgeLockTime: 1,
144
+ },
145
+ }, testLogger);
146
+ const rawBalances = {
147
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
148
+ [chain2]: ethers.utils.parseEther('100').toBigInt(),
149
+ };
150
+ const routes = strategy.getRebalancingRoutes(rawBalances);
151
+ expect(routes).to.be.empty;
152
+ });
153
+ it('should return a single route when a chain is unbalanced', () => {
154
+ const strategy = new WeightedStrategy({
155
+ [chain1]: {
156
+ weighted: { weight: 100n, tolerance: 0n },
157
+ bridge: ethers.constants.AddressZero,
158
+ bridgeLockTime: 1,
159
+ },
160
+ [chain2]: {
161
+ weighted: { weight: 100n, tolerance: 0n },
162
+ bridge: ethers.constants.AddressZero,
163
+ bridgeLockTime: 1,
164
+ },
165
+ }, testLogger);
166
+ const rawBalances = {
167
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
168
+ [chain2]: ethers.utils.parseEther('200').toBigInt(),
169
+ };
170
+ const routes = strategy.getRebalancingRoutes(rawBalances);
171
+ expect(routes).to.deep.equal([
172
+ {
173
+ origin: chain2,
174
+ destination: chain1,
175
+ amount: ethers.utils.parseEther('50').toBigInt(),
176
+ },
177
+ ]);
178
+ });
179
+ it('should return an empty array when a chain is unbalanced but has tolerance', () => {
180
+ const strategy = new WeightedStrategy({
181
+ [chain1]: {
182
+ weighted: { weight: 100n, tolerance: 1n },
183
+ bridge: ethers.constants.AddressZero,
184
+ bridgeLockTime: 1,
185
+ },
186
+ [chain2]: {
187
+ weighted: { weight: 100n, tolerance: 1n },
188
+ bridge: ethers.constants.AddressZero,
189
+ bridgeLockTime: 1,
190
+ },
191
+ }, testLogger);
192
+ const rawBalances = {
193
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
194
+ [chain2]: ethers.utils.parseEther('101').toBigInt(),
195
+ };
196
+ const routes = strategy.getRebalancingRoutes(rawBalances);
197
+ expect(routes).to.be.empty;
198
+ });
199
+ it('should return a single route when two chains are unbalanced and can be solved with a single transfer', () => {
200
+ const strategy = new WeightedStrategy({
201
+ [chain1]: {
202
+ weighted: { weight: 100n, tolerance: 0n },
203
+ bridge: ethers.constants.AddressZero,
204
+ bridgeLockTime: 1,
205
+ },
206
+ [chain2]: {
207
+ weighted: { weight: 100n, tolerance: 0n },
208
+ bridge: ethers.constants.AddressZero,
209
+ bridgeLockTime: 1,
210
+ },
211
+ [chain3]: {
212
+ weighted: { weight: 100n, tolerance: 0n },
213
+ bridge: ethers.constants.AddressZero,
214
+ bridgeLockTime: 1,
215
+ },
216
+ }, testLogger);
217
+ const rawBalances = {
218
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
219
+ [chain2]: ethers.utils.parseEther('200').toBigInt(),
220
+ [chain3]: ethers.utils.parseEther('300').toBigInt(),
221
+ };
222
+ const routes = strategy.getRebalancingRoutes(rawBalances);
223
+ expect(routes).to.deep.equal([
224
+ {
225
+ origin: chain3,
226
+ destination: chain1,
227
+ amount: ethers.utils.parseEther('100').toBigInt(),
228
+ },
229
+ ]);
230
+ });
231
+ it('should return two routes when two chains are unbalanced and cannot be solved with a single transfer', () => {
232
+ const strategy = new WeightedStrategy({
233
+ [chain1]: {
234
+ weighted: { weight: 100n, tolerance: 0n },
235
+ bridge: ethers.constants.AddressZero,
236
+ bridgeLockTime: 1,
237
+ },
238
+ [chain2]: {
239
+ weighted: { weight: 100n, tolerance: 0n },
240
+ bridge: ethers.constants.AddressZero,
241
+ bridgeLockTime: 1,
242
+ },
243
+ [chain3]: {
244
+ weighted: { weight: 100n, tolerance: 0n },
245
+ bridge: ethers.constants.AddressZero,
246
+ bridgeLockTime: 1,
247
+ },
248
+ }, testLogger);
249
+ const rawBalances = {
250
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
251
+ [chain2]: ethers.utils.parseEther('100').toBigInt(),
252
+ [chain3]: ethers.utils.parseEther('500').toBigInt(),
253
+ };
254
+ const routes = strategy.getRebalancingRoutes(rawBalances);
255
+ expect(routes).to.deep.equal([
256
+ {
257
+ origin: chain3,
258
+ destination: chain1,
259
+ amount: 133333333333333333333n,
260
+ },
261
+ {
262
+ origin: chain3,
263
+ destination: chain2,
264
+ amount: 133333333333333333333n,
265
+ },
266
+ ]);
267
+ });
268
+ it('should return routes to balance different weighted chains', () => {
269
+ const strategy = new WeightedStrategy({
270
+ [chain1]: {
271
+ weighted: { weight: 50n, tolerance: 0n },
272
+ bridge: ethers.constants.AddressZero,
273
+ bridgeLockTime: 1,
274
+ },
275
+ [chain2]: {
276
+ weighted: { weight: 25n, tolerance: 0n },
277
+ bridge: ethers.constants.AddressZero,
278
+ bridgeLockTime: 1,
279
+ },
280
+ [chain3]: {
281
+ weighted: { weight: 25n, tolerance: 0n },
282
+ bridge: ethers.constants.AddressZero,
283
+ bridgeLockTime: 1,
284
+ },
285
+ }, testLogger);
286
+ const rawBalances = {
287
+ [chain1]: ethers.utils.parseEther('100').toBigInt(),
288
+ [chain2]: ethers.utils.parseEther('100').toBigInt(),
289
+ [chain3]: ethers.utils.parseEther('100').toBigInt(),
290
+ };
291
+ const routes = strategy.getRebalancingRoutes(rawBalances);
292
+ expect(routes).to.deep.equal([
293
+ {
294
+ origin: chain2,
295
+ destination: chain1,
296
+ amount: ethers.utils.parseEther('25').toBigInt(),
297
+ },
298
+ {
299
+ origin: chain3,
300
+ destination: chain1,
301
+ amount: ethers.utils.parseEther('25').toBigInt(),
302
+ },
303
+ ]);
304
+ });
305
+ });
306
+ });
307
+ //# sourceMappingURL=WeightedStrategy.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WeightedStrategy.test.js","sourceRoot":"","sources":["../../src/strategy/WeightedStrategy.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { BaseStrategy } from './BaseStrategy.js';
2
+ export { MinAmountStrategy } from './MinAmountStrategy.js';
3
+ export { StrategyFactory } from './StrategyFactory.js';
4
+ export { WeightedStrategy } from './WeightedStrategy.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { BaseStrategy } from './BaseStrategy.js';
2
+ export { MinAmountStrategy } from './MinAmountStrategy.js';
3
+ export { StrategyFactory } from './StrategyFactory.js';
4
+ export { WeightedStrategy } from './WeightedStrategy.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { RebalancerConfig } from '../config/RebalancerConfig.js';
2
+ import type { IRebalancer } from '../interfaces/IRebalancer.js';
3
+ import type { RebalancingRoute } from '../interfaces/IStrategy.js';
4
+ export declare class MockRebalancer implements IRebalancer {
5
+ rebalance(_routes: RebalancingRoute[]): Promise<void>;
6
+ }
7
+ export declare function buildTestConfig(overrides?: Partial<RebalancerConfig>, chains?: string[]): RebalancerConfig;
8
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/test/helpers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,qBAAa,cAAe,YAAW,WAAW;IAChD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAGtD;AAED,wBAAgB,eAAe,CAC7B,SAAS,GAAE,OAAO,CAAC,gBAAgB,CAAM,EACzC,MAAM,GAAE,MAAM,EAAe,GAC5B,gBAAgB,CA4BlB"}
@@ -0,0 +1,33 @@
1
+ import { ethers } from 'ethers';
2
+ import { RebalancerStrategyOptions } from '@hyperlane-xyz/sdk';
3
+ export class MockRebalancer {
4
+ rebalance(_routes) {
5
+ return Promise.resolve();
6
+ }
7
+ }
8
+ export function buildTestConfig(overrides = {}, chains = ['chain1']) {
9
+ const baseChains = chains.reduce((acc, chain) => {
10
+ acc[chain] = {
11
+ bridgeLockTime: 60 * 1000,
12
+ bridge: ethers.constants.AddressZero,
13
+ weighted: {
14
+ weight: BigInt(1),
15
+ tolerance: BigInt(0),
16
+ },
17
+ };
18
+ return acc;
19
+ }, {});
20
+ return {
21
+ warpRouteId: 'test-route',
22
+ strategyConfig: {
23
+ rebalanceStrategy: RebalancerStrategyOptions.Weighted,
24
+ chains: {
25
+ ...baseChains,
26
+ ...(overrides.strategyConfig?.chains ?? {}),
27
+ },
28
+ ...overrides.strategyConfig,
29
+ },
30
+ ...overrides,
31
+ };
32
+ }
33
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/test/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM/D,MAAM,OAAO,cAAc;IACzB,SAAS,CAAC,OAA2B;QACnC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAC7B,YAAuC,EAAE,EACzC,SAAmB,CAAC,QAAQ,CAAC;IAE7B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QACZ,GAAW,CAAC,KAAK,CAAC,GAAG;YACpB,cAAc,EAAE,EAAE,GAAG,IAAI;YACzB,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW;YACpC,QAAQ,EAAE;gBACR,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;gBACjB,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;aACrB;SACF,CAAC;QACF,OAAO,GAAG,CAAC;IACb,CAAC,EACD,EAAyB,CAC1B,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,cAAc,EAAE;YACd,iBAAiB,EAAE,yBAAyB,CAAC,QAAQ;YACrD,MAAM,EAAE;gBACN,GAAG,UAAU;gBACb,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,IAAI,EAAE,CAAC;aAC5C;YACD,GAAG,SAAS,CAAC,cAAc;SAC5B;QACD,GAAG,SAAS;KACc,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Logger } from 'pino';
2
+ export type InflightRebalanceQueryParams = {
3
+ bridges: string[];
4
+ domains: number[];
5
+ txSender: string;
6
+ limit?: number;
7
+ };
8
+ export declare class ExplorerClient {
9
+ private readonly baseUrl;
10
+ constructor(baseUrl: string);
11
+ private toBytea;
12
+ hasUndeliveredRebalance(params: InflightRebalanceQueryParams, logger: Logger): Promise<boolean>;
13
+ }
14
+ //# sourceMappingURL=ExplorerClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExplorerClient.d.ts","sourceRoot":"","sources":["../../src/utils/ExplorerClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAE5C,OAAO,CAAC,OAAO;IAIT,uBAAuB,CAC3B,MAAM,EAAE,4BAA4B,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;CA+EpB"}
@@ -0,0 +1,82 @@
1
+ export class ExplorerClient {
2
+ baseUrl;
3
+ constructor(baseUrl) {
4
+ this.baseUrl = baseUrl;
5
+ }
6
+ toBytea(addr) {
7
+ return addr.replace(/^0x/i, '\\x').toLowerCase();
8
+ }
9
+ async hasUndeliveredRebalance(params, logger) {
10
+ const { bridges, domains, txSender, limit = 5 } = params;
11
+ const variables = {
12
+ senders: bridges.map((a) => this.toBytea(a)),
13
+ recipients: bridges.map((a) => this.toBytea(a)),
14
+ originDomains: domains,
15
+ destDomains: domains,
16
+ txSenders: [this.toBytea(txSender)],
17
+ limit,
18
+ };
19
+ logger.debug({ variables }, 'Explorer query variables');
20
+ const query = `
21
+ query InflightRebalancesForRoute(
22
+ $senders: [bytea!],
23
+ $recipients: [bytea!],
24
+ $originDomains: [Int!],
25
+ $destDomains: [Int!],
26
+ $txSenders: [bytea!],
27
+ $limit: Int = 25
28
+ ) {
29
+ message_view(
30
+ where: {
31
+ _and: [
32
+ { is_delivered: { _eq: false } },
33
+ { sender: { _in: $senders } },
34
+ { recipient: { _in: $recipients } },
35
+ { origin_domain_id: { _in: $originDomains } },
36
+ { destination_domain_id: { _in: $destDomains } },
37
+ { origin_tx_sender: { _in: $txSenders } }
38
+ ]
39
+ }
40
+ order_by: { origin_tx_id: desc }
41
+ limit: $limit
42
+ ) {
43
+ msg_id
44
+ origin_domain_id
45
+ destination_domain_id
46
+ sender
47
+ recipient
48
+ origin_tx_hash
49
+ origin_tx_sender
50
+ is_delivered
51
+ }
52
+ }`;
53
+ const res = await fetch(this.baseUrl, {
54
+ method: 'POST',
55
+ headers: { 'Content-Type': 'application/json' },
56
+ body: JSON.stringify({ query, variables }),
57
+ });
58
+ logger.debug({ status: res.status }, 'Explorer query response');
59
+ if (!res.ok) {
60
+ let errorDetails;
61
+ try {
62
+ const errorJson = await res.json();
63
+ errorDetails = JSON.stringify(errorJson);
64
+ }
65
+ catch (_e) {
66
+ try {
67
+ // Fallback to text if JSON parsing fails
68
+ errorDetails = await res.text();
69
+ }
70
+ catch (_textError) {
71
+ errorDetails = 'Unable to read response body';
72
+ }
73
+ }
74
+ throw new Error(`Explorer query failed: ${res.status} ${errorDetails}`);
75
+ }
76
+ const json = await res.json();
77
+ const rows = json?.data?.message_view ?? [];
78
+ logger.debug({ rows }, 'Explorer query rows');
79
+ return rows.length > 0;
80
+ }
81
+ }
82
+ //# sourceMappingURL=ExplorerClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExplorerClient.js","sourceRoot":"","sources":["../../src/utils/ExplorerClient.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAExC,OAAO,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,MAAoC,EACpC,MAAc;QAEd,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;QAEzD,MAAM,SAAS,GAAG;YAChB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC5C,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC/C,aAAa,EAAE,OAAO;YACtB,WAAW,EAAE,OAAO;YACpB,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACnC,KAAK;SACN,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,EAAE,0BAA0B,CAAC,CAAC;QAExD,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAgCV,CAAC;QAEL,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,yBAAyB,CAAC,CAAC;QAEhE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,YAAoB,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBACnC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IAAI,CAAC;oBACH,yCAAyC;oBACzC,YAAY,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAClC,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,YAAY,GAAG,8BAA8B,CAAC;gBAChD,CAAC;YACH,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,IAAI,YAAY,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,YAAY,IAAI,EAAE,CAAC;QAE5C,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,qBAAqB,CAAC,CAAC;QAE9C,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import { Logger } from 'pino';
2
+ import { ChainName, Token } from '@hyperlane-xyz/sdk';
3
+ import { MonitorEvent } from '../interfaces/IMonitor.js';
4
+ import { RawBalances } from '../interfaces/IStrategy.js';
5
+ /**
6
+ * Returns the raw balances required by the strategies from the monitor event
7
+ * @param chains - The chains that should be included in the raw balances (e.g. the chains in the rebalancer config)
8
+ * @param event - The monitor event to extract the raw balances from
9
+ * @returns An object mapping chain names to their raw balances.
10
+ */
11
+ export declare function getRawBalances(chains: ChainName[], event: MonitorEvent, logger: Logger): RawBalances;
12
+ export declare function formatBigInt(warpToken: Token, num: bigint): number;
13
+ //# sourceMappingURL=balanceUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balanceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/balanceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAIzD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EAAE,EACnB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,GACb,WAAW,CA6Cb;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAElE"}
@@ -0,0 +1,43 @@
1
+ import { isCollateralizedTokenEligibleForRebalancing } from './tokenUtils.js';
2
+ /**
3
+ * Returns the raw balances required by the strategies from the monitor event
4
+ * @param chains - The chains that should be included in the raw balances (e.g. the chains in the rebalancer config)
5
+ * @param event - The monitor event to extract the raw balances from
6
+ * @returns An object mapping chain names to their raw balances.
7
+ */
8
+ export function getRawBalances(chains, event, logger) {
9
+ const balances = {};
10
+ const chainSet = new Set(chains);
11
+ for (const tokenInfo of event.tokensInfo) {
12
+ const { token, bridgedSupply } = tokenInfo;
13
+ // Ignore tokens that are not in the provided chains list
14
+ if (!chainSet.has(token.chainName)) {
15
+ logger.info({
16
+ context: getRawBalances.name,
17
+ chain: token.chainName,
18
+ tokenSymbol: token.symbol,
19
+ tokenAddress: token.addressOrDenom,
20
+ }, 'Skipping token: not in configured chains list');
21
+ continue;
22
+ }
23
+ // Ignore tokens that are not collateralized or are otherwise ineligible
24
+ if (!isCollateralizedTokenEligibleForRebalancing(token)) {
25
+ logger.info({
26
+ context: getRawBalances.name,
27
+ chain: token.chainName,
28
+ tokenSymbol: token.symbol,
29
+ tokenAddress: token.addressOrDenom,
30
+ }, 'Skipping token: not collateralized or ineligible for rebalancing');
31
+ continue;
32
+ }
33
+ if (bridgedSupply === undefined) {
34
+ throw new Error(`bridgedSupply should not be undefined for collateralized token ${token.addressOrDenom}`);
35
+ }
36
+ balances[token.chainName] = bridgedSupply;
37
+ }
38
+ return balances;
39
+ }
40
+ export function formatBigInt(warpToken, num) {
41
+ return warpToken.amount(num).getDecimalFormattedAmount();
42
+ }
43
+ //# sourceMappingURL=balanceUtils.js.map