@@ -175,10 +175,13 @@ pub fn check_platform() {
175
175
/// * `D`: exactly one `Description` or `DescriptionHash`
176
176
/// * `H`: exactly one `PaymentHash`
177
177
/// * `T`: the timestamp is set
178
+ /// * `C`: XXX
179
+ /// * `S`: the payment secret is set
180
+ /// * `M`: payment metadata is set
178
181
///
179
182
/// (C-not exported) as we likely need to manually select one set of boolean type parameters.
180
183
#[ derive( Eq , PartialEq , Debug , Clone ) ]
181
- pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > {
184
+ pub struct InvoiceBuilder < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > {
182
185
currency : Currency ,
183
186
amount : Option < u64 > ,
184
187
si_prefix : Option < SiPrefix > ,
@@ -191,6 +194,7 @@ pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S:
191
194
phantom_t : std:: marker:: PhantomData < T > ,
192
195
phantom_c : std:: marker:: PhantomData < C > ,
193
196
phantom_s : std:: marker:: PhantomData < S > ,
197
+ phantom_m : std:: marker:: PhantomData < M > ,
194
198
}
195
199
196
200
/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
@@ -449,7 +453,7 @@ pub mod constants {
449
453
pub const TAG_FEATURES : u8 = 5 ;
450
454
}
451
455
452
- impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False > {
456
+ impl InvoiceBuilder < tb:: False , tb:: False , tb:: False , tb:: False , tb:: False , tb :: False > {
453
457
/// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
454
458
/// `InvoiceBuilder::build(self)` becomes available.
455
459
pub fn new ( currrency : Currency ) -> Self {
@@ -466,14 +470,15 @@ impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
466
470
phantom_t : std:: marker:: PhantomData ,
467
471
phantom_c : std:: marker:: PhantomData ,
468
472
phantom_s : std:: marker:: PhantomData ,
473
+ phantom_m : std:: marker:: PhantomData ,
469
474
}
470
475
}
471
476
}
472
477
473
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S > {
478
+ 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 > {
474
479
/// Helper function to set the completeness flags.
475
- 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 > {
476
- InvoiceBuilder :: < DN , HN , TN , CN , SN > {
480
+ 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 > {
481
+ InvoiceBuilder :: < DN , HN , TN , CN , SN , MN > {
477
482
currency : self . currency ,
478
483
amount : self . amount ,
479
484
si_prefix : self . si_prefix ,
@@ -486,6 +491,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
486
491
phantom_t : std:: marker:: PhantomData ,
487
492
phantom_c : std:: marker:: PhantomData ,
488
493
phantom_s : std:: marker:: PhantomData ,
494
+ phantom_m : std:: marker:: PhantomData ,
489
495
}
490
496
}
491
497
@@ -532,7 +538,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
532
538
}
533
539
}
534
540
535
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: True , C , S > {
541
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: True , C , S , M > {
536
542
/// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields.
537
543
pub fn build_raw ( self ) -> Result < RawInvoice , CreationError > {
538
544
@@ -565,9 +571,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
565
571
}
566
572
}
567
573
568
- impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < tb:: False , H , T , C , S > {
574
+ impl < H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < tb:: False , H , T , C , S , M > {
569
575
/// Set the description. This function is only available if no description (hash) was set.
570
- pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
576
+ pub fn description ( mut self , description : String ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
571
577
match Description :: new ( description) {
572
578
Ok ( d) => self . tagged_fields . push ( TaggedField :: Description ( d) ) ,
573
579
Err ( e) => self . error = Some ( e) ,
@@ -576,23 +582,23 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::Fals
576
582
}
577
583
578
584
/// Set the description hash. This function is only available if no description (hash) was set.
579
- pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S > {
585
+ pub fn description_hash ( mut self , description_hash : sha256:: Hash ) -> InvoiceBuilder < tb:: True , H , T , C , S , M > {
580
586
self . tagged_fields . push ( TaggedField :: DescriptionHash ( Sha256 ( description_hash) ) ) ;
581
587
self . set_flags ( )
582
588
}
583
589
}
584
590
585
- impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , tb:: False , T , C , S > {
591
+ impl < D : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , tb:: False , T , C , S , M > {
586
592
/// Set the payment hash. This function is only available if no payment hash was set.
587
- pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S > {
593
+ pub fn payment_hash ( mut self , hash : sha256:: Hash ) -> InvoiceBuilder < D , tb:: True , T , C , S , M > {
588
594
self . tagged_fields . push ( TaggedField :: PaymentHash ( Sha256 ( hash) ) ) ;
589
595
self . set_flags ( )
590
596
}
591
597
}
592
598
593
- impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , tb:: False , C , S > {
599
+ impl < D : tb:: Bool , H : tb:: Bool , C : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , tb:: False , C , S , M > {
594
600
/// Sets the timestamp.
595
- pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
601
+ pub fn timestamp ( mut self , time : SystemTime ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
596
602
match PositiveTimestamp :: from_system_time ( time) {
597
603
Ok ( t) => self . timestamp = Some ( t) ,
598
604
Err ( e) => self . error = Some ( e) ,
@@ -602,34 +608,94 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
602
608
}
603
609
604
610
/// Sets the timestamp to the current UNIX timestamp.
605
- pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
611
+ pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S , M > {
606
612
let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
607
613
self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
608
614
self . set_flags ( )
609
615
}
610
616
}
611
617
612
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , tb:: False , S > {
618
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , S : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , tb:: False , S , M > {
613
619
/// Sets `min_final_cltv_expiry`.
614
- pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S > {
620
+ pub fn min_final_cltv_expiry ( mut self , min_final_cltv_expiry : u64 ) -> InvoiceBuilder < D , H , T , tb:: True , S , M > {
615
621
self . tagged_fields . push ( TaggedField :: MinFinalCltvExpiry ( MinFinalCltvExpiry ( min_final_cltv_expiry) ) ) ;
616
622
self . set_flags ( )
617
623
}
618
624
}
619
625
620
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: False > {
626
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb :: Bool > InvoiceBuilder < D , H , T , C , tb:: False , M > {
621
627
/// Sets the payment secret and relevant features.
622
- pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True > {
623
- let features = InvoiceFeatures :: empty ( )
624
- . set_variable_length_onion_required ( )
625
- . set_payment_secret_required ( ) ;
628
+ pub fn payment_secret ( mut self , payment_secret : PaymentSecret ) -> InvoiceBuilder < D , H , T , C , tb:: True , M > {
629
+ let mut found_features = false ;
630
+ self . tagged_fields = self . tagged_fields
631
+ . drain ( ..)
632
+ . map ( |field| match field {
633
+ TaggedField :: Features ( f) => {
634
+ found_features = true ;
635
+ TaggedField :: Features ( f
636
+ . set_variable_length_onion_required ( )
637
+ . set_payment_secret_required ( ) )
638
+ } ,
639
+ _ => field,
640
+ } )
641
+ . collect ( ) ;
626
642
self . tagged_fields . push ( TaggedField :: PaymentSecret ( payment_secret) ) ;
627
- self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
643
+ if !found_features {
644
+ let features = InvoiceFeatures :: empty ( )
645
+ . set_variable_length_onion_required ( )
646
+ . set_payment_secret_required ( ) ;
647
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
648
+ }
628
649
self . set_flags ( )
629
650
}
630
651
}
631
652
632
- impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True > {
653
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: False > {
654
+ /// Sets the payment metadata.
655
+ ///
656
+ /// By default features are set to *optionally* allow the sender to include the payment metadata.
657
+ /// If you wish to require that the sender include the metadata (and fail to parse the invoice if
658
+ /// they don't support payment metadata fields), you need to call
659
+ /// [`InvoiceBuilder::require_payment_metadata`] after this.
660
+ pub fn payment_metadata ( mut self , payment_metadata : Vec < u8 > ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
661
+ self . tagged_fields . push ( TaggedField :: PaymentMetadata ( payment_metadata) ) ;
662
+ let mut found_features = false ;
663
+ self . tagged_fields = self . tagged_fields
664
+ . drain ( ..)
665
+ . map ( |field| match field {
666
+ TaggedField :: Features ( f) => {
667
+ found_features = true ;
668
+ TaggedField :: Features ( f. set_payment_metadata_optional ( ) )
669
+ } ,
670
+ _ => field,
671
+ } )
672
+ . collect ( ) ;
673
+ if !found_features {
674
+ let features = InvoiceFeatures :: empty ( )
675
+ . set_payment_metadata_optional ( ) ;
676
+ self . tagged_fields . push ( TaggedField :: Features ( features) ) ;
677
+ }
678
+ self . set_flags ( )
679
+ }
680
+ }
681
+
682
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , S : tb:: Bool > InvoiceBuilder < D , H , T , C , S , tb:: True > {
683
+ /// Sets the payment secret and relevant features.
684
+ pub fn require_payment_metadata ( mut self ) -> InvoiceBuilder < D , H , T , C , S , tb:: True > {
685
+ self . tagged_fields = self . tagged_fields
686
+ . drain ( ..)
687
+ . map ( |field| match field {
688
+ TaggedField :: Features ( f) => {
689
+ TaggedField :: Features ( f. set_payment_metadata_required ( ) )
690
+ } ,
691
+ _ => field,
692
+ } )
693
+ . collect ( ) ;
694
+ self
695
+ }
696
+ }
697
+
698
+ impl < D : tb:: Bool , H : tb:: Bool , T : tb:: Bool , C : tb:: Bool , M : tb:: Bool > InvoiceBuilder < D , H , T , C , tb:: True , M > {
633
699
/// Sets the `basic_mpp` feature as optional.
634
700
pub fn basic_mpp ( mut self ) -> Self {
635
701
self . tagged_fields = self . tagged_fields
@@ -643,7 +709,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T,
643
709
}
644
710
}
645
711
646
- impl InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True > {
712
+ impl < M : tb :: Bool > InvoiceBuilder < tb:: True , tb:: True , tb:: True , tb:: True , tb:: True , M > {
647
713
/// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
648
714
/// and MUST produce a recoverable signature valid for the given hash and if applicable also for
649
715
/// the included payee public key.
0 commit comments