@@ -43,7 +43,7 @@ use crate::offers::invoice_request::{
4343 InvoiceRequest , InvoiceRequestBuilder , InvoiceRequestVerifiedFromOffer , VerifiedInvoiceRequest ,
4444} ;
4545use crate :: offers:: nonce:: Nonce ;
46- use crate :: offers:: offer:: { Amount , DerivedMetadata , Offer , OfferBuilder } ;
46+ use crate :: offers:: offer:: { Amount , DerivedMetadata , Offer , OfferBuilder , RecurrenceFields } ;
4747use crate :: offers:: parse:: Bolt12SemanticError ;
4848use crate :: offers:: refund:: { Refund , RefundBuilder } ;
4949use crate :: offers:: static_invoice:: { StaticInvoice , StaticInvoiceBuilder } ;
@@ -539,7 +539,7 @@ where
539539 }
540540
541541 fn create_offer_builder_intern < ES : Deref , PF , I > (
542- & self , entropy_source : ES , make_paths : PF ,
542+ & self , entropy_source : ES , recurrence_fields : Option < RecurrenceFields > , make_paths : PF ,
543543 ) -> Result < ( OfferBuilder < ' _ , DerivedMetadata , secp256k1:: All > , Nonce ) , Bolt12SemanticError >
544544 where
545545 ES :: Target : EntropySource ,
@@ -562,6 +562,10 @@ where
562562 OfferBuilder :: deriving_signing_pubkey ( node_id, expanded_key, nonce, secp_ctx)
563563 . chain_hash ( self . chain_hash ) ;
564564
565+ if let Some ( recurrence) = recurrence_fields {
566+ builder = builder. recurrence ( recurrence) ;
567+ }
568+
565569 for path in make_paths ( node_id, context, secp_ctx) ? {
566570 builder = builder. path ( path)
567571 }
@@ -601,14 +605,48 @@ where
601605 where
602606 ES :: Target : EntropySource ,
603607 {
604- self . create_offer_builder_intern ( & * entropy_source, |_, context, _| {
608+ self . create_offer_builder_intern ( & * entropy_source, None , |_, context, _| {
605609 self . create_blinded_paths ( peers, context)
606610 . map ( |paths| paths. into_iter ( ) . take ( 1 ) )
607611 . map_err ( |_| Bolt12SemanticError :: MissingPaths )
608612 } )
609613 . map ( |( builder, _) | builder)
610614 }
611615
616+ /// Creates an [`OfferBuilder`] for a recurring offer.
617+ ///
618+ /// This behaves like [`Self::create_offer_builder`] but additionally embeds
619+ /// the recurrence TLVs defined in `recurrence_fields`.
620+ ///
621+ /// Use this when constructing subscription-style offers where each invoice
622+ /// request must correspond to a specific recurrence period. The provided
623+ /// [`RecurrenceFields`] specify:
624+ /// - how often invoices may be requested,
625+ /// - when the first period begins,
626+ /// - optional paywindows, and
627+ /// - optional period limits.
628+ ///
629+ /// Refer to [`Self::create_offer_builder`] for notes on privacy,
630+ /// requirements, and potential failure cases.
631+ pub fn create_offer_builder_with_recurrence < ES : Deref > (
632+ & self , entropy_source : ES , recurrence_fields : RecurrenceFields ,
633+ peers : Vec < MessageForwardNode > ,
634+ ) -> Result < OfferBuilder < ' _ , DerivedMetadata , secp256k1:: All > , Bolt12SemanticError >
635+ where
636+ ES :: Target : EntropySource ,
637+ {
638+ self . create_offer_builder_intern (
639+ & * entropy_source,
640+ Some ( recurrence_fields) ,
641+ |_, context, _| {
642+ self . create_blinded_paths ( peers, context)
643+ . map ( |paths| paths. into_iter ( ) . take ( 1 ) )
644+ . map_err ( |_| Bolt12SemanticError :: MissingPaths )
645+ } ,
646+ )
647+ . map ( |( builder, _) | builder)
648+ }
649+
612650 /// Same as [`Self::create_offer_builder`], but allows specifying a custom [`MessageRouter`]
613651 /// instead of using the one provided via the [`OffersMessageFlow`] parameterization.
614652 ///
@@ -626,7 +664,7 @@ where
626664 ES :: Target : EntropySource ,
627665 {
628666 let receive_key = self . get_receive_auth_key ( ) ;
629- self . create_offer_builder_intern ( & * entropy_source, |node_id, context, secp_ctx| {
667+ self . create_offer_builder_intern ( & * entropy_source, None , |node_id, context, secp_ctx| {
630668 router
631669 . create_blinded_paths ( node_id, receive_key, context, peers, secp_ctx)
632670 . map ( |paths| paths. into_iter ( ) . take ( 1 ) )
@@ -651,7 +689,7 @@ where
651689 where
652690 ES :: Target : EntropySource ,
653691 {
654- self . create_offer_builder_intern ( & * entropy_source, |_, _, _| {
692+ self . create_offer_builder_intern ( & * entropy_source, None , |_, _, _| {
655693 Ok ( message_paths_to_always_online_node)
656694 } )
657695 }
0 commit comments