diff --git a/ethers-providers/src/ws.rs b/ethers-providers/src/ws.rs deleted file mode 100644 index 3163f7e8..00000000 --- a/ethers-providers/src/ws.rs +++ /dev/null @@ -1,204 +0,0 @@ -use crate::{provider::ProviderError, JsonRpcClient}; - -use async_trait::async_trait; -use reqwest::{Client, Error as ReqwestError}; -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use std::{ - fmt, - str::FromStr, - sync::atomic::{AtomicU64, Ordering}, -}; -use thiserror::Error; -use url::Url; - -/// A low-level JSON-RPC Client over HTTP. -/// -/// # Example -/// -/// ```no_run -/// use ethers::{types::U64, providers::{JsonRpcClient, Http}}; -/// use std::str::FromStr; -/// -/// # async fn foo() -> Result<(), Box> { -/// let provider = Http::from_str("http://localhost:8545")?; -/// let block_number: U64 = provider.request("eth_blockNumber", None::<()>).await?; -/// # Ok(()) -/// # } -/// ``` -#[derive(Debug)] -pub struct Provider { - id: AtomicU64, - client: Client, - url: Url, -} - -#[derive(Error, Debug)] -/// Error thrown when sending an HTTP request -pub enum WsError { - /// Thrown if the request failed - #[error(transparent)] - ReqwestError(#[from] ReqwestError), - #[error(transparent)] - /// Thrown if the response could not be parsed - JsonRpcError(#[from] errors::JsonRpcError), -} - -impl From for ProviderError { - fn from(src: ClientError) -> Self { - ProviderError::JsonRpcClientError(Box::new(src)) - } -} - -#[async_trait] -impl JsonRpcClient for Provider { - type Error = ClientError; - - /// Sends a POST request with the provided method and the params serialized as JSON - /// over HTTP - async fn request Deserialize<'a>>( - &self, - method: &str, - params: T, - ) -> Result { - let next_id = self.id.load(Ordering::SeqCst) + 1; - self.id.store(next_id, Ordering::SeqCst); - - let payload = Request::new(next_id, method, params); - - let res = self - .client - .post(self.url.as_ref()) - .json(&payload) - .send() - .await?; - let res = res.json::>().await?; - - Ok(res.data.into_result()?) - } -} - -impl Provider { - /// Initializes a new HTTP Client - /// - /// # Example - /// - /// ``` - /// use ethers::providers::Http; - /// use url::Url; - /// - /// let url = Url::parse("http://localhost:8545").unwrap(); - /// let provider = Http::new(url); - /// ``` - pub fn new(url: impl Into) -> Self { - Self { - id: AtomicU64::new(0), - client: Client::new(), - url: url.into(), - } - } -} - -impl FromStr for Provider { - type Err = url::ParseError; - - fn from_str(src: &str) -> Result { - let url = Url::parse(src)?; - Ok(Provider::new(url)) - } -} - -impl Clone for Provider { - fn clone(&self) -> Self { - Self { - id: AtomicU64::new(0), - client: self.client.clone(), - url: self.url.clone(), - } - } -} - -// leak private type w/o exposing it -mod errors { - use super::*; - - #[derive(Serialize, Deserialize, Debug, Clone, Error)] - /// A JSON-RPC 2.0 error - pub struct JsonRpcError { - /// The error code - pub code: i64, - /// The error message - pub message: String, - /// Additional data - pub data: Option, - } - - impl fmt::Display for JsonRpcError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "(code: {}, message: {}, data: {:?})", - self.code, self.message, self.data - ) - } - } -} - -#[derive(Serialize, Deserialize, Debug)] -/// A JSON-RPC request -struct Request<'a, T> { - id: u64, - jsonrpc: &'a str, - method: &'a str, - params: T, -} - -impl<'a, T> Request<'a, T> { - /// Creates a new JSON RPC request - fn new(id: u64, method: &'a str, params: T) -> Self { - Self { - id, - jsonrpc: "2.0", - method, - params, - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -struct Response { - id: u64, - jsonrpc: String, - #[serde(flatten)] - data: ResponseData, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] -enum ResponseData { - Error { error: errors::JsonRpcError }, - Success { result: R }, -} - -impl ResponseData { - /// Consume response and return value - fn into_result(self) -> Result { - match self { - ResponseData::Success { result } => Ok(result), - ResponseData::Error { error } => Err(error), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn response() { - let response: Response = - serde_json::from_str(r#"{"jsonrpc": "2.0", "result": 19, "id": 1}"#).unwrap(); - assert_eq!(response.id, 1); - assert_eq!(response.data.into_result().unwrap(), 19); - } -}