@@ -218,10 +218,13 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18;
218218/// * `D`: exactly one [`TaggedField::Description`] or [`TaggedField::DescriptionHash`]
219219/// * `H`: exactly one [`TaggedField::PaymentHash`]
220220/// * `T`: the timestamp is set
221+ /// * `C`: the CLTV expiry is set
222+ /// * `S`: the payment secret is set
223+ /// * `M`: payment metadata is set
221224///
222225/// This is not exported to bindings users as we likely need to manually select one set of boolean type parameters.
223226#[ derive( Eq , PartialEq , Debug , Clone ) ]
224- pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > {
227+ pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > {
225228 currency : Currency ,
226229 amount : Option < u64 > ,
227230 si_prefix : Option < SiPrefix > ,
@@ -234,6 +237,7 @@ pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S:
234237 phantom_t : core:: marker:: PhantomData < T > ,
235238 phantom_c : core:: marker:: PhantomData < C > ,
236239 phantom_s : core:: marker:: PhantomData < S > ,
240+ phantom_m : core:: marker:: PhantomData < M > ,
237241}
238242
239243/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
@@ -488,7 +492,7 @@ pub mod constants {
488492 pub const TAG_FEATURES : u8 = 5 ;
489493}
490494
491- impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False > {
495+ impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False , tb :: False > {
492496 /// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
493497 /// `InvoiceBuilder::build(self)` becomes available.
494498 pub fn new ( currrency : Currency ) -> Self {
@@ -505,14 +509,15 @@ impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
505509 phantom_t : core:: marker:: PhantomData ,
506510 phantom_c : core:: marker:: PhantomData ,
507511 phantom_s : core:: marker:: PhantomData ,
512+ phantom_m : core:: marker:: PhantomData ,
508513 }
509514 }
510515}
511516
512- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S > {
517+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , C , S , M > {
513518 /// Helper function to set the completeness flags.
514- fn set_flags < DN : tb:: Bool , HN : tb:: Bool , TN : tb:: Bool , CN : tb:: Bool , SN : tb:: Bool > ( self ) -> InvoiceBuilder < DN , HN , TN , CN , SN > {
515- InvoiceBuilder :: < DN , HN , TN , CN , SN > {
519+ fn set_flags < DN : tb:: Bool , HN : tb:: Bool , TN : tb:: Bool , CN : tb:: Bool , SN : tb:: Bool , MN : tb :: Bool > ( self ) -> InvoiceBuilder < DN , HN , TN , CN , SN , MN > {
520+ InvoiceBuilder :: < DN , HN , TN , CN , SN , MN > {
516521 currency : self . currency ,
517522 amount : self . amount ,
518523 si_prefix : self . si_prefix ,
@@ -525,6 +530,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
525530 phantom_t : core:: marker:: PhantomData ,
526531 phantom_c : core:: marker:: PhantomData ,
527532 phantom_s : core:: marker:: PhantomData ,
533+ phantom_m : core:: marker:: PhantomData ,
528534 }
529535 }
530536
@@ -569,7 +575,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
569575 }
570576}
571577
572- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: True , C , S > {
578+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: True , C , S , M > {
573579 /// Builds a [`RawInvoice`] if no [`CreationError`] occurred while construction any of the
574580 /// fields.
575581 pub fn build_raw ( self ) -> Result < RawInvoice , CreationError > {
@@ -603,9 +609,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
603609 }
604610}
605611
606- impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < tb:: False , H , T , C , S > {
612+ impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < tb:: False , H , T , C , S , M > {
607613 /// Set the description. This function is only available if no description (hash) was set.
608- pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
614+ pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
609615 match Description :: new ( description) {
610616 Ok ( d) => self . tagged_fields . push ( TaggedField :: Description ( d) ) ,
611617 Err ( e) => self . error = Some ( e) ,
@@ -614,13 +620,13 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::Fals
614620 }
615621
616622 /// Set the description hash. This function is only available if no description (hash) was set.
617- pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
623+ pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
618624 self . tagged_fields . push ( TaggedField :: DescriptionHash ( Sha256 ( description_hash) ) ) ;
619625 self . set_flags ( )
620626 }
621627
622628 /// Set the description or description hash. This function is only available if no description (hash) was set.
623- pub fn invoice_description ( self , description : InvoiceDescription ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
629+ pub fn invoice_description ( self , description : InvoiceDescription ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
624630 match description {
625631 InvoiceDescription :: Direct ( desc) => {
626632 self . description ( desc. clone ( ) . into_inner ( ) )
@@ -632,18 +638,18 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::Fals
632638 }
633639}
634640
635- impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , tb:: False , T , C , S > {
641+ impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , tb:: False , T , C , S , M > {
636642 /// Set the payment hash. This function is only available if no payment hash was set.
637- pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S > {
643+ pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S , M > {
638644 self . tagged_fields . push ( TaggedField :: PaymentHash ( Sha256 ( hash) ) ) ;
639645 self . set_flags ( )
640646 }
641647}
642648
643- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: False , C , S > {
649+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: False , C , S , M > {
644650 /// Sets the timestamp to a specific [`SystemTime`].
645651 #[ cfg( feature = "std" ) ]
646- pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
652+ pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
647653 match PositiveTimestamp :: from_system_time ( time) {
648654 Ok ( t) => self . timestamp = Some ( t) ,
649655 Err ( e) => self . error = Some ( e) ,
@@ -654,7 +660,7 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
654660
655661 /// Sets the timestamp to a duration since the Unix epoch, dropping the subsecond part (which
656662 /// is not representable in BOLT 11 invoices).
657- pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
663+ pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
658664 match PositiveTimestamp :: from_duration_since_epoch ( time) {
659665 Ok ( t) => self . timestamp = Some ( t) ,
660666 Err ( e) => self . error = Some ( e) ,
@@ -665,34 +671,82 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
665671
666672 /// Sets the timestamp to the current system time.
667673 #[ cfg( feature = "std" ) ]
668- pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
674+ pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
669675 let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
670676 self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
671677 self . set_flags ( )
672678 }
673679}
674680
675- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , tb:: False , S > {
681+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , tb:: False , S , M > {
676682 /// Sets `min_final_cltv_expiry_delta`.
677- pub fn min_final_cltv_expiry_delta ( mut self , min_final_cltv_expiry_delta : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S > {
683+ pub fn min_final_cltv_expiry_delta ( mut self , min_final_cltv_expiry_delta : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S , M > {
678684 self . tagged_fields . push ( TaggedField :: MinFinalCltvExpiryDelta ( MinFinalCltvExpiryDelta ( min_final_cltv_expiry_delta) ) ) ;
679685 self . set_flags ( )
680686 }
681687}
682688
683- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: False > {
689+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , C , tb:: False , M > {
684690 /// Sets the payment secret and relevant features.
685- pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True > {
686- let mut features = InvoiceFeatures :: empty ( ) ;
687- features. set_variable_length_onion_required ( ) ;
688- features. set_payment_secret_required ( ) ;
691+ pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True , M > {
692+ let mut found_features = false ;
693+ for field in self . tagged_fields . iter_mut ( ) {
694+ if let TaggedField :: Features ( f) = field {
695+ found_features = true ;
696+ f. set_variable_length_onion_required ( ) ;
697+ f. set_payment_secret_required ( ) ;
698+ }
699+ }
689700 self . tagged_fields . push ( TaggedField :: PaymentSecret ( payment_secret) ) ;
690- self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
701+ if !found_features {
702+ let mut features = InvoiceFeatures :: empty ( ) ;
703+ features. set_variable_length_onion_required ( ) ;
704+ features. set_payment_secret_required ( ) ;
705+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
706+ }
691707 self . set_flags ( )
692708 }
693709}
694710
695- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True > {
711+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: False > {
712+ /// Sets the payment metadata.
713+ ///
714+ /// By default features are set to *optionally* allow the sender to include the payment metadata.
715+ /// If you wish to require that the sender include the metadata (and fail to parse the invoice if
716+ /// they don't support payment metadata fields), you need to call
717+ /// [`InvoiceBuilder::require_payment_metadata`] after this.
718+ pub fn payment_metadata ( mut self , payment_metadata : Vec < u8 > ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
719+ self . tagged_fields . push ( TaggedField :: PaymentMetadata ( payment_metadata) ) ;
720+ let mut found_features = false ;
721+ for field in self . tagged_fields . iter_mut ( ) {
722+ if let TaggedField :: Features ( f) = field {
723+ found_features = true ;
724+ f. set_payment_metadata_optional ( ) ;
725+ }
726+ }
727+ if !found_features {
728+ let mut features = InvoiceFeatures :: empty ( ) ;
729+ features. set_payment_metadata_optional ( ) ;
730+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
731+ }
732+ self . set_flags ( )
733+ }
734+ }
735+
736+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: True > {
737+ /// Sets forwarding of payment metadata as required. A reader of the invoice which does not
738+ /// support sending payment metadata will fail to read the invoice.
739+ pub fn require_payment_metadata ( mut self ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
740+ for field in self . tagged_fields . iter_mut ( ) {
741+ if let TaggedField :: Features ( f) = field {
742+ f. set_payment_metadata_required ( ) ;
743+ }
744+ }
745+ self
746+ }
747+ }
748+
749+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True , M > {
696750 /// Sets the `basic_mpp` feature as optional.
697751 pub fn basic_mpp ( mut self ) -> Self {
698752 for field in self . tagged_fields . iter_mut ( ) {
@@ -704,7 +758,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T,
704758 }
705759}
706760
707- impl InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True > {
761+ impl < M : tb :: Bool > InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True , M > {
708762 /// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
709763 /// and MUST produce a recoverable signature valid for the given hash and if applicable also for
710764 /// the included payee public key.
0 commit comments