diff --git a/moksha-core/src/fixtures/incomplete_mint_info.json b/moksha-core/src/fixtures/incomplete_mint_info.json new file mode 100644 index 00000000..f5c1bf7f --- /dev/null +++ b/moksha-core/src/fixtures/incomplete_mint_info.json @@ -0,0 +1,37 @@ +{ + "name": "My Cashu mint", + "pubkey": "03a2118b421e6b47f0656b97bb7eeea43c41096adbc0d0e511ff70de7d94dbd990", + "version": "MyMint", + "description": "The short mint description", + "description_long": "A long mint description that can be a long piece of text.", + "contact": [ + ["email", "contact@me.com"], + ["twitter", "@me"], + ["nostr", "npub..."] + ], + "motd": "Message to users", + "nuts": { + "4": { + "methods": [ + { + "method": "bolt11", + "unit": "sat", + "min_amount": 1, + "max_amount": 21 + } + ], + "disabled": false + }, + "5": { + "methods": [ + { + "method": "bolt11", + "unit": "sat", + "min_amount": 1, + "max_amount": 42 + } + ], + "disabled": false + } + } +} diff --git a/moksha-core/src/primitives.rs b/moksha-core/src/primitives.rs index 9241cb13..ac953018 100644 --- a/moksha-core/src/primitives.rs +++ b/moksha-core/src/primitives.rs @@ -331,7 +331,7 @@ pub struct GetMeltBtcOnchainResponse { pub paid: bool, } -#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq, Default, ToSchema)] +#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq, ToSchema)] pub struct Nuts { /// Minting tokens #[serde(rename = "4")] @@ -342,30 +342,29 @@ pub struct Nuts { pub nut5: Nut5, /// Token state check - #[serde(rename = "7")] - pub nut7: Nut7, + #[serde(rename = "7", skip_serializing_if = "Option::is_none")] + pub nut7: Option, /// Overpaid Lightning fees - #[serde(rename = "8")] - pub nut8: Nut8, + #[serde(rename = "8", skip_serializing_if = "Option::is_none")] + pub nut8: Option, /// Deterministic backup and restore - #[serde(rename = "9")] - pub nut9: Nut9, + #[serde(rename = "9", skip_serializing_if = "Option::is_none")] + pub nut9: Option, /// Spending conditions - #[serde(rename = "10")] - pub nut10: Nut10, + #[serde(rename = "10", skip_serializing_if = "Option::is_none")] + pub nut10: Option, /// Pay-To-Pubkey (P2PK) - #[serde(rename = "11")] - pub nut11: Nut11, + #[serde(rename = "11", skip_serializing_if = "Option::is_none")] + pub nut11: Option, - #[serde(rename = "12")] + #[serde(rename = "12", skip_serializing_if = "Option::is_none")] /// DLEQ proofs - pub nut12: Nut12, + pub nut12: Option, - // TODO remove this if nut-17 and nut-18 are merged #[serde(rename = "17", skip_serializing_if = "Option::is_none")] /// minting tokens btc onchain pub nut17: Option, @@ -375,6 +374,23 @@ pub struct Nuts { pub nut18: Option, } +impl Default for Nuts { + fn default() -> Self { + Self { + nut4: Nut4::default(), + nut5: Nut5::default(), + nut7: Some(Nut7 { supported: false }), + nut8: Some(Nut8 { supported: true }), + nut9: Some(Nut9 { supported: false }), + nut10: Some(Nut10 { supported: false }), + nut11: Some(Nut11 { supported: false }), + nut12: Some(Nut12 { supported: false }), + nut17: Some(Nut17::default()), + nut18: Some(Nut18::default()), + } + } +} + #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq, ToSchema)] pub struct Nut4 { #[serde(rename = "methods")] @@ -544,7 +560,7 @@ mod tests { } #[test] - fn test_deserialize_mint_info() -> anyhow::Result<()> { + fn test_serialize_mint_info() -> anyhow::Result<()> { let mint_info = MintInfoResponse { name: Some("Bob's Cashu mint".to_string()), pubkey: public_key_from_hex( @@ -576,4 +592,20 @@ mod tests { assert_eq!("Nutshell/0.15.0", info.version.unwrap()); Ok(()) } + + #[test] + fn test_deserialize_incomplete_mint_info() -> anyhow::Result<()> { + let mint_info = read_fixture("incomplete_mint_info.json")?; + let info = serde_json::from_str::(&mint_info); + assert!(info.is_ok()); + let info = info?; + assert_eq!("MyMint", info.version.unwrap()); + assert!(info.nuts.nut7.is_none()); + assert!(info.nuts.nut8.is_none()); + assert!(info.nuts.nut9.is_none()); + assert!(info.nuts.nut10.is_none()); + assert!(info.nuts.nut11.is_none()); + assert!(info.nuts.nut12.is_none()); + Ok(()) + } }