From 18629cc9b63a63e163ab268c0ca8bed7266c0ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Severin=20Alexander=20B=C3=BChler?= <8782386+SeverinAlexB@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:05:19 +0200 Subject: [PATCH] feat: publickey cli command (#47) --- cli/src/cli.rs | 20 +++++++++----- cli/src/commands/mod.rs | 5 +++- cli/src/commands/publickey.rs | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 cli/src/commands/publickey.rs diff --git a/cli/src/cli.rs b/cli/src/cli.rs index e915cf1..75fbb71 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -1,8 +1,4 @@ -use crate::commands::{generate::cli_generate_seed, publish::cli_publish, resolve::cli_resolve}; - - - - +use crate::commands::{cli_publickey, generate::cli_generate_seed, publish::cli_publish, resolve::cli_resolve}; /** * Main cli entry function. @@ -40,9 +36,16 @@ pub async fn run_cli() { .about("Resolve pkarr dns records.") .arg(clap::Arg::new("pubkey").required(false).help("Pkarr public key uri.")), ) + .subcommand(clap::Command::new("generate").about("Generate a new zbase32 pkarr seed")) .subcommand( - clap::Command::new("generate") - .about("Generate a new zbase32 pkarr seed") + clap::Command::new("publickey") + .about("Derive the public key from the seed.") + .arg( + clap::Arg::new("seed") + .required(false) + .help("File path to the pkarr seed file.") + .default_value("./seed.txt"), + ), ); let matches = cmd.get_matches(); @@ -56,6 +59,9 @@ pub async fn run_cli() { Some(("generate", matches)) => { cli_generate_seed(matches).await; } + Some(("publickey", matches)) => { + cli_publickey(matches).await; + } _ => { unimplemented!("command not implemented") } diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index 16aba74..efd6a25 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -1,3 +1,6 @@ pub mod resolve; pub mod publish; -pub mod generate; \ No newline at end of file +pub mod generate; +mod publickey; + +pub use publickey::cli_publickey; \ No newline at end of file diff --git a/cli/src/commands/publickey.rs b/cli/src/commands/publickey.rs new file mode 100644 index 0000000..418ad31 --- /dev/null +++ b/cli/src/commands/publickey.rs @@ -0,0 +1,49 @@ +use std::{fs::read_to_string, path::{Path, PathBuf}}; +use clap::ArgMatches; +use pkarr::Keypair; + + + +const SECRET_KEY_LENGTH: usize = 32; + +fn read_seed_file(matches: &ArgMatches) -> Keypair { + let unexpanded_path: &String = matches.get_one("seed").unwrap(); + let expanded_path: String = shellexpand::full(unexpanded_path) + .expect("Valid shell path.") + .into(); + let path = Path::new(&expanded_path); + let path = PathBuf::from(path); + + let seed = read_to_string(path); + if let Err(e) = seed { + eprintln!("Failed to read seed at {expanded_path}. {e}"); + std::process::exit(1); + }; + let seed = seed.unwrap(); + parse_seed(&seed) +} + +fn parse_seed(seed: &str) -> Keypair { + let seed = seed.trim(); + let decode_result = zbase32::decode_full_bytes_str(&seed); + if let Err(e) = decode_result { + eprintln!("Failed to parse the seed file. {e} {seed}"); + std::process::exit(1); + }; + + let plain_secret = decode_result.unwrap(); + + let slice: &[u8; SECRET_KEY_LENGTH] = &plain_secret[0..SECRET_KEY_LENGTH].try_into().unwrap(); + let keypair = Keypair::from_secret_key(slice); + keypair +} + +pub async fn cli_publickey(matches: &ArgMatches) { + + let keypair = read_seed_file(matches); + let pubkey = keypair.to_z32(); + + println!("{pubkey}"); + +} +