@@ -1568,10 +1568,12 @@ impl Readable for InvoiceRequestFields {
15681568mod tests {
15691569 use super :: {
15701570 ExperimentalInvoiceRequestTlvStreamRef , InvoiceRequest , InvoiceRequestFields ,
1571- InvoiceRequestTlvStreamRef , UnsignedInvoiceRequest , EXPERIMENTAL_INVOICE_REQUEST_TYPES ,
1572- INVOICE_REQUEST_TYPES , PAYER_NOTE_LIMIT , SIGNATURE_TAG ,
1571+ InvoiceRequestTlvStreamRef , InvoiceRequestVerifiedFromOffer , UnsignedInvoiceRequest ,
1572+ EXPERIMENTAL_INVOICE_REQUEST_TYPES , INVOICE_REQUEST_TYPES , PAYER_NOTE_LIMIT , SIGNATURE_TAG ,
15731573 } ;
15741574
1575+ use crate :: blinded_path:: message:: BlindedMessagePath ;
1576+ use crate :: blinded_path:: BlindedHop ;
15751577 use crate :: ln:: channelmanager:: PaymentId ;
15761578 use crate :: ln:: inbound_payment:: ExpandedKey ;
15771579 use crate :: ln:: msgs:: { DecodeError , MAX_VALUE_MSAT } ;
@@ -1593,6 +1595,7 @@ mod tests {
15931595 use crate :: types:: features:: { InvoiceRequestFeatures , OfferFeatures } ;
15941596 use crate :: types:: string:: { PrintableString , UntrustedString } ;
15951597 use crate :: util:: ser:: { BigSize , Readable , Writeable } ;
1598+ use crate :: util:: test_utils:: TestCurrencyConversion ;
15961599 use bitcoin:: constants:: ChainHash ;
15971600 use bitcoin:: network:: Network ;
15981601 use bitcoin:: secp256k1:: { self , Keypair , Secp256k1 , SecretKey } ;
@@ -2346,6 +2349,127 @@ mod tests {
23462349 }
23472350 }
23482351
2352+ #[ test]
2353+ fn responds_to_invoice_request_using_currency_conversion ( ) {
2354+ let expanded_key = ExpandedKey :: new ( [ 42 ; 32 ] ) ;
2355+ let entropy = FixedEntropy { } ;
2356+ let nonce = Nonce :: from_entropy_source ( & entropy) ;
2357+ let secp_ctx = Secp256k1 :: new ( ) ;
2358+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
2359+ let converter = TestCurrencyConversion { } ;
2360+
2361+ let invoice = OfferBuilder :: new ( recipient_pubkey ( ) , & converter)
2362+ . amount ( Amount :: Currency {
2363+ iso4217_code : CurrencyCode :: new ( * b"USD" ) . unwrap ( ) ,
2364+ amount : 10 ,
2365+ } )
2366+ . build ( )
2367+ . unwrap ( )
2368+ . request_invoice ( & expanded_key, nonce, & secp_ctx, payment_id)
2369+ . unwrap ( )
2370+ . build_and_sign ( )
2371+ . unwrap ( )
2372+ . respond_with_no_std ( & converter, payment_paths ( ) , payment_hash ( ) , now ( ) )
2373+ . unwrap ( )
2374+ . build ( )
2375+ . unwrap ( )
2376+ . sign ( recipient_sign)
2377+ . unwrap ( ) ;
2378+
2379+ assert_eq ! ( invoice. amount_msats( ) , 10_000 ) ;
2380+ assert_eq ! (
2381+ invoice. verify_using_payer_data( payment_id, nonce, & expanded_key, & secp_ctx) ,
2382+ Ok ( payment_id) ,
2383+ ) ;
2384+ }
2385+
2386+ #[ test]
2387+ fn fails_responding_to_invoice_request_with_insufficient_amount_for_currency_offer ( ) {
2388+ let expanded_key = ExpandedKey :: new ( [ 42 ; 32 ] ) ;
2389+ let entropy = FixedEntropy { } ;
2390+ let nonce = Nonce :: from_entropy_source ( & entropy) ;
2391+ let secp_ctx = Secp256k1 :: new ( ) ;
2392+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
2393+ let converter = TestCurrencyConversion { } ;
2394+
2395+ match OfferBuilder :: new ( recipient_pubkey ( ) , & converter)
2396+ . amount ( Amount :: Currency {
2397+ iso4217_code : CurrencyCode :: new ( * b"USD" ) . unwrap ( ) ,
2398+ amount : 10 ,
2399+ } )
2400+ . build ( )
2401+ . unwrap ( )
2402+ . request_invoice ( & expanded_key, nonce, & secp_ctx, payment_id)
2403+ . unwrap ( )
2404+ . amount_msats ( 9_999 )
2405+ . unwrap ( )
2406+ . build_and_sign ( )
2407+ . unwrap ( )
2408+ . respond_with_no_std ( & converter, payment_paths ( ) , payment_hash ( ) , now ( ) )
2409+ {
2410+ Ok ( _) => panic ! ( "expected error" ) ,
2411+ Err ( e) => assert_eq ! ( e, Bolt12SemanticError :: InsufficientAmount ) ,
2412+ }
2413+ }
2414+
2415+ #[ test]
2416+ fn responds_to_invoice_request_using_derived_keys_with_currency_conversion ( ) {
2417+ let expanded_key = ExpandedKey :: new ( [ 42 ; 32 ] ) ;
2418+ let entropy = FixedEntropy { } ;
2419+ let nonce = Nonce :: from_entropy_source ( & entropy) ;
2420+ let secp_ctx = Secp256k1 :: new ( ) ;
2421+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
2422+ let converter = TestCurrencyConversion { } ;
2423+ let blinded_path = BlindedMessagePath :: from_blinded_path (
2424+ pubkey ( 40 ) ,
2425+ pubkey ( 41 ) ,
2426+ vec ! [
2427+ BlindedHop { blinded_node_id: pubkey( 42 ) , encrypted_payload: vec![ 0 ; 43 ] } ,
2428+ BlindedHop { blinded_node_id: recipient_pubkey( ) , encrypted_payload: vec![ 0 ; 44 ] } ,
2429+ ] ,
2430+ ) ;
2431+
2432+ let offer = OfferBuilder :: deriving_signing_pubkey (
2433+ recipient_pubkey ( ) ,
2434+ & expanded_key,
2435+ nonce,
2436+ & converter,
2437+ & secp_ctx,
2438+ )
2439+ . amount ( Amount :: Currency { iso4217_code : CurrencyCode :: new ( * b"USD" ) . unwrap ( ) , amount : 10 } )
2440+ . path ( blinded_path)
2441+ . build ( )
2442+ . unwrap ( ) ;
2443+
2444+ let invoice_request = offer
2445+ . request_invoice ( & expanded_key, nonce, & secp_ctx, payment_id)
2446+ . unwrap ( )
2447+ . build_and_sign ( )
2448+ . unwrap ( ) ;
2449+ let verified_invoice_request =
2450+ invoice_request. verify_using_recipient_data ( nonce, & expanded_key, & secp_ctx) . unwrap ( ) ;
2451+
2452+ let invoice = match verified_invoice_request {
2453+ InvoiceRequestVerifiedFromOffer :: DerivedKeys ( request) => request
2454+ . respond_using_derived_keys_no_std (
2455+ & converter,
2456+ payment_paths ( ) ,
2457+ payment_hash ( ) ,
2458+ now ( ) ,
2459+ )
2460+ . unwrap ( )
2461+ . build_and_sign ( & secp_ctx)
2462+ . unwrap ( ) ,
2463+ InvoiceRequestVerifiedFromOffer :: ExplicitKeys ( _) => panic ! ( "expected derived keys" ) ,
2464+ } ;
2465+
2466+ assert_eq ! ( invoice. amount_msats( ) , 10_000 ) ;
2467+ assert_eq ! (
2468+ invoice. verify_using_payer_data( payment_id, nonce, & expanded_key, & secp_ctx) ,
2469+ Ok ( payment_id) ,
2470+ ) ;
2471+ }
2472+
23492473 #[ test]
23502474 fn parses_invoice_request_with_metadata ( ) {
23512475 let expanded_key = ExpandedKey :: new ( [ 42 ; 32 ] ) ;
0 commit comments