@@ -215,10 +215,13 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18;
215
215
/// * `D`: exactly one `Description` or `DescriptionHash`
216
216
/// * `H`: exactly one `PaymentHash`
217
217
/// * `T`: the timestamp is set
218
+ /// * `C`: the CLTV expiry is set
219
+ /// * `S`: the payment secret is set
220
+ /// * `M`: payment metadata is set
218
221
///
219
222
/// (C-not exported) as we likely need to manually select one set of boolean type parameters.
220
223
#[ derive( Eq , PartialEq , Debug , Clone ) ]
221
- pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > {
224
+ pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > {
222
225
currency : Currency ,
223
226
amount : Option < u64 > ,
224
227
si_prefix : Option < SiPrefix > ,
@@ -231,6 +234,7 @@ pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S:
231
234
phantom_t : core:: marker:: PhantomData < T > ,
232
235
phantom_c : core:: marker:: PhantomData < C > ,
233
236
phantom_s : core:: marker:: PhantomData < S > ,
237
+ phantom_m : core:: marker:: PhantomData < M > ,
234
238
}
235
239
236
240
/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
@@ -484,7 +488,7 @@ pub mod constants {
484
488
pub const TAG_FEATURES : u8 = 5 ;
485
489
}
486
490
487
- impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False > {
491
+ impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False , tb :: False > {
488
492
/// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
489
493
/// `InvoiceBuilder::build(self)` becomes available.
490
494
pub fn new ( currrency : Currency ) -> Self {
@@ -501,14 +505,15 @@ impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
501
505
phantom_t : core:: marker:: PhantomData ,
502
506
phantom_c : core:: marker:: PhantomData ,
503
507
phantom_s : core:: marker:: PhantomData ,
508
+ phantom_m : core:: marker:: PhantomData ,
504
509
}
505
510
}
506
511
}
507
512
508
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S > {
513
+ 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 > {
509
514
/// Helper function to set the completeness flags.
510
- 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 > {
511
- InvoiceBuilder :: < DN , HN , TN , CN , SN > {
515
+ 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 > {
516
+ InvoiceBuilder :: < DN , HN , TN , CN , SN , MN > {
512
517
currency : self . currency ,
513
518
amount : self . amount ,
514
519
si_prefix : self . si_prefix ,
@@ -521,6 +526,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
521
526
phantom_t : core:: marker:: PhantomData ,
522
527
phantom_c : core:: marker:: PhantomData ,
523
528
phantom_s : core:: marker:: PhantomData ,
529
+ phantom_m : core:: marker:: PhantomData ,
524
530
}
525
531
}
526
532
@@ -565,7 +571,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
565
571
}
566
572
}
567
573
568
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: True , C , S > {
574
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: True , C , S , M > {
569
575
/// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields.
570
576
pub fn build_raw ( self ) -> Result < RawInvoice , CreationError > {
571
577
@@ -598,9 +604,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
598
604
}
599
605
}
600
606
601
- impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < tb:: False , H , T , C , S > {
607
+ impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < tb:: False , H , T , C , S , M > {
602
608
/// Set the description. This function is only available if no description (hash) was set.
603
- pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
609
+ pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
604
610
match Description :: new ( description) {
605
611
Ok ( d) => self . tagged_fields . push ( TaggedField :: Description ( d) ) ,
606
612
Err ( e) => self . error = Some ( e) ,
@@ -609,24 +615,24 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::Fals
609
615
}
610
616
611
617
/// Set the description hash. This function is only available if no description (hash) was set.
612
- pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
618
+ pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
613
619
self . tagged_fields . push ( TaggedField :: DescriptionHash ( Sha256 ( description_hash) ) ) ;
614
620
self . set_flags ( )
615
621
}
616
622
}
617
623
618
- impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , tb:: False , T , C , S > {
624
+ impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , tb:: False , T , C , S , M > {
619
625
/// Set the payment hash. This function is only available if no payment hash was set.
620
- pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S > {
626
+ pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S , M > {
621
627
self . tagged_fields . push ( TaggedField :: PaymentHash ( Sha256 ( hash) ) ) ;
622
628
self . set_flags ( )
623
629
}
624
630
}
625
631
626
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: False , C , S > {
632
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: False , C , S , M > {
627
633
/// Sets the timestamp to a specific [`SystemTime`].
628
634
#[ cfg( feature = "std" ) ]
629
- pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
635
+ pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
630
636
match PositiveTimestamp :: from_system_time ( time) {
631
637
Ok ( t) => self . timestamp = Some ( t) ,
632
638
Err ( e) => self . error = Some ( e) ,
@@ -637,7 +643,7 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
637
643
638
644
/// Sets the timestamp to a duration since the Unix epoch, dropping the subsecond part (which
639
645
/// is not representable in BOLT 11 invoices).
640
- pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
646
+ pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
641
647
match PositiveTimestamp :: from_duration_since_epoch ( time) {
642
648
Ok ( t) => self . timestamp = Some ( t) ,
643
649
Err ( e) => self . error = Some ( e) ,
@@ -648,34 +654,81 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
648
654
649
655
/// Sets the timestamp to the current system time.
650
656
#[ cfg( feature = "std" ) ]
651
- pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
657
+ pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
652
658
let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
653
659
self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
654
660
self . set_flags ( )
655
661
}
656
662
}
657
663
658
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , tb:: False , S > {
664
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , tb:: False , S , M > {
659
665
/// Sets `min_final_cltv_expiry_delta`.
660
- pub fn min_final_cltv_expiry_delta ( mut self , min_final_cltv_expiry_delta : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S > {
666
+ pub fn min_final_cltv_expiry_delta ( mut self , min_final_cltv_expiry_delta : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S , M > {
661
667
self . tagged_fields . push ( TaggedField :: MinFinalCltvExpiryDelta ( MinFinalCltvExpiryDelta ( min_final_cltv_expiry_delta) ) ) ;
662
668
self . set_flags ( )
663
669
}
664
670
}
665
671
666
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: False > {
672
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , C , tb:: False , M > {
667
673
/// Sets the payment secret and relevant features.
668
- pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True > {
669
- let mut features = InvoiceFeatures :: empty ( ) ;
670
- features. set_variable_length_onion_required ( ) ;
671
- features. set_payment_secret_required ( ) ;
674
+ pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True , M > {
675
+ let mut found_features = false ;
676
+ for field in self . tagged_fields . iter_mut ( ) {
677
+ if let TaggedField :: Features ( f) = field {
678
+ found_features = true ;
679
+ f. set_variable_length_onion_required ( ) ;
680
+ f. set_payment_secret_required ( ) ;
681
+ }
682
+ }
672
683
self . tagged_fields . push ( TaggedField :: PaymentSecret ( payment_secret) ) ;
673
- self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
684
+ if !found_features {
685
+ let mut features = InvoiceFeatures :: empty ( ) ;
686
+ features. set_variable_length_onion_required ( ) ;
687
+ features. set_payment_secret_required ( ) ;
688
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
689
+ }
690
+ self . set_flags ( )
691
+ }
692
+ }
693
+
694
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: False > {
695
+ /// Sets the payment metadata.
696
+ ///
697
+ /// By default features are set to *optionally* allow the sender to include the payment metadata.
698
+ /// If you wish to require that the sender include the metadata (and fail to parse the invoice if
699
+ /// they don't support payment metadata fields), you need to call
700
+ /// [`InvoiceBuilder::require_payment_metadata`] after this.
701
+ pub fn payment_metadata ( mut self , payment_metadata : Vec < u8 > ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
702
+ self . tagged_fields . push ( TaggedField :: PaymentMetadata ( payment_metadata) ) ;
703
+ let mut found_features = false ;
704
+ for field in self . tagged_fields . iter_mut ( ) {
705
+ if let TaggedField :: Features ( f) = field {
706
+ found_features = true ;
707
+ f. set_payment_metadata_optional ( ) ;
708
+ }
709
+ }
710
+ if !found_features {
711
+ let mut features = InvoiceFeatures :: empty ( ) ;
712
+ features. set_payment_metadata_optional ( ) ;
713
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
714
+ }
674
715
self . set_flags ( )
675
716
}
676
717
}
677
718
678
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True > {
719
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: True > {
720
+ /// Sets the payment secret and relevant features.
721
+ pub fn require_payment_metadata ( mut self ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
722
+ for field in self . tagged_fields . iter_mut ( ) {
723
+ if let TaggedField :: Features ( f) = field {
724
+ f. set_payment_metadata_required ( ) ;
725
+ }
726
+ }
727
+ self
728
+ }
729
+ }
730
+
731
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True , M > {
679
732
/// Sets the `basic_mpp` feature as optional.
680
733
pub fn basic_mpp ( mut self ) -> Self {
681
734
for field in self . tagged_fields . iter_mut ( ) {
@@ -687,7 +740,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T,
687
740
}
688
741
}
689
742
690
- impl InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True > {
743
+ impl < M : tb :: Bool > InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True , M > {
691
744
/// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
692
745
/// and MUST produce a recoverable signature valid for the given hash and if applicable also for
693
746
/// the included payee public key.
0 commit comments