use bech32::{Bech32, Hrp};
use secp256k1::{SecretKey, XOnlyPublicKey};
use super::IdentityError;
const NPUB_HRP: Hrp = Hrp::parse_unchecked("npub");
const NSEC_HRP: Hrp = Hrp::parse_unchecked("nsec");
pub fn encode_npub(pubkey: &XOnlyPublicKey) -> String {
bech32::encode::<Bech32>(NPUB_HRP, &pubkey.serialize()).expect("npub encoding cannot fail")
}
pub fn decode_npub(npub: &str) -> Result<XOnlyPublicKey, IdentityError> {
let (hrp, data) = bech32::decode(npub)?;
if hrp != NPUB_HRP {
return Err(IdentityError::InvalidNpubPrefix(hrp.to_string()));
}
if data.len() != 32 {
return Err(IdentityError::InvalidNpubLength(data.len()));
}
let pubkey = XOnlyPublicKey::from_slice(&data)?;
Ok(pubkey)
}
pub fn encode_nsec(secret_key: &SecretKey) -> String {
bech32::encode::<Bech32>(NSEC_HRP, &secret_key.secret_bytes())
.expect("nsec encoding cannot fail")
}
pub fn decode_nsec(nsec: &str) -> Result<SecretKey, IdentityError> {
let (hrp, data) = bech32::decode(nsec)?;
if hrp != NSEC_HRP {
return Err(IdentityError::InvalidNsecPrefix(hrp.to_string()));
}
if data.len() != 32 {
return Err(IdentityError::InvalidNsecLength(data.len()));
}
let secret_key = SecretKey::from_slice(&data)?;
Ok(secret_key)
}
pub fn decode_secret(s: &str) -> Result<SecretKey, IdentityError> {
if s.starts_with("nsec1") {
decode_nsec(s)
} else {
let bytes = hex::decode(s)?;
if bytes.len() != 32 {
return Err(IdentityError::InvalidNsecLength(bytes.len()));
}
let secret_key = SecretKey::from_slice(&bytes)?;
Ok(secret_key)
}
}