@@ -70,7 +70,7 @@ use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
7070use crate::offers::nonce::Nonce;
7171use crate::offers::offer::Offer;
7272use crate::offers::parse::Bolt12SemanticError;
73- use crate::offers::refund::{ Refund, RefundBuilder} ;
73+ use crate::offers::refund::Refund;
7474use crate::offers::signer;
7575use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
7676use crate::onion_message::dns_resolution::HumanReadableName;
@@ -105,8 +105,6 @@ use {
105105 crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters},
106106 crate::sign::KeysManager,
107107};
108- #[cfg(c_bindings)]
109- use crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder;
110108
111109use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, CreationError, Currency, Description, InvoiceBuilder as Bolt11InvoiceBuilder, SignOrCreationError, DEFAULT_EXPIRY_TIME};
112110
@@ -2009,6 +2007,7 @@ where
20092007/// # use lightning::events::{Event, EventsProvider};
20102008/// # use lightning::types::payment::PaymentHash;
20112009/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, RecipientOnionFields, Retry};
2010+ /// # use lightning::offers::flow::OffersMessageCommons;
20122011/// # use lightning::routing::router::RouteParameters;
20132012/// #
20142013/// # fn example<T: AChannelManager>(
@@ -2063,6 +2062,7 @@ where
20632062/// ```
20642063/// # use lightning::events::{Event, EventsProvider};
20652064/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
2065+ /// # use lightning::offers::flow::OffersMessageCommons;
20662066/// # use lightning::offers::offer::Offer;
20672067/// #
20682068/// # fn example<T: AChannelManager>(
@@ -2109,67 +2109,8 @@ where
21092109/// ```
21102110///
21112111/// ## BOLT 12 Refunds
2112- ///
2113- /// A [`Refund`] is a request for an invoice to be paid. Like *paying* for an [`Offer`], *creating*
2114- /// a [`Refund`] involves maintaining state since it represents a future outbound payment.
2115- /// Therefore, use [`create_refund_builder`] when creating one, otherwise [`ChannelManager`] will
2116- /// refuse to pay any corresponding [`Bolt12Invoice`] that it receives.
2117- ///
2118- /// ```
2119- /// # use core::time::Duration;
2120- /// # use lightning::events::{Event, EventsProvider};
2121- /// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
2122- /// # use lightning::offers::parse::Bolt12SemanticError;
2123- /// #
2124- /// # fn example<T: AChannelManager>(
2125- /// # channel_manager: T, amount_msats: u64, absolute_expiry: Duration, retry: Retry,
2126- /// # max_total_routing_fee_msat: Option<u64>
2127- /// # ) -> Result<(), Bolt12SemanticError> {
2128- /// # let channel_manager = channel_manager.get_cm();
2129- /// let payment_id = PaymentId([42; 32]);
2130- /// let refund = channel_manager
2131- /// .create_refund_builder(
2132- /// amount_msats, absolute_expiry, payment_id, retry, max_total_routing_fee_msat
2133- /// )?
2134- /// # ;
2135- /// # // Needed for compiling for c_bindings
2136- /// # let builder: lightning::offers::refund::RefundBuilder<_> = refund.into();
2137- /// # let refund = builder
2138- /// .description("coffee".to_string())
2139- /// .payer_note("refund for order 1234".to_string())
2140- /// .build()?;
2141- /// let bech32_refund = refund.to_string();
2142- ///
2143- /// // First the payment will be waiting on an invoice
2144- /// let expected_payment_id = payment_id;
2145- /// assert!(
2146- /// channel_manager.list_recent_payments().iter().find(|details| matches!(
2147- /// details,
2148- /// RecentPaymentDetails::AwaitingInvoice { payment_id: expected_payment_id }
2149- /// )).is_some()
2150- /// );
2151- ///
2152- /// // Once the invoice is received, a payment will be sent
2153- /// assert!(
2154- /// channel_manager.list_recent_payments().iter().find(|details| matches!(
2155- /// details,
2156- /// RecentPaymentDetails::Pending { payment_id: expected_payment_id, .. }
2157- /// )).is_some()
2158- /// );
2159- ///
2160- /// // On the event processing thread
2161- /// channel_manager.process_pending_events(&|event| {
2162- /// match event {
2163- /// Event::PaymentSent { payment_id: Some(payment_id), .. } => println!("Paid {}", payment_id),
2164- /// Event::PaymentFailed { payment_id, .. } => println!("Failed paying {}", payment_id),
2165- /// // ...
2166- /// # _ => {},
2167- /// }
2168- /// Ok(())
2169- /// });
2170- /// # Ok(())
2171- /// # }
2172- /// ```
2112+ ///
2113+ /// For more information on creating refunds, see [`create_refund_builder`].
21732114///
21742115/// Use [`request_refund_payment`] to send a [`Bolt12Invoice`] for receiving the refund. Similar to
21752116/// *creating* an [`Offer`], this is stateless as it represents an inbound payment.
@@ -2298,7 +2239,6 @@ where
22982239/// [`offers`]: crate::offers
22992240/// [`pay_for_offer`]: Self::pay_for_offer
23002241/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
2301- /// [`create_refund_builder`]: Self::create_refund_builder
23022242/// [`request_refund_payment`]: Self::request_refund_payment
23032243/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
23042244/// [`funding_created`]: msgs::FundingCreated
@@ -2308,6 +2248,7 @@ where
23082248/// [`ChannelUpdate`]: msgs::ChannelUpdate
23092249/// [`read`]: ReadableArgs::read
23102250/// [`create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2251+ /// [`create_refund_builder`]: crate::offers::flow::OffersMessageFlow::create_refund_builder
23112252//
23122253// Lock order:
23132254// The tree structure below illustrates the lock order requirements for the different locks of the
@@ -2803,12 +2744,14 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
28032744/// The maximum expiration from the current time where an [`Offer`] or [`Refund`] is considered
28042745/// short-lived, while anything with a greater expiration is considered long-lived.
28052746///
2806- /// Using [`OffersMessageFlow::create_offer_builder`] or [`ChannelManager ::create_refund_builder`],
2747+ /// Using [`OffersMessageFlow::create_offer_builder`] or [`OffersMessageFlow ::create_refund_builder`],
28072748/// will included a [`BlindedMessagePath`] created using:
28082749/// - [`MessageRouter::create_compact_blinded_paths`] when short-lived, and
28092750/// - [`MessageRouter::create_blinded_paths`] when long-lived.
28102751///
28112752/// [`OffersMessageFlow::create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2753+ /// [`OffersMessageFlow::create_refund_builder`]: crate::offers::flow::OffersMessageFlow::create_refund_builder
2754+ ///
28122755///
28132756/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
28142757/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
@@ -9634,87 +9577,6 @@ impl Default for Bolt11InvoiceParameters {
96349577 }
96359578}
96369579
9637- macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
9638- /// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
9639- /// [`ChannelManager`] when handling [`Bolt12Invoice`] messages for the refund.
9640- ///
9641- /// # Payment
9642- ///
9643- /// The provided `payment_id` is used to ensure that only one invoice is paid for the refund.
9644- /// See [Avoiding Duplicate Payments] for other requirements once the payment has been sent.
9645- ///
9646- /// The builder will have the provided expiration set. Any changes to the expiration on the
9647- /// returned builder will not be honored by [`ChannelManager`]. For non-`std`, the highest seen
9648- /// block time minus two hours is used for the current time when determining if the refund has
9649- /// expired.
9650- ///
9651- /// To revoke the refund, use [`ChannelManager::abandon_payment`] prior to receiving the
9652- /// invoice. If abandoned, or an invoice isn't received before expiration, the payment will fail
9653- /// with an [`Event::PaymentFailed`].
9654- ///
9655- /// If `max_total_routing_fee_msat` is not specified, The default from
9656- /// [`RouteParameters::from_payment_params_and_value`] is applied.
9657- ///
9658- /// # Privacy
9659- ///
9660- /// Uses [`MessageRouter`] to construct a [`BlindedMessagePath`] for the refund based on the given
9661- /// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for
9662- /// privacy implications as well as those of the parameterized [`Router`], which implements
9663- /// [`MessageRouter`].
9664- ///
9665- /// Also, uses a derived payer id in the refund for payer privacy.
9666- ///
9667- /// # Limitations
9668- ///
9669- /// Requires a direct connection to an introduction node in the responding
9670- /// [`Bolt12Invoice::payment_paths`].
9671- ///
9672- /// # Errors
9673- ///
9674- /// Errors if:
9675- /// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
9676- /// - `amount_msats` is invalid, or
9677- /// - the parameterized [`Router`] is unable to create a blinded path for the refund.
9678- ///
9679- /// [`Refund`]: crate::offers::refund::Refund
9680- /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
9681- /// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
9682- /// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
9683- pub fn create_refund_builder(
9684- &$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId,
9685- retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>
9686- ) -> Result<$builder, Bolt12SemanticError> {
9687- let node_id = $self.get_our_node_id();
9688- let expanded_key = &$self.inbound_payment_key;
9689- let entropy = &*$self.entropy_source;
9690- let secp_ctx = &$self.secp_ctx;
9691-
9692- let nonce = Nonce::from_entropy_source(entropy);
9693- let context = OffersContext::OutboundPayment { payment_id, nonce, hmac: None };
9694- let path = $self.create_blinded_paths_using_absolute_expiry(context, Some(absolute_expiry))
9695- .and_then(|paths| paths.into_iter().next().ok_or(()))
9696- .map_err(|_| Bolt12SemanticError::MissingPaths)?;
9697-
9698- let builder = RefundBuilder::deriving_signing_pubkey(
9699- node_id, expanded_key, nonce, secp_ctx, amount_msats, payment_id
9700- )?
9701- .chain_hash($self.chain_hash)
9702- .absolute_expiry(absolute_expiry)
9703- .path(path);
9704-
9705- let _persistence_guard = PersistenceNotifierGuard::notify_on_drop($self);
9706-
9707- let expiration = StaleExpiration::AbsoluteTimeout(absolute_expiry);
9708- $self.pending_outbound_payments
9709- .add_new_awaiting_invoice(
9710- payment_id, expiration, retry_strategy, max_total_routing_fee_msat, None,
9711- )
9712- .map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
9713-
9714- Ok(builder.into())
9715- }
9716- } }
9717-
97189580impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref> OffersMessageCommons for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
97199581where
97209582 M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
@@ -9788,6 +9650,13 @@ where
97889650 fn get_chain_hash(&self) -> ChainHash {
97899651 self.chain_hash
97909652 }
9653+
9654+ fn add_new_awaiting_invoice(&self, payment_id: PaymentId, expiration: StaleExpiration, retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>, retryable_invoice_request: Option<RetryableInvoiceRequest>) -> Result<(), ()> {
9655+ let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
9656+ self.pending_outbound_payments.add_new_awaiting_invoice (
9657+ payment_id, expiration, retry_strategy, max_total_routing_fee_msat, retryable_invoice_request,
9658+ )
9659+ }
97919660}
97929661
97939662/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -9809,11 +9678,6 @@ where
98099678 MR::Target: MessageRouter,
98109679 L::Target: Logger,
98119680{
9812- #[cfg(not(c_bindings))]
9813- create_refund_builder!(self, RefundBuilder<secp256k1::All>);
9814-
9815- #[cfg(c_bindings)]
9816- create_refund_builder!(self, RefundMaybeWithDerivedMetadataBuilder);
98179681
98189682 /// Create an offer for receiving async payments as an often-offline recipient.
98199683 ///
0 commit comments