diff --git a/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts b/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts index 22ef7ee9af..12377e2ead 100644 --- a/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts +++ b/ironfish-cli/src/commands/wallet/multisig/dkg/create.ts @@ -284,9 +284,13 @@ export class DkgCreateCommand extends IronfishCommand { }> { this.log('\nCollecting Participant Info and Performing Round 1...') - let input = await ui.inputPrompt('Enter the total number of participants', true) - const totalParticipants = parseInt(input) - if (isNaN(totalParticipants) || totalParticipants < 2) { + const totalParticipants = await ui.inputNumberPrompt( + this.logger, + 'Enter the total number of participants', + { required: true, integer: true }, + ) + + if (totalParticipants < 2) { throw new Error('Total number of participants must be at least 2') } @@ -304,13 +308,15 @@ export class DkgCreateCommand extends IronfishCommand { errorOnDuplicate: true, }) - input = await ui.inputPrompt('Enter the number of minimum signers', true) - const minSigners = parseInt(input) - if (isNaN(minSigners) || minSigners < 2) { - throw new Error('Minimum number of signers must be at least 2') - } else if (minSigners > totalParticipants) { + const minSigners = await ui.inputNumberPrompt( + this.logger, + 'Enter the number of minimum signers', + { required: true, integer: true }, + ) + + if (minSigners < 2 || minSigners > totalParticipants) { throw new Error( - 'Minimum number of signers cannot be more than total number of participants', + 'Minimum number of signers must be between 2 and the total number of participants', ) } @@ -322,6 +328,7 @@ export class DkgCreateCommand extends IronfishCommand { identities, minSigners, ) + return { ...result, totalParticipants, diff --git a/ironfish-cli/src/ui/prompt.ts b/ironfish-cli/src/ui/prompt.ts index d29801f26d..5685bfdd05 100644 --- a/ironfish-cli/src/ui/prompt.ts +++ b/ironfish-cli/src/ui/prompt.ts @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { Logger } from '@ironfish/sdk' import { ux } from '@oclif/core' import inquirer from 'inquirer' import { longPrompt } from './longPrompt' @@ -45,6 +46,47 @@ async function _inputPrompt(message: string, options?: { password: boolean }): P return result.prompt.trim() } +export async function inputNumberPrompt( + logger: Logger, + message: string, + options: { + required?: boolean + integer?: boolean + }, +): Promise { + const validateNumber = (input: string): number => { + const num = Number(input) + + if (isNaN(num)) { + throw new Error('Input must be a number') + } + + if (options.integer && num % 1 !== 0) { + throw new Error('Input must be an integer') + } + + return num + } + + if (options.required) { + // eslint-disable-next-line no-constant-condition + while (true) { + try { + const userInput = await _inputPrompt(message) + return validateNumber(userInput) + } catch (e) { + if (e instanceof Error) { + logger.error(e.message) + } else { + logger.error('An error occurred. Please try again.') + } + } + } + } + + return validateNumber(await _inputPrompt(message)) +} + export async function inputPrompt( message: string, required: boolean = false,