From 8a7eadcdc2af56a9b496bbec9cc75c9b5a36463f Mon Sep 17 00:00:00 2001 From: ngutech21 Date: Mon, 19 Feb 2024 13:11:36 +0100 Subject: [PATCH] feat: show paid and returned fees in cli --- integrationtests/tests/tests.rs | 8 +++-- moksha-cli/src/main.rs | 58 +++++++++++++++++++++------------ moksha-wallet/src/wallet.rs | 45 ++++++++++++++++--------- 3 files changed, 72 insertions(+), 39 deletions(-) diff --git a/integrationtests/tests/tests.rs b/integrationtests/tests/tests.rs index a6543814..b9895f5f 100644 --- a/integrationtests/tests/tests.rs +++ b/integrationtests/tests/tests.rs @@ -1,4 +1,4 @@ -use moksha_core::primitives::PaymentMethod; +use moksha_core::primitives::{CurrencyUnit, PaymentMethod}; use moksha_wallet::client::CashuClient; use moksha_wallet::http::CrossPlatformHttpClient; @@ -116,7 +116,11 @@ pub fn test_integration() -> anyhow::Result<()> { // pay ln-invoice let invoice_1000 = read_fixture("invoice_1000.txt").unwrap(); - let result_pay_invoice = wallet.pay_invoice(invoice_1000).await; + let quote = wallet + .get_melt_quote_bolt11(invoice_1000.clone(), CurrencyUnit::Sat) + .await + .expect("Could not get melt quote"); + let result_pay_invoice = wallet.pay_invoice("e, invoice_1000).await; if result_pay_invoice.is_err() { println!("error in pay_invoice{:?}", result_pay_invoice); } diff --git a/moksha-cli/src/main.rs b/moksha-cli/src/main.rs index cce1dec5..1c75cb03 100644 --- a/moksha-cli/src/main.rs +++ b/moksha-cli/src/main.rs @@ -1,7 +1,7 @@ use clap::{Parser, Subcommand}; use dialoguer::{theme::ColorfulTheme, Confirm, Select}; use moksha_core::primitives::{ - PaymentMethod, PostMeltOnchainResponse, PostMintQuoteBolt11Response, + CurrencyUnit, PaymentMethod, PostMeltOnchainResponse, PostMintQuoteBolt11Response, PostMintQuoteOnchainResponse, }; use moksha_wallet::http::CrossPlatformHttpClient; @@ -26,34 +26,24 @@ struct Opts { #[derive(Subcommand, Clone)] enum Command { /// Mint tokens - Mint { - amount: u64, - }, + Mint { amount: u64 }, /// Pay Lightning invoice - Pay { - invoice: String, - }, + Pay { invoice: String }, - /// Pay bitcoin onchain - PayOnchain { - address: String, - amount: u64, - }, + /// Pay Bitcoin on chain + PayOnchain { address: String, amount: u64 }, /// Send tokens - Send { - amount: u64, - }, + Send { amount: u64 }, /// Receive tokens - Receive { - token: String, - }, + Receive { token: String }, /// Show local balance Balance, + /// Show version and configuration Info, } @@ -122,11 +112,35 @@ async fn main() -> anyhow::Result<()> { println!("Balance: {balance} (sat)"); } Command::Pay { invoice } => { - let response = wallet.pay_invoice(invoice).await?; + let quote = wallet + .get_melt_quote_bolt11(invoice.clone(), CurrencyUnit::Sat) + .await?; + + let pay_confirmed = Confirm::new() + .with_prompt(format!( + "Pay lightning invoice: amount {} + fee {} = {} (sat)?", + quote.amount, + quote.fee_reserve, + quote.amount + quote.fee_reserve + )) + .interact() + .unwrap(); + + if !pay_confirmed { + return Ok(()); + } + + let response = wallet.pay_invoice("e, invoice).await?; // FIXME handle not enough tokens error - if response.paid { + if response.0.paid { + if response.1 > 0 { + println!( + "Returned fees {} (sat)", + response.1.to_formatted_string(&Locale::en) + ); + } println!( "\nInvoice has been paid: Tokens melted successfully\nNew balance: {} (sat)", wallet.get_balance().await?.to_formatted_string(&Locale::en) @@ -143,7 +157,9 @@ async fn main() -> anyhow::Result<()> { return Ok(()); } - let quotes = wallet.pay_onchain_quote(address.clone(), amount).await?; + let quotes = wallet + .get_melt_quote_btconchain(address.clone(), amount) + .await?; if quotes.is_empty() { println!("Error: No quotes found"); diff --git a/moksha-wallet/src/wallet.rs b/moksha-wallet/src/wallet.rs index 517b7634..5163fe13 100644 --- a/moksha-wallet/src/wallet.rs +++ b/moksha-wallet/src/wallet.rs @@ -5,8 +5,8 @@ use moksha_core::{ keyset::V1Keyset, primitives::{ CurrencyUnit, KeyResponse, MintInfoResponse, PaymentMethod, PostMeltBolt11Response, - PostMeltOnchainResponse, PostMeltQuoteOnchainResponse, PostMintQuoteBolt11Response, - PostMintQuoteOnchainResponse, + PostMeltOnchainResponse, PostMeltQuoteBolt11Response, PostMeltQuoteOnchainResponse, + PostMintQuoteBolt11Response, PostMintQuoteOnchainResponse, }, proof::{Proof, Proofs}, token::TokenV3, @@ -264,17 +264,23 @@ where .await } + pub async fn get_melt_quote_bolt11( + &self, + invoice: String, + currency: CurrencyUnit, + ) -> Result { + self.client + .post_melt_quote_bolt11(&self.mint_url, invoice.clone(), currency) + .await + } + pub async fn pay_invoice( &self, + melt_quote: &PostMeltQuoteBolt11Response, invoice: String, - ) -> Result { + ) -> Result<(PostMeltBolt11Response, u64), MokshaWalletError> { let all_proofs = self.localstore.get_proofs().await?; - let melt_quote = self - .client - .post_melt_quote_bolt11(&self.mint_url, invoice.clone(), CurrencyUnit::Sat) - .await?; - let ln_amount = Self::get_invoice_amount(&invoice)? + melt_quote.fee_reserve; if ln_amount > all_proofs.total_amount() { @@ -314,7 +320,7 @@ where .collect::>(); match self - .melt_token(melt_quote.quote, ln_amount, &total_proofs, msgs) + .melt_token(melt_quote.to_owned().quote, ln_amount, &total_proofs, msgs) .await { Ok(response) => { @@ -328,7 +334,7 @@ where )?; self.localstore.add_proofs(&change_proofs).await?; - Ok(response) + Ok((response, change_proofs.total_amount())) } Err(e) => { self.localstore.add_proofs(&total_proofs).await?; @@ -337,7 +343,7 @@ where } } - pub async fn pay_onchain_quote( + pub async fn get_melt_quote_btconchain( &self, address: String, amount: u64, @@ -858,8 +864,12 @@ mod tests { // 21 sats let invoice = "lnbcrt210n1pjg6mqhpp5pza5wzh0csjjuvfpjpv4zdjmg30vedj9ycv5tyfes9x7dp8axy0sdqqcqzzsxqyz5vqsp5vtxg4c5tw2s2zxxya2a7an0psn9mcfmlqctxzntm3sngnpyk3muq9qyyssqf8z5f90yu3wrmsufnnza25qjlnvc6ukdr094ckzn63ktcy6z5fw5mxf9skndpg2p4648gfjfvvx4qg2lqvlryyycg5k7x9h4dw70t4qq37pegm".to_string(); - let result = wallet.pay_invoice(invoice).await?; - assert!(result.paid); + let quote = wallet + .get_melt_quote_bolt11(invoice.clone(), CurrencyUnit::Sat) + .await?; + + let result = wallet.pay_invoice("e, invoice).await?; + assert!(result.0.paid); Ok(()) } @@ -909,10 +919,13 @@ mod tests { // 21 sats let invoice = "lnbcrt210n1pjg6mqhpp5pza5wzh0csjjuvfpjpv4zdjmg30vedj9ycv5tyfes9x7dp8axy0sdqqcqzzsxqyz5vqsp5vtxg4c5tw2s2zxxya2a7an0psn9mcfmlqctxzntm3sngnpyk3muq9qyyssqf8z5f90yu3wrmsufnnza25qjlnvc6ukdr094ckzn63ktcy6z5fw5mxf9skndpg2p4648gfjfvvx4qg2lqvlryyycg5k7x9h4dw70t4qq37pegm".to_string(); - let result = wallet.pay_invoice(invoice).await?; - assert!(!result.paid); + let quote = wallet + .get_melt_quote_bolt11(invoice.clone(), CurrencyUnit::Sat) + .await?; + let result = wallet.pay_invoice("e, invoice).await?; + assert!(!result.0.paid); assert_eq!(64, localstore.get_proofs().await?.total_amount()); - assert!(!result.paid); + assert!(!result.0.paid); Ok(()) } }