@@ -509,3 +509,83 @@ impl TryFrom<(OfferTlvStream, InvoiceTlvStream)> for InvoiceContents {
509509 } )
510510 }
511511}
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