@@ -58,7 +58,7 @@ use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
5858use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
5959#[cfg(test)]
6060use 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};
6262use crate::ln::wire::Encode;
6363use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
6464use crate::offers::invoice_error::InvoiceError;
@@ -105,7 +105,7 @@ use core::time::Duration;
105105use 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};
109109use 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
@@ -10272,42 +10301,45 @@ where
1027210301 };
1027310302
1027410303 match response {
10275- Ok(invoice) => return responder.respond(OffersMessage::Invoice(invoice)),
10276- Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
10304+ Ok(invoice) => responder.respond(OffersMessage::Invoice(invoice)),
10305+ Err(error) => responder.respond(OffersMessage::InvoiceError(error.into())),
1027710306 }
1027810307 },
1027910308 OffersMessage::Invoice(invoice) => {
10280- let response = invoice
10281- .verify(expanded_key, secp_ctx)
10282- .map_err(|()| InvoiceError::from_string("Unrecognized invoice".to_owned()))
10283- .and_then(|payment_id| {
10309+ let result = match invoice.verify(expanded_key, secp_ctx) {
10310+ Ok(payment_id) => {
1028410311 let features = self.bolt12_invoice_features();
1028510312 if invoice.invoice_features().requires_unknown_bits_from(&features) {
1028610313 Err(InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures))
10314+ } else if self.default_configuration.manually_handle_bolt12_invoices {
10315+ let event = Event::InvoiceReceived { payment_id, invoice, responder };
10316+ self.pending_events.lock().unwrap().push_back((event, None));
10317+ return ResponseInstruction::NoResponse;
1028710318 } else {
10288- self.send_payment_for_bolt12_invoice (&invoice, payment_id)
10319+ self.send_payment_for_verified_bolt12_invoice (&invoice, payment_id)
1028910320 .map_err(|e| {
1029010321 log_trace!(self.logger, "Failed paying invoice: {:?}", e);
1029110322 InvoiceError::from_string(format!("{:?}", e))
1029210323 })
1029310324 }
10294- });
10325+ },
10326+ Err(()) => Err(InvoiceError::from_string("Unrecognized invoice".to_owned())),
10327+ };
1029510328
10296- match (responder, response) {
10297- (Some(responder), Err(e)) => responder.respond(OffersMessage::InvoiceError(e)),
10298- (None, Err(_)) => {
10299- log_trace!(
10300- self.logger,
10301- "A response was generated, but there is no reply_path specified for sending the response."
10302- );
10303- return ResponseInstruction::NoResponse;
10304- }
10305- _ => return ResponseInstruction::NoResponse,
10329+ match result {
10330+ Ok(()) => ResponseInstruction::NoResponse,
10331+ Err(e) => match responder {
10332+ Some(responder) => responder.respond(OffersMessage::InvoiceError(e)),
10333+ None => {
10334+ log_trace!(self.logger, "No reply path for sending invoice error: {:?}", e);
10335+ ResponseInstruction::NoResponse
10336+ },
10337+ },
1030610338 }
1030710339 },
1030810340 OffersMessage::InvoiceError(invoice_error) => {
1030910341 log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
10310- return ResponseInstruction::NoResponse;
10342+ ResponseInstruction::NoResponse
1031110343 },
1031210344 }
1031310345 }
0 commit comments