@@ -218,10 +218,13 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18;
218
218
/// * `D`: exactly one [`TaggedField::Description`] or [`TaggedField::DescriptionHash`]
219
219
/// * `H`: exactly one [`TaggedField::PaymentHash`]
220
220
/// * `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
221
224
///
222
225
/// This is not exported to bindings users as we likely need to manually select one set of boolean type parameters.
223
226
#[ 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 > {
225
228
currency : Currency ,
226
229
amount : Option < u64 > ,
227
230
si_prefix : Option < SiPrefix > ,
@@ -234,6 +237,7 @@ pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S:
234
237
phantom_t : core:: marker:: PhantomData < T > ,
235
238
phantom_c : core:: marker:: PhantomData < C > ,
236
239
phantom_s : core:: marker:: PhantomData < S > ,
240
+ phantom_m : core:: marker:: PhantomData < M > ,
237
241
}
238
242
239
243
/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
@@ -488,7 +492,7 @@ pub mod constants {
488
492
pub const TAG_FEATURES : u8 = 5 ;
489
493
}
490
494
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 > {
492
496
/// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
493
497
/// `InvoiceBuilder::build(self)` becomes available.
494
498
pub fn new ( currrency : Currency ) -> Self {
@@ -505,14 +509,15 @@ impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
505
509
phantom_t : core:: marker:: PhantomData ,
506
510
phantom_c : core:: marker:: PhantomData ,
507
511
phantom_s : core:: marker:: PhantomData ,
512
+ phantom_m : core:: marker:: PhantomData ,
508
513
}
509
514
}
510
515
}
511
516
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 > {
513
518
/// 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 > {
516
521
currency : self . currency ,
517
522
amount : self . amount ,
518
523
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
525
530
phantom_t : core:: marker:: PhantomData ,
526
531
phantom_c : core:: marker:: PhantomData ,
527
532
phantom_s : core:: marker:: PhantomData ,
533
+ phantom_m : core:: marker:: PhantomData ,
528
534
}
529
535
}
530
536
@@ -569,7 +575,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
569
575
}
570
576
}
571
577
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 > {
573
579
/// Builds a [`RawInvoice`] if no [`CreationError`] occurred while construction any of the
574
580
/// fields.
575
581
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
603
609
}
604
610
}
605
611
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 > {
607
613
/// 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 > {
609
615
match Description :: new ( description) {
610
616
Ok ( d) => self . tagged_fields . push ( TaggedField :: Description ( d) ) ,
611
617
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
614
620
}
615
621
616
622
/// 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 > {
618
624
self . tagged_fields . push ( TaggedField :: DescriptionHash ( Sha256 ( description_hash) ) ) ;
619
625
self . set_flags ( )
620
626
}
621
627
622
628
/// 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 > {
624
630
match description {
625
631
InvoiceDescription :: Direct ( desc) => {
626
632
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
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) ,
@@ -654,7 +660,7 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
654
660
655
661
/// Sets the timestamp to a duration since the Unix epoch, dropping the subsecond part (which
656
662
/// 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 > {
658
664
match PositiveTimestamp :: from_duration_since_epoch ( time) {
659
665
Ok ( t) => self . timestamp = Some ( t) ,
660
666
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
665
671
666
672
/// Sets the timestamp to the current system time.
667
673
#[ 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 > {
669
675
let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
670
676
self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
671
677
self . set_flags ( )
672
678
}
673
679
}
674
680
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 > {
676
682
/// 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 > {
678
684
self . tagged_fields . push ( TaggedField :: MinFinalCltvExpiryDelta ( MinFinalCltvExpiryDelta ( min_final_cltv_expiry_delta) ) ) ;
679
685
self . set_flags ( )
680
686
}
681
687
}
682
688
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 > {
684
690
/// 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
+ }
689
700
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
+ }
691
707
self . set_flags ( )
692
708
}
693
709
}
694
710
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 > {
696
750
/// Sets the `basic_mpp` feature as optional.
697
751
pub fn basic_mpp ( mut self ) -> Self {
698
752
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,
704
758
}
705
759
}
706
760
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 > {
708
762
/// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
709
763
/// and MUST produce a recoverable signature valid for the given hash and if applicable also for
710
764
/// the included payee public key.
0 commit comments