diff --git a/Cargo.toml b/Cargo.toml index 47045fc8..f794de0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,8 @@ authors = ["thesimplekid"] license = "BSD-3-Clause" readme = "README.md" repository = "https://github.com/thesimplekid/cashu-crab" -description = "Cashu rust library" +description = "Cashu rust wallet library" +exclude = ["integration_test"] [workspace] members = ["integration_test"] @@ -15,7 +16,6 @@ members = ["integration_test"] [dependencies] base64 = "0.21.0" bitcoin = { version = "0.30.0", features=["serde"] } -bitcoin-private = "0.1.0" bitcoin_hashes = "0.12.0" hex = "0.4.3" k256 = { version = "0.13.1", features=["arithmetic"] } @@ -24,7 +24,6 @@ minreq = { version = "2.7.0", features = ["json-using-serde", "https"] } rand = "0.8.5" getrandom = { version = "0.2", features = ["js"] } serde = { version = "1.0.160", features = ["derive"]} -serde_bytes = "0.11.9" serde_json = "1.0.96" thiserror = "1.0.40" url = "2.3.1" diff --git a/integration_test/src/main.rs b/integration_test/src/main.rs index 0faeb626..5ccc82a7 100644 --- a/integration_test/src/main.rs +++ b/integration_test/src/main.rs @@ -7,7 +7,7 @@ use std::time::Duration; use bitcoin::Amount; use cashu_crab::cashu_wallet::CashuWallet; use cashu_crab::client::Client; -use cashu_crab::types::{MintKeys, Token, TokenData}; +use cashu_crab::types::{MintKeys, Proof, Token, TokenData}; use lightning_invoice::Invoice; use url::Url; @@ -24,11 +24,20 @@ async fn main() { let wallet = CashuWallet::new(client.to_owned(), keys); test_get_mint_keysets(&client).await; test_request_mint(&wallet).await; - let token = test_mint(&wallet).await; - let new_token = test_receive(&wallet, &token).await; - + let proofs = test_mint(&wallet).await; + let token = TokenData::new( + client.mint_url.clone(), + proofs, + Some("Hello World".to_string()), + ); + let new_token = test_receive(&wallet, &token.to_string()).await; test_check_spendable(&client, &new_token).await; + let proofs = TokenData::from_str(&new_token).unwrap().token[0] + .clone() + .proofs; + test_send(&wallet, proofs).await; + test_check_fees(&client).await; } @@ -52,7 +61,7 @@ async fn test_request_mint(wallet: &CashuWallet) { assert!(mint.pr.check_signature().is_ok()) } -async fn test_mint(wallet: &CashuWallet) -> String { +async fn test_mint(wallet: &CashuWallet) -> Vec { let mint_req = wallet.request_mint(Amount::from_sat(21)).await.unwrap(); println!("Mint Req: {:?}", mint_req.pr.to_string()); @@ -61,14 +70,12 @@ async fn test_mint(wallet: &CashuWallet) -> String { // but for now pay it quick thread::sleep(Duration::from_secs(30)); - let mint_res = wallet + wallet .mint_token(Amount::from_sat(21), &mint_req.hash) .await - .unwrap(); + .unwrap() - println!("Mint: {:?}", mint_res.to_string()); - - mint_res.to_string() + // println!("Mint: {:?}", mint_res.to_string()); } async fn test_check_fees(mint: &Client) { @@ -102,45 +109,29 @@ async fn test_check_spendable(client: &Client, token: &str) { let wallet = CashuWallet::new(client.to_owned(), mint_keys); let token_data = TokenData::from_str(token).unwrap(); - let _spendable = wallet + let spendable = wallet .check_proofs_spent(token_data.token[0].clone().proofs) .await .unwrap(); + + assert!(!spendable.spendable.is_empty()); // println!("Spendable: {:?}", spendable); } -async fn _test_split(client: &Client, token: &str) { - let mint_keys = client.get_keys().await.unwrap(); - - let wallet = CashuWallet::new(client.clone(), mint_keys); - let proofs = wallet.receive(token).await.unwrap(); - - let split = wallet - .create_split(Amount::ONE_SAT, Amount::ONE_SAT, proofs) - .await - .unwrap(); - - println!("Split: {:#?}", split); - println!( - "splint JSON {:?}", - serde_json::to_string(&split.split_payload) - ); - - let split = client.split(split.split_payload).await; - println!("Split res: {:#?}", split); -} - -async fn _test_send(mint: &Client, token: &str) { - let mint_keys = mint.get_keys().await.unwrap(); - - let wallet = CashuWallet::new(mint.to_owned(), mint_keys); - let prom = wallet.receive(token).await.unwrap(); - let send = wallet.send(Amount::from_sat(2), prom).await.unwrap(); +async fn test_send(wallet: &CashuWallet, proofs: Vec) { + let send = wallet.send(Amount::from_sat(2), proofs).await.unwrap(); println!("{:?}", send); + + let keep_token = wallet.proofs_to_token(send.change_proofs, Some("Keeping these".to_string())); + + let send_token = wallet.proofs_to_token(send.send_proofs, Some("Sending these".to_string())); + + println!("Keep Token: {keep_token}"); + println!("Send Token: {send_token}"); } -async fn test_get_mint_info(mint: &Client) { +async fn _test_get_mint_info(mint: &Client) { let _mint_info = mint.get_info().await.unwrap(); // println!("{:?}", mint_info); diff --git a/src/cashu_wallet.rs b/src/cashu_wallet.rs index 7816d761..ac9008fd 100644 --- a/src/cashu_wallet.rs +++ b/src/cashu_wallet.rs @@ -9,7 +9,7 @@ use crate::{ error::Error, types::{ BlindedMessages, MintKeys, Proof, ProofsStatus, RequestMintResponse, SendProofs, - SplitPayload, SplitRequest, Token, TokenData, + SplitPayload, SplitRequest, TokenData, }, }; @@ -45,7 +45,11 @@ impl CashuWallet { } /// Mint Token - pub async fn mint_token(&self, amount: Amount, payment_hash: &str) -> Result { + pub async fn mint_token( + &self, + amount: Amount, + payment_hash: &str, + ) -> Result, Error> { let blinded_messages = BlindedMessages::random(amount)?; let mint_res = self @@ -60,15 +64,7 @@ impl CashuWallet { &self.mint_keys, )?; - let token = Token { - mint: self.client.mint_url.clone(), - proofs, - }; - - Ok(TokenData { - token: vec![token], - memo: None, - }) + Ok(proofs) } /// Check fee @@ -89,7 +85,7 @@ impl CashuWallet { let keys = if token.mint.eq(&self.client.mint_url) { self.mint_keys.clone() } else { - // TODO: + // FIXME: println!("No match"); self.mint_keys.clone() // CashuMint::new(token.mint).get_keys().await.unwrap() @@ -131,7 +127,7 @@ impl CashuWallet { } /// Create Split Payload - pub async fn create_split( + async fn create_split( &self, keep_amount: Amount, send_amount: Amount, @@ -150,7 +146,6 @@ impl CashuWallet { proofs, outputs, }; - println!("splint JSON {:?}", serde_json::to_string(&split_payload)); Ok(SplitPayload { keep_blinded_messages, @@ -181,7 +176,6 @@ impl CashuWallet { // If amount available is EQUAL to send amount no need to split if amount_available.eq(&amount) { - println!("Equal Proofs: {:#?}", send_proofs); return Ok(send_proofs); } @@ -210,12 +204,16 @@ impl CashuWallet { &self.mint_keys, )?; - println!("Send Proofs: {:#?}", send_proofs); - println!("Keep Proofs: {:#?}", keep_proofs); + // println!("Send Proofs: {:#?}", send_proofs); + // println!("Keep Proofs: {:#?}", keep_proofs); Ok(SendProofs { change_proofs: keep_proofs, send_proofs, }) } + + pub fn proofs_to_token(&self, proofs: Vec, memo: Option) -> String { + TokenData::new(self.client.mint_url.clone(), proofs, memo).to_string() + } } diff --git a/src/client.rs b/src/client.rs index 2adfe23f..40a17ba3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -56,7 +56,6 @@ impl Client { let mut url = self.mint_url.join("mint")?; url.query_pairs_mut() .append_pair("amount", &amount.to_sat().to_string()); - println!("{url}"); Ok(minreq::get(url).send()?.json::()?) } diff --git a/src/types.rs b/src/types.rs index 68e51307..e6388f4c 100644 --- a/src/types.rs +++ b/src/types.rs @@ -40,6 +40,7 @@ pub struct BlindedMessages { } impl BlindedMessages { + /// pub fn random(amount: Amount) -> Result { let mut blinded_messages = BlindedMessages::default(); @@ -294,12 +295,30 @@ pub struct Token { pub proofs: Vec, } +impl Token { + fn new(mint_url: Url, proofs: Vec) -> Self { + Self { + mint: mint_url, + proofs, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct TokenData { pub token: Vec, pub memo: Option, } +impl TokenData { + pub fn new(mint_url: Url, proofs: Vec, memo: Option) -> Self { + Self { + token: vec![Token::new(mint_url, proofs)], + memo, + } + } +} + impl FromStr for TokenData { type Err = Error;