Skip to content

Commit 65efd92

Browse files
committed
Expose send_payment_for_bolt12_invoice
UserConfig::manually_handle_bolt12_invoices allows deferring payment of BOLT12 invoices by generating Event::InvoiceReceived. Expose ChannelManager::send_payment_for_bolt12_invoice to allow users to pay the Bolt12Invoice included in the event. While the event contains the PaymentId for reference, that parameter is now removed from the method in favor of extracting the PaymentId from the invoice's payer_metadata.
1 parent 232959c commit 65efd92

File tree

4 files changed

+48
-7
lines changed

4 files changed

+48
-7
lines changed

lightning/src/events/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,16 @@ pub enum Event {
720720
/// Indicates a [`Bolt12Invoice`] in response to an [`InvoiceRequest`] or a [`Refund`] was
721721
/// received.
722722
///
723+
/// This event will only be generated if [`UserConfig::manually_handle_bolt12_invoices`] is set.
724+
/// Use [`ChannelManager::send_payment_for_bolt12_invoice`] to pay the invoice or
725+
/// [`ChannelManager::abandon_payment`] to abandon the associated payment. See those docs for
726+
/// further details.
727+
///
723728
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
724729
/// [`Refund`]: crate::offers::refund::Refund
730+
/// [`UserConfig::manually_handle_bolt12_invoices`]: crate::util::config::UserConfig::manually_handle_bolt12_invoices
731+
/// [`ChannelManager::send_payment_for_bolt12_invoice`]: crate::ln::channelmanager::ChannelManager::send_payment_for_bolt12_invoice
732+
/// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
725733
InvoiceReceived {
726734
/// The `payment_id` associated with payment for the invoice.
727735
payment_id: PaymentId,

lightning/src/ln/channelmanager.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
5858
use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
5959
#[cfg(test)]
6060
use crate::ln::outbound_payment;
61-
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs, StaleExpiration};
61+
use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs, StaleExpiration};
6262
use crate::ln::wire::Encode;
6363
use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
6464
use crate::offers::invoice_error::InvoiceError;
@@ -105,7 +105,7 @@ use core::time::Duration;
105105
use core::ops::Deref;
106106

107107
// Re-export this for use in the public API.
108-
pub use crate::ln::outbound_payment::{PaymentSendFailure, ProbeSendFailure, Retry, RetryableSendFailure, RecipientOnionFields};
108+
pub use crate::ln::outbound_payment::{Bolt12PaymentError, PaymentSendFailure, ProbeSendFailure, Retry, RetryableSendFailure, RecipientOnionFields};
109109
use crate::ln::script::ShutdownScript;
110110

111111
// We hold various information about HTLC relay in the HTLC objects in Channel itself:
@@ -3996,7 +3996,36 @@ where
39963996
self.pending_outbound_payments.test_set_payment_metadata(payment_id, new_payment_metadata);
39973997
}
39983998

3999-
pub(super) fn send_payment_for_bolt12_invoice(&self, invoice: &Bolt12Invoice, payment_id: PaymentId) -> Result<(), Bolt12PaymentError> {
3999+
/// Pays the [`Bolt12Invoice`] associated with the `payment_id` encoded in its `payer_metadata`.
4000+
///
4001+
/// The invoice's `payer_metadata` is used to authenticate that the invoice was indeed requested
4002+
/// before attempting a payment. [`Bolt12PaymentError::UnexpectedInvoice`] is returned if this
4003+
/// fails or if the encoded `payment_id` is not recognized. The latter may happen once the
4004+
/// payment is no longer tracked because the payment was attempted after:
4005+
/// - an invoice for the `payment_id` was already paid,
4006+
/// - one full [timer tick] has elapsed since initially requesting the invoice when paying an
4007+
/// offer, or
4008+
/// - the refund corresponding to the invoice has already expired.
4009+
///
4010+
/// To retry the payment, request another invoice using a new `payment_id`.
4011+
///
4012+
/// Attempting to pay the same invoice twice while the first payment is still pending will
4013+
/// result in a [`Bolt12PaymentError::DuplicateInvoice`].
4014+
///
4015+
/// Otherwise, either [`Event::PaymentSent`] or [`Event::PaymentFailed`] are used to indicate
4016+
/// whether or not the payment was successful.
4017+
///
4018+
/// [timer tick]: Self::timer_tick_occurred
4019+
pub fn send_payment_for_bolt12_invoice(&self, invoice: &Bolt12Invoice) -> Result<(), Bolt12PaymentError> {
4020+
let secp_ctx = &self.secp_ctx;
4021+
let expanded_key = &self.inbound_payment_key;
4022+
match invoice.verify(expanded_key, secp_ctx) {
4023+
Ok(payment_id) => self.send_payment_for_verified_bolt12_invoice(invoice, payment_id),
4024+
Err(()) => Err(Bolt12PaymentError::UnexpectedInvoice),
4025+
}
4026+
}
4027+
4028+
fn send_payment_for_verified_bolt12_invoice(&self, invoice: &Bolt12Invoice, payment_id: PaymentId) -> Result<(), Bolt12PaymentError> {
40004029
let best_block_height = self.best_block.read().unwrap().height;
40014030
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
40024031
self.pending_outbound_payments
@@ -10287,7 +10316,7 @@ where
1028710316
self.pending_events.lock().unwrap().push_back((event, None));
1028810317
return ResponseInstruction::NoResponse;
1028910318
} else {
10290-
self.send_payment_for_bolt12_invoice(&invoice, payment_id)
10319+
self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id)
1029110320
.map_err(|e| {
1029210321
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
1029310322
InvoiceError::from_string(format!("{:?}", e))

lightning/src/ln/outbound_payment.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,9 @@ pub enum PaymentSendFailure {
501501
},
502502
}
503503

504-
/// An error when attempting to pay a BOLT 12 invoice.
504+
/// An error when attempting to pay a [`Bolt12Invoice`].
505505
#[derive(Clone, Debug, PartialEq, Eq)]
506-
pub(super) enum Bolt12PaymentError {
506+
pub enum Bolt12PaymentError {
507507
/// The invoice was not requested.
508508
UnexpectedInvoice,
509509
/// Payment for an invoice with the corresponding [`PaymentId`] was already initiated.

lightning/src/util/config.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -859,12 +859,16 @@ pub struct UserConfig {
859859
/// If this is set to `true`, the user needs to manually pay [`Bolt12Invoice`]s when received.
860860
///
861861
/// When set to `true`, [`Event::InvoiceReceived`] will be generated for each received
862-
/// [`Bolt12Invoice`] instead of being automatically paid after verification.
862+
/// [`Bolt12Invoice`] instead of being automatically paid after verification. Use
863+
/// [`ChannelManager::send_payment_for_bolt12_invoice`] to pay the invoice or
864+
/// [`ChannelManager::abandon_payment`] to abandon the associated payment.
863865
///
864866
/// Default value: `false`
865867
///
866868
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
867869
/// [`Event::InvoiceReceived`]: crate::events::Event::InvoiceReceived
870+
/// [`ChannelManager::send_payment_for_bolt12_invoice`]: crate::ln::channelmanager::ChannelManager::send_payment_for_bolt12_invoice
871+
/// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
868872
pub manually_handle_bolt12_invoices: bool,
869873
}
870874

0 commit comments

Comments
 (0)