add remaining RPCs

This commit is contained in:
Niklas
2022-02-10 17:37:09 +01:00
parent 489650c9c4
commit 5f692acc84
5 changed files with 87 additions and 104 deletions
+11 -5
View File
@@ -15,11 +15,17 @@
// along with subxt. If not, see <http://www.gnu.org/licenses/>.
use subxt::{
rpc::SubxtRpcApiClient,
ClientBuilder,
Config,
DefaultConfig,
DefaultExtra,
};
type Hash = <DefaultConfig as Config>::Hash;
type Header = <DefaultConfig as Config>::Header;
type Extrinsic = <DefaultConfig as Config>::Header;
#[subxt::subxt(runtime_metadata_path = "examples/polkadot_metadata.scale")]
pub mod polkadot {}
@@ -35,11 +41,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let block_number = 1;
let block_hash = api
.client
.rpc()
.block_hash(Some(block_number.into()))
.await?;
let block_hash = SubxtRpcApiClient::<Hash, Header, Extrinsic>::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);
+13 -1
View File
@@ -24,13 +24,20 @@
use sp_keyring::AccountKeyring;
use subxt::{
rpc::SubxtRpcApiClient,
ClientBuilder,
Config,
DefaultConfig,
DefaultExtra,
EventStorageSubscription,
EventSubscription,
PairSigner,
};
type Hash = <DefaultConfig as Config>::Hash;
type Header = <DefaultConfig as Config>::Header;
type Extrinsic = <DefaultConfig as Config>::Header;
#[subxt::subxt(runtime_metadata_path = "examples/polkadot_metadata.scale")]
pub mod polkadot {}
@@ -46,7 +53,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, DefaultExtra<DefaultConfig>>>();
let sub = api.client.rpc().subscribe_events().await?;
let sub = SubxtRpcApiClient::<Hash, Header, Extrinsic>::subscribe_events(
api.client.rpc().inner(),
)
.await?;
let sub = EventStorageSubscription::Imported(sub);
let decoder = api.client.events_decoder();
let mut sub = EventSubscription::<DefaultConfig>::new(sub, decoder);
sub.filter_event::<polkadot::balances::events::Transfer>();
+30 -8
View File
@@ -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::<T::Hash, T::Header, T::Extrinsic>::metadata(&*rpc),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::genesis_hash(&*rpc),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::metadata(rpc.inner()),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::genesis_hash(
rpc.inner(),
),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::runtime_version(
&*rpc, None,
rpc.inner(),
None,
),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::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::<T::Hash, T::Header, T::Extrinsic>::watch_extrinsic(
self.client.rpc().inner(),
bytes,
)
.await?;
Ok(TransactionProgress::new(sub, self.client, ext_hash))
}
@@ -262,8 +274,18 @@ where
<A as AccountData>::AccountId: From<<T as Config>::AccountId>,
<A as AccountData>::Index: Into<<T as Config>::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::<T::Hash, T::Header, T::Extrinsic>::submit_extrinsic(
self.client.rpc().inner(),
bytes,
)
.await
.map_err(Into::into)
}
/// Creates a signed extrinsic.
+2 -1
View File
@@ -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
+31 -89
View File
@@ -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<Hash, Header, Xt: Serialize> {
/// 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<bool>;
/// 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<Hash>)]
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<Hash, Hash>
)]
fn watch_extrinsic<X: Encode>(&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<Hash>;
}
/// 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<T: Config> Clone for Rpc<T> {
}
}
impl<T: Config> Deref for Rpc<T> {
type Target = RpcClient;
fn deref(&self) -> &Self::Target {
&*self.client
}
}
impl<T: Config> Rpc<T> {
/// Create a new [`Rpc`]
pub fn new(client: RpcClient) -> Self {
@@ -365,21 +381,9 @@ impl<T: Config> Rpc<T> {
}
}
/// 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<EventStorageSubscription<T>, 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<T: Config> Rpc<T> {
Ok(EventStorageSubscription::Finalized(
FinalizedEventStorageSubscription::new(
self.clone(),
self.subscribe_finalized_blocks().await?,
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::subscribe_finalized_blocks(&*self.client).await?,
),
))
}
/// Subscribe to blocks.
pub async fn subscribe_blocks(&self) -> Result<Subscription<T::Header>, 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<Subscription<T::Header>, 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<X: Encode>(
&self,
extrinsic: X,
) -> Result<T::Hash, BasicError> {
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<X: Encode>(
&self,
extrinsic: X,
) -> Result<Subscription<SubstrateTransactionStatus<T::Hash, T::Hash>>, 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