diff --git a/README.md b/README.md index fc439c9..2d1c545 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ This is kind of bonkers, so here's a command-line utility that you can run to co ## Features: >Note: "keys" + "nip5" arguments accept multiple inputs for bulk operations -- convert from bech32 (npub/nsec/note) to hex -- convert from hex to bech32 (npub/nsec/note) +- convert from bech32 (npub/nsec/note/nprofile/nevent) to hex +- convert from hex to bech32 (npub/nsec/note/nprofile/nevent) - supports NIP-05 domain identifiers: - calls given nip5 domain to get nostr.json containing user pubkeys (located at domain.com/.well-known/nostr.json) - extracts and converts all pubkeys from hex to bech32 format @@ -44,15 +44,17 @@ Just provide the hex-encoded key or note-id and a `--kind` argument. The `kind`s - npub - nsec - note +- nprofile +- nevent -To convert from an `bech32(npub/nsec/note) to hex-encoding`, you can do +To convert from an `bech32(npub/nsec/note/nprofile/nevent) to hex-encoding`, you can do ```shell $> key-convertr --to-hex npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d ``` -To convert from an `hex-encoding to bech32 (npub/nsec/note)`, you can do +To convert from an `hex-encoding to bech32 (npub/nsec/note/nprofile/nevent)`, you can do ```shell $> key-convertr --kind npub 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d @@ -90,4 +92,4 @@ $> key-convertr --nip5 nostrplebs.com,strike.me,satoshivibes.com --- ## TODO Optimizations: -- multi threaded "--nip5" logic (multiple domains converted in parallel; some lists will be very large i.e nostrplebs.com) \ No newline at end of file +- multi threaded "--nip5" logic (multiple domains converted in parallel; some lists will be very large i.e nostrplebs.com) diff --git a/src/main.rs b/src/main.rs index fc32b9f..a7cbfcb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,12 +9,33 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use thiserror::Error; use tokio::task::JoinHandle; +use std::str::FromStr; #[derive(clap::ValueEnum, Clone, Debug, Copy)] enum Prefix { Npub, Nsec, Note, + Nprofile, + Nevent, +} + +#[derive(Debug, PartialEq, Eq)] +struct ParsePrefixError; + +impl FromStr for Prefix { + type Err = ParsePrefixError; + + fn from_str(s: &str) -> Result { + match s { + "npub" => Ok(Prefix::Npub), + "nsec" => Ok(Prefix::Nsec), + "note" => Ok(Prefix::Note), + "nprofile" => Ok(Prefix::Nprofile), + "nevent" => Ok(Prefix::Nevent), + _ => Err(ParsePrefixError), + } + } } // Display 'trait' needed for enum "to_string()" @@ -24,6 +45,8 @@ impl std::fmt::Display for Prefix { Prefix::Npub => write!(f, "npub"), Prefix::Nsec => write!(f, "nsec"), Prefix::Note => write!(f, "note"), + Prefix::Nprofile => write!(f, "nprofile"), + Prefix::Nevent => write!(f, "nevent"), } } } @@ -45,7 +68,7 @@ struct Args { #[arg( short, long, - help = "the kind of entity (npub/nsec/note) being converted from hex to bech32-formatted string", + help = "the kind of entity (npub/nsec/note/nprofile/nevent) being converted from hex to bech32-formatted string", requires = "keys" )] kind: Option, @@ -86,14 +109,19 @@ async fn main() -> Result<()> { let args = Args::parse(); if args.to_hex { - // convert bech32 npub/nsec/note to hex (accepts list of bech32's) + // convert bech32 npub/nsec/note/nprofile/nevent to hex (accepts list of bech32's) for s in &args.keys { - let (_, data, _) = bech32::decode(s)?; - println!("{}", hex::encode(Vec::::from_base32(&data)?)); + let (hrp, data, _) = bech32::decode(s)?; + let hrp = Prefix::from_str(hrp.as_str()).unwrap(); + match hrp { + Prefix::Nevent | + Prefix::Nprofile => println!("{}", &hex::encode(&Vec::::from_base32(&data)?)[4..]), + _ => println!("{}", hex::encode(&Vec::::from_base32(&data)?)), + }; } Ok(()) } else if args.kind.is_some() { - // convert hex to bech32 npub/nsec/note (accepts list of hex) + // convert hex to bech32 npub/nsec/note/nprofile/nevent (accepts list of hex) let hrp = args.kind.unwrap(); for key in &args.keys { let encoded = bech32_encode(hrp, key).unwrap(); @@ -159,9 +187,13 @@ enum KeyValidationError { } /// Converts a hex encoded string to bech32 format for given a Prefix (hrp) fn bech32_encode(hrp: Prefix, hex_key: &String) -> Result { + let hex_str = match hrp { + Prefix::Nevent | Prefix::Nprofile => format!("0020{hex_key}"), + _ => format!("{hex_key}"), + }; bech32::encode( &hrp.to_string(), - hex::decode(hex_key) + hex::decode(&hex_str) .map_err(|_| InvalidKeyDecode(hex_key.to_string()))? .to_base32(), Variant::Bech32,