@hyperlane-xyz/cli
Version:
A command-line utility for common Hyperlane operations
172 lines • 7.43 kB
JavaScript
import { DeployedCoreAddressesSchema, EvmCoreModule, } from '@hyperlane-xyz/sdk';
import { ProtocolType, assert } from '@hyperlane-xyz/utils';
import { DEFAULT_WARP_ROUTE_DEPLOYMENT_CONFIG_PATH } from '../../../commands/options.js';
import { readCoreDeployConfigs } from '../../../config/core.js';
import { readChainSubmissionStrategyConfig } from '../../../config/strategy.js';
import { log } from '../../../logger.js';
import { extractChainsFromObj, runMultiChainSelectionStep, runSingleChainSelectionStep, } from '../../../utils/chains.js';
import { isFile, readYamlOrJson, runFileSelectionStep, } from '../../../utils/files.js';
import { getWarpCoreConfigOrExit } from '../../../utils/warp.js';
var ChainSelectionMode;
(function (ChainSelectionMode) {
ChainSelectionMode[ChainSelectionMode["AGENT_KURTOSIS"] = 0] = "AGENT_KURTOSIS";
ChainSelectionMode[ChainSelectionMode["WARP_CONFIG"] = 1] = "WARP_CONFIG";
ChainSelectionMode[ChainSelectionMode["WARP_READ"] = 2] = "WARP_READ";
ChainSelectionMode[ChainSelectionMode["STRATEGY"] = 3] = "STRATEGY";
ChainSelectionMode[ChainSelectionMode["CORE_APPLY"] = 4] = "CORE_APPLY";
ChainSelectionMode[ChainSelectionMode["DEFAULT"] = 5] = "DEFAULT";
})(ChainSelectionMode || (ChainSelectionMode = {}));
// This class could be broken down into multiple strategies
/**
* @title MultiChainResolver
* @notice Resolves chains based on the specified selection mode.
*/
export class MultiChainResolver {
mode;
constructor(mode) {
this.mode = mode;
}
async resolveChains(argv) {
switch (this.mode) {
case ChainSelectionMode.WARP_CONFIG:
return this.resolveWarpRouteConfigChains(argv);
case ChainSelectionMode.WARP_READ:
return this.resolveWarpCoreConfigChains(argv);
case ChainSelectionMode.AGENT_KURTOSIS:
return this.resolveAgentChains(argv);
case ChainSelectionMode.STRATEGY:
return this.resolveStrategyChains(argv);
case ChainSelectionMode.CORE_APPLY:
return this.resolveCoreApplyChains(argv);
case ChainSelectionMode.DEFAULT:
default:
return this.resolveRelayerChains(argv);
}
}
async resolveWarpRouteConfigChains(argv) {
argv.config ||= DEFAULT_WARP_ROUTE_DEPLOYMENT_CONFIG_PATH;
argv.context.chains = await this.getWarpRouteConfigChains(argv.config.trim(), argv.context.skipConfirmation);
return argv.context.chains;
}
async resolveWarpCoreConfigChains(argv) {
if (argv.symbol || argv.warp) {
const warpCoreConfig = await getWarpCoreConfigOrExit({
context: argv.context,
warp: argv.warp,
symbol: argv.symbol,
});
argv.context.warpCoreConfig = warpCoreConfig;
const chains = extractChainsFromObj(warpCoreConfig);
return chains;
}
else if (argv.chain) {
return [argv.chain];
}
else {
throw new Error(`Please specify either a symbol, chain and address or warp file`);
}
}
async resolveAgentChains(argv) {
const { chainMetadata } = argv.context;
argv.origin =
argv.origin ??
(await runSingleChainSelectionStep(chainMetadata, 'Select the origin chain'));
if (!argv.targets) {
const selectedRelayChains = await runMultiChainSelectionStep({
chainMetadata: chainMetadata,
message: 'Select chains to relay between',
requireNumber: 2,
});
argv.targets = selectedRelayChains.join(',');
}
return [argv.origin, ...argv.targets];
}
async resolveStrategyChains(argv) {
const strategy = await readChainSubmissionStrategyConfig(argv.strategy);
return extractChainsFromObj(strategy);
}
async resolveRelayerChains(argv) {
const { multiProvider } = argv.context;
const chains = new Set();
if (argv.origin) {
chains.add(argv.origin);
}
if (argv.chain) {
chains.add(argv.chain);
}
if (argv.chains) {
const additionalChains = argv.chains
.split(',')
.map((item) => item.trim());
return Array.from(new Set([...chains, ...additionalChains]));
}
// If no destination is specified, return all EVM chains
if (!argv.destination) {
return Array.from(this.getEvmChains(multiProvider));
}
chains.add(argv.destination);
return Array.from(chains);
}
async getWarpRouteConfigChains(configPath, skipConfirmation) {
if (!configPath || !isFile(configPath)) {
assert(!skipConfirmation, 'Warp route deployment config is required');
configPath = await runFileSelectionStep('./configs', 'Warp route deployment config', 'warp');
}
else {
log(`Using warp route deployment config at ${configPath}`);
}
// Alternative to readWarpRouteDeployConfig that doesn't use context for signer and zod validation
const warpRouteConfig = (await readYamlOrJson(configPath));
const chains = Object.keys(warpRouteConfig);
assert(chains.length !== 0, 'No chains found in warp route deployment config');
return chains;
}
async resolveCoreApplyChains(argv) {
try {
const config = readCoreDeployConfigs(argv.config);
if (!config?.interchainAccountRouter) {
return [argv.chain];
}
const addresses = await argv.context.registry.getChainAddresses(argv.chain);
const coreAddresses = DeployedCoreAddressesSchema.parse(addresses);
const evmCoreModule = new EvmCoreModule(argv.context.multiProvider, {
chain: argv.chain,
config,
addresses: coreAddresses,
});
const transactions = await evmCoreModule.update(config);
return Array.from(new Set(transactions.map((tx) => tx.chainId))).map((chainId) => argv.context.multiProvider.getChainName(chainId));
}
catch (error) {
throw new Error(`Failed to resolve core apply chains`, {
cause: error,
});
}
}
getEvmChains(multiProvider) {
const chains = multiProvider.getKnownChainNames();
return chains.filter((chain) => multiProvider.getProtocol(chain) === ProtocolType.Ethereum);
}
static forAgentKurtosis() {
return new MultiChainResolver(ChainSelectionMode.AGENT_KURTOSIS);
}
static forRelayer() {
return new MultiChainResolver(ChainSelectionMode.DEFAULT);
}
static forStrategyConfig() {
return new MultiChainResolver(ChainSelectionMode.STRATEGY);
}
static forWarpRouteConfig() {
return new MultiChainResolver(ChainSelectionMode.WARP_CONFIG);
}
static forWarpCoreConfig() {
return new MultiChainResolver(ChainSelectionMode.WARP_READ);
}
static forCoreApply() {
return new MultiChainResolver(ChainSelectionMode.CORE_APPLY);
}
static default() {
return new MultiChainResolver(ChainSelectionMode.DEFAULT);
}
}
//# sourceMappingURL=MultiChainResolver.js.map