From 7bbbc2e20ea1552db3c77d20552d0cf68dd27c05 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Sun, 18 Feb 2024 10:39:04 +0000 Subject: [PATCH] refactor: unchecked secret --- crates/cashu/src/nuts/nut10.rs | 95 ++++++++++------------------------ crates/cashu/src/nuts/nut11.rs | 10 ++-- 2 files changed, 31 insertions(+), 74 deletions(-) diff --git a/crates/cashu/src/nuts/nut10.rs b/crates/cashu/src/nuts/nut10.rs index b8255838..a19e34ad 100644 --- a/crates/cashu/src/nuts/nut10.rs +++ b/crates/cashu/src/nuts/nut10.rs @@ -1,6 +1,11 @@ +use std::fmt; +use std::str::FromStr; + use serde::ser::SerializeTuple; use serde::{Deserialize, Serialize, Serializer}; +use crate::error::Error; + #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)] pub enum Kind { /// NUT-11 P2PK @@ -42,7 +47,6 @@ impl Serialize for Secret { s.end() } } -/* #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct UncheckedSecret(String); @@ -62,16 +66,24 @@ impl From for UncheckedSecret where S: Into, { - fn from(url: S) -> Self { - Self(url.into()) + fn from(inner: S) -> Self { + Self(inner.into()) + } +} + +impl TryFrom for UncheckedSecret { + type Error = serde_json::Error; + + fn try_from(secret: Secret) -> Result { + Ok(UncheckedSecret(serde_json::to_string(&secret)?)) } } impl FromStr for UncheckedSecret { - type Err = ParseError; + type Err = Error; - fn from_str(url: &str) -> Result { - Ok(Self::from(url)) + fn from_str(value: &str) -> Result { + Ok(Self::from(value)) } } @@ -83,50 +95,20 @@ impl TryFrom for Secret { } } +impl TryFrom<&UncheckedSecret> for Secret { + type Error = serde_json::Error; + + fn try_from(unchecked_secret: &UncheckedSecret) -> Result { + serde_json::from_str(&unchecked_secret.0) + } +} + #[cfg(test)] mod tests { use std::assert_eq; use super::*; - #[test] - fn test_secret_deserialize() { - let secret_str = r#"[ - "P2PK", - { - "nonce": "5d11913ee0f92fefdc82a6764fd2457a", - "data": "026562efcfadc8e86d44da6a8adf80633d974302e62c850774db1fb36ff4cc7198", - "tags": [["key", "value1", "value2"]] - } -]"# - .to_string(); - let secret_str = String::from( - r#"["P2PK",{"nonce":"5d11913ee0f92fefdc82a6764fd2457a","data":"026562efcfadc8e86d44da6a8adf80633d974302e62c850774db1fb36ff4cc7198","tags":[["key","value1","value2"]]}]"#, - ); - println!("{}", secret_str); - - let t = UncheckedSecret::from_str(&secret_str); - - let secret_ser: UncheckedSecret = serde_json::from_str(&secret_str).unwrap(); - let secret = Secret { - kind: Kind::P2PK, - secret_data: SecretData { - nonce: "5d11913ee0f92fefdc82a6764fd2457a".to_string(), - data: "026562efcfadc8e86d44da6a8adf80633d974302e62c850774db1fb36ff4cc7198" - .to_string(), - tags: Some(vec![vec![ - "key".to_string(), - "value1".to_string(), - "value2".to_string(), - ]]), - }, - }; - - println!("{}", serde_json::to_string(&secret).unwrap()); - - assert_eq!(secret, secret_ser.try_into().unwrap()); - } - #[test] fn test_secret_serialize() { let secret = Secret { @@ -145,29 +127,6 @@ mod tests { let secret_str = r#"["P2PK",{"nonce":"5d11913ee0f92fefdc82a6764fd2457a","data":"026562efcfadc8e86d44da6a8adf80633d974302e62c850774db1fb36ff4cc7198","tags":[["key","value1","value2"]]}]"#; - let secret = UncheckedSecret(secret_str.to_string()); - - println!("se; {}", secret); - - assert_eq!(secret.to_string(), secret_str); - } - - #[test] - fn test_secret_roundtrip() { - let secret_str = r#"["P2PK",{"nonce":"5d11913ee0f92fefdc82a6764fd2457a","data":"026562efcfadc8e86d44da6a8adf80633d974302e62c850774db1fb36ff4cc7198","tags":[["key","value1","value2"]]}]"#; - - let secret_ser: Secret = serde_json::from_str(secret_str).unwrap(); - - assert_eq!(serde_json::to_string(&secret_ser).unwrap(), secret_str) - } - - #[test] - fn test_unchecked_secret_roundtrip() { - let secret_str = r#"["P2PK",{"nonce":"5d11913ee0f92fefdc82a6764fd2457a","data":"026562efcfadc8e86d44da6a8adf80633d974302e62c850774db1fb36ff4cc7198","tags":[["key","value1","value2"]]}]"#.to_string(); - - let secret_ser: UncheckedSecret = serde_json::from_str(&secret_str).unwrap(); - - assert_eq!(secret_ser.to_string(), secret_str) + assert_eq!(serde_json::to_string(&secret).unwrap(), secret_str); } } -*/ diff --git a/crates/cashu/src/nuts/nut11.rs b/crates/cashu/src/nuts/nut11.rs index 9a416c31..f543caa7 100644 --- a/crates/cashu/src/nuts/nut11.rs +++ b/crates/cashu/src/nuts/nut11.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use super::nut01::PublicKey; use super::nut02::Id; -use super::nut10::{Secret, SecretData}; +use super::nut10::{Secret, SecretData, UncheckedSecret}; use crate::error::Error; use crate::utils::unix_time; use crate::Amount; @@ -31,7 +31,7 @@ pub struct Proof { /// Amount in satoshi pub amount: Amount, /// NUT-10 Secret - pub secret: String, + pub secret: UncheckedSecret, /// Unblinded signature #[serde(rename = "C")] pub c: PublicKey, @@ -179,9 +179,7 @@ impl TryFrom for P2PKConditions { impl Proof { pub fn verify_p2pk(&self) -> Result<(), Error> { - let secret: Secret = serde_json::from_str(&self.secret) - .map_err(|_err| Error::CustomError("Invalid secret".to_string()))?; - + let secret: Secret = (&self.secret).try_into().unwrap(); if secret.kind.ne(&super::nut10::Kind::P2PK) { return Err(Error::IncorrectSecretKind); } @@ -530,7 +528,7 @@ mod tests { let mut proof = Proof { id: None, amount: Amount::ZERO, - secret: serde_json::to_string(&secret).unwrap(), + secret: secret.try_into().unwrap(), c: PublicKey::from_str( "02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904", )