mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 02:51:01 +00:00
Support authors api. (#134)
This commit is contained in:
+9
-3
@@ -43,12 +43,14 @@ use jsonrpsee::{
|
|||||||
};
|
};
|
||||||
use sc_network::config::TransportConfig;
|
use sc_network::config::TransportConfig;
|
||||||
pub use sc_service::{
|
pub use sc_service::{
|
||||||
config::DatabaseConfig,
|
config::{
|
||||||
|
DatabaseConfig,
|
||||||
|
KeystoreConfig,
|
||||||
|
},
|
||||||
Error as ServiceError,
|
Error as ServiceError,
|
||||||
};
|
};
|
||||||
use sc_service::{
|
use sc_service::{
|
||||||
config::{
|
config::{
|
||||||
KeystoreConfig,
|
|
||||||
NetworkConfiguration,
|
NetworkConfiguration,
|
||||||
TaskType,
|
TaskType,
|
||||||
},
|
},
|
||||||
@@ -119,6 +121,8 @@ pub struct SubxtClientConfig<C: ChainSpec + 'static, S: AbstractService> {
|
|||||||
pub copyright_start_year: i32,
|
pub copyright_start_year: i32,
|
||||||
/// Database configuration.
|
/// Database configuration.
|
||||||
pub db: DatabaseConfig,
|
pub db: DatabaseConfig,
|
||||||
|
/// Keystore configuration.
|
||||||
|
pub keystore: KeystoreConfig,
|
||||||
/// Service builder.
|
/// Service builder.
|
||||||
pub builder: fn(Configuration) -> Result<S, sc_service::Error>,
|
pub builder: fn(Configuration) -> Result<S, sc_service::Error>,
|
||||||
/// Chain specification.
|
/// Chain specification.
|
||||||
@@ -216,7 +220,7 @@ fn start_subxt_client<C: ChainSpec + 'static, S: AbstractService>(
|
|||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
database: config.db,
|
database: config.db,
|
||||||
keystore: KeystoreConfig::InMemory,
|
keystore: config.keystore,
|
||||||
max_runtime_instances: 8,
|
max_runtime_instances: 8,
|
||||||
announce_block: true,
|
announce_block: true,
|
||||||
dev_key_seed: config.role.into(),
|
dev_key_seed: config.role.into(),
|
||||||
@@ -342,6 +346,7 @@ mod tests {
|
|||||||
path: tmp.path().into(),
|
path: tmp.path().into(),
|
||||||
cache_size: 64,
|
cache_size: 64,
|
||||||
},
|
},
|
||||||
|
keystore: KeystoreConfig::InMemory,
|
||||||
builder: test_node::service::new_light,
|
builder: test_node::service::new_light,
|
||||||
chain_spec,
|
chain_spec,
|
||||||
role: Role::Light,
|
role: Role::Light,
|
||||||
@@ -372,6 +377,7 @@ mod tests {
|
|||||||
path: tmp.path().into(),
|
path: tmp.path().into(),
|
||||||
cache_size: 128,
|
cache_size: 128,
|
||||||
},
|
},
|
||||||
|
keystore: KeystoreConfig::InMemory,
|
||||||
builder: test_node::service::new_full,
|
builder: test_node::service::new_full,
|
||||||
chain_spec: test_node::chain_spec::development_config(),
|
chain_spec: test_node::chain_spec::development_config(),
|
||||||
role: Role::Authority(AccountKeyring::Alice),
|
role: Role::Authority(AccountKeyring::Alice),
|
||||||
|
|||||||
+77
-4
@@ -52,9 +52,12 @@ use codec::Decode;
|
|||||||
use futures::future;
|
use futures::future;
|
||||||
use jsonrpsee::client::Subscription;
|
use jsonrpsee::client::Subscription;
|
||||||
use sc_rpc_api::state::ReadProof;
|
use sc_rpc_api::state::ReadProof;
|
||||||
use sp_core::storage::{
|
use sp_core::{
|
||||||
|
storage::{
|
||||||
StorageChangeSet,
|
StorageChangeSet,
|
||||||
StorageKey,
|
StorageKey,
|
||||||
|
},
|
||||||
|
Bytes,
|
||||||
};
|
};
|
||||||
pub use sp_runtime::traits::SignedExtension;
|
pub use sp_runtime::traits::SignedExtension;
|
||||||
use sp_version::RuntimeVersion;
|
use sp_version::RuntimeVersion;
|
||||||
@@ -425,6 +428,41 @@ impl<T: Runtime> Client<T> {
|
|||||||
let decoder = self.events_decoder::<C>();
|
let decoder = self.events_decoder::<C>();
|
||||||
self.submit_and_watch_extrinsic(extrinsic, decoder).await
|
self.submit_and_watch_extrinsic(extrinsic, decoder).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert a key into the keystore.
|
||||||
|
pub async fn insert_key(
|
||||||
|
&self,
|
||||||
|
key_type: String,
|
||||||
|
suri: String,
|
||||||
|
public: Bytes,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.rpc.insert_key(key_type, suri, public).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate new session keys and returns the corresponding public keys.
|
||||||
|
pub async fn rotate_keys(&self) -> Result<Bytes, Error> {
|
||||||
|
self.rpc.rotate_keys().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, Error> {
|
||||||
|
self.rpc.has_session_keys(session_keys).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, Error> {
|
||||||
|
self.rpc.has_key(public_key, key_type).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps an already encoded byte vector, prevents being encoded as a raw byte vector as part of
|
/// Wraps an already encoded byte vector, prevents being encoded as a raw byte vector as part of
|
||||||
@@ -456,6 +494,7 @@ mod tests {
|
|||||||
use sp_runtime::MultiSignature;
|
use sp_runtime::MultiSignature;
|
||||||
use substrate_subxt_client::{
|
use substrate_subxt_client::{
|
||||||
DatabaseConfig,
|
DatabaseConfig,
|
||||||
|
KeystoreConfig,
|
||||||
Role,
|
Role,
|
||||||
SubxtClient,
|
SubxtClient,
|
||||||
SubxtClientConfig,
|
SubxtClientConfig,
|
||||||
@@ -464,7 +503,9 @@ mod tests {
|
|||||||
|
|
||||||
pub(crate) type TestRuntime = crate::NodeTemplateRuntime;
|
pub(crate) type TestRuntime = crate::NodeTemplateRuntime;
|
||||||
|
|
||||||
pub(crate) async fn test_client() -> (Client<TestRuntime>, TempDir) {
|
pub(crate) async fn test_client_with(
|
||||||
|
key: AccountKeyring,
|
||||||
|
) -> (Client<TestRuntime>, TempDir) {
|
||||||
env_logger::try_init().ok();
|
env_logger::try_init().ok();
|
||||||
let tmp = TempDir::new("subxt-").expect("failed to create tempdir");
|
let tmp = TempDir::new("subxt-").expect("failed to create tempdir");
|
||||||
let config = SubxtClientConfig {
|
let config = SubxtClientConfig {
|
||||||
@@ -473,12 +514,16 @@ mod tests {
|
|||||||
author: "substrate subxt",
|
author: "substrate subxt",
|
||||||
copyright_start_year: 2020,
|
copyright_start_year: 2020,
|
||||||
db: DatabaseConfig::RocksDb {
|
db: DatabaseConfig::RocksDb {
|
||||||
path: tmp.path().into(),
|
path: tmp.path().join("db"),
|
||||||
cache_size: 128,
|
cache_size: 128,
|
||||||
},
|
},
|
||||||
|
keystore: KeystoreConfig::Path {
|
||||||
|
path: tmp.path().join("keystore"),
|
||||||
|
password: None,
|
||||||
|
},
|
||||||
builder: test_node::service::new_full,
|
builder: test_node::service::new_full,
|
||||||
chain_spec: test_node::chain_spec::development_config(),
|
chain_spec: test_node::chain_spec::development_config(),
|
||||||
role: Role::Authority(AccountKeyring::Alice),
|
role: Role::Authority(key),
|
||||||
};
|
};
|
||||||
let client = ClientBuilder::new()
|
let client = ClientBuilder::new()
|
||||||
.set_client(SubxtClient::new(config).expect("Error creating subxt client"))
|
.set_client(SubxtClient::new(config).expect("Error creating subxt client"))
|
||||||
@@ -488,6 +533,34 @@ mod tests {
|
|||||||
(client, tmp)
|
(client, tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn test_client() -> (Client<TestRuntime>, TempDir) {
|
||||||
|
test_client_with(AccountKeyring::Alice).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_insert_key() {
|
||||||
|
// Bob is not an authority, so block production should be disabled.
|
||||||
|
let (client, _tmp) = test_client_with(AccountKeyring::Bob).await;
|
||||||
|
let mut blocks = client.subscribe_blocks().await.unwrap();
|
||||||
|
// get the genesis block.
|
||||||
|
assert_eq!(blocks.next().await.number, 0);
|
||||||
|
let public = AccountKeyring::Alice.public().as_array_ref().to_vec();
|
||||||
|
client
|
||||||
|
.insert_key(
|
||||||
|
"aura".to_string(),
|
||||||
|
"//Alice".to_string(),
|
||||||
|
public.clone().into(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(client
|
||||||
|
.has_key(public.clone().into(), "aura".to_string())
|
||||||
|
.await
|
||||||
|
.unwrap());
|
||||||
|
// Alice is an authority, so blocks should be produced.
|
||||||
|
assert_eq!(blocks.next().await.number, 1);
|
||||||
|
}
|
||||||
|
|
||||||
#[async_std::test]
|
#[async_std::test]
|
||||||
async fn test_tx_transfer_balance() {
|
async fn test_tx_transfer_balance() {
|
||||||
let mut signer = PairSigner::new(AccountKeyring::Alice.pair());
|
let mut signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||||
|
|||||||
+47
@@ -396,6 +396,53 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
}
|
}
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert a key into the keystore.
|
||||||
|
pub async fn insert_key(
|
||||||
|
&self,
|
||||||
|
key_type: String,
|
||||||
|
suri: String,
|
||||||
|
public: Bytes,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let params = Params::Array(vec![
|
||||||
|
to_json_value(key_type)?,
|
||||||
|
to_json_value(suri)?,
|
||||||
|
to_json_value(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, Error> {
|
||||||
|
Ok(self
|
||||||
|
.client
|
||||||
|
.request("author_rotateKeys", Params::None)
|
||||||
|
.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, Error> {
|
||||||
|
let params = Params::Array(vec![to_json_value(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, Error> {
|
||||||
|
let params =
|
||||||
|
Params::Array(vec![to_json_value(public_key)?, to_json_value(key_type)?]);
|
||||||
|
Ok(self.client.request("author_hasKey", params).await?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Captures data for when an extrinsic is successfully included in a block
|
/// Captures data for when an extrinsic is successfully included in a block
|
||||||
|
|||||||
Reference in New Issue
Block a user