UNPKG

@hyperlane-xyz/cli

Version:

A command-line utility for common Hyperlane operations

172 lines 7.43 kB
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