@@ -58,7 +58,7 @@ use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
58
58
use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
59
59
#[cfg(test)]
60
60
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};
62
62
use crate::ln::wire::Encode;
63
63
use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
64
64
use crate::offers::invoice_error::InvoiceError;
@@ -105,7 +105,7 @@ use core::time::Duration;
105
105
use core::ops::Deref;
106
106
107
107
// 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};
109
109
use crate::ln::script::ShutdownScript;
110
110
111
111
// We hold various information about HTLC relay in the HTLC objects in Channel itself:
@@ -3996,7 +3996,36 @@ where
3996
3996
self.pending_outbound_payments.test_set_payment_metadata(payment_id, new_payment_metadata);
3997
3997
}
3998
3998
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> {
4000
4029
let best_block_height = self.best_block.read().unwrap().height;
4001
4030
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
4002
4031
self.pending_outbound_payments
@@ -10272,42 +10301,45 @@ where
10272
10301
};
10273
10302
10274
10303
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())),
10277
10306
}
10278
10307
},
10279
10308
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) => {
10284
10311
let features = self.bolt12_invoice_features();
10285
10312
if invoice.invoice_features().requires_unknown_bits_from(&features) {
10286
10313
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;
10287
10318
} else {
10288
- self.send_payment_for_bolt12_invoice (&invoice, payment_id)
10319
+ self.send_payment_for_verified_bolt12_invoice (&invoice, payment_id)
10289
10320
.map_err(|e| {
10290
10321
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
10291
10322
InvoiceError::from_string(format!("{:?}", e))
10292
10323
})
10293
10324
}
10294
- });
10325
+ },
10326
+ Err(()) => Err(InvoiceError::from_string("Unrecognized invoice".to_owned())),
10327
+ };
10295
10328
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
+ },
10306
10338
}
10307
10339
},
10308
10340
OffersMessage::InvoiceError(invoice_error) => {
10309
10341
log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
10310
- return ResponseInstruction::NoResponse;
10342
+ ResponseInstruction::NoResponse
10311
10343
},
10312
10344
}
10313
10345
}
0 commit comments