diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 5852a74c9..db51d1652 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -26,7 +26,7 @@ mod tests { use anyhow::Result; use bip39::{Language, Mnemonic}; - use crate::{ReceivePaymentRequest, Wallet, DEFAULT_DATA_DIR}; + use crate::{Network, ReceivePaymentRequest, Wallet, DEFAULT_DATA_DIR}; const PHRASE_FILE_NAME: &str = "phrase"; @@ -56,7 +56,8 @@ mod tests { #[test] fn normal_submarine_swap() -> Result<()> { - let breez_wallet = Wallet::init(get_mnemonic()?.to_string())?; + let breez_wallet = + Wallet::init(&get_mnemonic()?.to_string(), None, Network::LiquidTestnet)?; let mut invoice = String::new(); println!("Please paste the invoice to be paid: "); @@ -70,7 +71,8 @@ mod tests { #[test] fn reverse_submarine_swap_success() -> Result<()> { - let breez_wallet = Wallet::init(get_mnemonic()?.to_string())?; + let breez_wallet = + Wallet::init(&get_mnemonic()?.to_string(), None, Network::LiquidTestnet)?; let swap_response = breez_wallet.receive_payment(ReceivePaymentRequest { onchain_amount_sat: Some(1000), diff --git a/lib/src/model.rs b/lib/src/model.rs index d29b6a38f..570fc50a0 100644 --- a/lib/src/model.rs +++ b/lib/src/model.rs @@ -3,7 +3,7 @@ use boltz_client::network::Chain; use lwk_signer::SwSigner; use lwk_wollet::{ElectrumUrl, ElementsNetwork, WolletDescriptor}; -#[derive(Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq)] pub enum Network { Liquid, LiquidTestnet, @@ -27,6 +27,7 @@ impl From for Chain { } } +#[derive(Debug)] pub struct WalletOptions { pub signer: SwSigner, pub network: Network, @@ -42,28 +43,31 @@ pub struct WalletOptions { } #[derive(Debug)] -pub struct SwapLbtcResponse { - pub id: String, - pub invoice: String, +pub struct ReceivePaymentRequest { + pub invoice_amount_sat: Option, + pub onchain_amount_sat: Option, } -pub enum SwapStatus { - Created, - Mempool, - Completed, +#[derive(Debug)] +pub struct ReceivePaymentResponse { + pub id: String, + pub invoice: String, } -pub struct ReceivePaymentRequest { - pub invoice_amount_sat: Option, - pub onchain_amount_sat: Option, +#[derive(Debug)] +pub struct PreparePaymentResponse { + pub id: String, + pub funding_amount: u64, + pub funding_address: String, } +#[derive(Debug)] pub struct SendPaymentResponse { pub txid: String, } #[derive(thiserror::Error, Debug)] -pub enum SwapError { +pub enum PaymentError { #[error("Invoice amount is out of range")] AmountOutOfRange, @@ -86,9 +90,9 @@ pub enum SwapError { BoltzGeneric { err: String }, } -impl From for SwapError { +impl From for PaymentError { fn from(err: Error) -> Self { - SwapError::BoltzGeneric { + PaymentError::BoltzGeneric { err: format!("{err:?}"), } } @@ -154,10 +158,3 @@ impl From for Payment { } } } - -#[derive(Debug)] -pub struct PreparePaymentResponse { - pub id: String, - pub funding_amount: u64, - pub funding_address: String, -} diff --git a/lib/src/wallet.rs b/lib/src/wallet.rs index 1d069e20d..d24854b58 100644 --- a/lib/src/wallet.rs +++ b/lib/src/wallet.rs @@ -24,9 +24,9 @@ use lwk_wollet::{ }; use crate::{ - ensure_sdk, persist::Persister, Network, OngoingSwap, Payment, PaymentType, - ReceivePaymentRequest, SendPaymentResponse, SwapError, SwapLbtcResponse, WalletInfo, - WalletOptions, CLAIM_ABSOLUTE_FEES, DEFAULT_DATA_DIR, DEFAULT_ELECTRUM_URL, + ensure_sdk, persist::Persister, Network, OngoingSwap, Payment, PaymentError, PaymentType, + PreparePaymentResponse, ReceivePaymentRequest, ReceivePaymentResponse, SendPaymentResponse, + WalletInfo, WalletOptions, CLAIM_ABSOLUTE_FEES, DEFAULT_DATA_DIR, DEFAULT_ELECTRUM_URL, }; pub struct Wallet { @@ -114,7 +114,7 @@ impl Wallet { { match cloned.try_claim(&preimage, &redeem_script, &blinding_key, None) { Ok(_) => cloned.swap_persister.resolve_ongoing_swap(&id).unwrap(), - Err(e) => warn!("Could not claim yet. Err: {}", e), + Err(e) => warn!("Could not claim yet. Err: {e}"), } } }); @@ -197,28 +197,28 @@ impl Wallet { Ok(txid.to_string()) } - pub fn prepare_payment(&self, invoice: &str) -> Result { + pub fn prepare_payment(&self, invoice: &str) -> Result { let client = self.boltz_client(); let invoice = invoice .trim() .parse::() - .map_err(|_| SwapError::InvalidInvoice)?; + .map_err(|_| PaymentError::InvalidInvoice)?; // TODO Separate error type? Or make WalletError more generic? let lbtc_pair = client .get_pairs()? .get_lbtc_pair() - .ok_or(SwapError::WalletError)?; + .ok_or(PaymentError::WalletError)?; let amount_sat = invoice .amount_milli_satoshis() - .ok_or(SwapError::AmountOutOfRange)? + .ok_or(PaymentError::AmountOutOfRange)? / 1000; lbtc_pair .limits .within(amount_sat) - .map_err(|_| SwapError::AmountOutOfRange)?; + .map_err(|_| PaymentError::AmountOutOfRange)?; let swap_response = client.create_swap(CreateSwapRequest::new_lbtc_submarine( &lbtc_pair.hash, @@ -236,7 +236,7 @@ impl Wallet { amount_sat, funding_address: funding_address.clone(), }]) - .map_err(|_| SwapError::PersistError)?; + .map_err(|_| PaymentError::PersistError)?; Ok(PreparePaymentResponse { id, @@ -248,16 +248,18 @@ impl Wallet { pub fn send_payment( &self, res: &PreparePaymentResponse, - ) -> Result { + ) -> Result { let signer = AnySigner::Software(self.get_signer()); let txid = self .sign_and_send(&[signer], None, &res.funding_address, res.funding_amount) - .map_err(|_| SwapError::SendError)?; + .map_err(|err| PaymentError::SendError { + err: err.to_string(), + })?; self.swap_persister .resolve_ongoing_swap(&res.id) - .map_err(|_| SwapError::PersistError)?; + .map_err(|_| PaymentError::PersistError)?; Ok(SendPaymentResponse { txid }) } @@ -268,17 +270,17 @@ impl Wallet { redeem_script: &str, blinding_key: &str, absolute_fees: Option, - ) -> Result { + ) -> Result { let network_config = &self.get_network_config(); let rev_swap_tx = LBtcSwapTx::new_claim( LBtcSwapScript::reverse_from_str(redeem_script, blinding_key)?, self.address() - .map_err(|_| SwapError::WalletError)? + .map_err(|_| PaymentError::WalletError)? .to_string(), network_config, )?; - let mnemonic = self.signer.mnemonic().ok_or(SwapError::WalletError)?; + let mnemonic = self.signer.mnemonic().ok_or(PaymentError::WalletError)?; let swap_key = SwapKey::from_reverse_account(&mnemonic.to_string(), "", self.network.into(), 0)?; @@ -297,12 +299,12 @@ impl Wallet { pub fn receive_payment( &self, req: ReceivePaymentRequest, - ) -> Result { + ) -> Result { let client = self.boltz_client(); let lbtc_pair = client .get_pairs()? .get_lbtc_pair() - .ok_or(SwapError::WalletError)?; + .ok_or(PaymentError::WalletError)?; let (onchain_amount_sat, invoice_amount_sat) = match (req.onchain_amount_sat, req.invoice_amount_sat) { @@ -325,15 +327,18 @@ impl Wallet { let fees_claim = CLAIM_ABSOLUTE_FEES; // lbtc_pair.fees.reverse_claim_estimate(); let fees_total = fees_boltz + fees_lockup + fees_claim; - ensure_sdk!(invoice_amount_sat > fees_total, SwapError::AmountOutOfRange); + ensure_sdk!( + invoice_amount_sat > fees_total, + PaymentError::AmountOutOfRange + ); Ok((invoice_amount_sat - fees_total, invoice_amount_sat)) } - (None, None) => Err(SwapError::AmountOutOfRange), + (None, None) => Err(PaymentError::AmountOutOfRange), // TODO The request should not allow setting both invoice and onchain amounts, so this case shouldn't be possible. // See example of how it's done in the SDK. - _ => Err(SwapError::BoltzGeneric { + _ => Err(PaymentError::BoltzGeneric { err: "Both invoice and onchain amounts were specified".into(), }), }?; @@ -342,15 +347,15 @@ impl Wallet { lbtc_pair .limits .within(invoice_amount_sat) - .map_err(|_| SwapError::AmountOutOfRange)?; + .map_err(|_| PaymentError::AmountOutOfRange)?; - let mnemonic = self.signer.mnemonic().ok_or(SwapError::WalletError)?; + let mnemonic = self.signer.mnemonic().ok_or(PaymentError::WalletError)?; let swap_key = SwapKey::from_reverse_account(&mnemonic.to_string(), "", self.network.into(), 0)?; let lsk = LiquidSwapKey::try_from(swap_key)?; let preimage = Preimage::new(); - let preimage_str = preimage.to_string().ok_or(SwapError::InvalidPreimage)?; + let preimage_str = preimage.to_string().ok_or(PaymentError::InvalidPreimage)?; let preimage_hash = preimage.sha256.to_string(); let swap_response = if req.onchain_amount_sat.is_some() { @@ -377,12 +382,12 @@ impl Wallet { // Double check that the generated invoice includes our data // https://docs.boltz.exchange/v/api/dont-trust-verify#lightning-invoice-verification if invoice.payment_hash().to_string() != preimage_hash { - return Err(SwapError::InvalidInvoice); + return Err(PaymentError::InvalidInvoice); }; let invoice_amount_sat = invoice .amount_milli_satoshis() - .ok_or(SwapError::InvalidInvoice)? + .ok_or(PaymentError::InvalidInvoice)? / 1000; self.swap_persister @@ -394,9 +399,9 @@ impl Wallet { invoice_amount_sat, onchain_amount_sat, }])) - .map_err(|_| SwapError::PersistError)?; + .map_err(|_| PaymentError::PersistError)?; - Ok(SwapLbtcResponse { + Ok(ReceivePaymentResponse { id: swap_id, invoice: invoice.to_string(), })