@@ -10221,6 +10221,56 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
1022110221
1022210222 Ok(builder.into())
1022310223 }
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+ }
1022410274} }
1022510275
1022610276macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
@@ -10302,6 +10352,91 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
1030210352
1030310353 Ok(builder.into())
1030410354 }
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+ }
1030510440} }
1030610441
1030710442/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
0 commit comments