@@ -163,10 +163,13 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
163
163
/// * `D`: exactly one `Description` or `DescriptionHash`
164
164
/// * `H`: exactly one `PaymentHash`
165
165
/// * `T`: the timestamp is set
166
+ /// * `C`: the CLTV expiry is set
167
+ /// * `S`: the payment secret is set
168
+ /// * `M`: payment metadata is set
166
169
///
167
170
/// (C-not exported) as we likely need to manually select one set of boolean type parameters.
168
171
#[ derive( Eq , PartialEq , Debug , Clone ) ]
169
- pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > {
172
+ pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > {
170
173
currency : Currency ,
171
174
amount : Option < u64 > ,
172
175
si_prefix : Option < SiPrefix > ,
@@ -179,6 +182,7 @@ pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S:
179
182
phantom_t : core:: marker:: PhantomData < T > ,
180
183
phantom_c : core:: marker:: PhantomData < C > ,
181
184
phantom_s : core:: marker:: PhantomData < S > ,
185
+ phantom_m : core:: marker:: PhantomData < M > ,
182
186
}
183
187
184
188
/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
@@ -432,7 +436,7 @@ pub mod constants {
432
436
pub const TAG_FEATURES : u8 = 5 ;
433
437
}
434
438
435
- impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False > {
439
+ impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False , tb :: False > {
436
440
/// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
437
441
/// `InvoiceBuilder::build(self)` becomes available.
438
442
pub fn new ( currrency : Currency ) -> Self {
@@ -449,14 +453,15 @@ impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
449
453
phantom_t : core:: marker:: PhantomData ,
450
454
phantom_c : core:: marker:: PhantomData ,
451
455
phantom_s : core:: marker:: PhantomData ,
456
+ phantom_m : core:: marker:: PhantomData ,
452
457
}
453
458
}
454
459
}
455
460
456
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S > {
461
+ 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 > {
457
462
/// Helper function to set the completeness flags.
458
- 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 > {
459
- InvoiceBuilder :: < DN , HN , TN , CN , SN > {
463
+ 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 > {
464
+ InvoiceBuilder :: < DN , HN , TN , CN , SN , MN > {
460
465
currency : self . currency ,
461
466
amount : self . amount ,
462
467
si_prefix : self . si_prefix ,
@@ -469,6 +474,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
469
474
phantom_t : core:: marker:: PhantomData ,
470
475
phantom_c : core:: marker:: PhantomData ,
471
476
phantom_s : core:: marker:: PhantomData ,
477
+ phantom_m : core:: marker:: PhantomData ,
472
478
}
473
479
}
474
480
@@ -512,7 +518,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
512
518
}
513
519
}
514
520
515
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: True , C , S > {
521
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: True , C , S , M > {
516
522
/// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields.
517
523
pub fn build_raw ( self ) -> Result < RawInvoice , CreationError > {
518
524
@@ -545,9 +551,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
545
551
}
546
552
}
547
553
548
- impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < tb:: False , H , T , C , S > {
554
+ impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < tb:: False , H , T , C , S , M > {
549
555
/// Set the description. This function is only available if no description (hash) was set.
550
- pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
556
+ pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
551
557
match Description :: new ( description) {
552
558
Ok ( d) => self . tagged_fields . push ( TaggedField :: Description ( d) ) ,
553
559
Err ( e) => self . error = Some ( e) ,
@@ -556,24 +562,24 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::Fals
556
562
}
557
563
558
564
/// Set the description hash. This function is only available if no description (hash) was set.
559
- pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
565
+ pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
560
566
self . tagged_fields . push ( TaggedField :: DescriptionHash ( Sha256 ( description_hash) ) ) ;
561
567
self . set_flags ( )
562
568
}
563
569
}
564
570
565
- impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , tb:: False , T , C , S > {
571
+ impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , tb:: False , T , C , S , M > {
566
572
/// Set the payment hash. This function is only available if no payment hash was set.
567
- pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S > {
573
+ pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S , M > {
568
574
self . tagged_fields . push ( TaggedField :: PaymentHash ( Sha256 ( hash) ) ) ;
569
575
self . set_flags ( )
570
576
}
571
577
}
572
578
573
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: False , C , S > {
579
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: False , C , S , M > {
574
580
/// Sets the timestamp to a specific [`SystemTime`].
575
581
#[ cfg( feature = "std" ) ]
576
- pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
582
+ pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
577
583
match PositiveTimestamp :: from_system_time ( time) {
578
584
Ok ( t) => self . timestamp = Some ( t) ,
579
585
Err ( e) => self . error = Some ( e) ,
@@ -583,7 +589,7 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
583
589
}
584
590
585
591
/// Sets the timestamp to a duration since the Unix epoch.
586
- pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
592
+ pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
587
593
match PositiveTimestamp :: from_duration_since_epoch ( time) {
588
594
Ok ( t) => self . timestamp = Some ( t) ,
589
595
Err ( e) => self . error = Some ( e) ,
@@ -594,34 +600,94 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
594
600
595
601
/// Sets the timestamp to the current system time.
596
602
#[ cfg( feature = "std" ) ]
597
- pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
603
+ pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S . M > {
598
604
let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
599
605
self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
600
606
self . set_flags ( )
601
607
}
602
608
}
603
609
604
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , tb:: False , S > {
610
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , tb:: False , S , M > {
605
611
/// Sets `min_final_cltv_expiry`.
606
- pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S > {
612
+ pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S , M > {
607
613
self . tagged_fields . push ( TaggedField :: MinFinalCltvExpiry ( MinFinalCltvExpiry ( min_final_cltv_expiry) ) ) ;
608
614
self . set_flags ( )
609
615
}
610
616
}
611
617
612
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: False > {
618
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , C , tb:: False , M > {
613
619
/// Sets the payment secret and relevant features.
614
- pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True > {
615
- let features = InvoiceFeatures :: empty ( )
616
- . set_variable_length_onion_required ( )
617
- . set_payment_secret_required ( ) ;
620
+ pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True , M > {
621
+ let mut found_features = false ;
622
+ self . tagged_fields = self . tagged_fields
623
+ . drain ( ..)
624
+ . map ( |field| match field {
625
+ TaggedField :: Features ( f) => {
626
+ found_features = true ;
627
+ TaggedField :: Features ( f
628
+ . set_variable_length_onion_required ( )
629
+ . set_payment_secret_required ( ) )
630
+ } ,
631
+ _ => field,
632
+ } )
633
+ . collect ( ) ;
618
634
self . tagged_fields . push ( TaggedField :: PaymentSecret ( payment_secret) ) ;
619
- self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
635
+ if !found_features {
636
+ let features = InvoiceFeatures :: empty ( )
637
+ . set_variable_length_onion_required ( )
638
+ . set_payment_secret_required ( ) ;
639
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
640
+ }
620
641
self . set_flags ( )
621
642
}
622
643
}
623
644
624
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True > {
645
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: False > {
646
+ /// Sets the payment metadata.
647
+ ///
648
+ /// By default features are set to *optionally* allow the sender to include the payment metadata.
649
+ /// If you wish to require that the sender include the metadata (and fail to parse the invoice if
650
+ /// they don't support payment metadata fields), you need to call
651
+ /// [`InvoiceBuilder::require_payment_metadata`] after this.
652
+ pub fn payment_metadata ( mut self , payment_metadata : Vec < u8 > ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
653
+ self . tagged_fields . push ( TaggedField :: PaymentMetadata ( payment_metadata) ) ;
654
+ let mut found_features = false ;
655
+ self . tagged_fields = self . tagged_fields
656
+ . drain ( ..)
657
+ . map ( |field| match field {
658
+ TaggedField :: Features ( f) => {
659
+ found_features = true ;
660
+ TaggedField :: Features ( f. set_payment_metadata_optional ( ) )
661
+ } ,
662
+ _ => field,
663
+ } )
664
+ . collect ( ) ;
665
+ if !found_features {
666
+ let features = InvoiceFeatures :: empty ( )
667
+ . set_payment_metadata_optional ( ) ;
668
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
669
+ }
670
+ self . set_flags ( )
671
+ }
672
+ }
673
+
674
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: True > {
675
+ /// Sets the payment secret and relevant features.
676
+ pub fn require_payment_metadata ( mut self ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
677
+ self . tagged_fields = self . tagged_fields
678
+ . drain ( ..)
679
+ . map ( |field| match field {
680
+ TaggedField :: Features ( f) => {
681
+ TaggedField :: Features ( f. set_payment_metadata_required ( ) )
682
+ } ,
683
+ _ => field,
684
+ } )
685
+ . collect ( ) ;
686
+ self
687
+ }
688
+ }
689
+
690
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True , M > {
625
691
/// Sets the `basic_mpp` feature as optional.
626
692
pub fn basic_mpp ( mut self ) -> Self {
627
693
self . tagged_fields = self . tagged_fields
@@ -635,7 +701,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T,
635
701
}
636
702
}
637
703
638
- impl InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True > {
704
+ impl < M : tb :: Bool > InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True , M > {
639
705
/// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
640
706
/// and MUST produce a recoverable signature valid for the given hash and if applicable also for
641
707
/// the included payee public key.
0 commit comments