use clap::Parser;
use cosmrs::crypto::PublicKey;
use log::error;
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
use nym_validator_client::signing::signer::OfflineSigner;
use serde::Serialize;
use serde_json::json;
#[derive(Debug, Serialize)]
pub struct SignatureOutputJson {
pub account_id: String,
pub public_key: PublicKey,
pub signature_as_hex: String,
}
#[derive(Debug, Parser)]
pub struct Args {
#[clap(value_parser)]
#[clap(help = "The message to sign")]
pub message: String,
}
pub fn sign(args: Args, prefix: &str, mnemonic: Option<bip39::Mnemonic>) {
if args.message.trim().is_empty() {
error!("Message is empty or contains only whitespace");
return;
}
if mnemonic.is_none() {
error!(
"Please provide the mnemonic as an argument or using the MNEMONIC environment variable"
);
return;
}
let wallet = match DirectSecp256k1HdWallet::checked_from_mnemonic(
prefix,
mnemonic.expect("mnemonic not set"),
) {
Ok(wallet) => wallet,
Err(err) => {
error!("Could not derive an account key from the mnemonic: {err}");
return;
}
};
match wallet.get_accounts().first() {
Some(account) => {
let msg = args.message.into_bytes();
match wallet.sign_raw_with_account(account, msg) {
Ok(signature) => {
let output = SignatureOutputJson {
account_id: account.address().to_string(),
public_key: account.public_key(),
signature_as_hex: signature.to_string(),
};
println!("{}", json!(output));
}
Err(e) => {
error!("Failed to sign message. {e}");
}
}
}
None => {
error!("Could not derive an account key from the mnemonic",)
}
}
}