Skip to content

Commit 0986496

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. WIP: send_payment_for_bolt12_invoice
1 parent e13ec31 commit 0986496

File tree

4 files changed

+39
-7
lines changed

4 files changed

+39
-7
lines changed

lightning/src/events/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,8 +690,15 @@ pub enum Event {
690690
/// Indicates a [`Bolt12Invoice`] in response to an [`InvoiceRequest`] or a [`Refund`] was
691691
/// received.
692692
///
693+
/// This event will only be generated if [`UserConfig::manually_handle_bolt12_invoices`] is set.
694+
/// Use [`ChannelManager::send_payment_for_bolt12_invoice`] to pay the invoice or
695+
/// [`ChannelManager::abandon_payment`] to abandon the associated payment.
696+
///
693697
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
694698
/// [`Refund`]: crate::offers::refund::Refund
699+
/// [`UserConfig::manually_handle_bolt12_invoices`]: crate::util::config::UserConfig::manually_handle_bolt12_invoices
700+
/// [`ChannelManager::send_payment_for_bolt12_invoice`]: crate::ln::channelmanager::ChannelManager::send_payment_for_bolt12_invoice
701+
/// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
695702
InvoiceReceived {
696703
/// The `payment_id` associated with payment for the invoice.
697704
payment_id: PaymentId,

lightning/src/ln/channelmanager.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
5757
use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
5858
#[cfg(test)]
5959
use crate::ln::outbound_payment;
60-
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs, StaleExpiration};
60+
use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs, StaleExpiration};
6161
use crate::ln::wire::Encode;
6262
use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
6363
use crate::offers::invoice_error::InvoiceError;
@@ -104,7 +104,7 @@ use core::time::Duration;
104104
use core::ops::Deref;
105105

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

110110
// We hold various information about HTLC relay in the HTLC objects in Channel itself:
@@ -4272,7 +4272,28 @@ where
42724272
self.pending_outbound_payments.test_set_payment_metadata(payment_id, new_payment_metadata);
42734273
}
42744274

4275-
pub(super) fn send_payment_for_bolt12_invoice(&self, invoice: &Bolt12Invoice, payment_id: PaymentId) -> Result<(), Bolt12PaymentError> {
4275+
/// Pays the [`Bolt12Invoice`] associated with the `payment_id` encoded in its `payer_metadata`.
4276+
///
4277+
/// The invoice's `payer_metadata` is used to authenticate that the invoice was indeed requested
4278+
/// before attempting a payment. [`Bolt12PaymentError::UnexpectedInvoice`] is returned if this
4279+
/// fails or if the encoded `payment_id` is not recognized. The latter may happen once the
4280+
/// invoice is paid and the payment no longer tracked.
4281+
///
4282+
/// Attempting to pay the same invoice twice while the first payment is still pending will
4283+
/// result in a [`Bolt12PaymentError::DuplicateInvoice`].
4284+
///
4285+
/// Otherwise, either [`Event::PaymentSent`] or [`Event::PaymentFailed`] are used to indicate
4286+
/// whether or not the payment was successful.
4287+
pub fn send_payment_for_bolt12_invoice(&self, invoice: &Bolt12Invoice) -> Result<(), Bolt12PaymentError> {
4288+
let secp_ctx = &self.secp_ctx;
4289+
let expanded_key = &self.inbound_payment_key;
4290+
match invoice.verify(expanded_key, secp_ctx) {
4291+
Ok(payment_id) => self.send_payment_for_verified_bolt12_invoice(invoice, payment_id),
4292+
Err(()) => Err(Bolt12PaymentError::UnexpectedInvoice),
4293+
}
4294+
}
4295+
4296+
fn send_payment_for_verified_bolt12_invoice(&self, invoice: &Bolt12Invoice, payment_id: PaymentId) -> Result<(), Bolt12PaymentError> {
42764297
let best_block_height = self.best_block.read().unwrap().height;
42774298
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
42784299
self.pending_outbound_payments
@@ -10453,7 +10474,7 @@ where
1045310474
self.pending_events.lock().unwrap().push_back((event, None));
1045410475
return ResponseInstruction::NoResponse;
1045510476
} else {
10456-
self.send_payment_for_bolt12_invoice(&invoice, payment_id)
10477+
self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id)
1045710478
.map_err(|e| {
1045810479
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
1045910480
InvoiceError::from_string(format!("{:?}", e))

lightning/src/ln/outbound_payment.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,9 +493,9 @@ pub enum PaymentSendFailure {
493493
},
494494
}
495495

496-
/// An error when attempting to pay a BOLT 12 invoice.
496+
/// An error when attempting to pay a [`Bolt12Invoice`].
497497
#[derive(Clone, Debug, PartialEq, Eq)]
498-
pub(super) enum Bolt12PaymentError {
498+
pub enum Bolt12PaymentError {
499499
/// The invoice was not requested.
500500
UnexpectedInvoice,
501501
/// Payment for an invoice with the corresponding [`PaymentId`] was already initiated.

lightning/src/util/config.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,12 +850,16 @@ pub struct UserConfig {
850850
/// If this is set to true, the user needs to manually pay [`Bolt12Invoice`]s when received.
851851
///
852852
/// When set to true, [`Event::InvoiceReceived`] will be generated for each received
853-
/// [`Bolt12Invoice`] instead of being automatically paid after verification.
853+
/// [`Bolt12Invoice`] instead of being automatically paid after verification. Use
854+
/// [`ChannelManager::send_payment_for_bolt12_invoice`] to pay the invoice or
855+
/// [`ChannelManager::abandon_payment`] to abandon the associated payment.
854856
///
855857
/// Default value: false.
856858
///
857859
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
858860
/// [`Event::InvoiceReceived`]: crate::events::Event::InvoiceReceived
861+
/// [`ChannelManager::send_payment_for_bolt12_invoice`]: crate::ln::channelmanager::ChannelManager::send_payment_for_bolt12_invoice
862+
/// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
859863
pub manually_handle_bolt12_invoices: bool,
860864
}
861865

0 commit comments

Comments
 (0)