@@ -225,10 +225,13 @@ fn check_system_time_bounds() {
225
225
/// * `D`: exactly one `Description` or `DescriptionHash`
226
226
/// * `H`: exactly one `PaymentHash`
227
227
/// * `T`: the timestamp is set
228
+ /// * `C`: the CLTV expiry is set
229
+ /// * `S`: the payment secret is set
230
+ /// * `M`: payment metadata is set
228
231
///
229
232
/// (C-not exported) as we likely need to manually select one set of boolean type parameters.
230
233
#[ derive( Eq , PartialEq , Debug , Clone ) ]
231
- pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > {
234
+ pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > {
232
235
currency : Currency ,
233
236
amount : Option < u64 > ,
234
237
si_prefix : Option < SiPrefix > ,
@@ -241,6 +244,7 @@ pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S:
241
244
phantom_t : core:: marker:: PhantomData < T > ,
242
245
phantom_c : core:: marker:: PhantomData < C > ,
243
246
phantom_s : core:: marker:: PhantomData < S > ,
247
+ phantom_m : core:: marker:: PhantomData < M > ,
244
248
}
245
249
246
250
/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
@@ -499,7 +503,7 @@ pub mod constants {
499
503
pub const TAG_FEATURES : u8 = 5 ;
500
504
}
501
505
502
- impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False > {
506
+ impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False , tb :: False > {
503
507
/// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
504
508
/// `InvoiceBuilder::build(self)` becomes available.
505
509
pub fn new ( currrency : Currency ) -> Self {
@@ -516,14 +520,15 @@ impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
516
520
phantom_t : core:: marker:: PhantomData ,
517
521
phantom_c : core:: marker:: PhantomData ,
518
522
phantom_s : core:: marker:: PhantomData ,
523
+ phantom_m : core:: marker:: PhantomData ,
519
524
}
520
525
}
521
526
}
522
527
523
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S > {
528
+ 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 > {
524
529
/// Helper function to set the completeness flags.
525
- 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 > {
526
- InvoiceBuilder :: < DN , HN , TN , CN , SN > {
530
+ 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 > {
531
+ InvoiceBuilder :: < DN , HN , TN , CN , SN , MN > {
527
532
currency : self . currency ,
528
533
amount : self . amount ,
529
534
si_prefix : self . si_prefix ,
@@ -536,6 +541,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
536
541
phantom_t : core:: marker:: PhantomData ,
537
542
phantom_c : core:: marker:: PhantomData ,
538
543
phantom_s : core:: marker:: PhantomData ,
544
+ phantom_m : core:: marker:: PhantomData ,
539
545
}
540
546
}
541
547
@@ -582,7 +588,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
582
588
}
583
589
}
584
590
585
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: True , C , S > {
591
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: True , C , S , M > {
586
592
/// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields.
587
593
pub fn build_raw ( self ) -> Result < RawInvoice , CreationError > {
588
594
@@ -615,9 +621,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
615
621
}
616
622
}
617
623
618
- impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < tb:: False , H , T , C , S > {
624
+ impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < tb:: False , H , T , C , S , M > {
619
625
/// Set the description. This function is only available if no description (hash) was set.
620
- pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
626
+ pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
621
627
match Description :: new ( description) {
622
628
Ok ( d) => self . tagged_fields . push ( TaggedField :: Description ( d) ) ,
623
629
Err ( e) => self . error = Some ( e) ,
@@ -626,24 +632,24 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::Fals
626
632
}
627
633
628
634
/// Set the description hash. This function is only available if no description (hash) was set.
629
- pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
635
+ pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
630
636
self . tagged_fields . push ( TaggedField :: DescriptionHash ( Sha256 ( description_hash) ) ) ;
631
637
self . set_flags ( )
632
638
}
633
639
}
634
640
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 > {
636
642
/// 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 > {
638
644
self . tagged_fields . push ( TaggedField :: PaymentHash ( Sha256 ( hash) ) ) ;
639
645
self . set_flags ( )
640
646
}
641
647
}
642
648
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 > {
644
650
/// Sets the timestamp to a specific [`SystemTime`].
645
651
#[ 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 > {
647
653
match PositiveTimestamp :: from_system_time ( time) {
648
654
Ok ( t) => self . timestamp = Some ( t) ,
649
655
Err ( e) => self . error = Some ( e) ,
@@ -653,7 +659,7 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
653
659
}
654
660
655
661
/// Sets the timestamp to a duration since the UNIX epoch.
656
- pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
662
+ pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
657
663
match PositiveTimestamp :: from_duration_since_epoch ( time) {
658
664
Ok ( t) => self . timestamp = Some ( t) ,
659
665
Err ( e) => self . error = Some ( e) ,
@@ -664,34 +670,94 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
664
670
665
671
/// Sets the timestamp to the current system time.
666
672
#[ cfg( feature = "std" ) ]
667
- pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
673
+ pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S . M > {
668
674
let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
669
675
self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
670
676
self . set_flags ( )
671
677
}
672
678
}
673
679
674
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , tb:: False , S > {
680
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , tb:: False , S , M > {
675
681
/// Sets `min_final_cltv_expiry`.
676
- pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S > {
682
+ pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S , M > {
677
683
self . tagged_fields . push ( TaggedField :: MinFinalCltvExpiry ( MinFinalCltvExpiry ( min_final_cltv_expiry) ) ) ;
678
684
self . set_flags ( )
679
685
}
680
686
}
681
687
682
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: False > {
688
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , C , tb:: False , M > {
683
689
/// Sets the payment secret and relevant features.
684
- pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True > {
685
- let features = InvoiceFeatures :: empty ( )
686
- . set_variable_length_onion_required ( )
687
- . set_payment_secret_required ( ) ;
690
+ pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True , M > {
691
+ let mut found_features = false ;
692
+ self . tagged_fields = self . tagged_fields
693
+ . drain ( ..)
694
+ . map ( |field| match field {
695
+ TaggedField :: Features ( f) => {
696
+ found_features = true ;
697
+ TaggedField :: Features ( f
698
+ . set_variable_length_onion_required ( )
699
+ . set_payment_secret_required ( ) )
700
+ } ,
701
+ _ => field,
702
+ } )
703
+ . collect ( ) ;
688
704
self . tagged_fields . push ( TaggedField :: PaymentSecret ( payment_secret) ) ;
689
- self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
705
+ if !found_features {
706
+ let features = InvoiceFeatures :: empty ( )
707
+ . set_variable_length_onion_required ( )
708
+ . set_payment_secret_required ( ) ;
709
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
710
+ }
690
711
self . set_flags ( )
691
712
}
692
713
}
693
714
694
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True > {
715
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: False > {
716
+ /// Sets the payment metadata.
717
+ ///
718
+ /// By default features are set to *optionally* allow the sender to include the payment metadata.
719
+ /// If you wish to require that the sender include the metadata (and fail to parse the invoice if
720
+ /// they don't support payment metadata fields), you need to call
721
+ /// [`InvoiceBuilder::require_payment_metadata`] after this.
722
+ pub fn payment_metadata ( mut self , payment_metadata : Vec < u8 > ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
723
+ self . tagged_fields . push ( TaggedField :: PaymentMetadata ( payment_metadata) ) ;
724
+ let mut found_features = false ;
725
+ self . tagged_fields = self . tagged_fields
726
+ . drain ( ..)
727
+ . map ( |field| match field {
728
+ TaggedField :: Features ( f) => {
729
+ found_features = true ;
730
+ TaggedField :: Features ( f. set_payment_metadata_optional ( ) )
731
+ } ,
732
+ _ => field,
733
+ } )
734
+ . collect ( ) ;
735
+ if !found_features {
736
+ let features = InvoiceFeatures :: empty ( )
737
+ . set_payment_metadata_optional ( ) ;
738
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
739
+ }
740
+ self . set_flags ( )
741
+ }
742
+ }
743
+
744
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: True > {
745
+ /// Sets the payment secret and relevant features.
746
+ pub fn require_payment_metadata ( mut self ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
747
+ self . tagged_fields = self . tagged_fields
748
+ . drain ( ..)
749
+ . map ( |field| match field {
750
+ TaggedField :: Features ( f) => {
751
+ TaggedField :: Features ( f. set_payment_metadata_required ( ) )
752
+ } ,
753
+ _ => field,
754
+ } )
755
+ . collect ( ) ;
756
+ self
757
+ }
758
+ }
759
+
760
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True , M > {
695
761
/// Sets the `basic_mpp` feature as optional.
696
762
pub fn basic_mpp ( mut self ) -> Self {
697
763
self . tagged_fields = self . tagged_fields
@@ -705,7 +771,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T,
705
771
}
706
772
}
707
773
708
- impl InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True > {
774
+ impl < M : tb :: Bool > InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True , M > {
709
775
/// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
710
776
/// and MUST produce a recoverable signature valid for the given hash and if applicable also for
711
777
/// the included payee public key.
0 commit comments