@@ -1478,7 +1478,7 @@ impl Bolt11Invoice {
14781478 unreachable ! ( "ensured by constructor" ) ;
14791479 }
14801480
1481- /// Get the payee's public key if one was included in the invoice
1481+ /// Get the payee's public key if one was explicitly included in the invoice's `n` field.
14821482 pub fn payee_pub_key ( & self ) -> Option < & PublicKey > {
14831483 self . signed_invoice . payee_pub_key ( ) . map ( |x| & x. 0 )
14841484 }
@@ -1498,22 +1498,21 @@ impl Bolt11Invoice {
14981498 self . signed_invoice . features ( )
14991499 }
15001500
1501- /// Get the invoice 's payee public key.
1501+ /// Recover the payee 's public key from the invoice signature .
15021502 ///
1503- /// This uses the explicitly included payee public key, if present, otherwise it recovers the
1504- /// payee public key from the signature. Prefer [`Self::get_payee_pub_key`] for clarity.
1505- pub fn recover_payee_pub_key ( & self ) -> PublicKey {
1506- self . get_payee_pub_key ( )
1503+ /// This attempts signature recovery regardless of whether a payee public key was explicitly
1504+ /// included in the invoice's `n` field. Recovery can fail for a valid invoice with an included
1505+ /// `n` field, so [`Self::get_payee_pub_key`] should be used to obtain the invoice's payee key.
1506+ pub fn recover_payee_pub_key ( & self ) -> Option < PublicKey > {
1507+ self . signed_invoice . recover_payee_pub_key ( ) . ok ( ) . map ( |p| p. 0 )
15071508 }
15081509
15091510 /// Get the invoice's payee public key, preferring an explicitly included payee public key and
15101511 /// falling back to recovering the key from the signature.
15111512 pub fn get_payee_pub_key ( & self ) -> PublicKey {
15121513 match self . payee_pub_key ( ) {
15131514 Some ( pk) => * pk,
1514- None => {
1515- self . signed_invoice . recover_payee_pub_key ( ) . expect ( "was checked by constructor" ) . 0
1516- } ,
1515+ None => self . recover_payee_pub_key ( ) . expect ( "was checked by constructor" ) ,
15171516 }
15181517 }
15191518
@@ -2063,7 +2062,7 @@ mod test {
20632062 }
20642063
20652064 #[ test]
2066- fn recover_payee_pub_key_uses_included_payee_pub_key ( ) {
2065+ fn recover_payee_pub_key_returns_signature_recovery_result ( ) {
20672066 use crate :: {
20682067 Bolt11Invoice , Bolt11InvoiceSignature , Currency , InvoiceBuilder , PaymentHash ,
20692068 PaymentSecret , SignedRawBolt11Invoice ,
@@ -2076,17 +2075,28 @@ mod test {
20762075 let private_key = SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ;
20772076 let public_key = PublicKey :: from_secret_key ( & secp_ctx, & private_key) ;
20782077
2079- let invoice = InvoiceBuilder :: new ( Currency :: Bitcoin )
2078+ let invoice_without_payee_pub_key = InvoiceBuilder :: new ( Currency :: Bitcoin )
20802079 . description ( "Test" . to_string ( ) )
20812080 . payment_hash ( PaymentHash ( [ 0 ; 32 ] ) )
20822081 . payment_secret ( PaymentSecret ( [ 21 ; 32 ] ) )
2082+ . min_final_cltv_expiry_delta ( 144 )
2083+ . duration_since_epoch ( Duration :: from_secs ( 1234567 ) )
2084+ . build_signed ( |hash| secp_ctx. sign_ecdsa_recoverable ( hash, & private_key) )
2085+ . unwrap ( ) ;
2086+ assert_eq ! ( invoice_without_payee_pub_key. recover_payee_pub_key( ) , Some ( public_key) ) ;
2087+ assert_eq ! ( invoice_without_payee_pub_key. get_payee_pub_key( ) , public_key) ;
2088+
2089+ let invoice_with_payee_pub_key = InvoiceBuilder :: new ( Currency :: Bitcoin )
2090+ . description ( "Test" . to_string ( ) )
2091+ . payment_hash ( PaymentHash ( [ 1 ; 32 ] ) )
2092+ . payment_secret ( PaymentSecret ( [ 21 ; 32 ] ) )
20832093 . payee_pub_key ( public_key)
20842094 . min_final_cltv_expiry_delta ( 144 )
20852095 . duration_since_epoch ( Duration :: from_secs ( 1234567 ) )
20862096 . build_signed ( |hash| secp_ctx. sign_ecdsa_recoverable ( hash, & private_key) )
20872097 . unwrap ( ) ;
20882098
2089- let signed_raw = invoice . into_signed_raw ( ) ;
2099+ let signed_raw = invoice_with_payee_pub_key . into_signed_raw ( ) ;
20902100 let ( raw_invoice, hash, signature) = signed_raw. into_parts ( ) ;
20912101 let ( _orig_rid, sig_bytes) = signature. 0 . serialize_compact ( ) ;
20922102 let bad_rid = RecoveryId :: from_i32 ( 2 ) . unwrap ( ) ;
@@ -2099,7 +2109,7 @@ mod test {
20992109 let bad_invoice = Bolt11Invoice :: from_signed ( bad_signed_raw) . unwrap ( ) ;
21002110
21012111 assert_eq ! ( bad_invoice. payee_pub_key( ) , Some ( & public_key) ) ;
2102- assert_eq ! ( bad_invoice. recover_payee_pub_key( ) , public_key ) ;
2112+ assert_eq ! ( bad_invoice. recover_payee_pub_key( ) , None ) ;
21032113 assert_eq ! ( bad_invoice. get_payee_pub_key( ) , public_key) ;
21042114 }
21052115
0 commit comments