-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add read and write jsonrpc transport
- Loading branch information
clint
committed
Sep 27, 2023
1 parent
759d1b3
commit 61c905b
Showing
5 changed files
with
154 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use starknet_providers::{ | ||
jsonrpc::{HttpTransport, JsonRpcClient, RwTransport}, | ||
Provider, | ||
}; | ||
use url::Url; | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
let read = HttpTransport::new( | ||
Url::parse("https://starknet-goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161") | ||
.unwrap(), | ||
); | ||
let write = HttpTransport::new( | ||
Url::parse("https://starknet-goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161") | ||
.unwrap(), | ||
); | ||
let rw = RwTransport::new(read, write); | ||
let rpc_client = JsonRpcClient::new(rw); | ||
let block_number = rpc_client.block_number().await.unwrap(); | ||
dbg!(block_number); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
//! A [JsonRpcTransport] implementation that serves as a wrapper around two different [JsonRpcTransport] | ||
//! and uses a dedicated client for read and the other for write operations | ||
use std::{error::Error as StdError, fmt::Debug}; | ||
|
||
use async_trait::async_trait; | ||
use serde::{de::DeserializeOwned, Serialize}; | ||
use thiserror::Error; | ||
|
||
use crate::jsonrpc::{ | ||
JsonRpcMethod, | ||
JsonRpcMethod::{AddDeclareTransaction, AddDeployAccountTransaction, AddInvokeTransaction}, | ||
JsonRpcResponse, JsonRpcTransport, | ||
}; | ||
|
||
/// A client containing two clients. | ||
/// | ||
/// One is used for _read_ operations | ||
/// One is used for _write_ operations that consume gas `["starknet_addInvokeTransaction", | ||
/// "starknet_addDeclareTransaction", "starknet_addDeployAccountTransaction"]` | ||
/// | ||
/// **Note**: if the method is unknown this client falls back to the _read_ client | ||
// # Example | ||
#[derive(Debug, Clone)] | ||
pub struct RwTransport<Read, Write> { | ||
/// client used to read | ||
r: Read, | ||
/// client used to write | ||
w: Write, | ||
} | ||
|
||
impl<Read, Write> RwTransport<Read, Write> { | ||
/// Creates a new client using two different clients | ||
/// | ||
/// # Example | ||
/// | ||
/// ```no_run | ||
/// # use url::Url; | ||
/// async fn t(){ | ||
/// use starknet_providers::jsonrpc::{JsonRpcClient,HttpTransport,RwTransport}; | ||
/// let read = HttpTransport::new(Url::parse("http://localhost:5050").unwrap()); | ||
/// let write = HttpTransport::new(Url::parse("http://localhost:5050").unwrap()); | ||
/// let rw = RwTransport::new(read, write); | ||
/// let client = JsonRpcClient::new(rw); | ||
/// # } | ||
/// ``` | ||
pub fn new(r: Read, w: Write) -> RwTransport<Read, Write> { | ||
Self { r, w } | ||
} | ||
|
||
/// Returns the client used for read operations | ||
pub fn read_client(&self) -> &Read { | ||
&self.r | ||
} | ||
|
||
/// Returns the client used for write operations | ||
pub fn write_client(&self) -> &Write { | ||
&self.w | ||
} | ||
|
||
/// Returns a new `RwClient` with transposed clients | ||
pub fn transpose(self) -> RwTransport<Write, Read> { | ||
let RwTransport { r, w } = self; | ||
RwTransport::new(w, r) | ||
} | ||
|
||
/// Consumes the client and returns the underlying clients | ||
pub fn split(self) -> (Read, Write) { | ||
let RwTransport { r, w } = self; | ||
(r, w) | ||
} | ||
} | ||
|
||
#[derive(Error, Debug)] | ||
/// Error thrown when using either read or write client | ||
pub enum RwTransportError<Read, Write> | ||
where | ||
Read: JsonRpcTransport, | ||
<Read as JsonRpcTransport>::Error: StdError + Sync + Send, | ||
Write: JsonRpcTransport, | ||
<Write as JsonRpcTransport>::Error: StdError + Sync + Send, | ||
{ | ||
/// Thrown if the _read_ request failed | ||
#[error(transparent)] | ||
Read(Read::Error), | ||
#[error(transparent)] | ||
/// Thrown if the _write_ request failed | ||
Write(Write::Error), | ||
} | ||
|
||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] | ||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)] | ||
impl<Read, Write> JsonRpcTransport for RwTransport<Read, Write> | ||
where | ||
Read: JsonRpcTransport + Debug + Send + Sync, | ||
Write: JsonRpcTransport + Debug + Send + Sync, | ||
{ | ||
type Error = RwTransportError<Read, Write>; | ||
|
||
/// Sends a POST request with the provided method and the params serialized as JSON | ||
/// over HTTP | ||
async fn send_request<P, R>( | ||
&self, | ||
method: JsonRpcMethod, | ||
params: P, | ||
) -> Result<JsonRpcResponse<R>, Self::Error> | ||
where | ||
P: Serialize + Send + Sync, | ||
R: DeserializeOwned + Send, | ||
{ | ||
match method { | ||
AddInvokeTransaction | AddDeclareTransaction | AddDeployAccountTransaction => self | ||
.w | ||
.send_request(method, params) | ||
.await | ||
.map_err(RwTransportError::Write), | ||
_ => self | ||
.r | ||
.send_request(method, params) | ||
.await | ||
.map_err(RwTransportError::Read), | ||
} | ||
} | ||
} |