diff --git a/Cargo.toml b/Cargo.toml index 3c42f202..310b687a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,11 @@ name = "cashu-rs" version = "0.1.0" edition = "2021" -[workspace] -members = ["integration_test"] - - [dependencies] bitcoin = { version = "0.30.0", features=["serde"] } lightning-invoice = { version = "0.22.0", features=["serde"] } minreq = { version = "2.7.0", features = ["json-using-serde", "https"] } +secp256k1 = "0.27.0" serde = { version = "1.0.160", features = ["derive"]} thiserror = "1.0.40" url = "2.3.1" diff --git a/src/cashu_mint.rs b/src/cashu_mint.rs index abb584f8..5881a2e6 100644 --- a/src/cashu_mint.rs +++ b/src/cashu_mint.rs @@ -1,3 +1,4 @@ +use bitcoin::Amount; use lightning_invoice::Invoice; use url::Url; @@ -32,10 +33,11 @@ impl CashuMint { } /// Request Mint [NUT-03] - pub async fn request_mint(&self, amount: u64) -> Result { + pub async fn request_mint(&self, amount: Amount) -> Result { let mut url = self.url.join("mint")?; url.query_pairs_mut() - .append_pair("amount", &amount.to_string()); + .append_pair("amount", &amount.to_sat().to_string()); + println!("{url}"); Ok(minreq::get(url).send()?.json::()?) } @@ -97,7 +99,7 @@ impl CashuMint { /// Split Token [NUT-06] pub async fn split( &self, - amount: u64, + amount: Amount, proofs: Vec, outputs: Vec, ) -> Result { diff --git a/src/dhke.rs b/src/dhke.rs new file mode 100644 index 00000000..4c2a4586 --- /dev/null +++ b/src/dhke.rs @@ -0,0 +1 @@ +//! Diffie-Hellmann key exchange diff --git a/src/types.rs b/src/types.rs index 346168fa..6c6ce3f5 100644 --- a/src/types.rs +++ b/src/types.rs @@ -10,7 +10,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct BlindedMessage { /// Amount in satoshi - pub amount: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub amount: Amount, /// encrypted secret message (B_) #[serde(rename = "B_")] pub b: String, @@ -31,7 +32,8 @@ pub struct Promise { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Proof { /// Amount in satoshi - pub amount: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub amount: Amount, /// Secret message pub secret: String, /// Unblinded signature @@ -78,8 +80,9 @@ pub struct PostMintResponse { /// Check Fees Response [NUT-05] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct CheckFeesResponse { - /// Expected Mac Fee in satoshis - pub fee: u64, + /// Expected Mac Fee in satoshis + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub fee: Amount, } /// Check Fees request [NUT-05] @@ -112,7 +115,8 @@ pub struct MeltResposne { /// Split Request [NUT-06] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SplitRequest { - pub amount: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub amount: Amount, pub proofs: Vec, pub outputs: Vec, } @@ -163,7 +167,7 @@ impl<'de> Deserialize<'de> for MintVersion { D: Deserializer<'de>, { let combined = String::deserialize(deserializer)?; - let parts: Vec<&str> = combined.split(" / ").collect(); + let parts: Vec<&str> = combined.split('/').collect(); if parts.len() != 2 { return Err(serde::de::Error::custom("Invalid input string")); } diff --git a/tests/integration_test.rs b/tests/integration_test.rs index fedeb5d2..18945312 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,20 +1,13 @@ use std::str::FromStr; +use bitcoin::Amount; +use lightning_invoice::Invoice; use url::Url; use cashu_rs::cashu_mint::CashuMint; const MINTURL: &str = "https://legend.lnbits.com/cashu/api/v1/SKvHRus9dmjWHhstHrsazW/"; -#[ignore] -#[tokio::test] -async fn test_get_mint_info() { - let url = Url::from_str(MINTURL).unwrap(); - let mint = CashuMint::new(url); - let mint_info = mint.get_info().await.unwrap(); - // println!("{:?}", mint_info); -} - #[tokio::test] async fn test_get_mint_keys() { let url = Url::from_str(MINTURL).unwrap(); @@ -32,3 +25,34 @@ async fn test_get_mint_keysets() { assert!(!mint_keysets.keysets.is_empty()) } + +#[tokio::test] +async fn test_request_mint() { + let url = Url::from_str(MINTURL).unwrap(); + let mint = CashuMint::new(url); + + let mint = mint.request_mint(Amount::from_sat(21)).await.unwrap(); + + assert!(mint.pr.check_signature().is_ok()) +} + +#[tokio::test] +async fn test_check_fees() { + let invoice = Invoice::from_str("lnbc10n1p3a6s0dsp5n55r506t2fv4r0mjcg30v569nk2u9s40ur4v3r3mgtscjvkvnrqqpp5lzfv8fmjzduelk74y9rsrxrayvhyzcdsh3zkdgv0g50napzalvqsdqhf9h8vmmfvdjn5gp58qengdqxq8p3aaymdcqpjrzjqwryaup9lh50kkranzgcdnn2fgvx390wgj5jd07rwr3vxeje0glc7z70cgqqg4sqqqqqqqlgqqqqrucqjq9qyysgqrjky5axsldzhqsjwsc38xa37k6t04le3ws4t26nqej62vst5xkz56qw85r6c4a3tr79588e0ceuuahwgfnkqc6n6269unlwqtvwr5vqqy0ncdq").unwrap(); + + let url = Url::from_str(MINTURL).unwrap(); + let mint = CashuMint::new(url); + + let fee = mint.check_fees(invoice).await.unwrap(); + println!("{fee:?}"); +} + +#[ignore] +#[tokio::test] +async fn test_get_mint_info() { + let url = Url::from_str(MINTURL).unwrap(); + let mint = CashuMint::new(url); + let mint_info = mint.get_info().await.unwrap(); + + // println!("{:?}", mint_info); +}