feat: nut-10

This commit is contained in:
thesimplekid
2024-01-19 21:38:15 +00:00
parent 6550fcc14d
commit ee0a60e40c
3 changed files with 115 additions and 1 deletions

View File

@@ -15,9 +15,10 @@ description = "Cashu rust wallet and mint library"
default = ["mint", "wallet", "all-nuts"]
mint = []
wallet = []
all-nuts = ["nut07", "nut08"]
all-nuts = ["nut07", "nut08", "nut10"]
nut07 = []
nut08 = []
nut10 = []
[dependencies]

View File

@@ -9,6 +9,8 @@ pub mod nut06;
pub mod nut07;
#[cfg(feature = "nut08")]
pub mod nut08;
#[cfg(feature = "nut10")]
pub mod nut10;
#[cfg(feature = "wallet")]
pub use nut00::wallet::{PreMint, PreMintSecrets, Token};

View File

@@ -0,0 +1,111 @@
use serde::ser::SerializeTuple;
use serde::{Deserialize, Serialize, Serializer};
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
pub enum Kind {
/// NUT-11 P2PK
#[default]
P2PK,
}
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Eq, Serialize)]
pub struct SecretData {
/// Unique random string
pub nonce: String,
/// Expresses the spending condition specific to each kind
pub data: String,
/// Additional data committed to and can be used for feature extensions
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<Vec<String>>>,
}
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Eq)]
pub struct Secret {
/// Kind of the spending condition
pub kind: Kind,
pub secret_data: SecretData,
}
impl Serialize for Secret {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// Create a tuple representing the struct fields
let secret_tuple = (&self.kind, &self.secret_data);
// Serialize the tuple as a JSON array
let mut s = serializer.serialize_tuple(2)?;
s.serialize_element(&secret_tuple.0)?;
s.serialize_element(&secret_tuple.1)?;
s.end()
}
}
#[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_ser: Secret = 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(),
]]),
},
};
assert_eq!(secret, secret_ser);
}
#[test]
fn test_secret_serialize() {
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(),
]]),
},
};
let secret_str = r#"["P2PK",{"nonce":"5d11913ee0f92fefdc82a6764fd2457a","data":"026562efcfadc8e86d44da6a8adf80633d974302e62c850774db1fb36ff4cc7198","tags":[["key","value1","value2"]]}]"#;
assert_eq!(serde_json::to_string(&secret).unwrap(), 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)
}
}