pubkey.rs (4110B)
1 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 2 3 use crate::Error; 4 use std::borrow::Borrow; 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 #[derive(Eq, PartialEq, Clone, Copy, Hash, Ord, PartialOrd)] 13 pub struct PubkeyRef<'a>(&'a [u8; 32]); 14 15 static HRP_NPUB: bech32::Hrp = bech32::Hrp::parse_unchecked("npub"); 16 17 impl Borrow<[u8; 32]> for PubkeyRef<'_> { 18 fn borrow(&self) -> &[u8; 32] { 19 self.0 20 } 21 } 22 23 impl<'a> PubkeyRef<'a> { 24 pub fn new(bytes: &'a [u8; 32]) -> Self { 25 Self(bytes) 26 } 27 28 pub fn bytes(&self) -> &[u8; 32] { 29 self.0 30 } 31 32 pub fn to_owned(&self) -> Pubkey { 33 Pubkey::new(*self.bytes()) 34 } 35 36 pub fn hex(&self) -> String { 37 hex::encode(self.bytes()) 38 } 39 } 40 41 impl Deref for Pubkey { 42 type Target = [u8; 32]; 43 44 fn deref(&self) -> &Self::Target { 45 &self.0 46 } 47 } 48 49 impl Borrow<[u8; 32]> for Pubkey { 50 fn borrow(&self) -> &[u8; 32] { 51 &self.0 52 } 53 } 54 55 impl Pubkey { 56 pub fn new(data: [u8; 32]) -> Self { 57 Self(data) 58 } 59 60 pub fn hex(&self) -> String { 61 hex::encode(self.bytes()) 62 } 63 64 pub fn bytes(&self) -> &[u8; 32] { 65 &self.0 66 } 67 68 pub fn as_ref(&self) -> PubkeyRef<'_> { 69 PubkeyRef(self.bytes()) 70 } 71 72 pub fn parse(s: &str) -> Result<Self, Error> { 73 match Pubkey::from_hex(s) { 74 Ok(pk) => Ok(pk), 75 Err(_) => Pubkey::try_from_bech32_string(s, false), 76 } 77 } 78 79 pub fn from_hex(hex_str: &str) -> Result<Self, Error> { 80 Ok(Pubkey(hex::decode(hex_str)?.as_slice().try_into()?)) 81 } 82 83 pub fn try_from_hex_str_with_verify(hex_str: &str) -> Result<Self, Error> { 84 let vec: Vec<u8> = hex::decode(hex_str)?; 85 if vec.len() != 32 { 86 Err(Error::HexDecodeFailed) 87 } else { 88 let _ = match nostr::secp256k1::XOnlyPublicKey::from_slice(&vec) { 89 Ok(r) => Ok(r), 90 Err(_) => Err(Error::InvalidPublicKey), 91 }?; 92 93 Ok(Pubkey(vec.try_into().unwrap())) 94 } 95 } 96 97 pub fn try_from_bech32_string(s: &str, verify: bool) -> Result<Self, Error> { 98 let data = match bech32::decode(s) { 99 Ok(res) => Ok(res), 100 Err(_) => Err(Error::InvalidBech32), 101 }?; 102 103 if data.0 != HRP_NPUB { 104 Err(Error::InvalidBech32) 105 } else if data.1.len() != 32 { 106 Err(Error::InvalidByteSize) 107 } else { 108 if verify { 109 let _ = match nostr::secp256k1::XOnlyPublicKey::from_slice(&data.1) { 110 Ok(r) => Ok(r), 111 Err(_) => Err(Error::InvalidPublicKey), 112 }?; 113 } 114 Ok(Pubkey(data.1.try_into().unwrap())) 115 } 116 } 117 118 pub fn to_bech(&self) -> Option<String> { 119 bech32::encode::<bech32::Bech32>(HRP_NPUB, &self.0).ok() 120 } 121 } 122 123 impl fmt::Display for Pubkey { 124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 125 write!(f, "{}", self.hex()) 126 } 127 } 128 129 impl fmt::Debug for PubkeyRef<'_> { 130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 131 write!(f, "{}", self.hex()) 132 } 133 } 134 135 impl fmt::Debug for Pubkey { 136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 137 write!(f, "{}", self.hex()) 138 } 139 } 140 141 impl From<Pubkey> for String { 142 fn from(pk: Pubkey) -> Self { 143 pk.hex() 144 } 145 } 146 147 // Custom serialize function for Pubkey 148 impl Serialize for Pubkey { 149 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 150 where 151 S: Serializer, 152 { 153 serializer.serialize_str(&self.hex()) 154 } 155 } 156 157 // Custom deserialize function for Pubkey 158 impl<'de> Deserialize<'de> for Pubkey { 159 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 160 where 161 D: Deserializer<'de>, 162 { 163 debug!("decoding pubkey start"); 164 let s = String::deserialize(deserializer)?; 165 debug!("decoding pubkey {}", &s); 166 Pubkey::from_hex(&s).map_err(serde::de::Error::custom) 167 } 168 }