@hyperlane-xyz/rebalancer-sim 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +195 -0
- package/README.md +582 -0
- package/dist/BridgeMockController.d.ts +87 -0
- package/dist/BridgeMockController.d.ts.map +1 -0
- package/dist/BridgeMockController.js +300 -0
- package/dist/BridgeMockController.js.map +1 -0
- package/dist/KPICollector.d.ts +81 -0
- package/dist/KPICollector.d.ts.map +1 -0
- package/dist/KPICollector.js +239 -0
- package/dist/KPICollector.js.map +1 -0
- package/dist/MessageTracker.d.ts +82 -0
- package/dist/MessageTracker.d.ts.map +1 -0
- package/dist/MessageTracker.js +213 -0
- package/dist/MessageTracker.js.map +1 -0
- package/dist/RebalancerSimulationHarness.d.ts +72 -0
- package/dist/RebalancerSimulationHarness.d.ts.map +1 -0
- package/dist/RebalancerSimulationHarness.js +217 -0
- package/dist/RebalancerSimulationHarness.js.map +1 -0
- package/dist/ScenarioGenerator.d.ts +50 -0
- package/dist/ScenarioGenerator.d.ts.map +1 -0
- package/dist/ScenarioGenerator.js +326 -0
- package/dist/ScenarioGenerator.js.map +1 -0
- package/dist/ScenarioLoader.d.ts +18 -0
- package/dist/ScenarioLoader.d.ts.map +1 -0
- package/dist/ScenarioLoader.js +59 -0
- package/dist/ScenarioLoader.js.map +1 -0
- package/dist/SimulationDeployment.d.ts +20 -0
- package/dist/SimulationDeployment.d.ts.map +1 -0
- package/dist/SimulationDeployment.js +170 -0
- package/dist/SimulationDeployment.js.map +1 -0
- package/dist/SimulationEngine.d.ts +58 -0
- package/dist/SimulationEngine.d.ts.map +1 -0
- package/dist/SimulationEngine.js +302 -0
- package/dist/SimulationEngine.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/runners/NoOpRebalancer.d.ts +17 -0
- package/dist/runners/NoOpRebalancer.d.ts.map +1 -0
- package/dist/runners/NoOpRebalancer.js +28 -0
- package/dist/runners/NoOpRebalancer.js.map +1 -0
- package/dist/runners/ProductionRebalancerRunner.d.ts +22 -0
- package/dist/runners/ProductionRebalancerRunner.d.ts.map +1 -0
- package/dist/runners/ProductionRebalancerRunner.js +219 -0
- package/dist/runners/ProductionRebalancerRunner.js.map +1 -0
- package/dist/runners/SimpleRunner.d.ts +31 -0
- package/dist/runners/SimpleRunner.d.ts.map +1 -0
- package/dist/runners/SimpleRunner.js +286 -0
- package/dist/runners/SimpleRunner.js.map +1 -0
- package/dist/runners/SimulationRegistry.d.ts +46 -0
- package/dist/runners/SimulationRegistry.d.ts.map +1 -0
- package/dist/runners/SimulationRegistry.js +156 -0
- package/dist/runners/SimulationRegistry.js.map +1 -0
- package/dist/types.d.ts +637 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +158 -0
- package/dist/types.js.map +1 -0
- package/dist/visualizer/HtmlTimelineGenerator.d.ts +6 -0
- package/dist/visualizer/HtmlTimelineGenerator.d.ts.map +1 -0
- package/dist/visualizer/HtmlTimelineGenerator.js +1321 -0
- package/dist/visualizer/HtmlTimelineGenerator.js.map +1 -0
- package/dist/visualizer/index.d.ts +4 -0
- package/dist/visualizer/index.d.ts.map +1 -0
- package/dist/visualizer/index.js +3 -0
- package/dist/visualizer/index.js.map +1 -0
- package/package.json +62 -0
- package/src/BridgeMockController.ts +404 -0
- package/src/KPICollector.ts +304 -0
- package/src/MessageTracker.ts +312 -0
- package/src/RebalancerSimulationHarness.ts +325 -0
- package/src/ScenarioGenerator.ts +433 -0
- package/src/ScenarioLoader.ts +73 -0
- package/src/SimulationDeployment.ts +265 -0
- package/src/SimulationEngine.ts +432 -0
- package/src/index.ts +101 -0
- package/src/runners/NoOpRebalancer.ts +40 -0
- package/src/runners/ProductionRebalancerRunner.ts +289 -0
- package/src/runners/SimpleRunner.ts +382 -0
- package/src/runners/SimulationRegistry.ts +215 -0
- package/src/types.ts +878 -0
- package/src/visualizer/HtmlTimelineGenerator.ts +1341 -0
- package/src/visualizer/index.ts +7 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { ERC20Test__factory, HypERC20Collateral__factory, MockMailbox__factory, MockValueTransferBridge__factory, } from '@hyperlane-xyz/core';
|
|
3
|
+
import { ANVIL_BRIDGE_CONTROLLER_KEY, ANVIL_MAILBOX_PROCESSOR_KEY, ANVIL_REBALANCER_KEY, } from './types.js';
|
|
4
|
+
// Collateral multiplication factor: 100x the initial balance
|
|
5
|
+
// 1x for warp liquidity, 99x for deployer to execute test transfers
|
|
6
|
+
const COLLATERAL_MULTIPLIER = 100;
|
|
7
|
+
/**
|
|
8
|
+
* Deploys a multi-domain simulation environment on a single anvil instance.
|
|
9
|
+
*
|
|
10
|
+
* Creates MockMailboxes for each domain, deploys ERC20 collateral tokens,
|
|
11
|
+
* HypERC20Collateral warp tokens, and MockValueTransferBridge contracts.
|
|
12
|
+
* All domains share the same RPC endpoint but have different domain IDs.
|
|
13
|
+
*/
|
|
14
|
+
export async function deployMultiDomainSimulation(options) {
|
|
15
|
+
const { anvilRpc, deployerKey, rebalancerKey = ANVIL_REBALANCER_KEY, chains, initialCollateralBalance, tokenDecimals = 18, tokenSymbol = 'SIM', tokenName = 'Simulation Token', } = options;
|
|
16
|
+
const bridgeControllerKey = options.bridgeControllerKey || ANVIL_BRIDGE_CONTROLLER_KEY;
|
|
17
|
+
const mailboxProcessorKey = options.mailboxProcessorKey || ANVIL_MAILBOX_PROCESSOR_KEY;
|
|
18
|
+
// Create fresh provider with no caching
|
|
19
|
+
const provider = new ethers.providers.JsonRpcProvider(anvilRpc);
|
|
20
|
+
// Set fast polling interval for tx.wait() - ethers defaults to 4000ms
|
|
21
|
+
provider.pollingInterval = 100;
|
|
22
|
+
// Disable automatic polling - we don't need event subscriptions during deployment
|
|
23
|
+
provider.polling = false;
|
|
24
|
+
const deployer = new ethers.Wallet(deployerKey, provider);
|
|
25
|
+
const deployerAddress = await deployer.getAddress();
|
|
26
|
+
const rebalancerWallet = new ethers.Wallet(rebalancerKey, provider);
|
|
27
|
+
const rebalancerAddress = await rebalancerWallet.getAddress();
|
|
28
|
+
const bridgeControllerWallet = new ethers.Wallet(bridgeControllerKey, provider);
|
|
29
|
+
const bridgeControllerAddress = await bridgeControllerWallet.getAddress();
|
|
30
|
+
const mailboxProcessorWallet = new ethers.Wallet(mailboxProcessorKey, provider);
|
|
31
|
+
const mailboxProcessorAddress = await mailboxProcessorWallet.getAddress();
|
|
32
|
+
// Step 1: Deploy MockMailboxes for each domain
|
|
33
|
+
const mailboxes = {};
|
|
34
|
+
for (const chain of chains) {
|
|
35
|
+
const mailbox = await new MockMailbox__factory(deployer).deploy(chain.domainId);
|
|
36
|
+
await mailbox.deployed();
|
|
37
|
+
mailboxes[chain.domainId] = mailbox;
|
|
38
|
+
}
|
|
39
|
+
// Step 2: Link mailboxes together (each knows about all others)
|
|
40
|
+
for (const chain of chains) {
|
|
41
|
+
const mailbox = mailboxes[chain.domainId];
|
|
42
|
+
for (const otherChain of chains) {
|
|
43
|
+
if (chain.domainId !== otherChain.domainId) {
|
|
44
|
+
await mailbox.addRemoteMailbox(otherChain.domainId, mailboxes[otherChain.domainId].address);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Step 3: Deploy collateral tokens for each domain
|
|
49
|
+
const totalMint = ethers.BigNumber.from(initialCollateralBalance).mul(COLLATERAL_MULTIPLIER);
|
|
50
|
+
const collateralTokens = {};
|
|
51
|
+
for (const chain of chains) {
|
|
52
|
+
const token = await new ERC20Test__factory(deployer).deploy(tokenName, tokenSymbol, totalMint.toString(), tokenDecimals);
|
|
53
|
+
await token.deployed();
|
|
54
|
+
collateralTokens[chain.domainId] = token;
|
|
55
|
+
}
|
|
56
|
+
// Step 4: Deploy HypERC20Collateral warp tokens for each domain
|
|
57
|
+
const warpTokens = {};
|
|
58
|
+
for (const chain of chains) {
|
|
59
|
+
const scale = ethers.BigNumber.from(10).pow(tokenDecimals);
|
|
60
|
+
const warpToken = await new HypERC20Collateral__factory(deployer).deploy(collateralTokens[chain.domainId].address, scale, mailboxes[chain.domainId].address);
|
|
61
|
+
await warpToken.deployed();
|
|
62
|
+
// Initialize the warp token
|
|
63
|
+
await warpToken.initialize(ethers.constants.AddressZero, // hook
|
|
64
|
+
ethers.constants.AddressZero, // ISM
|
|
65
|
+
deployerAddress);
|
|
66
|
+
warpTokens[chain.domainId] = warpToken;
|
|
67
|
+
}
|
|
68
|
+
// Step 5: Enroll remote routers (link warp tokens together) - batch enrollment
|
|
69
|
+
for (const chain of chains) {
|
|
70
|
+
const warpToken = warpTokens[chain.domainId];
|
|
71
|
+
const remoteDomains = [];
|
|
72
|
+
const remoteRouters = [];
|
|
73
|
+
for (const otherChain of chains) {
|
|
74
|
+
if (chain.domainId !== otherChain.domainId) {
|
|
75
|
+
remoteDomains.push(otherChain.domainId);
|
|
76
|
+
remoteRouters.push(ethers.utils.hexZeroPad(warpTokens[otherChain.domainId].address, 32));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Use batch enrollment for efficiency
|
|
80
|
+
await warpToken.enrollRemoteRouters(remoteDomains, remoteRouters);
|
|
81
|
+
}
|
|
82
|
+
// Step 6: Deploy MockValueTransferBridge for each domain and add to allowed bridges
|
|
83
|
+
const bridges = {};
|
|
84
|
+
for (const chain of chains) {
|
|
85
|
+
const bridge = await new MockValueTransferBridge__factory(deployer).deploy(collateralTokens[chain.domainId].address);
|
|
86
|
+
await bridge.deployed();
|
|
87
|
+
bridges[chain.domainId] = bridge;
|
|
88
|
+
}
|
|
89
|
+
// Step 7: Add bridges to warp tokens for all destination domains
|
|
90
|
+
for (const chain of chains) {
|
|
91
|
+
const warpToken = warpTokens[chain.domainId];
|
|
92
|
+
for (const otherChain of chains) {
|
|
93
|
+
if (chain.domainId !== otherChain.domainId) {
|
|
94
|
+
await warpToken.addBridge(otherChain.domainId, bridges[chain.domainId].address);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Step 8: Add rebalancer (separate account) as allowed rebalancer on all warp tokens
|
|
99
|
+
for (const chain of chains) {
|
|
100
|
+
const warpToken = warpTokens[chain.domainId];
|
|
101
|
+
await warpToken.addRebalancer(rebalancerAddress);
|
|
102
|
+
}
|
|
103
|
+
// Step 9: Transfer collateral tokens to warp contracts
|
|
104
|
+
for (const chain of chains) {
|
|
105
|
+
const token = collateralTokens[chain.domainId];
|
|
106
|
+
const warpToken = warpTokens[chain.domainId];
|
|
107
|
+
const tx = await token.transfer(warpToken.address, initialCollateralBalance);
|
|
108
|
+
await tx.wait();
|
|
109
|
+
}
|
|
110
|
+
// CRITICAL: Clean up the deployment provider to prevent accumulation
|
|
111
|
+
// Each deployment creates a provider with 100ms polling that was never cleaned up
|
|
112
|
+
// After multiple test runs, these accumulate and overwhelm anvil
|
|
113
|
+
provider.removeAllListeners();
|
|
114
|
+
provider.polling = false;
|
|
115
|
+
// Build result
|
|
116
|
+
const domains = {};
|
|
117
|
+
for (const chain of chains) {
|
|
118
|
+
domains[chain.chainName] = {
|
|
119
|
+
chainName: chain.chainName,
|
|
120
|
+
domainId: chain.domainId,
|
|
121
|
+
mailbox: mailboxes[chain.domainId].address,
|
|
122
|
+
warpToken: warpTokens[chain.domainId].address,
|
|
123
|
+
collateralToken: collateralTokens[chain.domainId].address,
|
|
124
|
+
bridge: bridges[chain.domainId].address,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
anvilRpc,
|
|
129
|
+
deployer: deployerAddress,
|
|
130
|
+
deployerKey,
|
|
131
|
+
rebalancer: rebalancerAddress,
|
|
132
|
+
rebalancerKey,
|
|
133
|
+
bridgeController: bridgeControllerAddress,
|
|
134
|
+
bridgeControllerKey,
|
|
135
|
+
mailboxProcessor: mailboxProcessorAddress,
|
|
136
|
+
mailboxProcessorKey,
|
|
137
|
+
domains,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Creates a MultiProvider-compatible chain metadata config for simulation
|
|
142
|
+
*/
|
|
143
|
+
export function createSimulationChainMetadata(anvilRpc, chains) {
|
|
144
|
+
const metadata = {};
|
|
145
|
+
for (const chain of chains) {
|
|
146
|
+
metadata[chain.chainName] = {
|
|
147
|
+
name: chain.chainName,
|
|
148
|
+
chainId: 31337, // Anvil default
|
|
149
|
+
domainId: chain.domainId,
|
|
150
|
+
protocol: 'ethereum',
|
|
151
|
+
rpcUrls: [{ http: anvilRpc }],
|
|
152
|
+
nativeToken: {
|
|
153
|
+
name: 'Ether',
|
|
154
|
+
symbol: 'ETH',
|
|
155
|
+
decimals: 18,
|
|
156
|
+
},
|
|
157
|
+
isTestnet: true,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return metadata;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Gets the current collateral balance for a warp token
|
|
164
|
+
*/
|
|
165
|
+
export async function getWarpTokenBalance(provider, warpTokenAddress, collateralTokenAddress) {
|
|
166
|
+
const token = ERC20Test__factory.connect(collateralTokenAddress, provider);
|
|
167
|
+
const balance = await token.balanceOf(warpTokenAddress);
|
|
168
|
+
return balance.toBigInt();
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=SimulationDeployment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimulationDeployment.js","sourceRoot":"","sources":["../src/SimulationDeployment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { BridgeMockConfig, IRebalancerRunner, MultiDomainDeploymentResult, RebalancerSimConfig, SimulationResult, SimulationTiming, TransferScenario } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default timing for fast simulations
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_TIMING: SimulationTiming;
|
|
6
|
+
/**
|
|
7
|
+
* SimulationEngine orchestrates the execution of transfer scenarios
|
|
8
|
+
* with rebalancer monitoring and KPI collection.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SimulationEngine {
|
|
11
|
+
private readonly deployment;
|
|
12
|
+
private provider;
|
|
13
|
+
private bridgeController?;
|
|
14
|
+
private kpiCollector?;
|
|
15
|
+
private messageTracker?;
|
|
16
|
+
private isRunning;
|
|
17
|
+
private mailboxProcessingInterval?;
|
|
18
|
+
private mailboxProcessingInFlight;
|
|
19
|
+
constructor(deployment: MultiDomainDeploymentResult);
|
|
20
|
+
/**
|
|
21
|
+
* Run a simulation with the given scenario and rebalancer
|
|
22
|
+
*/
|
|
23
|
+
runSimulation(scenario: TransferScenario, rebalancer: IRebalancerRunner, bridgeConfig: BridgeMockConfig, timing: SimulationTiming | undefined, rebalancerStrategyConfig: RebalancerSimConfig['strategyConfig']): Promise<SimulationResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Execute transfers according to the scenario
|
|
26
|
+
*/
|
|
27
|
+
private executeTransfers;
|
|
28
|
+
/**
|
|
29
|
+
* Start periodic processing of mailbox messages (simulates relayer with delay)
|
|
30
|
+
*/
|
|
31
|
+
private startMailboxProcessing;
|
|
32
|
+
/**
|
|
33
|
+
* Stop mailbox processing
|
|
34
|
+
*/
|
|
35
|
+
private stopMailboxProcessing;
|
|
36
|
+
/**
|
|
37
|
+
* Process mailbox deliveries that are ready (past their delivery time)
|
|
38
|
+
* Uses MessageTracker for off-chain tracking with per-message control
|
|
39
|
+
*/
|
|
40
|
+
private processReadyMailboxDeliveries;
|
|
41
|
+
/**
|
|
42
|
+
* Wait for all pending user transfer deliveries to complete
|
|
43
|
+
*/
|
|
44
|
+
private waitForUserTransferDeliveries;
|
|
45
|
+
/**
|
|
46
|
+
* Build WarpCoreConfig from deployment
|
|
47
|
+
*/
|
|
48
|
+
private buildWarpConfig;
|
|
49
|
+
/**
|
|
50
|
+
* Reset internal tracking state (does not reset blockchain state)
|
|
51
|
+
*/
|
|
52
|
+
reset(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Check if simulation is currently running
|
|
55
|
+
*/
|
|
56
|
+
isSimulationRunning(): boolean;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=SimulationEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimulationEngine.d.ts","sourceRoot":"","sources":["../src/SimulationEngine.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,2BAA2B,EAC3B,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,gBAI5B,CAAC;AAEF;;;GAGG;AACH,qBAAa,gBAAgB;IASf,OAAO,CAAC,QAAQ,CAAC,UAAU;IARvC,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,gBAAgB,CAAC,CAAuB;IAChD,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,yBAAyB,CAAC,CAAiB;IACnD,OAAO,CAAC,yBAAyB,CAAS;gBAEb,UAAU,EAAE,2BAA2B;IAQpE;;OAEG;IACG,aAAa,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,iBAAiB,EAC7B,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,gBAAgB,YAAiB,EACzC,wBAAwB,EAAE,mBAAmB,CAAC,gBAAgB,CAAC,GAC9D,OAAO,CAAC,gBAAgB,CAAC;IAmJ5B;;OAEG;YACW,gBAAgB;IAiG9B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;;OAGG;YACW,6BAA6B;IAK3C;;OAEG;YACW,6BAA6B;IAwC3C;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,mBAAmB,IAAI,OAAO;CAG/B"}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { ERC20__factory, HypERC20Collateral__factory, } from '@hyperlane-xyz/core';
|
|
3
|
+
import { TokenStandard } from '@hyperlane-xyz/sdk';
|
|
4
|
+
import { rootLogger } from '@hyperlane-xyz/utils';
|
|
5
|
+
import { BridgeMockController } from './BridgeMockController.js';
|
|
6
|
+
import { KPICollector } from './KPICollector.js';
|
|
7
|
+
import { MessageTracker } from './MessageTracker.js';
|
|
8
|
+
const logger = rootLogger.child({ module: 'SimulationEngine' });
|
|
9
|
+
/**
|
|
10
|
+
* Default timing for fast simulations
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_TIMING = {
|
|
13
|
+
userTransferDeliveryDelay: 0, // Instant for fast tests
|
|
14
|
+
rebalancerPollingFrequency: 1000,
|
|
15
|
+
userTransferInterval: 100,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* SimulationEngine orchestrates the execution of transfer scenarios
|
|
19
|
+
* with rebalancer monitoring and KPI collection.
|
|
20
|
+
*/
|
|
21
|
+
export class SimulationEngine {
|
|
22
|
+
deployment;
|
|
23
|
+
provider;
|
|
24
|
+
bridgeController;
|
|
25
|
+
kpiCollector;
|
|
26
|
+
messageTracker;
|
|
27
|
+
isRunning = false;
|
|
28
|
+
mailboxProcessingInterval;
|
|
29
|
+
mailboxProcessingInFlight = false;
|
|
30
|
+
constructor(deployment) {
|
|
31
|
+
this.deployment = deployment;
|
|
32
|
+
this.provider = new ethers.providers.JsonRpcProvider(deployment.anvilRpc);
|
|
33
|
+
// Set fast polling interval for tx.wait() - ethers defaults to 4000ms
|
|
34
|
+
this.provider.pollingInterval = 100;
|
|
35
|
+
// Disable automatic polling (event subscriptions) but keep pollingInterval for tx.wait()
|
|
36
|
+
this.provider.polling = false;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Run a simulation with the given scenario and rebalancer
|
|
40
|
+
*/
|
|
41
|
+
async runSimulation(scenario, rebalancer, bridgeConfig, timing = DEFAULT_TIMING, rebalancerStrategyConfig) {
|
|
42
|
+
const startTime = Date.now();
|
|
43
|
+
this.isRunning = true;
|
|
44
|
+
try {
|
|
45
|
+
// Initialize components
|
|
46
|
+
// Use bridgeControllerKey for bridge operations to avoid nonce conflicts
|
|
47
|
+
this.bridgeController = new BridgeMockController(this.provider, this.deployment.domains, this.deployment.bridgeControllerKey, bridgeConfig);
|
|
48
|
+
this.kpiCollector = new KPICollector(this.provider, this.deployment.domains);
|
|
49
|
+
// Initialize MessageTracker for off-chain message tracking
|
|
50
|
+
this.messageTracker = new MessageTracker(this.provider, this.deployment.domains, this.deployment.mailboxProcessorKey);
|
|
51
|
+
await this.kpiCollector.initialize();
|
|
52
|
+
await this.messageTracker.initialize();
|
|
53
|
+
await this.bridgeController.start();
|
|
54
|
+
// Wire up MessageTracker events for KPI tracking
|
|
55
|
+
this.messageTracker.on('message_delivered', (message) => {
|
|
56
|
+
this.kpiCollector.recordTransferComplete(message.transferId);
|
|
57
|
+
});
|
|
58
|
+
this.messageTracker.on('message_failed', ({ message }) => {
|
|
59
|
+
// Don't record as failed yet - it will retry
|
|
60
|
+
logger.debug({
|
|
61
|
+
messageId: message.id,
|
|
62
|
+
attempts: message.attempts,
|
|
63
|
+
error: message.lastError,
|
|
64
|
+
}, 'Message failed, will retry');
|
|
65
|
+
});
|
|
66
|
+
// Set up bridge event handlers for rebalance KPI tracking
|
|
67
|
+
// Bridge transfers are rebalancer operations (user transfers go through warp token)
|
|
68
|
+
this.bridgeController.on('transfer_initiated', (event) => {
|
|
69
|
+
const rebalanceId = this.kpiCollector.recordRebalanceStart(event.transfer.origin, event.transfer.destination, event.transfer.amount, BigInt(0));
|
|
70
|
+
// Link bridge transfer ID to rebalance ID for completion tracking
|
|
71
|
+
this.kpiCollector.linkBridgeTransfer(event.transfer.id, rebalanceId);
|
|
72
|
+
});
|
|
73
|
+
this.bridgeController.on('transfer_delivered', (event) => {
|
|
74
|
+
this.kpiCollector.recordRebalanceComplete(event.transfer.id);
|
|
75
|
+
});
|
|
76
|
+
this.bridgeController.on('transfer_failed', (event) => {
|
|
77
|
+
this.kpiCollector.recordRebalanceFailed(event.transfer.id);
|
|
78
|
+
});
|
|
79
|
+
// Build warp config for rebalancer
|
|
80
|
+
const warpConfig = this.buildWarpConfig();
|
|
81
|
+
// Initialize rebalancer
|
|
82
|
+
const rebalancerConfig = {
|
|
83
|
+
pollingFrequency: timing.rebalancerPollingFrequency,
|
|
84
|
+
warpConfig,
|
|
85
|
+
strategyConfig: rebalancerStrategyConfig,
|
|
86
|
+
deployment: this.deployment,
|
|
87
|
+
};
|
|
88
|
+
await rebalancer.initialize(rebalancerConfig);
|
|
89
|
+
// Start rebalancer daemon
|
|
90
|
+
await rebalancer.start();
|
|
91
|
+
// Start periodic mailbox processing for delayed user transfer delivery
|
|
92
|
+
this.startMailboxProcessing();
|
|
93
|
+
// Execute transfers according to scenario
|
|
94
|
+
await this.executeTransfers(scenario, timing);
|
|
95
|
+
// Wait for all user transfer deliveries (respecting delay)
|
|
96
|
+
// Use a timeout to prevent indefinite hanging
|
|
97
|
+
await Promise.race([
|
|
98
|
+
this.waitForUserTransferDeliveries(),
|
|
99
|
+
new Promise((resolve) => setTimeout(resolve, 60000)), // 60s max
|
|
100
|
+
]);
|
|
101
|
+
// Wait for bridge deliveries to complete (rebalancer transfers)
|
|
102
|
+
await this.bridgeController.waitForAllDeliveries(30000);
|
|
103
|
+
// Wait for rebalancer to become idle
|
|
104
|
+
await rebalancer.waitForIdle(5000);
|
|
105
|
+
// Generate final KPIs
|
|
106
|
+
const kpis = await this.kpiCollector.generateKPIs();
|
|
107
|
+
const endTime = Date.now();
|
|
108
|
+
return {
|
|
109
|
+
scenarioName: scenario.name,
|
|
110
|
+
rebalancerName: rebalancer.name,
|
|
111
|
+
startTime,
|
|
112
|
+
endTime,
|
|
113
|
+
duration: endTime - startTime,
|
|
114
|
+
kpis,
|
|
115
|
+
transferRecords: this.kpiCollector.getTransferRecords(),
|
|
116
|
+
rebalanceRecords: this.kpiCollector.getRebalanceRecords(),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
// Always cleanup, even if we timeout or error
|
|
121
|
+
this.isRunning = false;
|
|
122
|
+
this.stopMailboxProcessing();
|
|
123
|
+
try {
|
|
124
|
+
await rebalancer.stop();
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Ignore stop errors
|
|
128
|
+
}
|
|
129
|
+
if (this.bridgeController) {
|
|
130
|
+
try {
|
|
131
|
+
await this.bridgeController.stop();
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Ignore stop errors
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (this.messageTracker) {
|
|
138
|
+
this.messageTracker.removeAllListeners();
|
|
139
|
+
}
|
|
140
|
+
// Clean up provider to release connections
|
|
141
|
+
this.provider.removeAllListeners();
|
|
142
|
+
// Force polling to stop
|
|
143
|
+
this.provider.polling = false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Execute transfers according to the scenario
|
|
148
|
+
*/
|
|
149
|
+
async executeTransfers(scenario, timing) {
|
|
150
|
+
const deployer = new ethers.Wallet(this.deployment.deployerKey, this.provider);
|
|
151
|
+
const startTime = Date.now();
|
|
152
|
+
for (let i = 0; i < scenario.transfers.length; i++) {
|
|
153
|
+
const transfer = scenario.transfers[i];
|
|
154
|
+
// Wait until it's time for this transfer
|
|
155
|
+
const targetTime = startTime + transfer.timestamp;
|
|
156
|
+
const waitTime = targetTime - Date.now();
|
|
157
|
+
if (waitTime > 0) {
|
|
158
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
159
|
+
}
|
|
160
|
+
// Record transfer start
|
|
161
|
+
this.kpiCollector.recordTransferStart(transfer.id, transfer.origin, transfer.destination, transfer.amount);
|
|
162
|
+
// Execute the transfer via warp token
|
|
163
|
+
const originDomain = this.deployment.domains[transfer.origin];
|
|
164
|
+
const destDomain = this.deployment.domains[transfer.destination];
|
|
165
|
+
const warpToken = HypERC20Collateral__factory.connect(originDomain.warpToken, deployer);
|
|
166
|
+
try {
|
|
167
|
+
const txStartTime = Date.now();
|
|
168
|
+
// Approve collateral token for warp transfer
|
|
169
|
+
const collateralToken = ERC20__factory.connect(originDomain.collateralToken, deployer);
|
|
170
|
+
const approveTx = await collateralToken.approve(originDomain.warpToken, transfer.amount);
|
|
171
|
+
await approveTx.wait();
|
|
172
|
+
const approveTime = Date.now() - txStartTime;
|
|
173
|
+
// Quote gas payment (mock mailbox should return 0)
|
|
174
|
+
const gasPayment = await warpToken.quoteGasPayment(destDomain.domainId);
|
|
175
|
+
// Transfer remote
|
|
176
|
+
const recipientBytes32 = ethers.utils.hexZeroPad(transfer.user, 32);
|
|
177
|
+
const transferTx = await warpToken.transferRemote(destDomain.domainId, recipientBytes32, transfer.amount, { value: gasPayment });
|
|
178
|
+
await transferTx.wait();
|
|
179
|
+
const totalTxTime = Date.now() - txStartTime;
|
|
180
|
+
// Log slow transfers (>1000ms suggests significant RPC contention)
|
|
181
|
+
if (totalTxTime > 1000) {
|
|
182
|
+
logger.warn({ transferId: transfer.id, totalTxTime, approveTime }, 'Slow transfer detected');
|
|
183
|
+
}
|
|
184
|
+
// Track message for delayed delivery via MessageTracker
|
|
185
|
+
await this.messageTracker.trackMessage(transfer.id, transfer.origin, transfer.destination, timing.userTransferDeliveryDelay);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
logger.error({
|
|
189
|
+
transferId: transfer.id,
|
|
190
|
+
error: error instanceof Error ? error.message : String(error),
|
|
191
|
+
}, 'Transfer failed');
|
|
192
|
+
this.kpiCollector.recordTransferFailed(transfer.id);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
logger.info('All transfers executed');
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Start periodic processing of mailbox messages (simulates relayer with delay)
|
|
199
|
+
*/
|
|
200
|
+
startMailboxProcessing() {
|
|
201
|
+
// Process mailbox every 100ms to check for deliveries due
|
|
202
|
+
const PROCESS_INTERVAL = 100;
|
|
203
|
+
this.mailboxProcessingInterval = setInterval(async () => {
|
|
204
|
+
// Guard against overlapping ticks to prevent nonce collisions
|
|
205
|
+
if (this.mailboxProcessingInFlight)
|
|
206
|
+
return;
|
|
207
|
+
this.mailboxProcessingInFlight = true;
|
|
208
|
+
try {
|
|
209
|
+
await this.processReadyMailboxDeliveries();
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
this.mailboxProcessingInFlight = false;
|
|
213
|
+
}
|
|
214
|
+
}, PROCESS_INTERVAL);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Stop mailbox processing
|
|
218
|
+
*/
|
|
219
|
+
stopMailboxProcessing() {
|
|
220
|
+
if (this.mailboxProcessingInterval) {
|
|
221
|
+
clearInterval(this.mailboxProcessingInterval);
|
|
222
|
+
this.mailboxProcessingInterval = undefined;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Process mailbox deliveries that are ready (past their delivery time)
|
|
227
|
+
* Uses MessageTracker for off-chain tracking with per-message control
|
|
228
|
+
*/
|
|
229
|
+
async processReadyMailboxDeliveries() {
|
|
230
|
+
if (!this.messageTracker)
|
|
231
|
+
return;
|
|
232
|
+
await this.messageTracker.processReadyMessages();
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Wait for all pending user transfer deliveries to complete
|
|
236
|
+
*/
|
|
237
|
+
async waitForUserTransferDeliveries(timeout = 30000) {
|
|
238
|
+
if (!this.messageTracker)
|
|
239
|
+
return;
|
|
240
|
+
const startTime = Date.now();
|
|
241
|
+
while (this.messageTracker.hasPendingMessages()) {
|
|
242
|
+
if (Date.now() - startTime > timeout) {
|
|
243
|
+
const pending = this.messageTracker.getPendingMessages();
|
|
244
|
+
logger.warn({ pendingCount: pending.length }, 'Timeout waiting for user transfer deliveries - marking as failed');
|
|
245
|
+
// Mark pending messages as failed so KPIs reflect reality
|
|
246
|
+
for (const msg of pending) {
|
|
247
|
+
logger.warn({
|
|
248
|
+
messageId: msg.id,
|
|
249
|
+
origin: msg.origin,
|
|
250
|
+
destination: msg.destination,
|
|
251
|
+
status: msg.status,
|
|
252
|
+
attempts: msg.attempts,
|
|
253
|
+
error: msg.lastError || 'timeout',
|
|
254
|
+
}, 'Marking pending message as failed');
|
|
255
|
+
// Record as failed in KPI collector
|
|
256
|
+
this.kpiCollector?.recordTransferFailed(msg.transferId);
|
|
257
|
+
}
|
|
258
|
+
// Clear pending messages so they don't block
|
|
259
|
+
this.messageTracker.clear();
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
// Interval handles processing; just wait
|
|
263
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Build WarpCoreConfig from deployment
|
|
268
|
+
*/
|
|
269
|
+
buildWarpConfig() {
|
|
270
|
+
const tokens = Object.entries(this.deployment.domains).map(([chainName, domain]) => ({
|
|
271
|
+
chainName,
|
|
272
|
+
standard: TokenStandard.EvmHypCollateral,
|
|
273
|
+
decimals: 18,
|
|
274
|
+
symbol: 'SIM',
|
|
275
|
+
name: 'Simulation Token',
|
|
276
|
+
addressOrDenom: domain.warpToken,
|
|
277
|
+
collateralAddressOrDenom: domain.collateralToken,
|
|
278
|
+
connections: Object.entries(this.deployment.domains)
|
|
279
|
+
.filter(([name]) => name !== chainName)
|
|
280
|
+
.map(([name, d]) => ({
|
|
281
|
+
token: `ethereum|${name}|${d.warpToken}`,
|
|
282
|
+
})),
|
|
283
|
+
}));
|
|
284
|
+
return { tokens };
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Reset internal tracking state (does not reset blockchain state)
|
|
288
|
+
*/
|
|
289
|
+
reset() {
|
|
290
|
+
// Clear message tracker state
|
|
291
|
+
if (this.messageTracker) {
|
|
292
|
+
this.messageTracker.clear();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Check if simulation is currently running
|
|
297
|
+
*/
|
|
298
|
+
isSimulationRunning() {
|
|
299
|
+
return this.isRunning;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=SimulationEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimulationEngine.js","sourceRoot":"","sources":["../src/SimulationEngine.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebalancer Simulation Framework
|
|
3
|
+
*
|
|
4
|
+
* A fast, real-time simulation framework for testing Hyperlane warp route
|
|
5
|
+
* rebalancers against synthetic transfer scenarios.
|
|
6
|
+
*/
|
|
7
|
+
export { BridgeMockController } from './BridgeMockController.js';
|
|
8
|
+
export { KPICollector } from './KPICollector.js';
|
|
9
|
+
export { MessageTracker } from './MessageTracker.js';
|
|
10
|
+
export { RebalancerSimulationHarness } from './RebalancerSimulationHarness.js';
|
|
11
|
+
export { deployMultiDomainSimulation, getWarpTokenBalance, } from './SimulationDeployment.js';
|
|
12
|
+
export { DEFAULT_TIMING, SimulationEngine } from './SimulationEngine.js';
|
|
13
|
+
export { ScenarioGenerator } from './ScenarioGenerator.js';
|
|
14
|
+
export { getScenariosDir, listScenarios, loadScenario, loadScenarioFile, } from './ScenarioLoader.js';
|
|
15
|
+
export { NoOpRebalancer } from './runners/NoOpRebalancer.js';
|
|
16
|
+
export { cleanupProductionRebalancer, ProductionRebalancerRunner, } from './runners/ProductionRebalancerRunner.js';
|
|
17
|
+
export { cleanupSimpleRunner, SimpleRunner } from './runners/SimpleRunner.js';
|
|
18
|
+
export { SimulationRegistry } from './runners/SimulationRegistry.js';
|
|
19
|
+
export { generateTimelineHtml } from './visualizer/HtmlTimelineGenerator.js';
|
|
20
|
+
export type { BridgeEvent, BridgeEventType, BridgeMockConfig, BridgeRouteConfig, PendingTransfer, DeployedDomain, MultiDomainDeploymentOptions, MultiDomainDeploymentResult, SimulatedChainConfig, ChainMetrics, ComparisonReport, RebalanceRecord, SimulationKPIs, SimulationResult, StateSnapshot, TransferRecord, ChainStrategyConfig, IRebalancerRunner, RebalancerEvent, RebalancerSimConfig, RebalancerStrategyConfig, RandomTrafficOptions, ScenarioExpectations, ScenarioFile, SerializedBridgeConfig, SerializedScenario, SerializedStrategyConfig, SerializedTransferEvent, SimulationTiming, SurgeScenarioOptions, TransferEvent, TransferScenario, UnidirectionalFlowOptions, HtmlGeneratorOptions, SimulationConfig, TimelineEvent, VisualizationData, } from './types.js';
|
|
21
|
+
export { ANVIL_BRIDGE_CONTROLLER_ADDRESS, ANVIL_BRIDGE_CONTROLLER_KEY, ANVIL_DEPLOYER_ADDRESS, ANVIL_DEPLOYER_KEY, ANVIL_MAILBOX_PROCESSOR_ADDRESS, ANVIL_MAILBOX_PROCESSOR_KEY, ANVIL_REBALANCER_ADDRESS, ANVIL_REBALANCER_KEY, createSymmetricBridgeConfig, DEFAULT_BRIDGE_ROUTE_CONFIG, DEFAULT_SIMULATED_CHAINS, toVisualizationData, } from './types.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAGrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAG7E,YAAY,EAEV,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EAEf,cAAc,EACd,4BAA4B,EAC5B,2BAA2B,EAC3B,oBAAoB,EAEpB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EAEd,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EAExB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EAEzB,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,EAC3B,sBAAsB,EACtB,kBAAkB,EAClB,+BAA+B,EAC/B,2BAA2B,EAC3B,wBAAwB,EACxB,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebalancer Simulation Framework
|
|
3
|
+
*
|
|
4
|
+
* A fast, real-time simulation framework for testing Hyperlane warp route
|
|
5
|
+
* rebalancers against synthetic transfer scenarios.
|
|
6
|
+
*/
|
|
7
|
+
// Core simulation classes
|
|
8
|
+
export { BridgeMockController } from './BridgeMockController.js';
|
|
9
|
+
export { KPICollector } from './KPICollector.js';
|
|
10
|
+
export { MessageTracker } from './MessageTracker.js';
|
|
11
|
+
export { RebalancerSimulationHarness } from './RebalancerSimulationHarness.js';
|
|
12
|
+
export { deployMultiDomainSimulation, getWarpTokenBalance, } from './SimulationDeployment.js';
|
|
13
|
+
export { DEFAULT_TIMING, SimulationEngine } from './SimulationEngine.js';
|
|
14
|
+
// Scenario generation and loading
|
|
15
|
+
export { ScenarioGenerator } from './ScenarioGenerator.js';
|
|
16
|
+
export { getScenariosDir, listScenarios, loadScenario, loadScenarioFile, } from './ScenarioLoader.js';
|
|
17
|
+
// Rebalancer runners
|
|
18
|
+
export { NoOpRebalancer } from './runners/NoOpRebalancer.js';
|
|
19
|
+
export { cleanupProductionRebalancer, ProductionRebalancerRunner, } from './runners/ProductionRebalancerRunner.js';
|
|
20
|
+
export { cleanupSimpleRunner, SimpleRunner } from './runners/SimpleRunner.js';
|
|
21
|
+
export { SimulationRegistry } from './runners/SimulationRegistry.js';
|
|
22
|
+
// Visualization
|
|
23
|
+
export { generateTimelineHtml } from './visualizer/HtmlTimelineGenerator.js';
|
|
24
|
+
// Constants and utility functions
|
|
25
|
+
export { ANVIL_BRIDGE_CONTROLLER_ADDRESS, ANVIL_BRIDGE_CONTROLLER_KEY, ANVIL_DEPLOYER_ADDRESS, ANVIL_DEPLOYER_KEY, ANVIL_MAILBOX_PROCESSOR_ADDRESS, ANVIL_MAILBOX_PROCESSOR_KEY, ANVIL_REBALANCER_ADDRESS, ANVIL_REBALANCER_KEY, createSymmetricBridgeConfig, DEFAULT_BRIDGE_ROUTE_CONFIG, DEFAULT_SIMULATED_CHAINS, toVisualizationData, } from './types.js';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,0BAA0B;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,kCAAkC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,qBAAqB;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,gBAAgB;AAChB,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAiD7E,kCAAkC;AAClC,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,EAC3B,sBAAsB,EACtB,kBAAkB,EAClB,+BAA+B,EAC/B,2BAA2B,EAC3B,wBAAwB,EACxB,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { IRebalancerRunner, RebalancerEvent, RebalancerSimConfig } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* NoOpRebalancer does nothing - used as a baseline to show what happens
|
|
5
|
+
* when no rebalancer is running. Useful for demonstrating that transfers
|
|
6
|
+
* fail without active liquidity management.
|
|
7
|
+
*/
|
|
8
|
+
export declare class NoOpRebalancer extends EventEmitter implements IRebalancerRunner {
|
|
9
|
+
readonly name = "NoOpRebalancer";
|
|
10
|
+
initialize(_config: RebalancerSimConfig): Promise<void>;
|
|
11
|
+
start(): Promise<void>;
|
|
12
|
+
stop(): Promise<void>;
|
|
13
|
+
isActive(): boolean;
|
|
14
|
+
waitForIdle(_timeoutMs?: number): Promise<void>;
|
|
15
|
+
on(_event: 'rebalance', _listener: (e: RebalancerEvent) => void): this;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=NoOpRebalancer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoOpRebalancer.d.ts","sourceRoot":"","sources":["../../src/runners/NoOpRebalancer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,YAAa,YAAW,iBAAiB;IAC3E,QAAQ,CAAC,IAAI,oBAAoB;IAE3B,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,QAAQ,IAAI,OAAO;IAIb,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;CAGvE"}
|