diff --git a/examples/examples/fetch_remote.rs b/examples/examples/fetch_remote.rs
index 7b41dc1862..8465934f9e 100644
--- a/examples/examples/fetch_remote.rs
+++ b/examples/examples/fetch_remote.rs
@@ -15,11 +15,17 @@
// along with subxt. If not, see .
use subxt::{
+ rpc::SubxtRpcApiClient,
ClientBuilder,
+ Config,
DefaultConfig,
DefaultExtra,
};
+type Hash = ::Hash;
+type Header = ::Header;
+type Extrinsic = ::Header;
+
#[subxt::subxt(runtime_metadata_path = "examples/polkadot_metadata.scale")]
pub mod polkadot {}
@@ -35,11 +41,11 @@ async fn main() -> Result<(), Box> {
let block_number = 1;
- let block_hash = api
- .client
- .rpc()
- .block_hash(Some(block_number.into()))
- .await?;
+ let block_hash = SubxtRpcApiClient::::block_hash(
+ api.client.rpc().inner(),
+ Some(block_number.into()),
+ )
+ .await?;
if let Some(hash) = block_hash {
println!("Block hash for block number {}: {}", block_number, hash);
diff --git a/examples/examples/transfer_subscribe.rs b/examples/examples/transfer_subscribe.rs
index 316d27248b..ae7feb383d 100644
--- a/examples/examples/transfer_subscribe.rs
+++ b/examples/examples/transfer_subscribe.rs
@@ -24,13 +24,20 @@
use sp_keyring::AccountKeyring;
use subxt::{
+ rpc::SubxtRpcApiClient,
ClientBuilder,
+ Config,
DefaultConfig,
DefaultExtra,
+ EventStorageSubscription,
EventSubscription,
PairSigner,
};
+type Hash = ::Hash;
+type Header = ::Header;
+type Extrinsic = ::Header;
+
#[subxt::subxt(runtime_metadata_path = "examples/polkadot_metadata.scale")]
pub mod polkadot {}
@@ -46,7 +53,12 @@ async fn main() -> Result<(), Box> {
.await?
.to_runtime_api::>>();
- let sub = api.client.rpc().subscribe_events().await?;
+ let sub = SubxtRpcApiClient::::subscribe_events(
+ api.client.rpc().inner(),
+ )
+ .await?;
+
+ let sub = EventStorageSubscription::Imported(sub);
let decoder = api.client.events_decoder();
let mut sub = EventSubscription::::new(sub, decoder);
sub.filter_event::();
diff --git a/subxt/src/client.rs b/subxt/src/client.rs
index 8cdd980e4f..bee3d70507 100644
--- a/subxt/src/client.rs
+++ b/subxt/src/client.rs
@@ -41,7 +41,10 @@ use crate::{
Config,
Metadata,
};
-use codec::Decode;
+use codec::{
+ Decode,
+ Encode,
+};
use derivative::Derivative;
use std::sync::Arc;
@@ -91,13 +94,16 @@ impl ClientBuilder {
};
let rpc = Rpc::new(client);
let (metadata_bytes, genesis_hash, runtime_version, properties) = future::join4(
- SubxtRpcApiClient::::metadata(&*rpc),
- SubxtRpcApiClient::::genesis_hash(&*rpc),
+ SubxtRpcApiClient::::metadata(rpc.inner()),
+ SubxtRpcApiClient::::genesis_hash(
+ rpc.inner(),
+ ),
SubxtRpcApiClient::::runtime_version(
- &*rpc, None,
+ rpc.inner(),
+ None,
),
SubxtRpcApiClient::::system_properties(
- &*rpc,
+ rpc.inner(),
),
)
.await;
@@ -238,8 +244,14 @@ where
// Get a hash of the extrinsic (we'll need this later).
let ext_hash = T::Hashing::hash_of(&extrinsic);
+ let bytes = extrinsic.encode().into();
+
// Submit and watch for transaction progress.
- let sub = self.client.rpc().watch_extrinsic(extrinsic).await?;
+ let sub = SubxtRpcApiClient::::watch_extrinsic(
+ self.client.rpc().inner(),
+ bytes,
+ )
+ .await?;
Ok(TransactionProgress::new(sub, self.client, ext_hash))
}
@@ -262,8 +274,18 @@ where
::AccountId: From<::AccountId>,
::Index: Into<::Index>,
{
- let extrinsic = self.create_signed(signer, Default::default()).await?;
- self.client.rpc().submit_extrinsic(extrinsic).await
+ let bytes = self
+ .create_signed(signer, Default::default())
+ .await?
+ .encode()
+ .into();
+
+ SubxtRpcApiClient::::submit_extrinsic(
+ self.client.rpc().inner(),
+ bytes,
+ )
+ .await
+ .map_err(Into::into)
}
/// Creates a signed extrinsic.
diff --git a/subxt/src/config.rs b/subxt/src/config.rs
index 15ed084795..eec63f128e 100644
--- a/subxt/src/config.rs
+++ b/subxt/src/config.rs
@@ -78,7 +78,8 @@ pub trait Config: 'static {
type Signature: Verify + Encode + Send + Sync + 'static;
/// Extrinsic type within blocks.
- // TODO(niklasad1): I have no idea if this ok or not ^^
+ // TODO(niklasad1): I have no idea if this ok or not ^^ => won't work otherwise
+ // because `jsonrpsee` requires `Deserialize + Send + Sync` for the return types.
type Extrinsic: Parameter
+ Extrinsic
+ Debug
diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs
index ede7b83db9..7322f3148f 100644
--- a/subxt/src/rpc.rs
+++ b/subxt/src/rpc.rs
@@ -23,7 +23,6 @@
use std::{
collections::HashMap,
- ops::Deref,
sync::Arc,
};
@@ -32,11 +31,9 @@ use crate::{
subscription::{
EventStorageSubscription,
FinalizedEventStorageSubscription,
- SystemEvents,
},
Config,
};
-use codec::Encode;
use core::marker::PhantomData;
use jsonrpsee::core::RpcResult;
pub use jsonrpsee::{
@@ -205,6 +202,33 @@ pub trait SubxtRpcApi {
/// Returns `true` if a private key could be found.
#[method(name = "author_hasKey")]
async fn has_key(&self, public_key: Bytes, key_type: String) -> RpcResult;
+
+ /// Subscribe to System Events that are imported into blocks.
+ ///
+ /// *WARNING* these may not be included in the finalized chain, use
+ /// `subscribe_finalized_events` to ensure events are finalized.
+ #[subscription(name = "state_subscribeStorage", item = StorageChangeSet)]
+ fn subscribe_events(&self) -> RpcResult<()>;
+
+ /// Subscribe to blocks.
+ #[subscription(name = "chain_subscribeNewHeads", item = Header)]
+ fn subscribe_blocks(&self) -> RpcResult<()>;
+
+ /// Subscribe to finalized blocks.
+ #[subscription(name = "chain_subscribeFinalizedHeads", item = Header)]
+ fn subscribe_finalized_blocks(&self) -> RpcResult<()>;
+
+ /// Create and submit an extrinsic and return a subscription to the events triggered.
+ #[subscription(
+ name = "author_submitAndWatchExtrinsic",
+ unsubscribe_aliases = ["author_unwatchExtrinsic"],
+ item = SubstrateTransactionStatus
+ )]
+ fn watch_extrinsic(&self, xt: Bytes) -> RpcResult<()>;
+
+ /// Create and submit an extrinsic and return corresponding Hash if successful
+ #[method(name = "author_submitExtrinsic")]
+ async fn submit_extrinsic(&self, extrinsic: Bytes) -> RpcResult;
}
/// A number type that can be serialized both as a number or a string that encodes a number in a
@@ -348,14 +372,6 @@ impl Clone for Rpc {
}
}
-impl Deref for Rpc {
- type Target = RpcClient;
-
- fn deref(&self) -> &Self::Target {
- &*self.client
- }
-}
-
impl Rpc {
/// Create a new [`Rpc`]
pub fn new(client: RpcClient) -> Self {
@@ -365,21 +381,9 @@ impl Rpc {
}
}
- /// Subscribe to System Events that are imported into blocks.
- ///
- /// *WARNING* these may not be included in the finalized chain, use
- /// `subscribe_finalized_events` to ensure events are finalized.
- pub async fn subscribe_events(
- &self,
- ) -> Result, BasicError> {
- let keys = Some(vec![StorageKey::from(SystemEvents::new())]);
- let params = rpc_params![keys];
-
- let subscription = self
- .client
- .subscribe("state_subscribeStorage", params, "state_unsubscribeStorage")
- .await?;
- Ok(EventStorageSubscription::Imported(subscription))
+ /// Get a reference to the client make calls.
+ pub fn inner(&self) -> &RpcClient {
+ &*self.client
}
/// Subscribe to finalized events.
@@ -389,72 +393,10 @@ impl Rpc {
Ok(EventStorageSubscription::Finalized(
FinalizedEventStorageSubscription::new(
self.clone(),
- self.subscribe_finalized_blocks().await?,
+ SubxtRpcApiClient::::subscribe_finalized_blocks(&*self.client).await?,
),
))
}
-
- /// Subscribe to blocks.
- pub async fn subscribe_blocks(&self) -> Result, BasicError> {
- let subscription = self
- .client
- .subscribe(
- "chain_subscribeNewHeads",
- rpc_params![],
- "chain_unsubscribeNewHeads",
- )
- .await?;
-
- Ok(subscription)
- }
-
- /// Subscribe to finalized blocks.
- pub async fn subscribe_finalized_blocks(
- &self,
- ) -> Result, BasicError> {
- let subscription = self
- .client
- .subscribe(
- "chain_subscribeFinalizedHeads",
- rpc_params![],
- "chain_unsubscribeFinalizedHeads",
- )
- .await?;
- Ok(subscription)
- }
-
- /// Create and submit an extrinsic and return corresponding Hash if successful
- pub async fn submit_extrinsic(
- &self,
- extrinsic: X,
- ) -> Result {
- let bytes: Bytes = extrinsic.encode().into();
- let params = rpc_params![bytes];
- let xt_hash = self
- .client
- .request("author_submitExtrinsic", params)
- .await?;
- Ok(xt_hash)
- }
-
- /// Create and submit an extrinsic and return a subscription to the events triggered.
- pub async fn watch_extrinsic(
- &self,
- extrinsic: X,
- ) -> Result>, BasicError>
- {
- let bytes: Bytes = extrinsic.encode().into();
- let params = rpc_params![bytes];
- let subscription = self
- .client
- .subscribe(
- "author_submitAndWatchExtrinsic",
- params,
- "author_unwatchExtrinsic",
- )
- .await?;
- Ok(subscription)
- }
}
/// Build WS RPC client from URL