mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 15:11:03 +00:00
introduce jsonrpsee proc macros API
This commit is contained in:
+1
-1
@@ -20,7 +20,7 @@ chameleon = "0.1.0"
|
||||
scale-info = { version = "1.0.0", features = ["bit-vec"] }
|
||||
futures = "0.3.13"
|
||||
hex = "0.4.3"
|
||||
jsonrpsee = { version = "0.8.0", features = ["async-client", "client-ws-transport"] }
|
||||
jsonrpsee = { version = "0.8.0", features = ["macros", "async-client", "client-ws-transport"] }
|
||||
log = "0.4.14"
|
||||
num-traits = { version = "0.2.14", default-features = false }
|
||||
serde = { version = "1.0.124", features = ["derive"] }
|
||||
|
||||
+14
-6
@@ -31,6 +31,7 @@ use crate::{
|
||||
Rpc,
|
||||
RpcClient,
|
||||
RuntimeVersion,
|
||||
SubxtRpcApiClient,
|
||||
SystemProperties,
|
||||
},
|
||||
storage::StorageClient,
|
||||
@@ -89,14 +90,21 @@ impl ClientBuilder {
|
||||
crate::rpc::build_ws_client(url).await?
|
||||
};
|
||||
let rpc = Rpc::new(client);
|
||||
let (metadata, genesis_hash, runtime_version, properties) = future::join4(
|
||||
rpc.metadata(),
|
||||
rpc.genesis_hash(),
|
||||
rpc.runtime_version(None),
|
||||
rpc.system_properties(),
|
||||
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>::runtime_version(
|
||||
&*rpc, None,
|
||||
),
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::system_properties(
|
||||
&*rpc,
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let metadata = metadata?;
|
||||
let metadata_bytes = metadata_bytes?;
|
||||
let meta: frame_metadata::RuntimeMetadataPrefixed =
|
||||
Decode::decode(&mut &metadata_bytes[..])?;
|
||||
let metadata: Metadata = meta.try_into()?;
|
||||
|
||||
let events_decoder = EventsDecoder::new(metadata.clone());
|
||||
|
||||
|
||||
+7
-1
@@ -78,7 +78,13 @@ pub trait Config: 'static {
|
||||
type Signature: Verify + Encode + Send + Sync + 'static;
|
||||
|
||||
/// Extrinsic type within blocks.
|
||||
type Extrinsic: Parameter + Extrinsic + Debug + MaybeSerializeDeserialize;
|
||||
// TODO(niklasad1): I have no idea if this ok or not ^^
|
||||
type Extrinsic: Parameter
|
||||
+ Extrinsic
|
||||
+ Debug
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Send
|
||||
+ Sync;
|
||||
}
|
||||
|
||||
/// Parameter trait copied from `substrate::frame_support`
|
||||
|
||||
+139
-225
@@ -23,29 +23,22 @@
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ops::Deref,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::BasicError,
|
||||
storage::StorageKeyPrefix,
|
||||
subscription::{
|
||||
EventStorageSubscription,
|
||||
FinalizedEventStorageSubscription,
|
||||
SystemEvents,
|
||||
},
|
||||
Config,
|
||||
Metadata,
|
||||
};
|
||||
use codec::{
|
||||
Decode,
|
||||
Encode,
|
||||
};
|
||||
use core::{
|
||||
convert::TryInto,
|
||||
marker::PhantomData,
|
||||
};
|
||||
use frame_metadata::RuntimeMetadataPrefixed;
|
||||
use codec::Encode;
|
||||
use core::marker::PhantomData;
|
||||
use jsonrpsee::core::RpcResult;
|
||||
pub use jsonrpsee::{
|
||||
client_transport::ws::{
|
||||
InvalidUri,
|
||||
@@ -67,6 +60,7 @@ pub use jsonrpsee::{
|
||||
Error as RpcError,
|
||||
JsonValue,
|
||||
},
|
||||
proc_macros::rpc,
|
||||
rpc_params,
|
||||
};
|
||||
use serde::{
|
||||
@@ -87,6 +81,132 @@ use sp_runtime::generic::{
|
||||
SignedBlock,
|
||||
};
|
||||
|
||||
/// subxt RPC API.
|
||||
#[rpc(client)]
|
||||
pub trait SubxtRpcApi<Hash, Header, Xt: Serialize> {
|
||||
/// Fetch a storage key
|
||||
#[method(name = "state_getStorage")]
|
||||
async fn storage(
|
||||
&self,
|
||||
key: &StorageKey,
|
||||
hash: Option<Hash>,
|
||||
) -> RpcResult<Option<StorageData>>;
|
||||
|
||||
/// Returns the keys with prefix with pagination support.
|
||||
/// Up to `count` keys will be returned.
|
||||
/// If `start_key` is passed, return next keys in storage in lexicographic order.
|
||||
#[method(name = "state_getKeysPaged")]
|
||||
async fn storage_keys_paged(
|
||||
&self,
|
||||
prefix: Option<StorageKey>,
|
||||
count: u32,
|
||||
start_key: Option<StorageKey>,
|
||||
hash: Option<Hash>,
|
||||
) -> RpcResult<Vec<StorageKey>>;
|
||||
|
||||
/// Query historical storage entries
|
||||
#[method(name = "state_queryStorage")]
|
||||
async fn query_storage(
|
||||
&self,
|
||||
keys: Vec<StorageKey>,
|
||||
from: Hash,
|
||||
to: Option<Hash>,
|
||||
) -> RpcResult<Vec<StorageChangeSet<Hash>>>;
|
||||
|
||||
/// Query historical storage entries
|
||||
#[method(name = "state_queryStorageAt")]
|
||||
async fn query_storage_at(
|
||||
&self,
|
||||
keys: &[StorageKey],
|
||||
at: Option<Hash>,
|
||||
) -> RpcResult<Vec<StorageChangeSet<Hash>>>;
|
||||
|
||||
/// Fetch the genesis hash
|
||||
#[method(name = "chain_getBlockHash")]
|
||||
async fn genesis_hash(&self) -> RpcResult<Hash>;
|
||||
|
||||
/// Fetch the metadata as bytes.
|
||||
#[method(name = "state_getMetadata")]
|
||||
async fn metadata(&self) -> RpcResult<sp_core::Bytes>;
|
||||
|
||||
/// Fetch system properties
|
||||
#[method(name = "system_properties")]
|
||||
async fn system_properties(&self) -> RpcResult<SystemProperties>;
|
||||
|
||||
/// Fetch system chain
|
||||
#[method(name = "system_chain")]
|
||||
async fn system_chain(&self) -> RpcResult<String>;
|
||||
|
||||
/// Fetch system name
|
||||
#[method(name = "system_name")]
|
||||
async fn system_name(&self) -> RpcResult<String>;
|
||||
|
||||
/// Fetch system version
|
||||
#[method(name = "system_version")]
|
||||
async fn system_version(&self) -> RpcResult<String>;
|
||||
|
||||
/// Fetch the runtime version
|
||||
#[method(name = "state_getRuntimeVersion")]
|
||||
async fn runtime_version(&self, at: Option<Hash>) -> RpcResult<RuntimeVersion>;
|
||||
|
||||
/// Get a header
|
||||
#[method(name = "state_getRuntimeVersion")]
|
||||
async fn header(&self, hash: Option<Hash>) -> RpcResult<Option<Header>>;
|
||||
|
||||
/// Get a block hash, returns hash of latest block by default
|
||||
#[method(name = "chain_getBlockHash")]
|
||||
async fn block_hash(
|
||||
&self,
|
||||
block_number: Option<BlockNumber>,
|
||||
) -> RpcResult<Option<Hash>>;
|
||||
|
||||
/// Get a block hash of the latest finalized block
|
||||
#[method(name = "chain_getFinalizedHead")]
|
||||
async fn finalized_head(&self) -> RpcResult<Hash>;
|
||||
|
||||
/// Get proof of storage entries at a specific block's state.
|
||||
#[method(name = "state_getReadProof")]
|
||||
async fn read_proof(
|
||||
&self,
|
||||
keys: Vec<StorageKey>,
|
||||
hash: Option<Hash>,
|
||||
) -> RpcResult<ReadProof<Hash>>;
|
||||
|
||||
/// Get a Block
|
||||
#[method(name = "chain_getBlock")]
|
||||
async fn block(
|
||||
&self,
|
||||
hash: Option<Hash>,
|
||||
) -> RpcResult<Option<SignedBlock<Block<Header, Xt>>>>;
|
||||
|
||||
/// Insert a key into the keystore.
|
||||
#[method(name = "author_insertKey")]
|
||||
async fn insert_key(
|
||||
&self,
|
||||
key_type: String,
|
||||
suri: String,
|
||||
public: Bytes,
|
||||
) -> RpcResult<()>;
|
||||
|
||||
/// Generate new session keys and returns the corresponding public keys.
|
||||
#[method(name = "author_rotateKeys")]
|
||||
async fn rotate_keys(&self) -> RpcResult<Bytes>;
|
||||
|
||||
/// Checks if the keystore has private keys for the given session public keys.
|
||||
///
|
||||
/// `session_keys` is the SCALE encoded session keys object from the runtime.
|
||||
///
|
||||
/// Returns `true` iff all private keys could be found.
|
||||
#[method(name = "author_hasSessionKeys")]
|
||||
async fn has_session_keys(&self, session_keys: Bytes) -> RpcResult<bool>;
|
||||
|
||||
/// Checks if the keystore has private keys for the given public key and key type.
|
||||
///
|
||||
/// 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>;
|
||||
}
|
||||
|
||||
/// A number type that can be serialized both as a number or a string that encodes a number in a
|
||||
/// string.
|
||||
///
|
||||
@@ -228,6 +348,14 @@ 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 {
|
||||
@@ -237,175 +365,6 @@ impl<T: Config> Rpc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch a storage key
|
||||
pub async fn storage(
|
||||
&self,
|
||||
key: &StorageKey,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<Option<StorageData>, BasicError> {
|
||||
let params = rpc_params![key, hash];
|
||||
let data = self.client.request("state_getStorage", params).await?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/// Returns the keys with prefix with pagination support.
|
||||
/// Up to `count` keys will be returned.
|
||||
/// If `start_key` is passed, return next keys in storage in lexicographic order.
|
||||
pub async fn storage_keys_paged(
|
||||
&self,
|
||||
prefix: Option<StorageKeyPrefix>,
|
||||
count: u32,
|
||||
start_key: Option<StorageKey>,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<Vec<StorageKey>, BasicError> {
|
||||
let prefix = prefix.map(|p| p.to_storage_key());
|
||||
let params = rpc_params![prefix, count, start_key, hash];
|
||||
let data = self.client.request("state_getKeysPaged", params).await?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/// Query historical storage entries
|
||||
pub async fn query_storage(
|
||||
&self,
|
||||
keys: Vec<StorageKey>,
|
||||
from: T::Hash,
|
||||
to: Option<T::Hash>,
|
||||
) -> Result<Vec<StorageChangeSet<T::Hash>>, BasicError> {
|
||||
let params = rpc_params![keys, from, to];
|
||||
self.client
|
||||
.request("state_queryStorage", params)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Query historical storage entries
|
||||
pub async fn query_storage_at(
|
||||
&self,
|
||||
keys: &[StorageKey],
|
||||
at: Option<T::Hash>,
|
||||
) -> Result<Vec<StorageChangeSet<T::Hash>>, BasicError> {
|
||||
let params = rpc_params![keys, at];
|
||||
self.client
|
||||
.request("state_queryStorageAt", params)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Fetch the genesis hash
|
||||
pub async fn genesis_hash(&self) -> Result<T::Hash, BasicError> {
|
||||
let block_zero = Some(ListOrValue::Value(NumberOrHex::Number(0)));
|
||||
let params = rpc_params![block_zero];
|
||||
let list_or_value: ListOrValue<Option<T::Hash>> =
|
||||
self.client.request("chain_getBlockHash", params).await?;
|
||||
match list_or_value {
|
||||
ListOrValue::Value(genesis_hash) => {
|
||||
genesis_hash.ok_or_else(|| "Genesis hash not found".into())
|
||||
}
|
||||
ListOrValue::List(_) => Err("Expected a Value, got a List".into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch the metadata
|
||||
pub async fn metadata(&self) -> Result<Metadata, BasicError> {
|
||||
let bytes: Bytes = self
|
||||
.client
|
||||
.request("state_getMetadata", rpc_params![])
|
||||
.await?;
|
||||
let meta: RuntimeMetadataPrefixed = Decode::decode(&mut &bytes[..])?;
|
||||
let metadata: Metadata = meta.try_into()?;
|
||||
Ok(metadata)
|
||||
}
|
||||
|
||||
/// Fetch system properties
|
||||
pub async fn system_properties(&self) -> Result<SystemProperties, BasicError> {
|
||||
Ok(self
|
||||
.client
|
||||
.request("system_properties", rpc_params![])
|
||||
.await?)
|
||||
}
|
||||
|
||||
/// Fetch system chain
|
||||
pub async fn system_chain(&self) -> Result<String, BasicError> {
|
||||
Ok(self.client.request("system_chain", rpc_params![]).await?)
|
||||
}
|
||||
|
||||
/// Fetch system name
|
||||
pub async fn system_name(&self) -> Result<String, BasicError> {
|
||||
Ok(self.client.request("system_name", rpc_params![]).await?)
|
||||
}
|
||||
|
||||
/// Fetch system version
|
||||
pub async fn system_version(&self) -> Result<String, BasicError> {
|
||||
Ok(self.client.request("system_version", rpc_params![]).await?)
|
||||
}
|
||||
|
||||
/// Get a header
|
||||
pub async fn header(
|
||||
&self,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<Option<T::Header>, BasicError> {
|
||||
let params = rpc_params![hash];
|
||||
let header = self.client.request("chain_getHeader", params).await?;
|
||||
Ok(header)
|
||||
}
|
||||
|
||||
/// Get a block hash, returns hash of latest block by default
|
||||
pub async fn block_hash(
|
||||
&self,
|
||||
block_number: Option<BlockNumber>,
|
||||
) -> Result<Option<T::Hash>, BasicError> {
|
||||
let block_number = block_number.map(ListOrValue::Value);
|
||||
let params = rpc_params![block_number];
|
||||
let list_or_value = self.client.request("chain_getBlockHash", params).await?;
|
||||
match list_or_value {
|
||||
ListOrValue::Value(hash) => Ok(hash),
|
||||
ListOrValue::List(_) => Err("Expected a Value, got a List".into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a block hash of the latest finalized block
|
||||
pub async fn finalized_head(&self) -> Result<T::Hash, BasicError> {
|
||||
let hash = self
|
||||
.client
|
||||
.request("chain_getFinalizedHead", rpc_params![])
|
||||
.await?;
|
||||
Ok(hash)
|
||||
}
|
||||
|
||||
/// Get a Block
|
||||
pub async fn block(
|
||||
&self,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<Option<ChainBlock<T>>, BasicError> {
|
||||
let params = rpc_params![hash];
|
||||
let block = self.client.request("chain_getBlock", params).await?;
|
||||
Ok(block)
|
||||
}
|
||||
|
||||
/// Get proof of storage entries at a specific block's state.
|
||||
pub async fn read_proof(
|
||||
&self,
|
||||
keys: Vec<StorageKey>,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<ReadProof<T::Hash>, BasicError> {
|
||||
let params = rpc_params![keys, hash];
|
||||
let proof = self.client.request("state_getReadProof", params).await?;
|
||||
Ok(proof)
|
||||
}
|
||||
|
||||
/// Fetch the runtime version
|
||||
pub async fn runtime_version(
|
||||
&self,
|
||||
at: Option<T::Hash>,
|
||||
) -> Result<RuntimeVersion, BasicError> {
|
||||
let params = rpc_params![at];
|
||||
let version = self
|
||||
.client
|
||||
.request("state_getRuntimeVersion", params)
|
||||
.await?;
|
||||
Ok(version)
|
||||
}
|
||||
|
||||
/// Subscribe to System Events that are imported into blocks.
|
||||
///
|
||||
/// *WARNING* these may not be included in the finalized chain, use
|
||||
@@ -496,51 +455,6 @@ impl<T: Config> Rpc<T> {
|
||||
.await?;
|
||||
Ok(subscription)
|
||||
}
|
||||
|
||||
/// Insert a key into the keystore.
|
||||
pub async fn insert_key(
|
||||
&self,
|
||||
key_type: String,
|
||||
suri: String,
|
||||
public: Bytes,
|
||||
) -> Result<(), BasicError> {
|
||||
let params = rpc_params![key_type, suri, public];
|
||||
self.client.request("author_insertKey", params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Generate new session keys and returns the corresponding public keys.
|
||||
pub async fn rotate_keys(&self) -> Result<Bytes, BasicError> {
|
||||
Ok(self
|
||||
.client
|
||||
.request("author_rotateKeys", rpc_params![])
|
||||
.await?)
|
||||
}
|
||||
|
||||
/// Checks if the keystore has private keys for the given session public keys.
|
||||
///
|
||||
/// `session_keys` is the SCALE encoded session keys object from the runtime.
|
||||
///
|
||||
/// Returns `true` iff all private keys could be found.
|
||||
pub async fn has_session_keys(
|
||||
&self,
|
||||
session_keys: Bytes,
|
||||
) -> Result<bool, BasicError> {
|
||||
let params = rpc_params![session_keys];
|
||||
Ok(self.client.request("author_hasSessionKeys", params).await?)
|
||||
}
|
||||
|
||||
/// Checks if the keystore has private keys for the given public key and key type.
|
||||
///
|
||||
/// Returns `true` if a private key could be found.
|
||||
pub async fn has_key(
|
||||
&self,
|
||||
public_key: Bytes,
|
||||
key_type: String,
|
||||
) -> Result<bool, BasicError> {
|
||||
let params = rpc_params![public_key, key_type];
|
||||
Ok(self.client.request("author_hasKey", params).await?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Build WS RPC client from URL
|
||||
|
||||
+48
-16
@@ -35,7 +35,10 @@ use crate::{
|
||||
Metadata,
|
||||
MetadataError,
|
||||
},
|
||||
rpc::Rpc,
|
||||
rpc::{
|
||||
Rpc,
|
||||
SubxtRpcApiClient,
|
||||
},
|
||||
Config,
|
||||
StorageHasher,
|
||||
};
|
||||
@@ -164,7 +167,14 @@ impl<'a, T: Config> StorageClient<'a, T> {
|
||||
key: StorageKey,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<Option<V>, BasicError> {
|
||||
if let Some(data) = self.rpc.storage(&key, hash).await? {
|
||||
if let Some(data) =
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage(
|
||||
&*self.rpc.client,
|
||||
&key,
|
||||
hash,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
Ok(Some(Decode::decode(&mut &data.0[..])?))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -177,7 +187,13 @@ impl<'a, T: Config> StorageClient<'a, T> {
|
||||
key: StorageKey,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<Option<StorageData>, BasicError> {
|
||||
self.rpc.storage(&key, hash).await
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage(
|
||||
&*self.rpc.client,
|
||||
&key,
|
||||
hash,
|
||||
)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Fetch a StorageKey with an optional block hash.
|
||||
@@ -215,7 +231,14 @@ impl<'a, T: Config> StorageClient<'a, T> {
|
||||
from: T::Hash,
|
||||
to: Option<T::Hash>,
|
||||
) -> Result<Vec<StorageChangeSet<T::Hash>>, BasicError> {
|
||||
self.rpc.query_storage(keys, from, to).await
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::query_storage(
|
||||
&*self.rpc.client,
|
||||
keys,
|
||||
from,
|
||||
to,
|
||||
)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Fetch up to `count` keys for a storage map in lexicographic order.
|
||||
@@ -227,10 +250,15 @@ impl<'a, T: Config> StorageClient<'a, T> {
|
||||
start_key: Option<StorageKey>,
|
||||
hash: Option<T::Hash>,
|
||||
) -> Result<Vec<StorageKey>, BasicError> {
|
||||
let prefix = StorageKeyPrefix::new::<F>();
|
||||
let keys = self
|
||||
.rpc
|
||||
.storage_keys_paged(Some(prefix), count, start_key, hash)
|
||||
let prefix = StorageKeyPrefix::new::<F>().to_storage_key();
|
||||
let keys =
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage_keys_paged(
|
||||
&*self.rpc.client,
|
||||
Some(prefix),
|
||||
count,
|
||||
start_key,
|
||||
hash,
|
||||
)
|
||||
.await?;
|
||||
Ok(keys)
|
||||
}
|
||||
@@ -243,10 +271,12 @@ impl<'a, T: Config> StorageClient<'a, T> {
|
||||
let hash = if let Some(hash) = hash {
|
||||
hash
|
||||
} else {
|
||||
self.rpc
|
||||
.block_hash(None)
|
||||
.await?
|
||||
.expect("didn't pass a block number; qed")
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::block_hash(
|
||||
&*self.rpc.client,
|
||||
None,
|
||||
)
|
||||
.await?
|
||||
.expect("didn't pass a block number; qed")
|
||||
};
|
||||
Ok(KeyIter {
|
||||
client: self.clone(),
|
||||
@@ -287,10 +317,12 @@ impl<'a, T: Config, F: StorageEntry> KeyIter<'a, T, F> {
|
||||
|
||||
self.start_key = keys.last().cloned();
|
||||
|
||||
let change_sets = self
|
||||
.client
|
||||
.rpc
|
||||
.query_storage_at(&keys, Some(self.hash))
|
||||
let change_sets =
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::query_storage_at(
|
||||
&*self.client.rpc.client,
|
||||
&keys,
|
||||
Some(self.hash),
|
||||
)
|
||||
.await?;
|
||||
for change_set in change_sets {
|
||||
for (k, v) in change_set.changes {
|
||||
|
||||
@@ -20,7 +20,10 @@ use crate::{
|
||||
EventsDecoder,
|
||||
RawEvent,
|
||||
},
|
||||
rpc::Rpc,
|
||||
rpc::{
|
||||
Rpc,
|
||||
SubxtRpcApiClient,
|
||||
},
|
||||
Config,
|
||||
Event,
|
||||
Phase,
|
||||
@@ -210,10 +213,13 @@ impl<T: Config> FinalizedEventStorageSubscription<T> {
|
||||
read_subscription_response("HeaderSubscription", &mut self.subscription)
|
||||
.await?;
|
||||
self.storage_changes.extend(
|
||||
self.rpc
|
||||
.query_storage_at(&[self.storage_key.clone()], Some(header.hash()))
|
||||
.await
|
||||
.ok()?,
|
||||
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::query_storage_at(
|
||||
&*self.rpc.client,
|
||||
&[self.storage_key.clone()],
|
||||
Some(header.hash()),
|
||||
)
|
||||
.await
|
||||
.ok()?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-17
@@ -31,7 +31,10 @@ use crate::{
|
||||
RuntimeError,
|
||||
TransactionError,
|
||||
},
|
||||
rpc::SubstrateTransactionStatus,
|
||||
rpc::{
|
||||
SubstrateTransactionStatus,
|
||||
SubxtRpcApiClient,
|
||||
},
|
||||
subscription::SystemEvents,
|
||||
Config,
|
||||
Phase,
|
||||
@@ -389,12 +392,12 @@ impl<'client, T: Config, E: Decode> TransactionInBlock<'client, T, E> {
|
||||
/// **Note:** This has to download block details from the node and decode events
|
||||
/// from them.
|
||||
pub async fn fetch_events(&self) -> Result<TransactionEvents<T>, BasicError> {
|
||||
let block = self
|
||||
.client
|
||||
.rpc()
|
||||
.block(Some(self.block_hash))
|
||||
.await?
|
||||
.ok_or(BasicError::Transaction(TransactionError::BlockHashNotFound))?;
|
||||
let block = SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::block(
|
||||
&*self.client.rpc().client,
|
||||
Some(self.block_hash),
|
||||
)
|
||||
.await?
|
||||
.ok_or(BasicError::Transaction(TransactionError::BlockHashNotFound))?;
|
||||
|
||||
let extrinsic_idx = block.block.extrinsics
|
||||
.iter()
|
||||
@@ -406,16 +409,14 @@ impl<'client, T: Config, E: Decode> TransactionInBlock<'client, T, E> {
|
||||
// extrinsic, the extrinsic should be in there somewhere..
|
||||
.ok_or(BasicError::Transaction(TransactionError::BlockHashNotFound))?;
|
||||
|
||||
let raw_events = self
|
||||
.client
|
||||
.rpc()
|
||||
.storage(
|
||||
&StorageKey::from(SystemEvents::new()),
|
||||
Some(self.block_hash),
|
||||
)
|
||||
.await?
|
||||
.map(|s| s.0)
|
||||
.unwrap_or_else(Vec::new);
|
||||
let raw_events = SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage(
|
||||
&*self.client.rpc().client,
|
||||
&StorageKey::from(SystemEvents::new()),
|
||||
Some(self.block_hash),
|
||||
)
|
||||
.await?
|
||||
.map(|s| s.0)
|
||||
.unwrap_or_else(Vec::new);
|
||||
|
||||
let events = self
|
||||
.client
|
||||
|
||||
@@ -19,6 +19,11 @@ use crate::{
|
||||
test_node_process_with,
|
||||
utils::node_runtime::system,
|
||||
};
|
||||
use subxt::{
|
||||
rpc::SubxtRpcApiClient,
|
||||
Config,
|
||||
DefaultConfig,
|
||||
};
|
||||
|
||||
use sp_core::storage::{
|
||||
well_known_keys,
|
||||
@@ -127,7 +132,22 @@ async fn test_iter() {
|
||||
async fn fetch_system_info() {
|
||||
let node_process = test_node_process().await;
|
||||
let client = node_process.client();
|
||||
assert_eq!(client.rpc().system_chain().await.unwrap(), "Development");
|
||||
assert_eq!(client.rpc().system_name().await.unwrap(), "Substrate Node");
|
||||
assert!(!client.rpc().system_version().await.unwrap().is_empty());
|
||||
let rpc = client.rpc().client.clone();
|
||||
|
||||
type Hash = <DefaultConfig as Config>::Hash;
|
||||
|
||||
assert_eq!(
|
||||
SubxtRpcApiClient::<Hash>::system_chain(&*rpc)
|
||||
.await
|
||||
.unwrap(),
|
||||
"Development"
|
||||
);
|
||||
assert_eq!(
|
||||
SubxtRpcApiClient::<Hash>::system_name(&*rpc).await.unwrap(),
|
||||
"Substrate Node"
|
||||
);
|
||||
assert!(!SubxtRpcApiClient::<Hash>::system_version(&*rpc)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_empty());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user