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