@@ -509,3 +509,83 @@ impl TryFrom<(OfferTlvStream, InvoiceTlvStream)> for InvoiceContents {
509
509
} )
510
510
}
511
511
}
512
+
513
+ #[ cfg( test) ]
514
+ mod tests {
515
+ use super :: { StaticInvoiceBuilder , DEFAULT_RELATIVE_EXPIRY } ;
516
+
517
+ use crate :: blinded_path:: { BlindedHop , BlindedPath , IntroductionNode } ;
518
+ use crate :: ln:: features:: { Bolt12InvoiceFeatures , OfferFeatures } ;
519
+ use crate :: ln:: inbound_payment:: ExpandedKey ;
520
+ use crate :: offers:: invoice:: SIGNATURE_TAG ;
521
+ use crate :: offers:: merkle;
522
+ use crate :: offers:: merkle:: TaggedHash ;
523
+ use crate :: offers:: offer:: { OfferBuilder , Quantity } ;
524
+ use crate :: offers:: test_utils:: * ;
525
+ use crate :: sign:: KeyMaterial ;
526
+ use crate :: util:: ser:: Writeable ;
527
+ use bitcoin:: blockdata:: constants:: ChainHash ;
528
+ use bitcoin:: network:: constants:: Network ;
529
+ use bitcoin:: secp256k1:: Secp256k1 ;
530
+
531
+ #[ test]
532
+ fn builds_invoice_for_offer_with_defaults ( ) {
533
+ let node_id = recipient_pubkey ( ) ;
534
+ let payment_paths = payment_paths ( ) ;
535
+ let now = now ( ) ;
536
+ let expanded_key = ExpandedKey :: new ( & KeyMaterial ( [ 42 ; 32 ] ) ) ;
537
+ let entropy = FixedEntropy { } ;
538
+ let secp_ctx = Secp256k1 :: new ( ) ;
539
+
540
+ let blinded_path = BlindedPath {
541
+ introduction_node : IntroductionNode :: NodeId ( pubkey ( 40 ) ) ,
542
+ blinding_point : pubkey ( 41 ) ,
543
+ blinded_hops : vec ! [
544
+ BlindedHop { blinded_node_id: pubkey( 42 ) , encrypted_payload: vec![ 0 ; 43 ] } ,
545
+ BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![ 0 ; 44 ] } ,
546
+ ] ,
547
+ } ;
548
+
549
+ let offer =
550
+ OfferBuilder :: deriving_signing_pubkey ( node_id, & expanded_key, & entropy, & secp_ctx)
551
+ . path ( blinded_path. clone ( ) )
552
+ . build ( )
553
+ . unwrap ( ) ;
554
+
555
+ let ( _offer_id, keys_opt) = offer. verify ( & expanded_key, & secp_ctx) . unwrap ( ) ;
556
+ let invoice = StaticInvoiceBuilder :: for_offer_using_keys (
557
+ & offer,
558
+ payment_paths. clone ( ) ,
559
+ now,
560
+ keys_opt. unwrap ( ) ,
561
+ )
562
+ . unwrap ( )
563
+ . build_and_sign ( & secp_ctx)
564
+ . unwrap ( ) ;
565
+
566
+ let mut buffer = Vec :: new ( ) ;
567
+ invoice. write ( & mut buffer) . unwrap ( ) ;
568
+
569
+ assert_eq ! ( invoice. bytes, buffer. as_slice( ) ) ;
570
+ assert ! ( invoice. metadata( ) . is_some( ) ) ;
571
+ assert_eq ! ( invoice. amount( ) , None ) ;
572
+ assert_eq ! ( invoice. description( ) , None ) ;
573
+ assert_eq ! ( invoice. offer_features( ) , & OfferFeatures :: empty( ) ) ;
574
+ assert_eq ! ( invoice. absolute_expiry( ) , None ) ;
575
+ assert_eq ! ( invoice. message_paths( ) , & [ blinded_path] ) ;
576
+ assert_eq ! ( invoice. issuer( ) , None ) ;
577
+ assert_eq ! ( invoice. supported_quantity( ) , Quantity :: One ) ;
578
+ assert_ne ! ( invoice. signing_pubkey( ) , recipient_pubkey( ) ) ;
579
+ assert_eq ! ( invoice. chain( ) , ChainHash :: using_genesis_block( Network :: Bitcoin ) ) ;
580
+ assert_eq ! ( invoice. payment_paths( ) , payment_paths. as_slice( ) ) ;
581
+ assert_eq ! ( invoice. created_at( ) , now) ;
582
+ assert_eq ! ( invoice. relative_expiry( ) , DEFAULT_RELATIVE_EXPIRY ) ;
583
+ #[ cfg( feature = "std" ) ]
584
+ assert ! ( !invoice. is_expired( ) ) ;
585
+ assert_eq ! ( invoice. fallbacks( ) , vec![ ] ) ;
586
+ assert_eq ! ( invoice. invoice_features( ) , & Bolt12InvoiceFeatures :: empty( ) ) ;
587
+
588
+ let message = TaggedHash :: from_valid_tlv_stream_bytes ( SIGNATURE_TAG , & invoice. bytes ) ;
589
+ assert ! ( merkle:: verify_signature( & invoice. signature, & message, keys_opt. unwrap( ) . public_key( ) ) . is_ok( ) ) ;
590
+ }
591
+ }
0 commit comments