use super::*;
use clap::builder::NonEmptyStringValueParser;
#[derive(Debug, Zeroize, Parser)]
#[command(
group(clap::ArgGroup::new("key").required(true).multiple(false))
)]
pub struct Sign {
#[clap(long, default_value_t=MainnetV0::ID, long, value_parser = network_id_parser())]
pub(super) network: u16,
#[clap(long, group = "key", value_parser=NonEmptyStringValueParser::default())]
pub(super) private_key: Option<String>,
#[clap(long, group = "key", value_parser=NonEmptyStringValueParser::default())]
pub(super) private_key_file: Option<String>,
#[clap(long, group = "key")]
pub(super) dev_key: Option<u16>,
#[clap(short = 'm', long)]
pub(super) message: String,
#[clap(short = 'r', long)]
pub(super) raw: bool,
}
impl Sign {
pub fn execute(self) -> Result<String> {
match self.network {
MainnetV0::ID => self.sign::<MainnetV0>(),
TestnetV0::ID => self.sign::<TestnetV0>(),
CanaryV0::ID => self.sign::<CanaryV0>(),
unknown_id => bail!("Unknown network ID ({unknown_id})"),
}
}
fn sign<N: Network>(self) -> Result<String> {
let mut rng = ChaChaRng::from_entropy();
let private_key = parse_private_key(self.private_key.clone(), self.private_key_file.clone(), self.dev_key)?;
let signature = if self.raw {
private_key.sign_bytes(self.message.as_bytes(), &mut rng)
} else {
let fields = aleo_literal_to_fields::<N>(&self.message)
.map_err(|_| anyhow!("Failed to parse a valid Aleo literal"))?;
private_key.sign(&fields, &mut rng)
}
.map_err(|_| anyhow!("Failed to sign the message"))?
.to_string();
Ok(signature)
}
}