@@ -5,36 +5,36 @@ use bitcoin::consensus::encode::Decodable;
55use bitcoin:: consensus:: Encodable ;
66use url:: Url ;
77
8- use super :: error:: ParseReceiverPubkeyError ;
8+ use super :: error:: { ParseOhttpKeysParamError , ParseReceiverPubkeyParamError } ;
99use crate :: hpke:: HpkePublicKey ;
10- use crate :: OhttpKeys ;
10+ use crate :: ohttp :: OhttpKeys ;
1111
1212/// Parse and set fragment parameters from `&pj=` URI parameter URLs
1313pub ( crate ) trait UrlExt {
14- fn receiver_pubkey ( & self ) -> Result < HpkePublicKey , ParseReceiverPubkeyError > ;
14+ fn receiver_pubkey ( & self ) -> Result < HpkePublicKey , ParseReceiverPubkeyParamError > ;
1515 fn set_receiver_pubkey ( & mut self , exp : HpkePublicKey ) ;
16- fn ohttp ( & self ) -> Option < OhttpKeys > ;
16+ fn ohttp ( & self ) -> Result < OhttpKeys , ParseOhttpKeysParamError > ;
1717 fn set_ohttp ( & mut self , ohttp : OhttpKeys ) ;
1818 fn exp ( & self ) -> Option < std:: time:: SystemTime > ;
1919 fn set_exp ( & mut self , exp : std:: time:: SystemTime ) ;
2020}
2121
2222impl UrlExt for Url {
2323 /// Retrieve the receiver's public key from the URL fragment
24- fn receiver_pubkey ( & self ) -> Result < HpkePublicKey , ParseReceiverPubkeyError > {
24+ fn receiver_pubkey ( & self ) -> Result < HpkePublicKey , ParseReceiverPubkeyParamError > {
2525 let value = get_param ( self , "RK1" , |v| Some ( v. to_owned ( ) ) )
26- . ok_or ( ParseReceiverPubkeyError :: MissingPubkey ) ?;
26+ . ok_or ( ParseReceiverPubkeyParamError :: MissingPubkey ) ?;
2727
2828 let ( hrp, bytes) = crate :: bech32:: nochecksum:: decode ( & value)
29- . map_err ( ParseReceiverPubkeyError :: DecodeBech32 ) ?;
29+ . map_err ( ParseReceiverPubkeyParamError :: DecodeBech32 ) ?;
3030
3131 let rk_hrp: Hrp = Hrp :: parse ( "RK" ) . unwrap ( ) ;
3232 if hrp != rk_hrp {
33- return Err ( ParseReceiverPubkeyError :: InvalidHrp ( hrp) ) ;
33+ return Err ( ParseReceiverPubkeyParamError :: InvalidHrp ( hrp) ) ;
3434 }
3535
3636 HpkePublicKey :: from_compressed_bytes ( & bytes[ ..] )
37- . map_err ( ParseReceiverPubkeyError :: InvalidPubkey )
37+ . map_err ( ParseReceiverPubkeyParamError :: InvalidPubkey )
3838 }
3939
4040 /// Set the receiver's public key in the URL fragment
@@ -50,8 +50,10 @@ impl UrlExt for Url {
5050 }
5151
5252 /// Retrieve the ohttp parameter from the URL fragment
53- fn ohttp ( & self ) -> Option < OhttpKeys > {
54- get_param ( self , "OH1" , |value| OhttpKeys :: from_str ( value) . ok ( ) )
53+ fn ohttp ( & self ) -> Result < OhttpKeys , ParseOhttpKeysParamError > {
54+ let value = get_param ( self , "OH1" , |v| Some ( v. to_owned ( ) ) )
55+ . ok_or ( ParseOhttpKeysParamError :: MissingOhttpKeys ) ?;
56+ OhttpKeys :: from_str ( & value) . map_err ( ParseOhttpKeysParamError :: InvalidOhttpKeys )
5557 }
5658
5759 /// Set the ohttp parameter in the URL fragment
@@ -142,7 +144,24 @@ mod tests {
142144 url. set_ohttp ( ohttp_keys. clone ( ) ) ;
143145
144146 assert_eq ! ( url. fragment( ) , Some ( serialized) ) ;
145- assert_eq ! ( url. ohttp( ) , Some ( ohttp_keys) ) ;
147+ assert_eq ! ( url. ohttp( ) . unwrap( ) , ohttp_keys) ;
148+ }
149+
150+ #[ test]
151+ fn test_errors_when_parsing_ohttp ( ) {
152+ let missing_ohttp_url = Url :: parse ( "https://example.com" ) . unwrap ( ) ;
153+ assert ! ( matches!(
154+ missing_ohttp_url. ohttp( ) ,
155+ Err ( ParseOhttpKeysParamError :: MissingOhttpKeys )
156+ ) ) ;
157+
158+ let invalid_ohttp_url =
159+ Url :: parse ( "https://example.com?pj=https://test-payjoin-url#OH1invalid_bech_32" )
160+ . unwrap ( ) ;
161+ assert ! ( matches!(
162+ invalid_ohttp_url. ohttp( ) ,
163+ Err ( ParseOhttpKeysParamError :: InvalidOhttpKeys ( _) )
164+ ) ) ;
146165 }
147166
148167 #[ test]
@@ -163,7 +182,7 @@ mod tests {
163182 &pjos=0&pj=HTTPS://EXAMPLE.COM/\
164183 %23OH1QYPM5JXYNS754Y4R45QWE336QFX6ZR8DQGVQCULVZTV20TFVEYDMFQC";
165184 let pjuri = Uri :: try_from ( uri) . unwrap ( ) . assume_checked ( ) . check_pj_supported ( ) . unwrap ( ) ;
166- assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_some ( ) ) ;
185+ assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_ok ( ) ) ;
167186 assert_eq ! ( format!( "{}" , pjuri) , uri) ;
168187
169188 let reordered = "bitcoin:12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX?amount=0.01\
@@ -172,7 +191,7 @@ mod tests {
172191 &pjos=0";
173192 let pjuri =
174193 Uri :: try_from ( reordered) . unwrap ( ) . assume_checked ( ) . check_pj_supported ( ) . unwrap ( ) ;
175- assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_some ( ) ) ;
194+ assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_ok ( ) ) ;
176195 assert_eq ! ( format!( "{}" , pjuri) , uri) ;
177196 }
178197}
0 commit comments