From b7a29a5efe60f7c21de556f737e486cfcc852cf3 Mon Sep 17 00:00:00 2001 From: James Wilson Date: Thu, 19 Jan 2023 10:49:00 +0000 Subject: [PATCH] Add ability to set custom metadata etc on OnlineClient (#794) * Add _at and _with methods to OnlineClient to allow for more instantiation options * tweak warnings * move a confusing comment * expose ability to set metadata and such in OnlineClient, but remove most _at methods --- subxt/src/client/mod.rs | 6 +++ subxt/src/client/online_client.rs | 86 +++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/subxt/src/client/mod.rs b/subxt/src/client/mod.rs index 8ec0d3c78c..f056abde9d 100644 --- a/subxt/src/client/mod.rs +++ b/subxt/src/client/mod.rs @@ -23,3 +23,9 @@ pub use online_client::{ Update, UpgradeError, }; + +#[cfg(any( + feature = "jsonrpsee-ws", + all(feature = "jsonrpsee-web", target_arch = "wasm32") +))] +pub use online_client::default_rpc_client; diff --git a/subxt/src/client/online_client.rs b/subxt/src/client/online_client.rs index f5917166d4..6babec8971 100644 --- a/subxt/src/client/online_client.rs +++ b/subxt/src/client/online_client.rs @@ -68,6 +68,18 @@ impl std::fmt::Debug for OnlineClient { } } +/// The default RPC client that's used (based on [`jsonrpsee`]). +#[cfg(any( + feature = "jsonrpsee-ws", + all(feature = "jsonrpsee-web", target_arch = "wasm32") +))] +pub async fn default_rpc_client>(url: U) -> Result { + let client = jsonrpsee_helpers::client(url.as_ref()) + .await + .map_err(|e| crate::error::RpcError::ClientError(Box::new(e)))?; + Ok(client) +} + // The default constructors assume Jsonrpsee. #[cfg(any( feature = "jsonrpsee-ws", @@ -83,9 +95,7 @@ impl OnlineClient { /// Construct a new [`OnlineClient`], providing a URL to connect to. pub async fn from_url(url: impl AsRef) -> Result, Error> { - let client = jsonrpsee_helpers::client(url.as_ref()) - .await - .map_err(|e| crate::error::RpcError::ClientError(Box::new(e)))?; + let client = default_rpc_client(url).await?; OnlineClient::from_rpc_client(Arc::new(client)).await } } @@ -96,8 +106,7 @@ impl OnlineClient { pub async fn from_rpc_client( rpc_client: Arc, ) -> Result, Error> { - let rpc = Rpc::new(rpc_client); - + let rpc = Rpc::::new(rpc_client.clone()); let (genesis_hash, runtime_version, metadata) = future::join3( rpc.genesis_hash(), rpc.runtime_version(None), @@ -105,13 +114,39 @@ impl OnlineClient { ) .await; + OnlineClient::from_rpc_client_with( + genesis_hash?, + runtime_version?, + metadata?, + rpc_client, + ) + } + + /// Construct a new [`OnlineClient`] by providing all of the underlying details needed + /// to make it work. + /// + /// # Warning + /// + /// This is considered the most primitive and also error prone way to + /// instantiate a client; the genesis hash, metadata and runtime version provided will + /// entirely determine which node and blocks this client will be able to interact with, + /// and whether it will be able to successfully do things like submit transactions. + /// + /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate + /// a client. + pub fn from_rpc_client_with( + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: Metadata, + rpc_client: Arc, + ) -> Result, Error> { Ok(OnlineClient { inner: Arc::new(RwLock::new(Inner { - genesis_hash: genesis_hash?, - runtime_version: runtime_version?, - metadata: metadata?, + genesis_hash, + runtime_version, + metadata, })), - rpc, + rpc: Rpc::new(rpc_client), }) } @@ -175,18 +210,51 @@ impl OnlineClient { inner.metadata.clone() } + /// Change the [`Metadata`] used in this client. + /// + /// # Warning + /// + /// Setting custom metadata may leave Subxt unable to work with certain blocks, + /// subscribe to latest blocks or submit valid transactions. + pub fn set_metadata(&self, metadata: Metadata) { + let mut inner = self.inner.write(); + inner.metadata = metadata; + } + /// Return the genesis hash. pub fn genesis_hash(&self) -> T::Hash { let inner = self.inner.read(); inner.genesis_hash } + /// Change the genesis hash used in this client. + /// + /// # Warning + /// + /// Setting a custom genesis hash may leave Subxt unable to + /// submit valid transactions. + pub fn set_genesis_hash(&self, genesis_hash: T::Hash) { + let mut inner = self.inner.write(); + inner.genesis_hash = genesis_hash; + } + /// Return the runtime version. pub fn runtime_version(&self) -> RuntimeVersion { let inner = self.inner.read(); inner.runtime_version.clone() } + /// Change the [`RuntimeVersion`] used in this client. + /// + /// # Warning + /// + /// Setting a custom runtime version may leave Subxt unable to + /// submit valid transactions. + pub fn set_runtime_version(&self, runtime_version: RuntimeVersion) { + let mut inner = self.inner.write(); + inner.runtime_version = runtime_version; + } + /// Return an RPC client to make raw requests with. pub fn rpc(&self) -> &Rpc { &self.rpc