@@ -5,15 +5,15 @@ use bitcoin::consensus::encode::Decodable;
55use bitcoin:: consensus:: Encodable ;
66use url:: Url ;
77
8- use super :: error:: ParseReceiverPubkeyError ;
8+ use super :: error:: { ParseOhttpKeysParamError , ParseReceiverPubkeyError } ;
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 {
1414 fn receiver_pubkey ( & self ) -> Result < HpkePublicKey , ParseReceiverPubkeyError > ;
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 ) ;
@@ -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,16 @@ 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!( missing_ohttp_url. ohttp( ) , Err ( ParseOhttpKeysParamError :: MissingOhttpKeys ) ) ) ;
154+
155+ let invalid_ohttp_url = Url :: parse ( "https://example.com?pj=https://test-payjoin-url#OH1invalid_bech_32" ) . unwrap ( ) ;
156+ assert ! ( matches!( invalid_ohttp_url. ohttp( ) , Err ( ParseOhttpKeysParamError :: InvalidOhttpKeys ( _) ) ) ) ;
146157 }
147158
148159 #[ test]
@@ -163,7 +174,7 @@ mod tests {
163174 &pjos=0&pj=HTTPS://EXAMPLE.COM/\
164175 %23OH1QYPM5JXYNS754Y4R45QWE336QFX6ZR8DQGVQCULVZTV20TFVEYDMFQC";
165176 let pjuri = Uri :: try_from ( uri) . unwrap ( ) . assume_checked ( ) . check_pj_supported ( ) . unwrap ( ) ;
166- assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_some ( ) ) ;
177+ assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_ok ( ) ) ;
167178 assert_eq ! ( format!( "{}" , pjuri) , uri) ;
168179
169180 let reordered = "bitcoin:12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX?amount=0.01\
@@ -172,7 +183,7 @@ mod tests {
172183 &pjos=0";
173184 let pjuri =
174185 Uri :: try_from ( reordered) . unwrap ( ) . assume_checked ( ) . check_pj_supported ( ) . unwrap ( ) ;
175- assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_some ( ) ) ;
186+ assert ! ( pjuri. extras. endpoint( ) . ohttp( ) . is_ok ( ) ) ;
176187 assert_eq ! ( format!( "{}" , pjuri) , uri) ;
177188 }
178189}
0 commit comments