@@ -687,6 +687,53 @@ impl Readable for InterceptId {
687687 }
688688}
689689
690+ /// Optional arguments to [`ChannelManager::pay_for_offer`]
691+ #[cfg_attr(
692+ feature = "dnssec",
693+ doc = "and [`ChannelManager::pay_for_offer_from_human_readable_name`]"
694+ )]
695+ /// .
696+ ///
697+ /// These fields will often not need to be set, and the provided [`Self::default`] can be used.
698+ pub struct OptionalOfferPaymentInfo {
699+ /// The quantity of the offer which we wish to pay for. This is communicated to the recipient
700+ /// and determines the minimum value which we must pay.
701+ ///
702+ /// This must be set if we're paying for an offer that has [`Offer::expects_quantity`].
703+ ///
704+ #[cfg_attr(
705+ feature = "dnssec",
706+ doc = "Note that setting this will cause [`ChannelManager::pay_for_offer_from_human_readable_name`] to fail."
707+ )]
708+ pub quantity: Option<u64>,
709+ /// A note which is communicated to the recipient about this payment via
710+ /// [`InvoiceRequest::payer_note`].
711+ pub payer_note: Option<String>,
712+ /// Pathfinding options which tweak how the path is constructed to the recipient.
713+ pub route_params_config: RouteParametersConfig,
714+ /// The number of tries or time during which we'll retry this payment if some paths to the
715+ /// recipient fail.
716+ ///
717+ /// Once the retry limit is reached, further path failures will not be retried and the payment
718+ /// will ultimately fail once all pending paths have failed (generating an
719+ /// [`Event::PaymentFailed`]).
720+ pub retry_strategy: Retry,
721+ }
722+
723+ impl Default for OptionalOfferPaymentInfo {
724+ fn default() -> Self {
725+ Self {
726+ quantity: None,
727+ payer_note: None,
728+ route_params_config: Default::default(),
729+ #[cfg(feature = "std")]
730+ retry_strategy: Retry::Timeout(core::time::Duration::from_secs(2)),
731+ #[cfg(not(feature = "std"))]
732+ retry_strategy: Retry::Attempts(3),
733+ }
734+ }
735+ }
736+
690737#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
691738/// Uniquely describes an HTLC by its source. Just the guaranteed-unique subset of [`HTLCSource`].
692739pub(crate) enum SentHTLCId {
@@ -2256,18 +2303,16 @@ where
22562303///
22572304/// ```
22582305/// # use lightning::events::{Event, EventsProvider};
2259- /// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry };
2306+ /// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails};
22602307/// # use lightning::offers::offer::Offer;
2261- /// # use lightning::routing::router::RouteParametersConfig;
22622308/// #
22632309/// # fn example<T: AChannelManager>(
2264- /// # channel_manager: T, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
2265- /// # payer_note: Option<String>, retry: Retry, route_params_config: RouteParametersConfig
2310+ /// # channel_manager: T, offer: &Offer, amount_msats: Option<u64>,
22662311/// # ) {
22672312/// # let channel_manager = channel_manager.get_cm();
22682313/// let payment_id = PaymentId([42; 32]);
22692314/// match channel_manager.pay_for_offer(
2270- /// offer, quantity, amount_msats, payer_note, payment_id, retry, route_params_config
2315+ /// offer, amount_msats, payment_id, Default::default(),
22712316/// ) {
22722317/// Ok(()) => println!("Requesting invoice for offer"),
22732318/// Err(e) => println!("Unable to request invoice for offer: {:?}", e),
@@ -5024,6 +5069,9 @@ where
50245069 /// Sends a payment to the route found using the provided [`RouteParameters`], retrying failed
50255070 /// payment paths based on the provided `Retry`.
50265071 ///
5072+ /// You should likely prefer [`Self::pay_for_bolt11_invoice`] or [`Self::pay_for_offer`] in
5073+ /// general, however this method may allow for slightly more customization.
5074+ ///
50275075 /// May generate [`UpdateHTLCs`] message(s) event on success, which should be relayed (e.g. via
50285076 /// [`PeerManager::process_events`]).
50295077 ///
@@ -11128,16 +11176,9 @@ where
1112811176 ///
1112911177 /// Uses [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is recognized by
1113011178 /// the [`ChannelManager`] when handling a [`Bolt12Invoice`] message in response to the request.
11131- /// The optional parameters are used in the builder, if `Some`:
11132- /// - `quantity` for [`InvoiceRequest::quantity`] which must be set if
11133- /// [`Offer::expects_quantity`] is `true`.
11134- /// - `amount_msats` if overpaying what is required for the given `quantity` is desired, and
11135- /// - `payer_note` for [`InvoiceRequest::payer_note`].
1113611179 ///
11137- /// # Custom Routing Parameters
11138- ///
11139- /// Users can customize routing parameters via [`RouteParametersConfig`].
11140- /// To use default settings, call the function with [`RouteParametersConfig::default`].
11180+ /// `amount_msats` allows you to overpay what is required to satisfy the offer, or may be
11181+ /// required if the offer does not require a specific amount.
1114111182 ///
1114211183 /// # Payment
1114311184 ///
@@ -11179,9 +11220,8 @@ where
1117911220 /// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
1118011221 /// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
1118111222 pub fn pay_for_offer(
11182- &self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
11183- payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
11184- route_params_config: RouteParametersConfig,
11223+ &self, offer: &Offer, amount_msats: Option<u64>, payment_id: PaymentId,
11224+ optional_info: OptionalOfferPaymentInfo,
1118511225 ) -> Result<(), Bolt12SemanticError> {
1118611226 let create_pending_payment_fn = |invoice_request: &InvoiceRequest, nonce| {
1118711227 let expiration = StaleExpiration::TimerTicks(1);
@@ -11194,18 +11234,18 @@ where
1119411234 .add_new_awaiting_invoice(
1119511235 payment_id,
1119611236 expiration,
11197- retry_strategy,
11198- route_params_config,
11237+ optional_info. retry_strategy,
11238+ optional_info. route_params_config,
1119911239 Some(retryable_invoice_request),
1120011240 )
1120111241 .map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
1120211242 };
1120311243
1120411244 self.pay_for_offer_intern(
1120511245 offer,
11206- quantity,
11246+ optional_info. quantity,
1120711247 amount_msats,
11208- payer_note,
11248+ optional_info. payer_note,
1120911249 payment_id,
1121011250 None,
1121111251 create_pending_payment_fn,
@@ -11313,11 +11353,6 @@ where
1131311353 /// implementing [`DNSResolverMessageHandler`]) directly to look up a URI and then delegate to
1131411354 /// your normal URI handling.
1131511355 ///
11316- /// # Custom Routing Parameters
11317- ///
11318- /// Users can customize routing parameters via [`RouteParametersConfig`].
11319- /// To use default settings, call the function with [`RouteParametersConfig::default`].
11320- ///
1132111356 /// # Payment
1132211357 ///
1132311358 /// The provided `payment_id` is used to ensure that only one invoice is paid for the request
@@ -11345,6 +11380,7 @@ where
1134511380 ///
1134611381 /// Errors if:
1134711382 /// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
11383+ /// - [`OptionalOfferPaymentInfo.quantity`] is set.
1134811384 ///
1134911385 /// [BIP 353]: https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki
1135011386 /// [bLIP 32]: https://github.com/lightning/blips/blob/master/blip-0032.md
@@ -11358,20 +11394,23 @@ where
1135811394 #[cfg(feature = "dnssec")]
1135911395 pub fn pay_for_offer_from_human_readable_name(
1136011396 &self, name: HumanReadableName, amount_msats: u64, payment_id: PaymentId,
11361- payer_note: Option<String>, retry_strategy: Retry,
11362- route_params_config: RouteParametersConfig, dns_resolvers: Vec<Destination>,
11397+ optional_info: OptionalOfferPaymentInfo, dns_resolvers: Vec<Destination>,
1136311398 ) -> Result<(), ()> {
11399+ if optional_info.quantity.is_some() {
11400+ return Err(());
11401+ }
11402+
1136411403 let (onion_message, context) =
1136511404 self.flow.hrn_resolver.resolve_name(payment_id, name, &*self.entropy_source)?;
1136611405
1136711406 let expiration = StaleExpiration::TimerTicks(1);
1136811407 self.pending_outbound_payments.add_new_awaiting_offer(
1136911408 payment_id,
1137011409 expiration,
11371- retry_strategy,
11372- route_params_config,
11410+ optional_info. retry_strategy,
11411+ optional_info. route_params_config,
1137311412 amount_msats,
11374- payer_note,
11413+ optional_info. payer_note,
1137511414 )?;
1137611415
1137711416 self.flow
0 commit comments