@@ -205,10 +205,13 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
205
205
/// * `D`: exactly one `Description` or `DescriptionHash`
206
206
/// * `H`: exactly one `PaymentHash`
207
207
/// * `T`: the timestamp is set
208
+ /// * `C`: the CLTV expiry is set
209
+ /// * `S`: the payment secret is set
210
+ /// * `M`: payment metadata is set
208
211
///
209
212
/// (C-not exported) as we likely need to manually select one set of boolean type parameters.
210
213
#[ derive( Eq , PartialEq , Debug , Clone ) ]
211
- pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > {
214
+ pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > {
212
215
currency : Currency ,
213
216
amount : Option < u64 > ,
214
217
si_prefix : Option < SiPrefix > ,
@@ -221,6 +224,7 @@ pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S:
221
224
phantom_t : core:: marker:: PhantomData < T > ,
222
225
phantom_c : core:: marker:: PhantomData < C > ,
223
226
phantom_s : core:: marker:: PhantomData < S > ,
227
+ phantom_m : core:: marker:: PhantomData < M > ,
224
228
}
225
229
226
230
/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
@@ -474,7 +478,7 @@ pub mod constants {
474
478
pub const TAG_FEATURES : u8 = 5 ;
475
479
}
476
480
477
- impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False > {
481
+ impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False , tb :: False > {
478
482
/// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
479
483
/// `InvoiceBuilder::build(self)` becomes available.
480
484
pub fn new ( currrency : Currency ) -> Self {
@@ -491,14 +495,15 @@ impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
491
495
phantom_t : core:: marker:: PhantomData ,
492
496
phantom_c : core:: marker:: PhantomData ,
493
497
phantom_s : core:: marker:: PhantomData ,
498
+ phantom_m : core:: marker:: PhantomData ,
494
499
}
495
500
}
496
501
}
497
502
498
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S > {
503
+ 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 > {
499
504
/// Helper function to set the completeness flags.
500
- 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 > {
501
- InvoiceBuilder :: < DN , HN , TN , CN , SN > {
505
+ 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 > {
506
+ InvoiceBuilder :: < DN , HN , TN , CN , SN , MN > {
502
507
currency : self . currency ,
503
508
amount : self . amount ,
504
509
si_prefix : self . si_prefix ,
@@ -511,6 +516,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
511
516
phantom_t : core:: marker:: PhantomData ,
512
517
phantom_c : core:: marker:: PhantomData ,
513
518
phantom_s : core:: marker:: PhantomData ,
519
+ phantom_m : core:: marker:: PhantomData ,
514
520
}
515
521
}
516
522
@@ -554,7 +560,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
554
560
}
555
561
}
556
562
557
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: True , C , S > {
563
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: True , C , S , M > {
558
564
/// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields.
559
565
pub fn build_raw ( self ) -> Result < RawInvoice , CreationError > {
560
566
@@ -587,9 +593,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
587
593
}
588
594
}
589
595
590
- impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < tb:: False , H , T , C , S > {
596
+ impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < tb:: False , H , T , C , S , M > {
591
597
/// Set the description. This function is only available if no description (hash) was set.
592
- pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
598
+ pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
593
599
match Description :: new ( description) {
594
600
Ok ( d) => self . tagged_fields . push ( TaggedField :: Description ( d) ) ,
595
601
Err ( e) => self . error = Some ( e) ,
@@ -598,24 +604,24 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::Fals
598
604
}
599
605
600
606
/// Set the description hash. This function is only available if no description (hash) was set.
601
- pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
607
+ pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
602
608
self . tagged_fields . push ( TaggedField :: DescriptionHash ( Sha256 ( description_hash) ) ) ;
603
609
self . set_flags ( )
604
610
}
605
611
}
606
612
607
- impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , tb:: False , T , C , S > {
613
+ impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , tb:: False , T , C , S , M > {
608
614
/// Set the payment hash. This function is only available if no payment hash was set.
609
- pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S > {
615
+ pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S , M > {
610
616
self . tagged_fields . push ( TaggedField :: PaymentHash ( Sha256 ( hash) ) ) ;
611
617
self . set_flags ( )
612
618
}
613
619
}
614
620
615
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: False , C , S > {
621
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: False , C , S , M > {
616
622
/// Sets the timestamp to a specific [`SystemTime`].
617
623
#[ cfg( feature = "std" ) ]
618
- pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
624
+ pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
619
625
match PositiveTimestamp :: from_system_time ( time) {
620
626
Ok ( t) => self . timestamp = Some ( t) ,
621
627
Err ( e) => self . error = Some ( e) ,
@@ -625,7 +631,7 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
625
631
}
626
632
627
633
/// Sets the timestamp to a duration since the Unix epoch.
628
- pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
634
+ pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
629
635
match PositiveTimestamp :: from_duration_since_epoch ( time) {
630
636
Ok ( t) => self . timestamp = Some ( t) ,
631
637
Err ( e) => self . error = Some ( e) ,
@@ -636,34 +642,96 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
636
642
637
643
/// Sets the timestamp to the current system time.
638
644
#[ cfg( feature = "std" ) ]
639
- pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
645
+ pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
640
646
let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
641
647
self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
642
648
self . set_flags ( )
643
649
}
644
650
}
645
651
646
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , tb:: False , S > {
652
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , tb:: False , S , M > {
647
653
/// Sets `min_final_cltv_expiry`.
648
- pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S > {
654
+ pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S , M > {
649
655
self . tagged_fields . push ( TaggedField :: MinFinalCltvExpiry ( MinFinalCltvExpiry ( min_final_cltv_expiry) ) ) ;
650
656
self . set_flags ( )
651
657
}
652
658
}
653
659
654
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: False > {
660
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , C , tb:: False , M > {
655
661
/// Sets the payment secret and relevant features.
656
- pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True > {
657
- let mut features = InvoiceFeatures :: empty ( ) ;
658
- features. set_variable_length_onion_required ( ) ;
659
- features. set_payment_secret_required ( ) ;
662
+ pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True , M > {
663
+ let mut found_features = false ;
664
+ self . tagged_fields = self . tagged_fields
665
+ . drain ( ..)
666
+ . map ( |field| match field {
667
+ TaggedField :: Features ( mut f) => {
668
+ found_features = true ;
669
+ f. set_variable_length_onion_required ( ) ;
670
+ f. set_payment_secret_required ( ) ;
671
+ TaggedField :: Features ( f)
672
+ } ,
673
+ _ => field,
674
+ } )
675
+ . collect ( ) ;
660
676
self . tagged_fields . push ( TaggedField :: PaymentSecret ( payment_secret) ) ;
661
- self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
677
+ if !found_features {
678
+ let mut features = InvoiceFeatures :: empty ( ) ;
679
+ features. set_variable_length_onion_required ( ) ;
680
+ features. set_payment_secret_required ( ) ;
681
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
682
+ }
662
683
self . set_flags ( )
663
684
}
664
685
}
665
686
666
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True > {
687
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: False > {
688
+ /// Sets the payment metadata.
689
+ ///
690
+ /// By default features are set to *optionally* allow the sender to include the payment metadata.
691
+ /// If you wish to require that the sender include the metadata (and fail to parse the invoice if
692
+ /// they don't support payment metadata fields), you need to call
693
+ /// [`InvoiceBuilder::require_payment_metadata`] after this.
694
+ pub fn payment_metadata ( mut self , payment_metadata : Vec < u8 > ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
695
+ self . tagged_fields . push ( TaggedField :: PaymentMetadata ( payment_metadata) ) ;
696
+ let mut found_features = false ;
697
+ self . tagged_fields = self . tagged_fields
698
+ . drain ( ..)
699
+ . map ( |field| match field {
700
+ TaggedField :: Features ( mut f) => {
701
+ found_features = true ;
702
+ f. set_payment_metadata_optional ( ) ;
703
+ TaggedField :: Features ( f)
704
+ } ,
705
+ _ => field,
706
+ } )
707
+ . collect ( ) ;
708
+ if !found_features {
709
+ let mut features = InvoiceFeatures :: empty ( ) ;
710
+ features. set_payment_metadata_optional ( ) ;
711
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
712
+ }
713
+ self . set_flags ( )
714
+ }
715
+ }
716
+
717
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: True > {
718
+ /// Sets the payment secret and relevant features.
719
+ pub fn require_payment_metadata ( mut self ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
720
+ self . tagged_fields = self . tagged_fields
721
+ . drain ( ..)
722
+ . map ( |field| match field {
723
+ TaggedField :: Features ( mut f) => {
724
+ f. set_payment_metadata_required ( ) ;
725
+ TaggedField :: Features ( f)
726
+ } ,
727
+ _ => field,
728
+ } )
729
+ . collect ( ) ;
730
+ self
731
+ }
732
+ }
733
+
734
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True , M > {
667
735
/// Sets the `basic_mpp` feature as optional.
668
736
pub fn basic_mpp ( mut self ) -> Self {
669
737
for field in self . tagged_fields . iter_mut ( ) {
@@ -675,7 +743,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T,
675
743
}
676
744
}
677
745
678
- impl InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True > {
746
+ impl < M : tb :: Bool > InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True , M > {
679
747
/// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
680
748
/// and MUST produce a recoverable signature valid for the given hash and if applicable also for
681
749
/// the included payee public key.
0 commit comments