@@ -54,12 +54,15 @@ use crate::ln::onion_utils::HTLCFailReason;
54
54
use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
55
55
#[cfg(test)]
56
56
use crate::ln::outbound_payment;
57
- use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs};
57
+ use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PaymentAttempts, PendingOutboundPayment, SendAlongPathArgs};
58
58
use crate::ln::wire::Encode;
59
+ use crate::offers::invoice::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, InvoiceBuilder};
60
+ use crate::offers::invoice_error::InvoiceError;
61
+ use crate::offers::merkle::SignError;
59
62
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
60
63
use crate::offers::parse::Bolt12SemanticError;
61
64
use crate::offers::refund::RefundBuilder;
62
- use crate::onion_message::{Destination, OffersMessage, PendingOnionMessage};
65
+ use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage};
63
66
use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, WriteableEcdsaChannelSigner};
64
67
use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate};
65
68
use crate::util::wakers::{Future, Notifier};
@@ -3470,6 +3473,17 @@ where
3470
3473
self.pending_outbound_payments.test_set_payment_metadata(payment_id, new_payment_metadata);
3471
3474
}
3472
3475
3476
+ pub(super) fn send_payment_for_bolt12_invoice(&self, invoice: &Bolt12Invoice, payment_id: PaymentId) -> Result<(), Bolt12PaymentError> {
3477
+ let best_block_height = self.best_block.read().unwrap().height();
3478
+ let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
3479
+ self.pending_outbound_payments
3480
+ .send_payment_for_bolt12_invoice(
3481
+ invoice, payment_id, &self.router, self.list_usable_channels(),
3482
+ || self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer,
3483
+ best_block_height, &self.logger, &self.pending_events,
3484
+ |args| self.send_payment_along_path(args)
3485
+ )
3486
+ }
3473
3487
3474
3488
/// Signals that no further attempts for the given payment should occur. Useful if you have a
3475
3489
/// pending outbound payment with retries remaining, but wish to stop retrying the payment before
@@ -8229,6 +8243,125 @@ where
8229
8243
}
8230
8244
}
8231
8245
8246
+ impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
8247
+ OffersMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, L>
8248
+ where
8249
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
8250
+ T::Target: BroadcasterInterface,
8251
+ ES::Target: EntropySource,
8252
+ NS::Target: NodeSigner,
8253
+ SP::Target: SignerProvider,
8254
+ F::Target: FeeEstimator,
8255
+ R::Target: Router,
8256
+ L::Target: Logger,
8257
+ {
8258
+ fn handle_message(&self, message: OffersMessage) -> Option<OffersMessage> {
8259
+ let secp_ctx = &self.secp_ctx;
8260
+ let expanded_key = &self.inbound_payment_key;
8261
+
8262
+ match message {
8263
+ OffersMessage::InvoiceRequest(invoice_request) => {
8264
+ let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
8265
+ &invoice_request
8266
+ ) {
8267
+ Ok(amount_msats) => Some(amount_msats),
8268
+ Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
8269
+ };
8270
+ let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
8271
+ Ok(invoice_request) => invoice_request,
8272
+ Err(()) => {
8273
+ let error = Bolt12SemanticError::InvalidMetadata;
8274
+ return Some(OffersMessage::InvoiceError(error.into()));
8275
+ },
8276
+ };
8277
+ let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
8278
+
8279
+ match self.create_inbound_payment(amount_msats, relative_expiry, None) {
8280
+ Ok((payment_hash, _payment_secret)) if invoice_request.keys.is_some() => {
8281
+ // TODO: Include payment_secret in payment_paths.
8282
+ let payment_paths = vec![];
8283
+ #[cfg(not(feature = "no-std"))]
8284
+ let builder = invoice_request.respond_using_derived_keys(
8285
+ payment_paths, payment_hash
8286
+ );
8287
+ #[cfg(feature = "no-std")]
8288
+ let created_at = Duration::from_secs(
8289
+ self.highest_seen_timestamp.load(Ordering::Acquire) as u64
8290
+ );
8291
+ #[cfg(feature = "no-std")]
8292
+ let builder = invoice_request.respond_using_derived_keys_no_std(
8293
+ payment_paths, payment_hash, created_at
8294
+ );
8295
+ match builder.and_then(|b| b.allow_mpp().build_and_sign(secp_ctx)) {
8296
+ Ok(invoice) => Some(OffersMessage::Invoice(invoice)),
8297
+ Err(error) => Some(OffersMessage::InvoiceError(error.into())),
8298
+ }
8299
+ },
8300
+ Ok((payment_hash, _payment_secret)) => {
8301
+ // TODO: Include payment_secret in payment_paths.
8302
+ let payment_paths = vec![];
8303
+ #[cfg(not(feature = "no-std"))]
8304
+ let builder = invoice_request.respond_with(payment_paths, payment_hash);
8305
+ #[cfg(feature = "no-std")]
8306
+ let created_at = Duration::from_secs(
8307
+ self.highest_seen_timestamp.load(Ordering::Acquire) as u64
8308
+ );
8309
+ #[cfg(feature = "no-std")]
8310
+ let builder = invoice_request.respond_with_no_std(
8311
+ payment_paths, payment_hash, created_at
8312
+ );
8313
+ let response = builder.and_then(|builder| builder.allow_mpp().build())
8314
+ .map_err(|e| OffersMessage::InvoiceError(e.into()))
8315
+ .and_then(|invoice|
8316
+ match invoice.sign(|invoice| self.node_signer.sign_bolt12_invoice(invoice)) {
8317
+ Ok(invoice) => Ok(OffersMessage::Invoice(invoice)),
8318
+ Err(SignError::Signing(())) => Err(OffersMessage::InvoiceError(
8319
+ InvoiceError::from_str("Failed signing invoice")
8320
+ )),
8321
+ Err(SignError::Verification(_)) => Err(OffersMessage::InvoiceError(
8322
+ InvoiceError::from_str("Failed invoice signature verification")
8323
+ )),
8324
+ });
8325
+ match response {
8326
+ Ok(invoice) => Some(invoice),
8327
+ Err(error) => Some(error),
8328
+ }
8329
+ },
8330
+ Err(()) => {
8331
+ Some(OffersMessage::InvoiceError(Bolt12SemanticError::InvalidAmount.into()))
8332
+ },
8333
+ }
8334
+ },
8335
+ OffersMessage::Invoice(invoice) => {
8336
+ match invoice.verify(expanded_key, secp_ctx) {
8337
+ Err(()) => {
8338
+ Some(OffersMessage::InvoiceError(InvoiceError::from_str("Unrecognized invoice")))
8339
+ },
8340
+ Ok(_) if invoice.invoice_features().requires_unknown_bits_from(&self.bolt12_invoice_features()) => {
8341
+ Some(OffersMessage::InvoiceError(Bolt12SemanticError::UnknownRequiredFeatures.into()))
8342
+ },
8343
+ Ok(payment_id) => {
8344
+ if let Err(e) = self.send_payment_for_bolt12_invoice(&invoice, payment_id) {
8345
+ log_trace!(self.logger, "Failed paying invoice: {:?}", e);
8346
+ Some(OffersMessage::InvoiceError(InvoiceError::from_str(&format!("{:?}", e))))
8347
+ } else {
8348
+ None
8349
+ }
8350
+ },
8351
+ }
8352
+ },
8353
+ OffersMessage::InvoiceError(invoice_error) => {
8354
+ log_trace!(self.logger, "Received invoice_error: {}", invoice_error);
8355
+ None
8356
+ },
8357
+ }
8358
+ }
8359
+
8360
+ fn release_pending_messages(&self) -> Vec<PendingOnionMessage<OffersMessage>> {
8361
+ core::mem::take(&mut self.pending_offers_messages.lock().unwrap())
8362
+ }
8363
+ }
8364
+
8232
8365
/// Fetches the set of [`NodeFeatures`] flags that are provided by or required by
8233
8366
/// [`ChannelManager`].
8234
8367
pub(crate) fn provided_node_features(config: &UserConfig) -> NodeFeatures {
0 commit comments