diff --git a/Cargo.toml b/Cargo.toml index 70be327b..38537e43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" authors = ["thesimplekid"] license = "BSD-3-Clause" readme = "README.md" +documentation = "https://docs.rs/crate/cashu-crab" repository = "https://github.com/thesimplekid/cashu-crab" description = "Cashu rust wallet and mint library" # exclude = ["integration_test"] @@ -12,6 +13,10 @@ description = "Cashu rust wallet and mint library" #[workspace] #members = ["integration_test"] +[features] +default = ["mint", "wallet"] +mint = [] +wallet = [] [dependencies] base64 = "0.21.0" diff --git a/src/client.rs b/src/client.rs index d2ae16c1..1cc6149b 100644 --- a/src/client.rs +++ b/src/client.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use url::Url; -use crate::nuts::nut00::{BlindedMessage, BlindedMessages, Proof}; +use crate::nuts::nut00::{wallet::BlindedMessages, BlindedMessage, Proof}; use crate::nuts::nut01::Keys; use crate::nuts::nut03::RequestMintResponse; use crate::nuts::nut04::{MintRequest, PostMintResponse}; diff --git a/src/dhke.rs b/src/dhke.rs index 81969f9e..e0a2dcc8 100644 --- a/src/dhke.rs +++ b/src/dhke.rs @@ -4,14 +4,21 @@ use std::ops::Mul; use bitcoin_hashes::sha256; use bitcoin_hashes::Hash; -use k256::{ProjectivePoint, Scalar, SecretKey}; -use crate::error::Error; -use crate::nuts::nut00::BlindedSignature; -use crate::nuts::nut00::Proof; -use crate::nuts::nut00::Proofs; -use crate::nuts::nut01::Keys; -use crate::nuts::nut01::PublicKey; +#[cfg(feature = "wallet")] +use k256::ProjectivePoint; + +use k256::{Scalar, SecretKey}; + +use crate::error; + +#[cfg(feature = "wallet")] +use crate::nuts::nut00::{BlindedSignature, Proof, Proofs}; + +#[cfg(feature = "wallet")] +use crate::nuts::nut01::{Keys, PublicKey}; + +#[cfg(feature = "wallet")] use crate::nuts::*; fn hash_to_curve(message: &[u8]) -> k256::PublicKey { @@ -32,11 +39,12 @@ fn hash_to_curve(message: &[u8]) -> k256::PublicKey { } } +#[cfg(feature = "wallet")] /// Blind Message Alice Step one pub fn blind_message( secret: &[u8], blinding_factor: Option, -) -> Result<(PublicKey, SecretKey), Error> { +) -> Result<(PublicKey, SecretKey), error::wallet::Error> { let y = hash_to_curve(secret); let r: SecretKey = match blinding_factor { @@ -49,6 +57,7 @@ pub fn blind_message( Ok((k256::PublicKey::try_from(b)?.into(), r)) } +#[cfg(feature = "wallet")] /// Unblind Message (Alice Step 3) pub fn unblind_message( // C_ @@ -56,7 +65,7 @@ pub fn unblind_message( r: SecretKey, // A mint_pubkey: PublicKey, -) -> Result { +) -> Result { // C // Unblinded message let c = ProjectivePoint::from(Into::::into(blinded_key).as_affine()) @@ -67,19 +76,22 @@ pub fn unblind_message( Ok(k256::PublicKey::try_from(c)?.into()) } +#[cfg(feature = "wallet")] /// Construct Proof pub fn construct_proofs( promises: Vec, rs: Vec, secrets: Vec, keys: &Keys, -) -> Result { +) -> Result { let mut proofs = vec![]; for (i, promise) in promises.into_iter().enumerate() { let blinded_c = promise.c; let a: PublicKey = keys .amount_key(promise.amount) - .ok_or(Error::CustomError("Could not get proofs".to_string()))? + .ok_or(error::wallet::Error::CustomError( + "Could not get proofs".to_string(), + ))? .to_owned(); let unblinded_signature = unblind_message(blinded_c, rs[i].clone().into(), a)?; @@ -98,11 +110,12 @@ pub fn construct_proofs( Ok(proofs) } +#[cfg(feature = "mint")] /// Sign Blinded Message (Step2 bob) pub fn sign_message( a: SecretKey, blinded_message: k256::PublicKey, -) -> Result { +) -> Result { Ok(k256::PublicKey::try_from( blinded_message .as_affine() @@ -110,12 +123,13 @@ pub fn sign_message( )?) } +#[cfg(feature = "mint")] /// Verify Message pub fn verify_message( a: SecretKey, unblinded_message: k256::PublicKey, msg: &str, -) -> Result<(), Error> { +) -> Result<(), error::mint::Error> { // Y let y = hash_to_curve(msg.as_bytes()); @@ -125,7 +139,7 @@ pub fn verify_message( return Ok(()); } - Err(Error::TokenNotVerifed) + Err(error::mint::Error::TokenNotVerifed) } #[cfg(test)] diff --git a/src/error.rs b/src/error.rs index 43a637aa..7262785b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,53 +4,37 @@ use std::string::FromUtf8Error; #[derive(Debug)] pub enum Error { - /// Min req error - MinReqError(minreq::Error), /// Parse Url Error UrlParseError(url::ParseError), - /// Unsupported Token - UnsupportedToken, /// Utf8 parse error Utf8ParseError(FromUtf8Error), /// Serde Json error SerdeJsonError(serde_json::Error), /// Base64 error Base64Error(base64::DecodeError), - /// Insufficaint Funds - InsufficantFunds, CustomError(String), /// From hex error HexError(hex::FromHexError), - /// From elliptic curve - EllipticError(k256::elliptic_curve::Error), AmountKey, Amount, TokenSpent, TokenNotVerifed, - OutputOrdering, InvoiceAmountUndefined, - CrabMintError(crate::client::Error), } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Error::MinReqError(err) => write!(f, "{}", err), Error::UrlParseError(err) => write!(f, "{}", err), - Error::UnsupportedToken => write!(f, "Unsuppported Token"), Error::Utf8ParseError(err) => write!(f, "{}", err), Error::SerdeJsonError(err) => write!(f, "{}", err), Error::Base64Error(err) => write!(f, "{}", err), - Error::InsufficantFunds => write!(f, "Insufficant Funds"), Error::CustomError(err) => write!(f, "{}", err), Error::HexError(err) => write!(f, "{}", err), - Error::EllipticError(err) => write!(f, "{}", err), Error::AmountKey => write!(f, "No Key for amount"), Error::Amount => write!(f, "Amount miss match"), Error::TokenSpent => write!(f, "Token Spent"), Error::TokenNotVerifed => write!(f, "Token Not Verified"), - Error::CrabMintError(err) => write!(f, "{}", err), - Error::OutputOrdering => write!(f, "Output ordering"), Error::InvoiceAmountUndefined => write!(f, "Invoice without amount"), } } @@ -58,12 +42,6 @@ impl fmt::Display for Error { impl StdError for Error {} -impl From for Error { - fn from(err: minreq::Error) -> Error { - Error::MinReqError(err) - } -} - impl From for Error { fn from(err: url::ParseError) -> Error { Error::UrlParseError(err) @@ -94,14 +72,112 @@ impl From for Error { } } -impl From for Error { - fn from(err: k256::elliptic_curve::Error) -> Error { - Error::EllipticError(err) +#[cfg(feature = "wallet")] +pub mod wallet { + use std::error::Error as StdError; + use std::fmt; + use std::string::FromUtf8Error; + + #[derive(Debug)] + pub enum Error { + CrabMintError(crate::client::Error), + /// Serde Json error + SerdeJsonError(serde_json::Error), + /// From elliptic curve + EllipticError(k256::elliptic_curve::Error), + /// Insufficaint Funds + InsufficantFunds, + /// Utf8 parse error + Utf8ParseError(FromUtf8Error), + /// Base64 error + Base64Error(base64::DecodeError), + /// Unsupported Token + UnsupportedToken, + CustomError(String), + } + + impl StdError for Error {} + + impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::CrabMintError(err) => write!(f, "{}", err), + Error::CustomError(err) => write!(f, "{}", err), + Error::InsufficantFunds => write!(f, "Insufficant Funds"), + Error::Utf8ParseError(err) => write!(f, "{}", err), + Error::Base64Error(err) => write!(f, "{}", err), + Error::UnsupportedToken => write!(f, "Unsuppported Token"), + Error::EllipticError(err) => write!(f, "{}", err), + Error::SerdeJsonError(err) => write!(f, "{}", err), + } + } + } + + impl From for Error { + fn from(err: crate::client::Error) -> Error { + Error::CrabMintError(err) + } + } + + impl From for Error { + fn from(err: serde_json::Error) -> Error { + Error::SerdeJsonError(err) + } + } + + impl From for Error { + fn from(err: k256::elliptic_curve::Error) -> Error { + Error::EllipticError(err) + } + } + + impl From for Error { + fn from(err: FromUtf8Error) -> Error { + Error::Utf8ParseError(err) + } + } + + impl From for Error { + fn from(err: base64::DecodeError) -> Error { + Error::Base64Error(err) + } } } -impl From for Error { - fn from(err: crate::client::Error) -> Error { - Error::CrabMintError(err) +#[cfg(feature = "mint")] +pub mod mint { + use std::error::Error as StdError; + use std::fmt; + + #[derive(Debug)] + pub enum Error { + AmountKey, + Amount, + TokenSpent, + /// From elliptic curve + EllipticError(k256::elliptic_curve::Error), + TokenNotVerifed, + InvoiceAmountUndefined, + } + + impl StdError for Error {} + + impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::AmountKey => write!(f, "No Key for amount"), + Error::Amount => write!(f, "Amount miss match"), + Error::TokenSpent => write!(f, "Token Spent"), + Error::EllipticError(err) => write!(f, "{}", err), + Error::TokenNotVerifed => write!(f, "Token Not Verified"), + Error::InvoiceAmountUndefined => write!(f, "Invoice without amount"), + } + } + } + + impl From for Error { + fn from(err: k256::elliptic_curve::Error) -> Error { + Error::EllipticError(err) + } } } diff --git a/src/lib.rs b/src/lib.rs index 5f191192..5bf63af7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,15 @@ pub mod amount; +#[cfg(feature = "wallet")] pub mod client; pub mod dhke; pub mod error; +#[cfg(feature = "mint")] pub mod mint; pub mod nuts; pub mod serde_utils; pub mod types; pub mod utils; +#[cfg(feature = "wallet")] pub mod wallet; pub use amount::Amount; diff --git a/src/mint.rs b/src/mint.rs index e7fc0d44..51732688 100644 --- a/src/mint.rs +++ b/src/mint.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use crate::dhke::sign_message; use crate::dhke::verify_message; -use crate::error::Error; +use crate::error::mint::Error; use crate::nuts::nut00::BlindedMessage; use crate::nuts::nut00::BlindedSignature; use crate::nuts::nut00::Proof; @@ -169,7 +169,11 @@ impl Mint { let proofs_total = melt_request.proofs_amount(); // TODO: Fee reserve - if proofs_total < melt_request.invoice_amount()? { + if proofs_total + < melt_request + .invoice_amount() + .map_err(|_| Error::InvoiceAmountUndefined)? + { return Err(Error::Amount); } diff --git a/src/nuts/nut00.rs b/src/nuts/nut00.rs index b806e617..706ae658 100644 --- a/src/nuts/nut00.rs +++ b/src/nuts/nut00.rs @@ -1,17 +1,13 @@ //! Notation and Models // https://github.com/cashubtc/nuts/blob/main/00.md -use std::str::FromStr; - -use base64::{engine::general_purpose, Engine as _}; -use serde::{Deserialize, Serialize}; use url::Url; -use crate::utils::generate_secret; +use crate::serde_utils::serde_url; use crate::Amount; -use crate::{dhke::blind_message, error::Error, serde_utils::serde_url, utils::split_amount}; +use serde::{Deserialize, Serialize}; -use super::nut01::{self, PublicKey}; +use super::nut01::PublicKey; /// Blinded Message [NUT-00] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -23,67 +19,155 @@ pub struct BlindedMessage { pub b: PublicKey, } -/// Blinded Messages [NUT-00] -#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct BlindedMessages { - /// Blinded messages - pub blinded_messages: Vec, - /// Secrets - pub secrets: Vec, - /// Rs - pub rs: Vec, - /// Amounts - pub amounts: Vec, -} +#[cfg(feature = "wallet")] +pub mod wallet { + use std::str::FromStr; -impl BlindedMessages { - /// Outputs for speceifed amount with random secret - pub fn random(amount: Amount) -> Result { - let mut blinded_messages = BlindedMessages::default(); + use base64::{engine::general_purpose, Engine as _}; + use serde::{Deserialize, Serialize}; + use url::Url; - for amount in split_amount(amount) { - let secret = generate_secret(); - let (blinded, r) = blind_message(secret.as_bytes(), None)?; + use crate::error; + use crate::error::wallet; + use crate::nuts::nut00::BlindedMessage; + use crate::nuts::nut00::Proofs; + use crate::nuts::nut01; + use crate::utils::generate_secret; + use crate::Amount; + use crate::{dhke::blind_message, utils::split_amount}; - let blinded_message = BlindedMessage { amount, b: blinded }; + use super::MintProofs; - blinded_messages.secrets.push(secret); - blinded_messages.blinded_messages.push(blinded_message); - blinded_messages.rs.push(r.into()); - blinded_messages.amounts.push(amount); - } - - Ok(blinded_messages) + /// Blinded Messages [NUT-00] + #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] + pub struct BlindedMessages { + /// Blinded messages + pub blinded_messages: Vec, + /// Secrets + pub secrets: Vec, + /// Rs + pub rs: Vec, + /// Amounts + pub amounts: Vec, } - /// Blank Outputs used for NUT-08 change - pub fn blank(fee_reserve: Amount) -> Result { - let mut blinded_messages = BlindedMessages::default(); + impl BlindedMessages { + /// Outputs for speceifed amount with random secret + pub fn random(amount: Amount) -> Result { + let mut blinded_messages = BlindedMessages::default(); - let fee_reserve = bitcoin::Amount::from_sat(fee_reserve.to_sat()); + for amount in split_amount(amount) { + let secret = generate_secret(); + let (blinded, r) = blind_message(secret.as_bytes(), None)?; - let count = (fee_reserve - .to_float_in(bitcoin::Denomination::Satoshi) - .log2() - .ceil() as u64) - .max(1); + let blinded_message = BlindedMessage { amount, b: blinded }; - for _i in 0..count { - let secret = generate_secret(); - let (blinded, r) = blind_message(secret.as_bytes(), None)?; + blinded_messages.secrets.push(secret); + blinded_messages.blinded_messages.push(blinded_message); + blinded_messages.rs.push(r.into()); + blinded_messages.amounts.push(amount); + } - let blinded_message = BlindedMessage { - amount: Amount::ZERO, - b: blinded, - }; - - blinded_messages.secrets.push(secret); - blinded_messages.blinded_messages.push(blinded_message); - blinded_messages.rs.push(r.into()); - blinded_messages.amounts.push(Amount::ZERO); + Ok(blinded_messages) } - Ok(blinded_messages) + /// Blank Outputs used for NUT-08 change + pub fn blank(fee_reserve: Amount) -> Result { + let mut blinded_messages = BlindedMessages::default(); + + let fee_reserve = bitcoin::Amount::from_sat(fee_reserve.to_sat()); + + let count = (fee_reserve + .to_float_in(bitcoin::Denomination::Satoshi) + .log2() + .ceil() as u64) + .max(1); + + for _i in 0..count { + let secret = generate_secret(); + let (blinded, r) = blind_message(secret.as_bytes(), None)?; + + let blinded_message = BlindedMessage { + amount: Amount::ZERO, + b: blinded, + }; + + blinded_messages.secrets.push(secret); + blinded_messages.blinded_messages.push(blinded_message); + blinded_messages.rs.push(r.into()); + blinded_messages.amounts.push(Amount::ZERO); + } + + Ok(blinded_messages) + } + } + + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] + pub struct Token { + pub token: Vec, + pub memo: Option, + } + + impl Token { + pub fn new(mint_url: Url, proofs: Proofs, memo: Option) -> Self { + Self { + token: vec![MintProofs::new(mint_url, proofs)], + memo, + } + } + + pub fn token_info(&self) -> (u64, String) { + let mut amount = Amount::ZERO; + + for proofs in &self.token { + for proof in &proofs.proofs { + amount += proof.amount; + } + } + + (amount.to_sat(), self.token[0].mint.to_string()) + } + } + + impl FromStr for Token { + type Err = error::wallet::Error; + + fn from_str(s: &str) -> Result { + if !s.starts_with("cashuA") { + return Err(wallet::Error::UnsupportedToken); + } + + let s = s.replace("cashuA", ""); + let decoded = general_purpose::STANDARD.decode(s)?; + let decoded_str = String::from_utf8(decoded)?; + let token: Token = serde_json::from_str(&decoded_str)?; + Ok(token) + } + } + + impl Token { + pub fn convert_to_string(&self) -> Result { + let json_string = serde_json::to_string(self)?; + let encoded = general_purpose::STANDARD.encode(json_string); + Ok(format!("cashuA{}", encoded)) + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct MintProofs { + #[serde(with = "serde_url")] + pub mint: Url, + pub proofs: Proofs, +} + +#[cfg(feature = "wallet")] +impl MintProofs { + fn new(mint_url: Url, proofs: Proofs) -> Self { + Self { + mint: mint_url, + proofs, + } } } @@ -130,77 +214,6 @@ impl From for mint::Proof { } } -pub fn mint_proofs_from_proofs(proofs: Proofs) -> mint::Proofs { - proofs.iter().map(|p| p.to_owned().into()).collect() -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct MintProofs { - #[serde(with = "serde_url")] - pub mint: Url, - pub proofs: Proofs, -} - -impl MintProofs { - fn new(mint_url: Url, proofs: Proofs) -> Self { - Self { - mint: mint_url, - proofs, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Token { - pub token: Vec, - pub memo: Option, -} - -impl Token { - pub fn new(mint_url: Url, proofs: Proofs, memo: Option) -> Self { - Self { - token: vec![MintProofs::new(mint_url, proofs)], - memo, - } - } - - pub fn token_info(&self) -> (u64, String) { - let mut amount = Amount::ZERO; - - for proofs in &self.token { - for proof in &proofs.proofs { - amount += proof.amount; - } - } - - (amount.to_sat(), self.token[0].mint.to_string()) - } -} - -impl FromStr for Token { - type Err = Error; - - fn from_str(s: &str) -> Result { - if !s.starts_with("cashuA") { - return Err(Error::UnsupportedToken); - } - - let s = s.replace("cashuA", ""); - let decoded = general_purpose::STANDARD.decode(s)?; - let decoded_str = String::from_utf8(decoded)?; - let token: Token = serde_json::from_str(&decoded_str)?; - Ok(token) - } -} - -impl Token { - pub fn convert_to_string(&self) -> Result { - let json_string = serde_json::to_string(self)?; - let encoded = general_purpose::STANDARD.encode(json_string); - Ok(format!("cashuA{}", encoded)) - } -} - pub mod mint { use serde::{Deserialize, Serialize}; @@ -228,10 +241,18 @@ pub mod mint { /// List of proofs pub type Proofs = Vec; + + pub fn mint_proofs_from_proofs(proofs: super::Proofs) -> Proofs { + proofs.iter().map(|p| p.to_owned().into()).collect() + } } #[cfg(test)] mod tests { + use std::str::FromStr; + use url::Url; + + use super::wallet::*; use super::*; #[test] diff --git a/src/nuts/nut06.rs b/src/nuts/nut06.rs index d5f234e0..b2c23cba 100644 --- a/src/nuts/nut06.rs +++ b/src/nuts/nut06.rs @@ -2,11 +2,15 @@ // https://github.com/cashubtc/nuts/blob/main/06.md use serde::{Deserialize, Serialize}; -use crate::nuts::nut00::{BlindedMessage, BlindedMessages, Proofs}; +use crate::nuts::nut00::{BlindedMessage, Proofs}; use crate::Amount; +#[cfg(feature = "wallet")] +use crate::nuts::nut00::wallet::BlindedMessages; + use super::nut00::BlindedSignature; +#[cfg(feature = "wallet")] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SplitPayload { pub blinded_messages: BlindedMessages, diff --git a/src/wallet.rs b/src/wallet.rs index 55d60b39..53db8ace 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -2,14 +2,16 @@ use std::str::FromStr; use crate::dhke::unblind_message; -use crate::nuts::nut00::{mint, BlindedMessages, BlindedSignature, Proof, Proofs, Token}; +use crate::nuts::nut00::{ + mint, wallet::BlindedMessages, wallet::Token, BlindedSignature, Proof, Proofs, +}; use crate::nuts::nut01::Keys; use crate::nuts::nut03::RequestMintResponse; use crate::nuts::nut06::{SplitPayload, SplitRequest}; use crate::types::{Melted, ProofsStatus, SendProofs}; use crate::Amount; pub use crate::Invoice; -use crate::{client::Client, dhke::construct_proofs, error::Error}; +use crate::{client::Client, dhke::construct_proofs, error}; #[derive(Clone, Debug)] pub struct Wallet { @@ -30,7 +32,10 @@ impl Wallet { // TODO: getter method for keys that if it cant get them try again /// Check if a proof is spent - pub async fn check_proofs_spent(&self, proofs: &mint::Proofs) -> Result { + pub async fn check_proofs_spent( + &self, + proofs: &mint::Proofs, + ) -> Result { let spendable = self.client.check_spendable(proofs).await?; // Separate proofs in spent and unspent based on mint response @@ -46,12 +51,19 @@ impl Wallet { } /// Request Token Mint - pub async fn request_mint(&self, amount: Amount) -> Result { + pub async fn request_mint( + &self, + amount: Amount, + ) -> Result { Ok(self.client.request_mint(amount).await?) } /// Mint Token - pub async fn mint_token(&self, amount: Amount, hash: &str) -> Result { + pub async fn mint_token( + &self, + amount: Amount, + hash: &str, + ) -> Result { let proofs = self.mint(amount, hash).await?; let token = Token::new(self.client.mint_url.clone(), proofs, None); @@ -59,7 +71,7 @@ impl Wallet { } /// Mint Proofs - pub async fn mint(&self, amount: Amount, hash: &str) -> Result { + pub async fn mint(&self, amount: Amount, hash: &str) -> Result { let blinded_messages = BlindedMessages::random(amount)?; let mint_res = self.client.mint(blinded_messages.clone(), hash).await?; @@ -75,12 +87,12 @@ impl Wallet { } /// Check fee - pub async fn check_fee(&self, invoice: Invoice) -> Result { + pub async fn check_fee(&self, invoice: Invoice) -> Result { Ok(self.client.check_fees(invoice).await?.fee) } /// Receive - pub async fn receive(&self, encoded_token: &str) -> Result { + pub async fn receive(&self, encoded_token: &str) -> Result { let token_data = Token::from_str(encoded_token)?; let mut proofs: Vec = vec![vec![]]; @@ -113,7 +125,7 @@ impl Wallet { } /// Create Split Payload - fn create_split(&self, proofs: Proofs) -> Result { + fn create_split(&self, proofs: Proofs) -> Result { let value = proofs.iter().map(|p| p.amount).sum(); let blinded_messages = BlindedMessages::random(value)?; @@ -133,7 +145,7 @@ impl Wallet { &self, blinded_messages: BlindedMessages, promises: Vec, - ) -> Result { + ) -> Result { let BlindedMessages { blinded_messages: _, secrets, @@ -169,7 +181,11 @@ impl Wallet { } /// Send - pub async fn send(&self, amount: Amount, proofs: Proofs) -> Result { + pub async fn send( + &self, + amount: Amount, + proofs: Proofs, + ) -> Result { let mut amount_available = Amount::ZERO; let mut send_proofs = SendProofs::default(); @@ -185,7 +201,7 @@ impl Wallet { if amount_available.lt(&amount) { println!("Not enough funds"); - return Err(Error::InsufficantFunds); + return Err(error::wallet::Error::InsufficantFunds); } // If amount available is EQUAL to send amount no need to split @@ -227,7 +243,7 @@ impl Wallet { invoice: Invoice, proofs: Proofs, fee_reserve: Amount, - ) -> Result { + ) -> Result { let blinded = BlindedMessages::blank(fee_reserve)?; let melt_response = self .client @@ -253,7 +269,11 @@ impl Wallet { Ok(melted) } - pub fn proofs_to_token(&self, proofs: Proofs, memo: Option) -> Result { + pub fn proofs_to_token( + &self, + proofs: Proofs, + memo: Option, + ) -> Result { Token::new(self.client.mint_url.clone(), proofs, memo).convert_to_string() } }