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