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