diff --git a/client/src/client.rs b/client/src/client.rs index 39402e92..8a67f84b 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1366,6 +1366,32 @@ impl Client { client, }) } + + /// Creates a client to a bitcoind JSON-RPC server with custom timeout configuration. + pub async fn with_timeouts( + url: &str, + auth: Auth, + timeout: Option, + connect_timeout: Option, + ) -> Result { + let mut parsed_url = Url::parse(url)?; + + if let (Some(user), pass) = auth.get_user_pass()? { + parsed_url + .set_username(&user) + .map_err(|_| Error::Auth("Failed to set username".to_string()))?; + parsed_url + .set_password(pass.as_deref()) + .map_err(|_| Error::Auth("Failed to set password".to_string()))?; + } + + let transport = ReqwestTransport::with_timeouts(parsed_url, timeout, connect_timeout); + let client = JsonRpcClient::with_transport(transport); + + Ok(Self { + client, + }) + } } #[async_trait] diff --git a/client/src/transport.rs b/client/src/transport.rs index 81b5ab3c..ad3818bc 100644 --- a/client/src/transport.rs +++ b/client/src/transport.rs @@ -1,7 +1,10 @@ use async_trait::async_trait; use jsonrpc_async::Transport; +use std::time::Duration; use url::Url; +const DEFAULT_TIMEOUT: Duration = Duration::from_secs(15); + pub struct ReqwestTransport { client: reqwest::Client, url: Url, @@ -9,8 +12,30 @@ pub struct ReqwestTransport { impl ReqwestTransport { pub fn new(url: Url) -> Self { + let client = reqwest::Client::builder() + .timeout(DEFAULT_TIMEOUT) + .build() + .expect("Failed to build reqwest client"); + + Self { + client, + url, + } + } + + pub fn with_timeouts( + url: Url, + timeout: Option, + connect_timeout: Option, + ) -> Self { + let builder = reqwest::Client::builder() + .timeout(timeout.unwrap_or(DEFAULT_TIMEOUT)) + .connect_timeout(connect_timeout.unwrap_or(DEFAULT_TIMEOUT)); + + let client = builder.build().expect("Failed to build reqwest client"); + Self { - client: reqwest::Client::new(), + client, url, } }