@@ -65,7 +65,7 @@ use crate::offers::merkle::SignError;
65
65
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
66
66
use crate::offers::parse::Bolt12SemanticError;
67
67
use crate::offers::refund::{Refund, RefundBuilder};
68
- use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message};
68
+ use crate::onion_message::{Destination, MessageRouter, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message};
69
69
use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider};
70
70
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
71
71
use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate};
@@ -7483,32 +7483,43 @@ where
7483
7483
///
7484
7484
/// # Privacy
7485
7485
///
7486
- /// Uses a one-hop [`BlindedPath`] for the offer with [`ChannelManager::get_our_node_id`] as the
7487
- /// introduction node and a derived signing pubkey for recipient privacy. As such, currently,
7488
- /// the node must be announced. Otherwise, there is no way to find a path to the introduction
7489
- /// node in order to send the [`InvoiceRequest`].
7486
+ /// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the offer.
7487
+ /// However, if one is not found, uses a one-hop [`BlindedPath`] with
7488
+ /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
7489
+ /// the node must be announced, otherwise, there is no way to find a path to the introduction in
7490
+ /// order to send the [`InvoiceRequest`].
7491
+ ///
7492
+ /// Also, uses a derived signing pubkey in the offer for recipient privacy.
7490
7493
///
7491
7494
/// # Limitations
7492
7495
///
7493
7496
/// Requires a direct connection to the introduction node in the responding [`InvoiceRequest`]'s
7494
7497
/// reply path.
7495
7498
///
7499
+ /// # Errors
7500
+ ///
7501
+ /// Errors if the parameterized [`Router`] is unable to create a blinded path for the offer.
7502
+ ///
7496
7503
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
7497
7504
///
7498
7505
/// [`Offer`]: crate::offers::offer::Offer
7499
7506
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
7500
7507
pub fn create_offer_builder(
7501
7508
&self, description: String
7502
- ) -> OfferBuilder<DerivedMetadata, secp256k1::All> {
7509
+ ) -> Result< OfferBuilder<DerivedMetadata, secp256k1::All>, Bolt12SemanticError > {
7503
7510
let node_id = self.get_our_node_id();
7504
7511
let expanded_key = &self.inbound_payment_key;
7505
7512
let entropy = &*self.entropy_source;
7506
7513
let secp_ctx = &self.secp_ctx;
7507
- let path = self.create_one_hop_blinded_path();
7508
7514
7509
- OfferBuilder::deriving_signing_pubkey(description, node_id, expanded_key, entropy, secp_ctx)
7515
+ let path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
7516
+ let builder = OfferBuilder::deriving_signing_pubkey(
7517
+ description, node_id, expanded_key, entropy, secp_ctx
7518
+ )
7510
7519
.chain_hash(self.chain_hash)
7511
- .path(path)
7520
+ .path(path);
7521
+
7522
+ Ok(builder)
7512
7523
}
7513
7524
7514
7525
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
@@ -7533,10 +7544,13 @@ where
7533
7544
///
7534
7545
/// # Privacy
7535
7546
///
7536
- /// Uses a one-hop [`BlindedPath`] for the refund with [`ChannelManager::get_our_node_id`] as
7537
- /// the introduction node and a derived payer id for payer privacy. As such, currently, the
7538
- /// node must be announced. Otherwise, there is no way to find a path to the introduction node
7539
- /// in order to send the [`Bolt12Invoice`].
7547
+ /// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the refund.
7548
+ /// However, if one is not found, uses a one-hop [`BlindedPath`] with
7549
+ /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
7550
+ /// the node must be announced, otherwise, there is no way to find a path to the introduction in
7551
+ /// order to send the [`Bolt12Invoice`].
7552
+ ///
7553
+ /// Also, uses a derived payer id in the refund for payer privacy.
7540
7554
///
7541
7555
/// # Limitations
7542
7556
///
@@ -7545,8 +7559,10 @@ where
7545
7559
///
7546
7560
/// # Errors
7547
7561
///
7548
- /// Errors if a duplicate `payment_id` is provided given the caveats in the aforementioned link
7549
- /// or if `amount_msats` is invalid.
7562
+ /// Errors if:
7563
+ /// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
7564
+ /// - `amount_msats` is invalid, or
7565
+ /// - the parameterized [`Router`] is unable to create a blinded path for the refund.
7550
7566
///
7551
7567
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
7552
7568
///
@@ -7561,8 +7577,8 @@ where
7561
7577
let expanded_key = &self.inbound_payment_key;
7562
7578
let entropy = &*self.entropy_source;
7563
7579
let secp_ctx = &self.secp_ctx;
7564
- let path = self.create_one_hop_blinded_path();
7565
7580
7581
+ let path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
7566
7582
let builder = RefundBuilder::deriving_payer_id(
7567
7583
description, node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
7568
7584
)?
@@ -7620,8 +7636,11 @@ where
7620
7636
///
7621
7637
/// # Errors
7622
7638
///
7623
- /// Errors if a duplicate `payment_id` is provided given the caveats in the aforementioned link
7624
- /// or if the provided parameters are invalid for the offer.
7639
+ /// Errors if:
7640
+ /// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
7641
+ /// - the provided parameters are invalid for the offer,
7642
+ /// - the parameterized [`Router`] is unable to create a blinded reply path for the invoice
7643
+ /// request.
7625
7644
///
7626
7645
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
7627
7646
/// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity
@@ -7654,9 +7673,8 @@ where
7654
7673
None => builder,
7655
7674
Some(payer_note) => builder.payer_note(payer_note),
7656
7675
};
7657
-
7658
7676
let invoice_request = builder.build_and_sign()?;
7659
- let reply_path = self.create_one_hop_blinded_path() ;
7677
+ let reply_path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)? ;
7660
7678
7661
7679
let expiration = StaleExpiration::TimerTicks(1);
7662
7680
self.pending_outbound_payments
@@ -7732,7 +7750,8 @@ where
7732
7750
payment_paths, payment_hash, created_at, expanded_key, entropy
7733
7751
)?;
7734
7752
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
7735
- let reply_path = self.create_one_hop_blinded_path();
7753
+ let reply_path = self.create_blinded_path()
7754
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
7736
7755
7737
7756
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
7738
7757
if refund.paths().is_empty() {
@@ -7859,12 +7878,23 @@ where
7859
7878
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
7860
7879
}
7861
7880
7862
- /// Creates a one-hop blinded path with [`ChannelManager::get_our_node_id`] as the introduction
7863
- /// node.
7864
- fn create_one_hop_blinded_path(&self) -> BlindedPath {
7881
+ /// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
7882
+ ///
7883
+ /// Errors if the `MessageRouter` errors or returns an empty `Vec`.
7884
+ fn create_blinded_path(&self) -> Result<BlindedPath, ()> {
7885
+ let recipient = self.get_our_node_id();
7865
7886
let entropy_source = self.entropy_source.deref();
7866
7887
let secp_ctx = &self.secp_ctx;
7867
- BlindedPath::one_hop_for_message(self.get_our_node_id(), entropy_source, secp_ctx).unwrap()
7888
+
7889
+ let peers = self.per_peer_state.read().unwrap()
7890
+ .iter()
7891
+ .filter(|(_, peer)| peer.lock().unwrap().latest_features.supports_onion_messages())
7892
+ .map(|(node_id, _)| *node_id)
7893
+ .collect::<Vec<_>>();
7894
+
7895
+ self.router
7896
+ .create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
7897
+ .and_then(|paths| paths.into_iter().next().ok_or(()))
7868
7898
}
7869
7899
7870
7900
/// Creates a one-hop blinded payment path with [`ChannelManager::get_our_node_id`] as the
0 commit comments