From e396a1a63bf20183a36706db1ba43172c7c32aef Mon Sep 17 00:00:00 2001 From: Camillarhi Date: Tue, 27 May 2025 00:04:36 +0100 Subject: [PATCH] continue receive flow on offer/invoice creation failure --- src/payment/unified_qr.rs | 14 ++++++++----- tests/integration_tests_rust.rs | 37 +++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/payment/unified_qr.rs b/src/payment/unified_qr.rs index ec37931a0..5e6c1ef60 100644 --- a/src/payment/unified_qr.rs +++ b/src/payment/unified_qr.rs @@ -68,6 +68,10 @@ impl UnifiedQrPayment { /// can always pay using the provided on-chain address, while newer wallets will /// typically opt to use the provided BOLT11 invoice or BOLT12 offer. /// + /// The URI will always include an on-chain address. A BOLT11 invoice will be included + /// unless invoice generation fails, while a BOLT12 offer will only be included when + /// the node has suitable channels for routing. + /// /// # Parameters /// - `amount_sats`: The amount to be received, specified in satoshis. /// - `description`: A description or note associated with the payment. @@ -75,9 +79,9 @@ impl UnifiedQrPayment { /// - `expiry_sec`: The expiration time for the payment, specified in seconds. /// /// Returns a payable URI that can be used to request and receive a payment of the amount - /// given. In case of an error, the function returns `Error::WalletOperationFailed`for on-chain - /// address issues, `Error::InvoiceCreationFailed` for BOLT11 invoice issues, or - /// `Error::OfferCreationFailed` for BOLT12 offer issues. + /// given. Failure to generate the on-chain address will result in an error return + /// (`Error::WalletOperationFailed`), while failures in invoice or offer generation will + /// result in those components being omitted from the URI. /// /// The generated URI can then be given to a QR code library. /// @@ -95,7 +99,7 @@ impl UnifiedQrPayment { Ok(offer) => Some(offer), Err(e) => { log_error!(self.logger, "Failed to create offer: {}", e); - return Err(Error::OfferCreationFailed); + None }, }; @@ -111,7 +115,7 @@ impl UnifiedQrPayment { Ok(invoice) => Some(invoice), Err(e) => { log_error!(self.logger, "Failed to create invoice {}", e); - return Err(Error::InvoiceCreationFailed); + None }, }; diff --git a/tests/integration_tests_rust.rs b/tests/integration_tests_rust.rs index fde566202..db48eca23 100644 --- a/tests/integration_tests_rust.rs +++ b/tests/integration_tests_rust.rs @@ -1083,6 +1083,21 @@ fn generate_bip21_uri() { let address_a = node_a.onchain_payment().new_address().unwrap(); let premined_sats = 5_000_000; + let expected_amount_sats = 100_000; + let expiry_sec = 4_000; + + // Test 1: Verify URI generation (on-chain + BOLT11) works + // even before any channels are opened. This checks the graceful fallback behavior. + let initial_uqr_payment = node_b + .unified_qr_payment() + .receive(expected_amount_sats, "asdf", expiry_sec) + .expect("Failed to generate URI"); + println!("Initial URI (no channels): {}", initial_uqr_payment); + + assert!(initial_uqr_payment.contains("bitcoin:")); + assert!(initial_uqr_payment.contains("lightning=")); + assert!(!initial_uqr_payment.contains("lno=")); // BOLT12 requires channels + premine_and_distribute_funds( &bitcoind.client, &electrsd.client, @@ -1100,20 +1115,16 @@ fn generate_bip21_uri() { expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); - let expected_amount_sats = 100_000; - let expiry_sec = 4_000; - - let uqr_payment = node_b.unified_qr_payment().receive(expected_amount_sats, "asdf", expiry_sec); + // Test 2: Verify URI generation (on-chain + BOLT11 + BOLT12) works after channels are established. + let uqr_payment = node_b + .unified_qr_payment() + .receive(expected_amount_sats, "asdf", expiry_sec) + .expect("Failed to generate URI"); - match uqr_payment.clone() { - Ok(ref uri) => { - println!("Generated URI: {}", uri); - assert!(uri.contains("bitcoin:")); - assert!(uri.contains("lightning=")); - assert!(uri.contains("lno=")); - }, - Err(e) => panic!("Failed to generate URI: {:?}", e), - } + println!("Generated URI: {}", uqr_payment); + assert!(uqr_payment.contains("bitcoin:")); + assert!(uqr_payment.contains("lightning=")); + assert!(uqr_payment.contains("lno=")); } #[test]