pubkey.rs (2853B)
1 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 2 3 use crate::Error; 4 use nostr::bech32::Hrp; 5 use std::fmt; 6 use tracing::debug; 7 8 #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)] 9 pub struct Pubkey([u8; 32]); 10 11 static HRP_NPUB: Hrp = Hrp::parse_unchecked("npub"); 12 13 impl Pubkey { 14 pub fn new(data: [u8; 32]) -> Self { 15 Self(data) 16 } 17 18 pub fn hex(&self) -> String { 19 hex::encode(self.bytes()) 20 } 21 22 pub fn bytes(&self) -> &[u8; 32] { 23 &self.0 24 } 25 26 pub fn parse(s: &str) -> Result<Self, Error> { 27 match Pubkey::from_hex(s) { 28 Ok(pk) => Ok(pk), 29 Err(_) => Pubkey::try_from_bech32_string(s, false), 30 } 31 } 32 33 pub fn from_hex(hex_str: &str) -> Result<Self, Error> { 34 Ok(Pubkey(hex::decode(hex_str)?.as_slice().try_into()?)) 35 } 36 37 pub fn try_from_hex_str_with_verify(hex_str: &str) -> Result<Self, Error> { 38 let vec: Vec<u8> = hex::decode(hex_str)?; 39 if vec.len() != 32 { 40 Err(Error::HexDecodeFailed) 41 } else { 42 let _ = match nostr::secp256k1::XOnlyPublicKey::from_slice(&vec) { 43 Ok(r) => Ok(r), 44 Err(_) => Err(Error::InvalidPublicKey), 45 }?; 46 47 Ok(Pubkey(vec.try_into().unwrap())) 48 } 49 } 50 51 pub fn try_from_bech32_string(s: &str, verify: bool) -> Result<Self, Error> { 52 let data = match nostr::bech32::decode(s) { 53 Ok(res) => Ok(res), 54 Err(_) => Err(Error::InvalidBech32), 55 }?; 56 57 if data.0 != HRP_NPUB { 58 Err(Error::InvalidBech32) 59 } else if data.1.len() != 32 { 60 Err(Error::InvalidByteSize) 61 } else { 62 if verify { 63 let _ = match nostr::secp256k1::XOnlyPublicKey::from_slice(&data.1) { 64 Ok(r) => Ok(r), 65 Err(_) => Err(Error::InvalidPublicKey), 66 }?; 67 } 68 Ok(Pubkey(data.1.try_into().unwrap())) 69 } 70 } 71 } 72 73 impl fmt::Display for Pubkey { 74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 75 write!(f, "{}", self.hex()) 76 } 77 } 78 79 impl From<Pubkey> for String { 80 fn from(pk: Pubkey) -> Self { 81 pk.hex() 82 } 83 } 84 85 // Custom serialize function for Pubkey 86 impl Serialize for Pubkey { 87 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 88 where 89 S: Serializer, 90 { 91 serializer.serialize_str(&self.hex()) 92 } 93 } 94 95 // Custom deserialize function for Pubkey 96 impl<'de> Deserialize<'de> for Pubkey { 97 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 98 where 99 D: Deserializer<'de>, 100 { 101 debug!("decoding pubkey start"); 102 let s = String::deserialize(deserializer)?; 103 debug!("decoding pubkey {}", &s); 104 Pubkey::from_hex(&s).map_err(serde::de::Error::custom) 105 } 106 }