Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/payment/unified_qr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,20 @@ 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.
/// This message is visible to the payer and can provide context or details about the payment.
/// - `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.
///
Expand All @@ -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
},
};

Expand All @@ -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
},
};

Expand Down
37 changes: 24 additions & 13 deletions tests/integration_tests_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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]
Expand Down
Loading