From dcf8b800a9a4c06b140efc3092b72bf995f1452a Mon Sep 17 00:00:00 2001 From: J M Rossy Date: Fri, 15 Dec 2023 11:34:33 -0500 Subject: [PATCH] Fixes for commands with --yes flag (#3063) ### Description Consistently respect --yes flag for all user prompts in the core and warp deploy commands ### Related issues Fixes #3056 ### Backward compatibility Yes ### Testing Locally with CI test alterations --- .changeset/lovely-laws-cover.md | 5 +++++ typescript/cli/src/config/artifacts.ts | 20 +++++++++++++----- typescript/cli/src/context.ts | 22 ++++++++++++------- typescript/cli/src/deploy/core.ts | 29 +++++++++++++++++++++----- typescript/cli/src/deploy/warp.ts | 7 +++++++ 5 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 .changeset/lovely-laws-cover.md diff --git a/.changeset/lovely-laws-cover.md b/.changeset/lovely-laws-cover.md new file mode 100644 index 000000000..71078de54 --- /dev/null +++ b/.changeset/lovely-laws-cover.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/cli': patch +--- + +Fixes for commands with --yes flag diff --git a/typescript/cli/src/config/artifacts.ts b/typescript/cli/src/config/artifacts.ts index 5b54b169f..87a994ded 100644 --- a/typescript/cli/src/config/artifacts.ts +++ b/typescript/cli/src/config/artifacts.ts @@ -33,14 +33,24 @@ export function readDeploymentArtifacts(filePath: string) { return artifacts; } -export async function runDeploymentArtifactStep( - artifactsPath?: string, - message?: string, - selectedChains?: ChainName[], +export async function runDeploymentArtifactStep({ + artifactsPath, + message, + selectedChains, defaultArtifactsPath = './artifacts', defaultArtifactsNamePattern = 'core-deployment', -): Promise | undefined> { + skipConfirmation = false, +}: { + artifactsPath?: string; + message?: string; + selectedChains?: ChainName[]; + defaultArtifactsPath?: string; + defaultArtifactsNamePattern?: string; + skipConfirmation?: boolean; +}): Promise | undefined> { if (!artifactsPath) { + if (skipConfirmation) return undefined; + const useArtifacts = await confirm({ message: message || 'Do you want use some existing contract addresses?', }); diff --git a/typescript/cli/src/context.ts b/typescript/cli/src/context.ts index d3aa6d58e..11fa8326d 100644 --- a/typescript/cli/src/context.ts +++ b/typescript/cli/src/context.ts @@ -55,6 +55,7 @@ interface ContextSettings { key?: string; promptMessage?: string; }; + skipConfirmation?: boolean; } interface CommandContextBase { @@ -75,29 +76,34 @@ export async function getContext

({ chainConfigPath, coreConfig, keyConfig, + skipConfirmation, }: P): Promise> { const customChains = readChainConfigsIfExists(chainConfigPath); let signer = undefined; if (keyConfig) { - const key = - keyConfig.key || - (await input({ + let key: string; + if (keyConfig.key) key = keyConfig.key; + else if (skipConfirmation) throw new Error('No key provided'); + else + key = await input({ message: keyConfig.promptMessage || 'Please enter a private key or use the HYP_KEY environment variable', - })); + }); signer = keyToSigner(key); } let coreArtifacts = undefined; if (coreConfig) { coreArtifacts = - (await runDeploymentArtifactStep( - coreConfig.coreArtifactsPath, - coreConfig.promptMessage || + (await runDeploymentArtifactStep({ + artifactsPath: coreConfig.coreArtifactsPath, + message: + coreConfig.promptMessage || 'Do you want to use some core deployment address artifacts? This is required for PI chains (non-core chains).', - )) || {}; + skipConfirmation, + })) || {}; } const multiProvider = getMultiProvider(customChains, signer); diff --git a/typescript/cli/src/deploy/core.ts b/typescript/cli/src/deploy/core.ts index c49875ba2..47d0b688c 100644 --- a/typescript/cli/src/deploy/core.ts +++ b/typescript/cli/src/deploy/core.ts @@ -79,17 +79,23 @@ export async function runCoreDeploy({ const { customChains, multiProvider, signer } = await getContext({ chainConfigPath, keyConfig: { key }, + skipConfirmation, }); if (!chains?.length) { + if (skipConfirmation) throw new Error('No chains provided'); chains = await runMultiChainSelectionStep( customChains, 'Select chains to connect', true, ); } - const artifacts = await runArtifactStep(chains, artifactsPath); - const result = await runIsmStep(chains, ismConfigPath); + const artifacts = await runArtifactStep( + chains, + skipConfirmation, + artifactsPath, + ); + const result = await runIsmStep(chains, skipConfirmation, ismConfigPath); // we can either specify the full ISM config or just the multisig config const isIsmConfig = isISMConfig(result); const ismConfigs = isIsmConfig ? (result as ChainMap) : undefined; @@ -118,14 +124,26 @@ export async function runCoreDeploy({ await executeDeploy(deploymentParams); } -function runArtifactStep(selectedChains: ChainName[], artifactsPath?: string) { +function runArtifactStep( + selectedChains: ChainName[], + skipConfirmation: boolean, + artifactsPath?: string, +) { logBlue( '\nDeployments can be totally new or can use some existing contract addresses.', ); - return runDeploymentArtifactStep(artifactsPath, undefined, selectedChains); + return runDeploymentArtifactStep({ + artifactsPath, + selectedChains, + skipConfirmation, + }); } -async function runIsmStep(selectedChains: ChainName[], ismConfigPath?: string) { +async function runIsmStep( + selectedChains: ChainName[], + skipConfirmation: boolean, + ismConfigPath?: string, +) { if (!ismConfigPath) { logBlue( '\n', @@ -134,6 +152,7 @@ async function runIsmStep(selectedChains: ChainName[], ismConfigPath?: string) { logGray( 'Example config: https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/cli/typescript/cli/examples/ism.yaml', ); + if (skipConfirmation) throw new Error('ISM config required'); ismConfigPath = await runFileSelectionStep( './configs', 'ISM config', diff --git a/typescript/cli/src/deploy/warp.ts b/typescript/cli/src/deploy/warp.ts index 778160edc..adc70844d 100644 --- a/typescript/cli/src/deploy/warp.ts +++ b/typescript/cli/src/deploy/warp.ts @@ -52,9 +52,11 @@ export async function runWarpDeploy({ chainConfigPath, coreConfig: { coreArtifactsPath }, keyConfig: { key }, + skipConfirmation, }); if (!warpConfigPath || !isFile(warpConfigPath)) { + if (skipConfirmation) throw new Error('Warp config required'); warpConfigPath = await runFileSelectionStep( './configs', 'Warp config', @@ -70,6 +72,7 @@ export async function runWarpDeploy({ coreArtifacts, multiProvider, signer, + skipConfirmation, }); const deploymentParams = { @@ -95,11 +98,13 @@ async function runBuildConfigStep({ multiProvider, signer, coreArtifacts, + skipConfirmation, }: { warpRouteConfig: WarpRouteConfig; multiProvider: MultiProvider; signer: ethers.Signer; coreArtifacts?: HyperlaneContractsMap; + skipConfirmation: boolean; }) { log('Assembling token configs'); const { base, synthetics } = warpRouteConfig; @@ -164,6 +169,8 @@ async function runBuildConfigStep({ for (const [chain, token] of Object.entries(configMap)) { for (const field of requiredRouterFields) { if (token[field]) continue; + if (skipConfirmation) + throw new Error(`Field ${field} for token on ${chain} required`); if (!hasShownInfo) { logBlue( 'Some router fields are missing. Please enter them now, add them to your warp config, or use the --core flag to use deployment artifacts.',