diff --git a/src/schnorrsig.rs b/src/schnorrsig.rs index f56e2b141..71c40f4a8 100644 --- a/src/schnorrsig.rs +++ b/src/schnorrsig.rs @@ -80,6 +80,46 @@ impl str::FromStr for Signature { pub struct KeyPair(ffi::KeyPair); impl_display_secret!(KeyPair); +impl ::core::str::FromStr for KeyPair { + type Err = Error; + + fn from_str(s: &str) -> Result { + let ctx = unsafe { + Secp256k1::from_raw_all(ffi::secp256k1_context_no_precomp as *mut ffi::Context) + }; + KeyPair::from_seckey_str(&ctx, s) + } +} + +impl ::serde::Serialize for KeyPair { + fn serialize(&self, s: S) -> Result { + if s.is_human_readable() { + s.serialize_str(&self.display_secret().to_string()) + } else { + s.serialize_bytes(&self.0[..]) + } + } +} + +#[cfg(feature = "serde")] +impl<'de> ::serde::Deserialize<'de> for KeyPair { + fn deserialize>(d: D) -> Result { + if d.is_human_readable() { + d.deserialize_str(super::serde_util::FromStrVisitor::new( + "a hex string representing 32 byte KeyPair" + )) + } else { + d.deserialize_bytes(super::serde_util::BytesVisitor::new( + "raw 32 bytes KeyPair", + |data| unsafe { + let ctx = Secp256k1::from_raw_all(ffi::secp256k1_context_no_precomp as *mut ffi::Context); + KeyPair::from_seckey_slice(&ctx, data) + } + )) + } + } +} + /// A Schnorr public key, used for verification of Schnorr signatures #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] pub struct PublicKey(ffi::XOnlyPublicKey);