@@ -10221,6 +10221,57 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
10221
10221
10222
10222
Ok(builder.into())
10223
10223
}
10224
+
10225
+ /// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
10226
+ /// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer.
10227
+ ///
10228
+ /// # Privacy
10229
+ ///
10230
+ /// Uses [`MessageRouter`] to construct a [`BlindedMessagePath`] for the offer based on the given
10231
+ /// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for
10232
+ /// privacy implications as well as those of the parameterized [`Router`], which implements
10233
+ /// [`MessageRouter`].
10234
+ ///
10235
+ /// Also, uses a derived signing pubkey in the offer for recipient privacy.
10236
+ ///
10237
+ /// # Limitations
10238
+ ///
10239
+ /// Requires a direct connection to the introduction node in the responding [`InvoiceRequest`]'s
10240
+ /// reply path.
10241
+ ///
10242
+ /// # Errors
10243
+ ///
10244
+ /// Errors if the provided [`Router`] is unable to create a blinded path for the offer.
10245
+ ///
10246
+ /// [`Offer`]: crate::offers::offer::Offer
10247
+ /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
10248
+ pub fn create_offer_builder_using_router<ME: MessageRouter>(
10249
+ &$self,
10250
+ router: ME,
10251
+ ) -> Result<$builder, Bolt12SemanticError> {
10252
+ let node_id = $self.get_our_node_id();
10253
+ let expanded_key = &$self.inbound_payment_key;
10254
+ let entropy = &*$self.entropy_source;
10255
+ let secp_ctx = &$self.secp_ctx;
10256
+
10257
+ let nonce = Nonce::from_entropy_source(entropy);
10258
+ let context = MessageContext::Offers(OffersContext::InvoiceRequest { nonce });
10259
+
10260
+ let peers = $self.get_peers_for_blinded_path();
10261
+
10262
+ let path = router.create_blinded_paths(node_id, context, peers, secp_ctx)
10263
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?
10264
+ .into_iter().next();
10265
+
10266
+ let mut builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
10267
+ .chain_hash($self.chain_hash);
10268
+
10269
+ if let Some(path) = path {
10270
+ builder = builder.path(path)
10271
+ }
10272
+
10273
+ Ok(builder.into())
10274
+ }
10224
10275
} }
10225
10276
10226
10277
macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
@@ -10302,6 +10353,91 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
10302
10353
10303
10354
Ok(builder.into())
10304
10355
}
10356
+
10357
+ /// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
10358
+ /// [`ChannelManager`] when handling [`Bolt12Invoice`] messages for the refund.
10359
+ ///
10360
+ /// # Payment
10361
+ ///
10362
+ /// The provided `payment_id` is used to ensure that only one invoice is paid for the refund.
10363
+ /// See [Avoiding Duplicate Payments] for other requirements once the payment has been sent.
10364
+ ///
10365
+ /// The builder will have the provided expiration set. Any changes to the expiration on the
10366
+ /// returned builder will not be honored by [`ChannelManager`]. For non-`std`, the highest seen
10367
+ /// block time minus two hours is used for the current time when determining if the refund has
10368
+ /// expired.
10369
+ ///
10370
+ /// To revoke the refund, use [`ChannelManager::abandon_payment`] prior to receiving the
10371
+ /// invoice. If abandoned, or an invoice isn't received before expiration, the payment will fail
10372
+ /// with an [`Event::PaymentFailed`].
10373
+ ///
10374
+ /// If `max_total_routing_fee_msat` is not specified, The default from
10375
+ /// [`RouteParameters::from_payment_params_and_value`] is applied.
10376
+ ///
10377
+ /// # Privacy
10378
+ ///
10379
+ /// Constructs a [`BlindedMessagePath`] for the refund using a custom [`MessageRouter`].
10380
+ /// Users can implement a custom [`MessageRouter`] to define properties of the
10381
+ /// [`BlindedMessagePath`] as required or opt not to create any `BlindedMessagePath`.
10382
+ ///
10383
+ /// Also, uses a derived payer id in the refund for payer privacy.
10384
+ ///
10385
+ /// # Limitations
10386
+ ///
10387
+ /// Requires a direct connection to an introduction node in the responding
10388
+ /// [`Bolt12Invoice::payment_paths`].
10389
+ ///
10390
+ /// # Errors
10391
+ ///
10392
+ /// Errors if:
10393
+ /// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
10394
+ /// - `amount_msats` is invalid, or
10395
+ /// - the provided [`Router`] is unable to create a blinded path for the refund.
10396
+ ///
10397
+ /// [`Refund`]: crate::offers::refund::Refund
10398
+ /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
10399
+ /// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
10400
+ /// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
10401
+ pub fn create_refund_builder_using_router<ME: MessageRouter>(
10402
+ &$self, router: ME, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId,
10403
+ retry_strategy: Retry, route_params_config: RouteParametersConfig
10404
+ ) -> Result<$builder, Bolt12SemanticError> {
10405
+ let node_id = $self.get_our_node_id();
10406
+ let expanded_key = &$self.inbound_payment_key;
10407
+ let entropy = &*$self.entropy_source;
10408
+ let secp_ctx = &$self.secp_ctx;
10409
+
10410
+ let nonce = Nonce::from_entropy_source(entropy);
10411
+ let context = MessageContext::Offers(
10412
+ OffersContext::OutboundPayment { payment_id, nonce, hmac: None }
10413
+ );
10414
+
10415
+ let peers = $self.get_peers_for_blinded_path();
10416
+ let path = router.create_blinded_paths(node_id, context, peers, secp_ctx)
10417
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?
10418
+ .into_iter().next();
10419
+
10420
+ let mut builder = RefundBuilder::deriving_signing_pubkey(
10421
+ node_id, expanded_key, nonce, secp_ctx, amount_msats, payment_id
10422
+ )?
10423
+ .chain_hash($self.chain_hash)
10424
+ .absolute_expiry(absolute_expiry);
10425
+
10426
+ if let Some(path) = path {
10427
+ builder = builder.path(path)
10428
+ }
10429
+
10430
+ let _persistence_guard = PersistenceNotifierGuard::notify_on_drop($self);
10431
+
10432
+ let expiration = StaleExpiration::AbsoluteTimeout(absolute_expiry);
10433
+ $self.pending_outbound_payments
10434
+ .add_new_awaiting_invoice(
10435
+ payment_id, expiration, retry_strategy, route_params_config, None,
10436
+ )
10437
+ .map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
10438
+
10439
+ Ok(builder.into())
10440
+ }
10305
10441
} }
10306
10442
10307
10443
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
0 commit comments