From 9c3a64b02904b2949a5f7735bc84111162a9d896 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Fri, 6 Jun 2025 23:12:46 +0100 Subject: [PATCH] fix: handle old nut15 spec --- crates/cashu/src/nuts/nut15.rs | 61 ++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/crates/cashu/src/nuts/nut15.rs b/crates/cashu/src/nuts/nut15.rs index 095b996b..d3fb5a82 100644 --- a/crates/cashu/src/nuts/nut15.rs +++ b/crates/cashu/src/nuts/nut15.rs @@ -2,7 +2,7 @@ //! //! -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use super::{CurrencyUnit, PaymentMethod}; use crate::Amount; @@ -27,9 +27,66 @@ pub struct MppMethodSettings { } /// Mpp Settings -#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize)] #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema), schema(as = nut15::Settings))] pub struct Settings { /// Method settings pub methods: Vec, } + +// Custom deserialization to handle both array and object formats +impl<'de> Deserialize<'de> for Settings { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(untagged)] + enum SettingsFormat { + Array(Vec), + Object { methods: Vec }, + } + + let format = SettingsFormat::deserialize(deserializer)?; + match format { + SettingsFormat::Array(methods) => Ok(Settings { methods }), + SettingsFormat::Object { methods } => Ok(Settings { methods }), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::PaymentMethod; + + #[test] + fn test_nut15_settings_deserialization() { + // Test array format + let array_json = r#"[{"method":"bolt11","unit":"sat"}]"#; + let settings: Settings = serde_json::from_str(array_json).unwrap(); + assert_eq!(settings.methods.len(), 1); + assert_eq!(settings.methods[0].method, PaymentMethod::Bolt11); + assert_eq!(settings.methods[0].unit, CurrencyUnit::Sat); + + // Test object format + let object_json = r#"{"methods":[{"method":"bolt11","unit":"sat"}]}"#; + let settings: Settings = serde_json::from_str(object_json).unwrap(); + assert_eq!(settings.methods.len(), 1); + assert_eq!(settings.methods[0].method, PaymentMethod::Bolt11); + assert_eq!(settings.methods[0].unit, CurrencyUnit::Sat); + } + + #[test] + fn test_nut15_settings_serialization() { + let settings = Settings { + methods: vec![MppMethodSettings { + method: PaymentMethod::Bolt11, + unit: CurrencyUnit::Sat, + }], + }; + + let json = serde_json::to_string(&settings).unwrap(); + assert_eq!(json, r#"{"methods":[{"method":"bolt11","unit":"sat"}]}"#); + } +}