diff --git a/.changeset/hot-spies-share.md b/.changeset/hot-spies-share.md new file mode 100644 index 0000000000..4a215ae53c --- /dev/null +++ b/.changeset/hot-spies-share.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/cli': minor +--- + +fix signer strategy init for broken cli commands diff --git a/typescript/cli/src/commands/signCommands.ts b/typescript/cli/src/commands/signCommands.ts index 8cfa6d4c1a..8243a10a88 100644 --- a/typescript/cli/src/commands/signCommands.ts +++ b/typescript/cli/src/commands/signCommands.ts @@ -13,7 +13,8 @@ export const SIGN_COMMANDS = [ export function isSignCommand(argv: any): boolean { //TODO: fix reading and checking warp without signer, and remove this const temporarySignCommandsCheck = - argv._[0] === 'warp' && (argv._[1] === 'read' || argv._[1] === 'check'); + argv._[0] === 'warp' && + (argv._[1] === 'read' || argv._[1] === 'check' || argv._[1] === 'verify'); return ( SIGN_COMMANDS.includes(argv._[0]) || (argv._.length > 1 && SIGN_COMMANDS.includes(argv._[1])) || diff --git a/typescript/cli/src/context/strategies/chain/ChainResolverFactory.ts b/typescript/cli/src/context/strategies/chain/ChainResolverFactory.ts index e417ba27b3..8e91417501 100644 --- a/typescript/cli/src/context/strategies/chain/ChainResolverFactory.ts +++ b/typescript/cli/src/context/strategies/chain/ChainResolverFactory.ts @@ -1,7 +1,6 @@ import { CommandType } from '../../../commands/signCommands.js'; import { MultiChainResolver } from './MultiChainResolver.js'; -import { SingleChainResolver } from './SingleChainResolver.js'; import { ChainResolver } from './types.js'; /** @@ -11,13 +10,16 @@ import { ChainResolver } from './types.js'; export class ChainResolverFactory { private static strategyMap: Map ChainResolver> = new Map([ [CommandType.WARP_DEPLOY, () => MultiChainResolver.forWarpRouteConfig()], - [CommandType.WARP_SEND, () => MultiChainResolver.forOriginDestination()], + // Using the forRelayer resolver because warp send allows the user to self relay the tx + [CommandType.WARP_SEND, () => MultiChainResolver.forRelayer()], [CommandType.WARP_APPLY, () => MultiChainResolver.forWarpRouteConfig()], [CommandType.WARP_READ, () => MultiChainResolver.forWarpCoreConfig()], [CommandType.WARP_CHECK, () => MultiChainResolver.forWarpCoreConfig()], - [CommandType.SEND_MESSAGE, () => MultiChainResolver.forOriginDestination()], + // Using the forRelayer resolver because send allows the user to self relay the tx + [CommandType.SEND_MESSAGE, () => MultiChainResolver.forRelayer()], [CommandType.AGENT_KURTOSIS, () => MultiChainResolver.forAgentKurtosis()], - [CommandType.STATUS, () => MultiChainResolver.forOriginDestination()], + // Using the forRelayer resolver because status allows the user to self relay the tx + [CommandType.STATUS, () => MultiChainResolver.forRelayer()], [CommandType.SUBMIT, () => MultiChainResolver.forStrategyConfig()], [CommandType.RELAYER, () => MultiChainResolver.forRelayer()], [CommandType.CORE_APPLY, () => MultiChainResolver.forCoreApply()], @@ -30,7 +32,7 @@ export class ChainResolverFactory { static getStrategy(argv: Record): ChainResolver { const commandKey = `${argv._[0]}:${argv._[1] || ''}`.trim() as CommandType; const createStrategy = - this.strategyMap.get(commandKey) || (() => new SingleChainResolver()); + this.strategyMap.get(commandKey) || (() => MultiChainResolver.default()); return createStrategy(); } } diff --git a/typescript/cli/src/context/strategies/chain/MultiChainResolver.ts b/typescript/cli/src/context/strategies/chain/MultiChainResolver.ts index 64f3257520..8563e9e5d9 100644 --- a/typescript/cli/src/context/strategies/chain/MultiChainResolver.ts +++ b/typescript/cli/src/context/strategies/chain/MultiChainResolver.ts @@ -4,8 +4,9 @@ import { DeployedCoreAddresses, DeployedCoreAddressesSchema, EvmCoreModule, + MultiProvider, } from '@hyperlane-xyz/sdk'; -import { assert } from '@hyperlane-xyz/utils'; +import { ProtocolType, assert } from '@hyperlane-xyz/utils'; import { DEFAULT_WARP_ROUTE_DEPLOYMENT_CONFIG_PATH } from '../../../commands/options.js'; import { readCoreDeployConfigs } from '../../../config/core.js'; @@ -26,13 +27,12 @@ import { getWarpCoreConfigOrExit } from '../../../utils/warp.js'; import { ChainResolver } from './types.js'; enum ChainSelectionMode { - ORIGIN_DESTINATION, AGENT_KURTOSIS, WARP_CONFIG, WARP_READ, STRATEGY, - RELAYER, CORE_APPLY, + DEFAULT, } // This class could be broken down into multiple strategies @@ -54,13 +54,11 @@ export class MultiChainResolver implements ChainResolver { return this.resolveAgentChains(argv); case ChainSelectionMode.STRATEGY: return this.resolveStrategyChains(argv); - case ChainSelectionMode.RELAYER: - return this.resolveRelayerChains(argv); case ChainSelectionMode.CORE_APPLY: return this.resolveCoreApplyChains(argv); - case ChainSelectionMode.ORIGIN_DESTINATION: + case ChainSelectionMode.DEFAULT: default: - return this.resolveOriginDestinationChains(argv); + return this.resolveRelayerChains(argv); } } @@ -119,28 +117,6 @@ export class MultiChainResolver implements ChainResolver { return [argv.origin, ...argv.targets]; } - private async resolveOriginDestinationChains( - argv: Record, - ): Promise { - const { chainMetadata } = argv.context; - - argv.origin = - argv.origin ?? - (await runSingleChainSelectionStep( - chainMetadata, - 'Select the origin chain', - )); - - argv.destination = - argv.destination ?? - (await runSingleChainSelectionStep( - chainMetadata, - 'Select the destination chain', - )); - - return [argv.origin, argv.destination]; - } - private async resolveStrategyChains( argv: Record, ): Promise { @@ -151,7 +127,29 @@ export class MultiChainResolver implements ChainResolver { private async resolveRelayerChains( argv: Record, ): Promise { - return argv.chains.split(',').map((item: string) => item.trim()); + const { multiProvider } = argv.context; + const chains = []; + + if (argv.origin) { + chains.push(argv.origin); + } + + if (argv.destination) { + chains.push(argv.destination); + } + + if (!argv.chains) { + return Array.from( + new Set([...chains, ...this.getEvmChains(multiProvider)]), + ); + } + + return Array.from( + new Set([ + ...chains, + ...argv.chains.split(',').map((item: string) => item.trim()), + ]), + ); } private async getWarpRouteConfigChains( @@ -219,16 +217,20 @@ export class MultiChainResolver implements ChainResolver { } } - static forAgentKurtosis(): MultiChainResolver { - return new MultiChainResolver(ChainSelectionMode.AGENT_KURTOSIS); + private getEvmChains(multiProvider: MultiProvider): ChainName[] { + const chains = multiProvider.getKnownChainNames(); + + return chains.filter( + (chain) => multiProvider.getProtocol(chain) === ProtocolType.Ethereum, + ); } - static forOriginDestination(): MultiChainResolver { - return new MultiChainResolver(ChainSelectionMode.ORIGIN_DESTINATION); + static forAgentKurtosis(): MultiChainResolver { + return new MultiChainResolver(ChainSelectionMode.AGENT_KURTOSIS); } static forRelayer(): MultiChainResolver { - return new MultiChainResolver(ChainSelectionMode.RELAYER); + return new MultiChainResolver(ChainSelectionMode.DEFAULT); } static forStrategyConfig(): MultiChainResolver { @@ -246,4 +248,8 @@ export class MultiChainResolver implements ChainResolver { static forCoreApply(): MultiChainResolver { return new MultiChainResolver(ChainSelectionMode.CORE_APPLY); } + + static default(): MultiChainResolver { + return new MultiChainResolver(ChainSelectionMode.DEFAULT); + } } diff --git a/typescript/cli/src/context/strategies/signer/MultiProtocolSignerManager.ts b/typescript/cli/src/context/strategies/signer/MultiProtocolSignerManager.ts index 12f9c0f819..f8e411bad1 100644 --- a/typescript/cli/src/context/strategies/signer/MultiProtocolSignerManager.ts +++ b/typescript/cli/src/context/strategies/signer/MultiProtocolSignerManager.ts @@ -118,12 +118,12 @@ export class MultiProtocolSignerManager { let privateKey: string; if (this.options.key) { - this.logger.info( + this.logger.debug( `Using private key passed via CLI --key flag for chain ${chain}`, ); privateKey = this.options.key; } else if (ENV.HYP_KEY) { - this.logger.info(`Using private key from .env for chain ${chain}`); + this.logger.debug(`Using private key from .env for chain ${chain}`); privateKey = ENV.HYP_KEY; } else { privateKey = await this.extractPrivateKey(chain, signerStrategy); @@ -145,7 +145,7 @@ export class MultiProtocolSignerManager { `No private key found for chain ${chain}`, ); - this.logger.info( + this.logger.debug( `Extracting private key from strategy config/user prompt for chain ${chain}`, ); return strategyConfig.privateKey;