diff --git a/cli/src/commands/account.rs b/cli/src/commands/account.rs index 29fd401ea0..2f97baaf73 100644 --- a/cli/src/commands/account.rs +++ b/cli/src/commands/account.rs @@ -108,53 +108,76 @@ impl Account { bail!("Cannot specify both the '--seed' and '--vanity' flags"); } - match vanity { - // Generate a vanity account for the specified network. - Some(vanity) => match network { - MainnetV0::ID => Self::new_vanity::(vanity.as_str(), discreet), - TestnetV0::ID => Self::new_vanity::(vanity.as_str(), discreet), - CanaryV0::ID => Self::new_vanity::(vanity.as_str(), discreet), - unknown_id => bail!("Unknown network ID ({unknown_id})"), - }, - // Generate a seeded account for the specified network. - None => match network { - MainnetV0::ID => Self::new_seeded::(seed, discreet), - TestnetV0::ID => Self::new_seeded::(seed, discreet), - CanaryV0::ID => Self::new_seeded::(seed, discreet), - unknown_id => bail!("Unknown network ID ({unknown_id})"), - }, - } + Self::generate_account(network, seed, vanity, discreet) } Self::Sign { network, message, seed, raw, private_key, private_key_file } => { - let key = match (private_key, private_key_file) { - (Some(private_key), None) => private_key, - (None, Some(private_key_file)) => { - let path = private_key_file.parse::().map_err(|e| anyhow!("Invalid path - {e}"))?; - std::fs::read_to_string(path)?.trim().to_string() - } - (None, None) => bail!("Missing the '--private-key' or '--private-key-file' argument"), - (Some(_), Some(_)) => { - bail!("Cannot specify both the '--private-key' and '--private-key-file' flags") - } - }; - + let key = Self::get_private_key(private_key, private_key_file)?; // Sign the message for the specified network. - match network { - MainnetV0::ID => Self::sign::(key, message, seed, raw), - TestnetV0::ID => Self::sign::(key, message, seed, raw), - CanaryV0::ID => Self::sign::(key, message, seed, raw), - unknown_id => bail!("Unknown network ID ({unknown_id})"), - } + Self::process_message(network, key, message, seed, raw, Self::sign) } Self::Verify { network, address, signature, message, raw } => { // Verify the signature for the specified network. - match network { - MainnetV0::ID => Self::verify::(address, signature, message, raw), - TestnetV0::ID => Self::verify::(address, signature, message, raw), - CanaryV0::ID => Self::verify::(address, signature, message, raw), - unknown_id => bail!("Unknown network ID ({unknown_id})"), - } + Self::process_message(network, address, signature, message, raw, Self::verify) + } + } + } + + fn generate_account(network: u16, seed: Option, vanity: Option, discreet: bool) -> Result { + match vanity { + // Generate a vanity account for the specified network. + Some(vanity) => Self::new_vanity_account(network, &vanity, discreet), + // Generate a seeded account for the specified network. + None => Self::new_seeded_account(network, seed, discreet), + } + } + + // Generate a vanity account for the specified network. + fn new_vanity_account(network: u16, vanity: &str, discreet: bool) -> Result { + Self::execute_for_network(network, |net| Self::new_vanity::(vanity, discreet)) + } + + // Generate a seeded account for the specified network. + fn new_seeded_account(network: u16, seed: Option, discreet: bool) -> Result { + Self::execute_for_network(network, |net| Self::new_seeded::(seed, discreet)) + } + + fn get_private_key(private_key: Option, private_key_file: Option) -> Result { + match (private_key, private_key_file) { + (Some(private_key), None) => Ok(private_key), + (None, Some(private_key_file)) => { + let path = private_key_file.parse::().map_err(|e| anyhow!("Invalid path - {e}"))?; + Ok(std::fs::read_to_string(path)?.trim().to_string()) } + (None, None) => bail!("Missing the '--private-key' or '--private-key-file' argument"), + (Some(_), Some(_)) => bail!("Cannot specify both the '--private-key' and '--private-key-file' flags"), + } + } + + // Abstract the logic for processing messages + fn process_message( + network: u16, + key: String, + message: String, + seed: Option, + raw: bool, + func: F, + ) -> Result + where + F: Fn(String, String, Option, bool) -> Result, + { + Self::execute_for_network(network, |net| func::(key, message, seed, raw)) + } + + // Abstract Network Execution Logic + fn execute_for_network(network: u16, func: F) -> Result + where + F: FnOnce(&dyn Network) -> Result, + { + match network { + MainnetV0::ID => func(&MainnetV0), + TestnetV0::ID => func(&TestnetV0), + CanaryV0::ID => func(&CanaryV0), + unknown_id => bail!("Unknown network ID ({unknown_id})"), } }