@@ -68,7 +68,7 @@ use crate::ln::outbound_payment::{OutboundPayments, PendingOutboundPayment, Retr
68
68
use crate::offers::invoice::{Bolt12Invoice, DerivedSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice, DEFAULT_RELATIVE_EXPIRY};
69
69
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
70
70
use crate::offers::nonce::Nonce;
71
- use crate::offers::offer::{ Offer, OfferBuilder} ;
71
+ use crate::offers::offer::Offer;
72
72
use crate::offers::parse::Bolt12SemanticError;
73
73
use crate::offers::refund::{Refund, RefundBuilder};
74
74
use crate::offers::signer;
@@ -96,18 +96,14 @@ use crate::onion_message::dns_resolution::{DNSResolverMessage, DNSResolverMessag
96
96
97
97
#[cfg(not(c_bindings))]
98
98
use {
99
- crate::offers::offer::DerivedMetadata,
100
99
crate::onion_message::messenger::DefaultMessageRouter,
101
100
crate::routing::router::DefaultRouter,
102
101
crate::routing::gossip::NetworkGraph,
103
102
crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters},
104
103
crate::sign::KeysManager,
105
104
};
106
105
#[cfg(c_bindings)]
107
- use {
108
- crate::offers::offer::OfferWithDerivedMetadataBuilder,
109
- crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder,
110
- };
106
+ use crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder;
111
107
112
108
use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, CreationError, Currency, Description, InvoiceBuilder as Bolt11InvoiceBuilder, SignOrCreationError, DEFAULT_EXPIRY_TIME};
113
109
@@ -1923,6 +1919,7 @@ where
1923
1919
/// ```
1924
1920
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
1925
1921
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt11InvoiceParameters};
1922
+ /// # use lightning::offers::flow::OffersMessageCommons;
1926
1923
/// #
1927
1924
/// # fn example<T: AChannelManager>(channel_manager: T) {
1928
1925
/// # let channel_manager = channel_manager.get_cm();
@@ -2023,56 +2020,8 @@ where
2023
2020
/// ```
2024
2021
///
2025
2022
/// ## BOLT 12 Offers
2026
- ///
2027
- /// The [`offers`] module is useful for creating BOLT 12 offers. An [`Offer`] is a precursor to a
2028
- /// [`Bolt12Invoice`], which must first be requested by the payer. The interchange of these messages
2029
- /// as defined in the specification is handled by [`ChannelManager`]. However, this only works with
2030
- /// an [`Offer`] created using a builder returned by [`create_offer_builder`]. With this approach,
2031
- /// BOLT 12 offers and invoices are stateless just as BOLT 11 invoices are.
2032
- ///
2033
- /// ```
2034
- /// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
2035
- /// # use lightning::ln::channelmanager::AChannelManager;
2036
- /// # use lightning::offers::parse::Bolt12SemanticError;
2037
- /// #
2038
- /// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
2039
- /// # let channel_manager = channel_manager.get_cm();
2040
- /// # let absolute_expiry = None;
2041
- /// let offer = channel_manager
2042
- /// .create_offer_builder(absolute_expiry)?
2043
- /// # ;
2044
- /// # // Needed for compiling for c_bindings
2045
- /// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into();
2046
- /// # let offer = builder
2047
- /// .description("coffee".to_string())
2048
- /// .amount_msats(10_000_000)
2049
- /// .build()?;
2050
- /// let bech32_offer = offer.to_string();
2051
- ///
2052
- /// // On the event processing thread
2053
- /// channel_manager.process_pending_events(&|event| {
2054
- /// match event {
2055
- /// Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
2056
- /// PaymentPurpose::Bolt12OfferPayment { payment_preimage: Some(payment_preimage), .. } => {
2057
- /// println!("Claiming payment {}", payment_hash);
2058
- /// channel_manager.claim_funds(payment_preimage);
2059
- /// },
2060
- /// PaymentPurpose::Bolt12OfferPayment { payment_preimage: None, .. } => {
2061
- /// println!("Unknown payment hash: {}", payment_hash);
2062
- /// }
2063
- /// # _ => {},
2064
- /// },
2065
- /// Event::PaymentClaimed { payment_hash, amount_msat, .. } => {
2066
- /// println!("Claimed {} msats", amount_msat);
2067
- /// },
2068
- /// // ...
2069
- /// # _ => {},
2070
- /// }
2071
- /// Ok(())
2072
- /// });
2073
- /// # Ok(())
2074
- /// # }
2075
- /// ```
2023
+ ///
2024
+ /// For more information on creating offers, see [`create_offer_builder`].
2076
2025
///
2077
2026
/// Use [`pay_for_offer`] to initiated payment, which sends an [`InvoiceRequest`] for an [`Offer`]
2078
2027
/// and pays the [`Bolt12Invoice`] response.
@@ -2194,6 +2143,7 @@ where
2194
2143
/// ```
2195
2144
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
2196
2145
/// # use lightning::ln::channelmanager::AChannelManager;
2146
+ /// # use lightning::offers::flow::OffersMessageCommons;
2197
2147
/// # use lightning::offers::refund::Refund;
2198
2148
/// #
2199
2149
/// # fn example<T: AChannelManager>(channel_manager: T, refund: &Refund) {
@@ -2312,7 +2262,6 @@ where
2312
2262
/// [`claim_funds`]: Self::claim_funds
2313
2263
/// [`send_payment`]: Self::send_payment
2314
2264
/// [`offers`]: crate::offers
2315
- /// [`create_offer_builder`]: Self::create_offer_builder
2316
2265
/// [`pay_for_offer`]: Self::pay_for_offer
2317
2266
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
2318
2267
/// [`create_refund_builder`]: Self::create_refund_builder
@@ -2324,6 +2273,7 @@ where
2324
2273
/// [`update_channel`]: chain::Watch::update_channel
2325
2274
/// [`ChannelUpdate`]: msgs::ChannelUpdate
2326
2275
/// [`read`]: ReadableArgs::read
2276
+ /// [`create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2327
2277
//
2328
2278
// Lock order:
2329
2279
// The tree structure below illustrates the lock order requirements for the different locks of the
@@ -2822,11 +2772,13 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
2822
2772
/// The maximum expiration from the current time where an [`Offer`] or [`Refund`] is considered
2823
2773
/// short-lived, while anything with a greater expiration is considered long-lived.
2824
2774
///
2825
- /// Using [`ChannelManager ::create_offer_builder`] or [`ChannelManager::create_refund_builder`],
2775
+ /// Using [`OffersMessageFlow ::create_offer_builder`] or [`ChannelManager::create_refund_builder`],
2826
2776
/// will included a [`BlindedMessagePath`] created using:
2827
2777
/// - [`MessageRouter::create_compact_blinded_paths`] when short-lived, and
2828
2778
/// - [`MessageRouter::create_blinded_paths`] when long-lived.
2829
2779
///
2780
+ /// [`OffersMessageFlow::create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2781
+ ///
2830
2782
/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
2831
2783
/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
2832
2784
/// become invalid over time as channels are closed. Thus, they are only suitable for short-term use.
@@ -6795,7 +6747,7 @@ where
6795
6747
/// [`Event::PaymentClaimable::claim_deadline`]: crate::events::Event::PaymentClaimable::claim_deadline
6796
6748
/// [`Event::PaymentClaimed`]: crate::events::Event::PaymentClaimed
6797
6749
/// [`process_pending_events`]: EventsProvider::process_pending_events
6798
- /// [`create_inbound_payment`]: Self ::create_inbound_payment
6750
+ /// [`create_inbound_payment`]: ChannelManager ::create_inbound_payment
6799
6751
/// [`create_inbound_payment_for_hash`]: ChannelManager::create_inbound_payment_for_hash
6800
6752
/// [`claim_funds_with_known_custom_tlvs`]: ChannelManager::claim_funds_with_known_custom_tlvs
6801
6753
pub fn claim_funds(&self, payment_preimage: PaymentPreimage) {
@@ -9719,57 +9671,6 @@ impl Default for Bolt11InvoiceParameters {
9719
9671
}
9720
9672
}
9721
9673
9722
- macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
9723
- /// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
9724
- /// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer's
9725
- /// expiration will be `absolute_expiry` if `Some`, otherwise it will not expire.
9726
- ///
9727
- /// # Privacy
9728
- ///
9729
- /// Uses [`MessageRouter`] to construct a [`BlindedMessagePath`] for the offer based on the given
9730
- /// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for
9731
- /// privacy implications as well as those of the parameterized [`Router`], which implements
9732
- /// [`MessageRouter`].
9733
- ///
9734
- /// Also, uses a derived signing pubkey in the offer for recipient privacy.
9735
- ///
9736
- /// # Limitations
9737
- ///
9738
- /// Requires a direct connection to the introduction node in the responding [`InvoiceRequest`]'s
9739
- /// reply path.
9740
- ///
9741
- /// # Errors
9742
- ///
9743
- /// Errors if the parameterized [`Router`] is unable to create a blinded path for the offer.
9744
- ///
9745
- /// [`Offer`]: crate::offers::offer::Offer
9746
- /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
9747
- pub fn create_offer_builder(
9748
- &$self, absolute_expiry: Option<Duration>
9749
- ) -> Result<$builder, Bolt12SemanticError> {
9750
- let node_id = $self.get_our_node_id();
9751
- let expanded_key = &$self.inbound_payment_key;
9752
- let entropy = &*$self.entropy_source;
9753
- let secp_ctx = &$self.secp_ctx;
9754
-
9755
- let nonce = Nonce::from_entropy_source(entropy);
9756
- let context = OffersContext::InvoiceRequest { nonce };
9757
- let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
9758
- .and_then(|paths| paths.into_iter().next().ok_or(()))
9759
- .map_err(|_| Bolt12SemanticError::MissingPaths)?;
9760
- let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
9761
- .chain_hash($self.chain_hash)
9762
- .path(path);
9763
-
9764
- let builder = match absolute_expiry {
9765
- None => builder,
9766
- Some(absolute_expiry) => builder.absolute_expiry(absolute_expiry),
9767
- };
9768
-
9769
- Ok(builder.into())
9770
- }
9771
- } }
9772
-
9773
9674
macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
9774
9675
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
9775
9676
/// [`ChannelManager`] when handling [`Bolt12Invoice`] messages for the refund.
@@ -10057,6 +9958,23 @@ where
10057
9958
10058
9959
res
10059
9960
}
9961
+
9962
+ fn create_blinded_paths_using_absolute_expiry(
9963
+ &self, context: OffersContext, absolute_expiry: Option<Duration>,
9964
+ ) -> Result<Vec<BlindedMessagePath>, ()> {
9965
+ let now = self.duration_since_epoch();
9966
+ let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
9967
+
9968
+ if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
9969
+ self.create_compact_blinded_paths(context)
9970
+ } else {
9971
+ self.create_blinded_paths(MessageContext::Offers(context))
9972
+ }
9973
+ }
9974
+
9975
+ fn get_chain_hash(&self) -> ChainHash {
9976
+ self.chain_hash
9977
+ }
10060
9978
}
10061
9979
10062
9980
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -10078,13 +9996,9 @@ where
10078
9996
MR::Target: MessageRouter,
10079
9997
L::Target: Logger,
10080
9998
{
10081
- #[cfg(not(c_bindings))]
10082
- create_offer_builder!(self, OfferBuilder<DerivedMetadata, secp256k1::All>);
10083
9999
#[cfg(not(c_bindings))]
10084
10000
create_refund_builder!(self, RefundBuilder<secp256k1::All>);
10085
10001
10086
- #[cfg(c_bindings)]
10087
- create_offer_builder!(self, OfferWithDerivedMetadataBuilder);
10088
10002
#[cfg(c_bindings)]
10089
10003
create_refund_builder!(self, RefundMaybeWithDerivedMetadataBuilder);
10090
10004
@@ -10436,25 +10350,6 @@ where
10436
10350
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
10437
10351
}
10438
10352
10439
- /// Creates a collection of blinded paths by delegating to [`MessageRouter`] based on
10440
- /// the path's intended lifetime.
10441
- ///
10442
- /// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
10443
- /// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
10444
- /// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
10445
- fn create_blinded_paths_using_absolute_expiry(
10446
- &self, context: OffersContext, absolute_expiry: Option<Duration>,
10447
- ) -> Result<Vec<BlindedMessagePath>, ()> {
10448
- let now = self.duration_since_epoch();
10449
- let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
10450
-
10451
- if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
10452
- self.create_compact_blinded_paths(context)
10453
- } else {
10454
- self.create_blinded_paths(MessageContext::Offers(context))
10455
- }
10456
- }
10457
-
10458
10353
pub(super) fn duration_since_epoch(&self) -> Duration {
10459
10354
#[cfg(not(feature = "std"))]
10460
10355
let now = Duration::from_secs(
@@ -15427,6 +15322,7 @@ pub mod bench {
15427
15322
use crate::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId, RecipientOnionFields, Retry};
15428
15323
use crate::ln::functional_test_utils::*;
15429
15324
use crate::ln::msgs::{ChannelMessageHandler, Init};
15325
+ use crate::offers::flow::OffersMessageCommons;
15430
15326
use crate::routing::gossip::NetworkGraph;
15431
15327
use crate::routing::router::{PaymentParameters, RouteParameters};
15432
15328
use crate::util::test_utils;
0 commit comments