From 558024d7fef90e121ab9d8ae0801e8149a517f7e Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Wed, 19 Mar 2025 12:34:23 +0100 Subject: [PATCH] Ser/Deserialize SecretKey either as bytes or string --- crates/cashu/src/nuts/nut01/secret_key.rs | 48 +++++++++++++++++------ 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/crates/cashu/src/nuts/nut01/secret_key.rs b/crates/cashu/src/nuts/nut01/secret_key.rs index 23eca6e3..9961387b 100644 --- a/crates/cashu/src/nuts/nut01/secret_key.rs +++ b/crates/cashu/src/nuts/nut01/secret_key.rs @@ -8,6 +8,7 @@ use bitcoin::secp256k1; use bitcoin::secp256k1::rand::rngs::OsRng; use bitcoin::secp256k1::schnorr::Signature; use bitcoin::secp256k1::{Keypair, Message, Scalar}; +use serde::de::Visitor; use serde::{Deserialize, Deserializer, Serialize}; use super::{Error, PublicKey}; @@ -115,21 +116,46 @@ impl FromStr for SecretKey { } impl Serialize for SecretKey { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_secret_hex()) + fn serialize(&self, serializer: S) -> Result { + match serializer.is_human_readable() { + // For human-readable formats like JSON, serialize as hex string + true => serializer.serialize_str(&self.to_secret_hex()), + // For binary formats like CBOR, use the bytes serialization + false => serializer.serialize_bytes(self.as_secret_bytes()), + } } } impl<'de> Deserialize<'de> for SecretKey { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let secret_key: String = String::deserialize(deserializer)?; - Self::from_hex(secret_key).map_err(serde::de::Error::custom) + fn deserialize>(deserializer: D) -> Result { + match deserializer.is_human_readable() { + // For human-readable formats like JSON, deserialize from hex string + true => { + let secret_key: String = String::deserialize(deserializer)?; + SecretKey::from_hex(secret_key).map_err(serde::de::Error::custom) + } + // For binary formats like CBOR, use the bytes deserialization + false => { + struct SecretKeyVisitor; + + impl Visitor<'_> for SecretKeyVisitor { + type Value = SecretKey; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array") + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: serde::de::Error, + { + SecretKey::from_slice(value).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_bytes(SecretKeyVisitor) + } + } } }