mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 22:51:03 +00:00
Get workspace compiling via 'cargo check'
This commit is contained in:
@@ -144,7 +144,7 @@ pub async fn run(opts: Opts, output: &mut impl std::io::Write) -> color_eyre::Re
|
|||||||
// get the metadata
|
// get the metadata
|
||||||
let file_or_url = opts.file_or_url;
|
let file_or_url = opts.file_or_url;
|
||||||
let bytes = file_or_url.fetch().await?;
|
let bytes = file_or_url.fetch().await?;
|
||||||
let metadata = Metadata::decode(&mut &bytes[..])?;
|
let metadata = Metadata::decode(&mut &bytes[..])?.arc();
|
||||||
|
|
||||||
let pallet_placeholder = "<PALLET>".blue();
|
let pallet_placeholder = "<PALLET>".blue();
|
||||||
let runtime_api_placeholder = "<RUNTIME_API>".blue();
|
let runtime_api_placeholder = "<RUNTIME_API>".blue();
|
||||||
@@ -185,7 +185,14 @@ pub async fn run(opts: Opts, output: &mut impl std::io::Write) -> color_eyre::Re
|
|||||||
.pallets()
|
.pallets()
|
||||||
.find(|e| e.name().eq_ignore_ascii_case(&name))
|
.find(|e| e.name().eq_ignore_ascii_case(&name))
|
||||||
{
|
{
|
||||||
pallets::run(opts.subcommand, pallet, &metadata, file_or_url, output).await
|
pallets::run(
|
||||||
|
opts.subcommand,
|
||||||
|
pallet,
|
||||||
|
metadata.clone(),
|
||||||
|
file_or_url,
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
.await
|
||||||
} else {
|
} else {
|
||||||
Err(eyre!(
|
Err(eyre!(
|
||||||
"pallet \"{name}\" not found in metadata!\n{}",
|
"pallet \"{name}\" not found in metadata!\n{}",
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ use indoc::{formatdoc, writedoc};
|
|||||||
use scale_info::form::PortableForm;
|
use scale_info::form::PortableForm;
|
||||||
use scale_info::{PortableRegistry, Type, TypeDef, TypeDefVariant};
|
use scale_info::{PortableRegistry, Type, TypeDef, TypeDefVariant};
|
||||||
use scale_value::{Composite, ValueDef};
|
use scale_value::{Composite, ValueDef};
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use subxt::tx;
|
|
||||||
use subxt::utils::H256;
|
|
||||||
use subxt::{
|
use subxt::{
|
||||||
OfflineClient,
|
OfflineClient, OfflineClientAtBlock,
|
||||||
config::SubstrateConfig,
|
config::SubstrateConfig,
|
||||||
metadata::{Metadata, PalletMetadata},
|
metadata::{ArcMetadata, PalletMetadata},
|
||||||
|
tx,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
@@ -30,7 +27,7 @@ pub struct CallsSubcommand {
|
|||||||
pub fn explore_calls(
|
pub fn explore_calls(
|
||||||
command: CallsSubcommand,
|
command: CallsSubcommand,
|
||||||
pallet_metadata: PalletMetadata,
|
pallet_metadata: PalletMetadata,
|
||||||
metadata: &Metadata,
|
metadata: ArcMetadata,
|
||||||
output: &mut impl std::io::Write,
|
output: &mut impl std::io::Write,
|
||||||
) -> color_eyre::Result<()> {
|
) -> color_eyre::Result<()> {
|
||||||
let pallet_name = pallet_metadata.name();
|
let pallet_name = pallet_metadata.name();
|
||||||
@@ -148,18 +145,20 @@ fn get_calls_enum_type<'a>(
|
|||||||
Ok((calls_enum_type_def, calls_enum_type))
|
Ok((calls_enum_type_def, calls_enum_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The specific values used for construction do not matter too much, we just need any OfflineClient to create unsigned extrinsics
|
/// We don't care about any specific genesis hash etc; we just need any OfflineClient to create unsigned extrinsics
|
||||||
fn mocked_offline_client(metadata: Metadata) -> OfflineClient<SubstrateConfig> {
|
fn mocked_offline_client(metadata: ArcMetadata) -> OfflineClientAtBlock<SubstrateConfig> {
|
||||||
let genesis_hash =
|
let config = SubstrateConfig::builder()
|
||||||
H256::from_str("91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3")
|
.set_spec_version_for_block_ranges([subxt::config::substrate::SpecVersionForRange {
|
||||||
.expect("Valid hash; qed");
|
block_range: 0..1,
|
||||||
|
spec_version: 1,
|
||||||
|
transaction_version: 1,
|
||||||
|
}])
|
||||||
|
.set_metadata_for_spec_versions([(1, metadata)])
|
||||||
|
.build();
|
||||||
|
|
||||||
let runtime_version = subxt::client::RuntimeVersion {
|
OfflineClient::<SubstrateConfig>::new(config)
|
||||||
spec_version: 9370,
|
.at_block(0u64)
|
||||||
transaction_version: 20,
|
.expect("Should not fail since we plugged consistent data into the config")
|
||||||
};
|
|
||||||
|
|
||||||
OfflineClient::<SubstrateConfig>::new(genesis_hash, runtime_version, metadata)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// composites stay composites, all other types are converted into a 1-fielded unnamed composite
|
/// composites stay composites, all other types are converted into a 1-fielded unnamed composite
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use clap::Args;
|
|||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use indoc::{formatdoc, writedoc};
|
use indoc::{formatdoc, writedoc};
|
||||||
use scale_typegen_description::type_description;
|
use scale_typegen_description::type_description;
|
||||||
use subxt::metadata::{Metadata, PalletMetadata};
|
use subxt::metadata::{ArcMetadata, PalletMetadata};
|
||||||
|
|
||||||
use crate::utils::{Indent, SyntaxHighlight, first_paragraph_of_docs, format_scale_value};
|
use crate::utils::{Indent, SyntaxHighlight, first_paragraph_of_docs, format_scale_value};
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ pub struct ConstantsSubcommand {
|
|||||||
pub fn explore_constants(
|
pub fn explore_constants(
|
||||||
command: ConstantsSubcommand,
|
command: ConstantsSubcommand,
|
||||||
pallet_metadata: PalletMetadata,
|
pallet_metadata: PalletMetadata,
|
||||||
metadata: &Metadata,
|
metadata: ArcMetadata,
|
||||||
output: &mut impl std::io::Write,
|
output: &mut impl std::io::Write,
|
||||||
) -> color_eyre::Result<()> {
|
) -> color_eyre::Result<()> {
|
||||||
let pallet_name = pallet_metadata.name();
|
let pallet_name = pallet_metadata.name();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use clap::Args;
|
|||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use indoc::{formatdoc, writedoc};
|
use indoc::{formatdoc, writedoc};
|
||||||
use scale_info::{Variant, form::PortableForm};
|
use scale_info::{Variant, form::PortableForm};
|
||||||
use subxt::metadata::{Metadata, PalletMetadata};
|
use subxt::metadata::{ArcMetadata, PalletMetadata};
|
||||||
|
|
||||||
use crate::utils::{Indent, fields_description, first_paragraph_of_docs};
|
use crate::utils::{Indent, fields_description, first_paragraph_of_docs};
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ pub struct EventsSubcommand {
|
|||||||
pub fn explore_events(
|
pub fn explore_events(
|
||||||
command: EventsSubcommand,
|
command: EventsSubcommand,
|
||||||
pallet_metadata: PalletMetadata,
|
pallet_metadata: PalletMetadata,
|
||||||
metadata: &Metadata,
|
metadata: ArcMetadata,
|
||||||
output: &mut impl std::io::Write,
|
output: &mut impl std::io::Write,
|
||||||
) -> color_eyre::Result<()> {
|
) -> color_eyre::Result<()> {
|
||||||
let pallet_name = pallet_metadata.name();
|
let pallet_name = pallet_metadata.name();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
|
|
||||||
use indoc::writedoc;
|
use indoc::writedoc;
|
||||||
use subxt::Metadata;
|
use subxt::ArcMetadata;
|
||||||
use subxt_metadata::PalletMetadata;
|
use subxt_metadata::PalletMetadata;
|
||||||
|
|
||||||
use crate::utils::{FileOrUrl, Indent, first_paragraph_of_docs};
|
use crate::utils::{FileOrUrl, Indent, first_paragraph_of_docs};
|
||||||
@@ -33,7 +33,7 @@ pub enum PalletSubcommand {
|
|||||||
pub async fn run<'a>(
|
pub async fn run<'a>(
|
||||||
subcommand: Option<PalletSubcommand>,
|
subcommand: Option<PalletSubcommand>,
|
||||||
pallet_metadata: PalletMetadata<'a>,
|
pallet_metadata: PalletMetadata<'a>,
|
||||||
metadata: &'a Metadata,
|
metadata: ArcMetadata,
|
||||||
file_or_url: FileOrUrl,
|
file_or_url: FileOrUrl,
|
||||||
output: &mut impl std::io::Write,
|
output: &mut impl std::io::Write,
|
||||||
) -> color_eyre::Result<()> {
|
) -> color_eyre::Result<()> {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use scale_typegen_description::type_description;
|
|||||||
use scale_value::Value;
|
use scale_value::Value;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::write;
|
use std::write;
|
||||||
use subxt::metadata::{Metadata, PalletMetadata, StorageMetadata};
|
use subxt::metadata::{ArcMetadata, PalletMetadata, StorageMetadata};
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
FileOrUrl, Indent, SyntaxHighlight, create_client, first_paragraph_of_docs,
|
FileOrUrl, Indent, SyntaxHighlight, create_client, first_paragraph_of_docs,
|
||||||
@@ -24,7 +24,7 @@ pub struct StorageSubcommand {
|
|||||||
pub async fn explore_storage(
|
pub async fn explore_storage(
|
||||||
command: StorageSubcommand,
|
command: StorageSubcommand,
|
||||||
pallet_metadata: PalletMetadata<'_>,
|
pallet_metadata: PalletMetadata<'_>,
|
||||||
metadata: &Metadata,
|
metadata: ArcMetadata,
|
||||||
file_or_url: FileOrUrl,
|
file_or_url: FileOrUrl,
|
||||||
output: &mut impl std::io::Write,
|
output: &mut impl std::io::Write,
|
||||||
) -> color_eyre::Result<()> {
|
) -> color_eyre::Result<()> {
|
||||||
@@ -197,9 +197,9 @@ pub async fn explore_storage(
|
|||||||
|
|
||||||
// Fetch the value:
|
// Fetch the value:
|
||||||
let storage_value = client
|
let storage_value = client
|
||||||
.storage()
|
.at_current_block()
|
||||||
.at_latest()
|
|
||||||
.await?
|
.await?
|
||||||
|
.storage()
|
||||||
.fetch((pallet_name, storage.name()), storage_entry_keys)
|
.fetch((pallet_name, storage.name()), storage_entry_keys)
|
||||||
.await?
|
.await?
|
||||||
.decode()?;
|
.decode()?;
|
||||||
|
|||||||
@@ -172,9 +172,9 @@ pub async fn run<'a>(
|
|||||||
subxt::dynamic::runtime_api_call::<_, Value>(api_name, method.name(), args_data);
|
subxt::dynamic::runtime_api_call::<_, Value>(api_name, method.name(), args_data);
|
||||||
let client = create_client(&file_or_url).await?;
|
let client = create_client(&file_or_url).await?;
|
||||||
let output_value = client
|
let output_value = client
|
||||||
.runtime_api()
|
.at_current_block()
|
||||||
.at_latest()
|
|
||||||
.await?
|
.await?
|
||||||
|
.runtime_apis()
|
||||||
.call(method_call)
|
.call(method_call)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -232,9 +232,10 @@ impl<T: Display> Indent for T {}
|
|||||||
pub async fn create_client(
|
pub async fn create_client(
|
||||||
file_or_url: &FileOrUrl,
|
file_or_url: &FileOrUrl,
|
||||||
) -> color_eyre::Result<OnlineClient<PolkadotConfig>> {
|
) -> color_eyre::Result<OnlineClient<PolkadotConfig>> {
|
||||||
|
let config = PolkadotConfig::new();
|
||||||
let client = match &file_or_url.url {
|
let client = match &file_or_url.url {
|
||||||
Some(url) => OnlineClient::<PolkadotConfig>::from_url(url).await?,
|
Some(url) => OnlineClient::<PolkadotConfig>::from_url(config, url).await?,
|
||||||
None => OnlineClient::<PolkadotConfig>::new().await?,
|
None => OnlineClient::<PolkadotConfig>::new(config).await?,
|
||||||
};
|
};
|
||||||
Ok(client)
|
Ok(client)
|
||||||
}
|
}
|
||||||
@@ -326,7 +327,7 @@ pub fn validate_url_security(url: Option<&Url>, allow_insecure: bool) -> color_e
|
|||||||
let Some(url) = url else {
|
let Some(url) = url else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
match subxt::utils::url_is_secure(url.as_str()) {
|
match subxt::ext::subxt_rpcs::utils::url_is_secure(url.as_str()) {
|
||||||
Ok(is_secure) => {
|
Ok(is_secure) => {
|
||||||
if !allow_insecure && !is_secure {
|
if !allow_insecure && !is_secure {
|
||||||
bail!(
|
bail!(
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ pub fn generate_calls(
|
|||||||
pub fn #fn_name(
|
pub fn #fn_name(
|
||||||
&self,
|
&self,
|
||||||
#( #call_fn_args, )*
|
#( #call_fn_args, )*
|
||||||
) -> #crate_path::transactions::payload::StaticPayload<types::#struct_name> {
|
) -> #crate_path::transactions::StaticPayload<types::#struct_name> {
|
||||||
#crate_path::transactions::payload::StaticPayload::new_static(
|
#crate_path::transactions::StaticPayload::new_static(
|
||||||
#pallet_name,
|
#pallet_name,
|
||||||
#call_name,
|
#call_name,
|
||||||
types::#struct_name { #( #call_args, )* },
|
types::#struct_name { #( #call_args, )* },
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ pub fn generate_constants(
|
|||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#docs
|
#docs
|
||||||
pub fn #fn_name(&self) -> #crate_path::constants::address::StaticAddress<#return_ty> {
|
pub fn #fn_name(&self) -> #crate_path::constants::StaticAddress<#return_ty> {
|
||||||
#crate_path::constants::address::StaticAddress::new_static(
|
#crate_path::constants::StaticAddress::new_static(
|
||||||
#pallet_name,
|
#pallet_name,
|
||||||
#constant_name,
|
#constant_name,
|
||||||
[#(#constant_hash,)*]
|
[#(#constant_hash,)*]
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ fn generate_custom_value_fn(
|
|||||||
};
|
};
|
||||||
|
|
||||||
Some(quote!(
|
Some(quote!(
|
||||||
pub fn #fn_name_ident(&self) -> #crate_path::custom_values::address::StaticAddress<#return_ty, #decodable> {
|
pub fn #fn_name_ident(&self) -> #crate_path::custom_values::StaticAddress<#return_ty, #decodable> {
|
||||||
#crate_path::custom_values::address::StaticAddress::new_static(#name, [#(#custom_value_hash,)*])
|
#crate_path::custom_values::StaticAddress::new_static(#name, [#(#custom_value_hash,)*])
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,11 +167,11 @@ fn generate_pallet_view_function(
|
|||||||
pub fn #view_function_name_ident(
|
pub fn #view_function_name_ident(
|
||||||
&self,
|
&self,
|
||||||
#(#input_args),*
|
#(#input_args),*
|
||||||
) -> #crate_path::view_functions::payload::StaticPayload<
|
) -> #crate_path::view_functions::StaticPayload<
|
||||||
(#(#input_tuple_types,)*),
|
(#(#input_tuple_types,)*),
|
||||||
#view_function_name_ident::output::Output
|
#view_function_name_ident::output::Output
|
||||||
> {
|
> {
|
||||||
#crate_path::view_functions::payload::StaticPayload::new_static(
|
#crate_path::view_functions::StaticPayload::new_static(
|
||||||
#pallet_name,
|
#pallet_name,
|
||||||
#view_function_name_str,
|
#view_function_name_str,
|
||||||
(#(#input_param_names,)*),
|
(#(#input_param_names,)*),
|
||||||
|
|||||||
@@ -183,11 +183,11 @@ fn generate_runtime_api(
|
|||||||
pub fn #method_name(
|
pub fn #method_name(
|
||||||
&self,
|
&self,
|
||||||
#(#input_args),*
|
#(#input_args),*
|
||||||
) -> #crate_path::runtime_apis::payload::StaticPayload<
|
) -> #crate_path::runtime_apis::StaticPayload<
|
||||||
(#(#input_tuple_types,)*),
|
(#(#input_tuple_types,)*),
|
||||||
#method_name::output::Output
|
#method_name::output::Output
|
||||||
> {
|
> {
|
||||||
#crate_path::runtime_apis::payload::StaticPayload::new_static(
|
#crate_path::runtime_apis::StaticPayload::new_static(
|
||||||
#trait_name_str,
|
#trait_name_str,
|
||||||
#method_name_str,
|
#method_name_str,
|
||||||
(#(#input_param_names,)*),
|
(#(#input_param_names,)*),
|
||||||
|
|||||||
@@ -153,12 +153,12 @@ fn generate_storage_entry_fns(
|
|||||||
|
|
||||||
let storage_entry_method = quote!(
|
let storage_entry_method = quote!(
|
||||||
#docs
|
#docs
|
||||||
pub fn #storage_entry_snake_case_ident(&self) -> #crate_path::storage::address::StaticAddress<
|
pub fn #storage_entry_snake_case_ident(&self) -> #crate_path::storage::StaticAddress<
|
||||||
(#(#storage_key_tuple_types,)*),
|
(#(#storage_key_tuple_types,)*),
|
||||||
#storage_entry_snake_case_ident::output::Output,
|
#storage_entry_snake_case_ident::output::Output,
|
||||||
#is_plain
|
#is_plain
|
||||||
> {
|
> {
|
||||||
#crate_path::storage::address::StaticAddress::new_static(
|
#crate_path::storage::StaticAddress::new_static(
|
||||||
#pallet_name,
|
#pallet_name,
|
||||||
#storage_entry_name_str,
|
#storage_entry_name_str,
|
||||||
[#(#validation_hash,)*],
|
[#(#validation_hash,)*],
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ mod utils;
|
|||||||
use alloc::borrow::Cow;
|
use alloc::borrow::Cow;
|
||||||
use alloc::collections::BTreeMap;
|
use alloc::collections::BTreeMap;
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
|
use alloc::sync::Arc;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use frame_decode::constants::{ConstantEntry, ConstantInfo, ConstantInfoError};
|
use frame_decode::constants::{ConstantEntry, ConstantInfo, ConstantInfoError};
|
||||||
use frame_decode::custom_values::{CustomValue, CustomValueInfo, CustomValueInfoError};
|
use frame_decode::custom_values::{CustomValue, CustomValueInfo, CustomValueInfoError};
|
||||||
@@ -58,6 +59,9 @@ pub use from::legacy::Error as LegacyFromError;
|
|||||||
|
|
||||||
type CustomMetadataInner = frame_metadata::v15::CustomMetadata<PortableForm>;
|
type CustomMetadataInner = frame_metadata::v15::CustomMetadata<PortableForm>;
|
||||||
|
|
||||||
|
/// Metadata is often passed around wrapped in an [`Arc`] so that it can be cheaply cloned.
|
||||||
|
pub type ArcMetadata = Arc<Metadata>;
|
||||||
|
|
||||||
/// Node metadata. This can be constructed by providing some compatible [`frame_metadata`]
|
/// Node metadata. This can be constructed by providing some compatible [`frame_metadata`]
|
||||||
/// which is then decoded into this. We aim to preserve all of the existing information in
|
/// which is then decoded into this. We aim to preserve all of the existing information in
|
||||||
/// the incoming metadata while optimizing the format a little for Subxt's use cases.
|
/// the incoming metadata while optimizing the format a little for Subxt's use cases.
|
||||||
@@ -370,6 +374,12 @@ impl frame_decode::custom_values::CustomValueEntryInfo for Metadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Metadata {
|
impl Metadata {
|
||||||
|
/// Metadata tends to be passed around wrapped in an [`Arc`] so that it can be
|
||||||
|
/// cheaply cloned. This is a shorthand to return that.
|
||||||
|
pub fn arc(self) -> ArcMetadata {
|
||||||
|
Arc::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
/// This is essentially an alias for `<Metadata as codec::Decode>::decode(&mut bytes)`
|
/// This is essentially an alias for `<Metadata as codec::Decode>::decode(&mut bytes)`
|
||||||
pub fn decode_from(mut bytes: &[u8]) -> Result<Self, codec::Error> {
|
pub fn decode_from(mut bytes: &[u8]) -> Result<Self, codec::Error> {
|
||||||
<Self as codec::Decode>::decode(&mut bytes)
|
<Self as codec::Decode>::decode(&mut bytes)
|
||||||
|
|||||||
+2
-2
@@ -365,9 +365,9 @@ mod test {
|
|||||||
use bip39::Mnemonic;
|
use bip39::Mnemonic;
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
use secp256k1::Secp256k1;
|
use secp256k1::Secp256k1;
|
||||||
use subxt::utils::AccountId20;
|
|
||||||
use subxt::transactions::Signer as SignerT;
|
|
||||||
use subxt::config::{Config, HashFor, substrate};
|
use subxt::config::{Config, HashFor, substrate};
|
||||||
|
use subxt::transactions::Signer as SignerT;
|
||||||
|
use subxt::utils::AccountId20;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|||||||
+12
-3
@@ -14,12 +14,15 @@ use crate::view_functions::ViewFunctionsClient;
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use subxt_metadata::Metadata;
|
use subxt_metadata::Metadata;
|
||||||
|
|
||||||
pub use offline_client::{OfflineClient, OfflineClientAtBlock, OfflineClientAtBlockT};
|
pub use offline_client::{OfflineClient, OfflineClientAtBlockImpl, OfflineClientAtBlockT};
|
||||||
pub use online_client::{
|
pub use online_client::{
|
||||||
BlockNumberOrRef, OnlineClient, OnlineClientAtBlock, OnlineClientAtBlockT,
|
BlockNumberOrRef, OnlineClient, OnlineClientAtBlockImpl, OnlineClientAtBlockT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This represents a client at a specific block number.
|
/// This represents a client at a specific block number. This wraps a client impl
|
||||||
|
/// which will either be [`OfflineClientAtBlockImpl`] or [`OnlineClientAtBlockImpl`].
|
||||||
|
/// Prefer to use the type aliases [`OfflineClientAtBlock`] and [`OnlineClientAtBlock`]
|
||||||
|
/// if you need to refer to the concrete instances of this.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ClientAtBlock<T, Client> {
|
pub struct ClientAtBlock<T, Client> {
|
||||||
pub(crate) client: Client,
|
pub(crate) client: Client,
|
||||||
@@ -125,3 +128,9 @@ where
|
|||||||
Ok(header)
|
Ok(header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An offline client at a specific block.
|
||||||
|
pub type OfflineClientAtBlock<T> = ClientAtBlock<T, OfflineClientAtBlockImpl<T>>;
|
||||||
|
|
||||||
|
/// An online client at a specific block.
|
||||||
|
pub type OnlineClientAtBlock<T> = ClientAtBlock<T, OnlineClientAtBlockImpl<T>>;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ impl<T: Config> OfflineClient<T> {
|
|||||||
pub fn at_block(
|
pub fn at_block(
|
||||||
&self,
|
&self,
|
||||||
block_number: impl Into<u64>,
|
block_number: impl Into<u64>,
|
||||||
) -> Result<ClientAtBlock<T, OfflineClientAtBlock<T>>, OfflineClientAtBlockError> {
|
) -> Result<ClientAtBlock<T, OfflineClientAtBlockImpl<T>>, OfflineClientAtBlockError> {
|
||||||
let block_number = block_number.into();
|
let block_number = block_number.into();
|
||||||
let (spec_version, transaction_version) = self
|
let (spec_version, transaction_version) = self
|
||||||
.config
|
.config
|
||||||
@@ -36,7 +36,7 @@ impl<T: Config> OfflineClient<T> {
|
|||||||
|
|
||||||
let hasher = <T::Hasher as Hasher>::new(&metadata);
|
let hasher = <T::Hasher as Hasher>::new(&metadata);
|
||||||
|
|
||||||
let offline_client_at_block = OfflineClientAtBlock {
|
let offline_client_at_block = OfflineClientAtBlockImpl {
|
||||||
metadata,
|
metadata,
|
||||||
block_number,
|
block_number,
|
||||||
genesis_hash,
|
genesis_hash,
|
||||||
@@ -49,8 +49,11 @@ impl<T: Config> OfflineClient<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An implementation of the [`OfflineClientAtBlockT`] trait, which is used in conjunction
|
||||||
|
/// with [`crate::client::ClientAtBlock`] to provide a working client. You won't tend to need this
|
||||||
|
/// type and instead should prefer to refer to [`crate::client::OfflineClientAtBlock`].
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct OfflineClientAtBlock<T: Config> {
|
pub struct OfflineClientAtBlockImpl<T: Config> {
|
||||||
metadata: ArcMetadata,
|
metadata: ArcMetadata,
|
||||||
block_number: u64,
|
block_number: u64,
|
||||||
genesis_hash: Option<HashFor<T>>,
|
genesis_hash: Option<HashFor<T>>,
|
||||||
@@ -81,7 +84,7 @@ pub trait OfflineClientAtBlockT<T: Config>: Clone {
|
|||||||
fn transaction_version(&self) -> u32;
|
fn transaction_version(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> OfflineClientAtBlockT<T> for OfflineClientAtBlock<T> {
|
impl<T: Config> OfflineClientAtBlockT<T> for OfflineClientAtBlockImpl<T> {
|
||||||
fn metadata_ref(&self) -> &Metadata {
|
fn metadata_ref(&self) -> &Metadata {
|
||||||
&self.metadata
|
&self.metadata
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,10 +65,7 @@ impl<T: Config> OnlineClient<T> {
|
|||||||
url: impl AsRef<str>,
|
url: impl AsRef<str>,
|
||||||
) -> Result<OnlineClient<T>, OnlineClientError> {
|
) -> Result<OnlineClient<T>, OnlineClientError> {
|
||||||
let url_str = url.as_ref();
|
let url_str = url.as_ref();
|
||||||
let url = url::Url::parse(url_str).map_err(|_| OnlineClientError::InvalidUrl {
|
if !subxt_rpcs::utils::url_is_secure(url_str).map_err(OnlineClientError::RpcError)? {
|
||||||
url: url_str.to_string(),
|
|
||||||
})?;
|
|
||||||
if !Self::is_url_secure(&url) {
|
|
||||||
return Err(OnlineClientError::RpcError(subxt_rpcs::Error::InsecureUrl(
|
return Err(OnlineClientError::RpcError(subxt_rpcs::Error::InsecureUrl(
|
||||||
url_str.to_string(),
|
url_str.to_string(),
|
||||||
)));
|
)));
|
||||||
@@ -88,16 +85,6 @@ impl<T: Config> OnlineClient<T> {
|
|||||||
OnlineClient::from_rpc_client(config, rpc_client).await
|
OnlineClient::from_rpc_client(config, rpc_client).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_url_secure(url: &url::Url) -> bool {
|
|
||||||
let secure_scheme = url.scheme() == "https" || url.scheme() == "wss";
|
|
||||||
let is_localhost = url.host().is_some_and(|e| match e {
|
|
||||||
url::Host::Domain(e) => e == "localhost",
|
|
||||||
url::Host::Ipv4(e) => e.is_loopback(),
|
|
||||||
url::Host::Ipv6(e) => e.is_loopback(),
|
|
||||||
});
|
|
||||||
secure_scheme || is_localhost
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct a new [`OnlineClient`] by providing an [`RpcClient`] to drive the connection.
|
/// Construct a new [`OnlineClient`] by providing an [`RpcClient`] to drive the connection.
|
||||||
/// This will use the current default [`Backend`], which may change in future releases.
|
/// This will use the current default [`Backend`], which may change in future releases.
|
||||||
#[cfg(all(feature = "jsonrpsee", feature = "runtime"))]
|
#[cfg(all(feature = "jsonrpsee", feature = "runtime"))]
|
||||||
@@ -210,7 +197,7 @@ impl<T: Config> OnlineClient<T> {
|
|||||||
/// This does not track new blocks.
|
/// This does not track new blocks.
|
||||||
pub async fn at_current_block(
|
pub async fn at_current_block(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<ClientAtBlock<T, OnlineClientAtBlock<T>>, OnlineClientAtBlockError> {
|
) -> Result<ClientAtBlock<T, OnlineClientAtBlockImpl<T>>, OnlineClientAtBlockError> {
|
||||||
let latest_block = self
|
let latest_block = self
|
||||||
.inner
|
.inner
|
||||||
.backend
|
.backend
|
||||||
@@ -225,7 +212,7 @@ impl<T: Config> OnlineClient<T> {
|
|||||||
pub async fn at_block(
|
pub async fn at_block(
|
||||||
&self,
|
&self,
|
||||||
number_or_hash: impl Into<BlockNumberOrRef<T>>,
|
number_or_hash: impl Into<BlockNumberOrRef<T>>,
|
||||||
) -> Result<ClientAtBlock<T, OnlineClientAtBlock<T>>, OnlineClientAtBlockError> {
|
) -> Result<ClientAtBlock<T, OnlineClientAtBlockImpl<T>>, OnlineClientAtBlockError> {
|
||||||
let number_or_hash = number_or_hash.into();
|
let number_or_hash = number_or_hash.into();
|
||||||
|
|
||||||
// We are given either a block hash or number. We need both.
|
// We are given either a block hash or number. We need both.
|
||||||
@@ -274,7 +261,7 @@ impl<T: Config> OnlineClient<T> {
|
|||||||
&self,
|
&self,
|
||||||
block_ref: impl Into<BlockRef<HashFor<T>>>,
|
block_ref: impl Into<BlockRef<HashFor<T>>>,
|
||||||
block_number: u64,
|
block_number: u64,
|
||||||
) -> Result<ClientAtBlock<T, OnlineClientAtBlock<T>>, OnlineClientAtBlockError> {
|
) -> Result<ClientAtBlock<T, OnlineClientAtBlockImpl<T>>, OnlineClientAtBlockError> {
|
||||||
let block_ref = block_ref.into();
|
let block_ref = block_ref.into();
|
||||||
let block_hash = block_ref.hash();
|
let block_hash = block_ref.hash();
|
||||||
|
|
||||||
@@ -427,7 +414,7 @@ impl<T: Config> OnlineClient<T> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let online_client_at_block = OnlineClientAtBlock {
|
let online_client_at_block = OnlineClientAtBlockImpl {
|
||||||
client: self.clone(),
|
client: self.clone(),
|
||||||
hasher: <T::Hasher as Hasher>::new(&metadata),
|
hasher: <T::Hasher as Hasher>::new(&metadata),
|
||||||
metadata,
|
metadata,
|
||||||
@@ -458,9 +445,11 @@ pub trait OnlineClientAtBlockT<T: Config>: OfflineClientAtBlockT<T> {
|
|||||||
) -> impl Future<Output = Result<ClientAtBlock<T, Self>, OnlineClientAtBlockError>>;
|
) -> impl Future<Output = Result<ClientAtBlock<T, Self>, OnlineClientAtBlockError>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inner type providing the necessary data to work online at a specific block.
|
/// An implementation of the [`OnlineClientAtBlockImpl`] trait, which is used in conjunction
|
||||||
|
/// with [`crate::client::ClientAtBlock`] to provide a working client. You won't tend to need this
|
||||||
|
/// type and instead should prefer to refer to [`crate::client::OnlineClientAtBlock`].
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct OnlineClientAtBlock<T: Config> {
|
pub struct OnlineClientAtBlockImpl<T: Config> {
|
||||||
client: OnlineClient<T>,
|
client: OnlineClient<T>,
|
||||||
metadata: ArcMetadata,
|
metadata: ArcMetadata,
|
||||||
hasher: T::Hasher,
|
hasher: T::Hasher,
|
||||||
@@ -470,7 +459,7 @@ pub struct OnlineClientAtBlock<T: Config> {
|
|||||||
transaction_version: u32,
|
transaction_version: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> OnlineClientAtBlockT<T> for OnlineClientAtBlock<T> {
|
impl<T: Config> OnlineClientAtBlockT<T> for OnlineClientAtBlockImpl<T> {
|
||||||
fn backend(&self) -> &dyn Backend<T> {
|
fn backend(&self) -> &dyn Backend<T> {
|
||||||
&*self.client.inner.backend
|
&*self.client.inner.backend
|
||||||
}
|
}
|
||||||
@@ -485,7 +474,7 @@ impl<T: Config> OnlineClientAtBlockT<T> for OnlineClientAtBlock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> OfflineClientAtBlockT<T> for OnlineClientAtBlock<T> {
|
impl<T: Config> OfflineClientAtBlockT<T> for OnlineClientAtBlockImpl<T> {
|
||||||
fn metadata_ref(&self) -> &Metadata {
|
fn metadata_ref(&self) -> &Metadata {
|
||||||
&self.metadata
|
&self.metadata
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::backend::{BlockRef, StreamOfResults};
|
use crate::backend::{BlockRef, StreamOfResults};
|
||||||
use crate::client::{ClientAtBlock, OnlineClient, OnlineClientAtBlock};
|
use crate::client::{ClientAtBlock, OnlineClient, OnlineClientAtBlockImpl};
|
||||||
use crate::config::{Config, HashFor, Header};
|
use crate::config::{Config, HashFor, Header};
|
||||||
use crate::error::{BlocksError, OnlineClientAtBlockError};
|
use crate::error::{BlocksError, OnlineClientAtBlockError};
|
||||||
use futures::{Stream, StreamExt};
|
use futures::{Stream, StreamExt};
|
||||||
@@ -70,7 +70,7 @@ impl<T: Config> Block<T> {
|
|||||||
/// Instantiate a client at this block.
|
/// Instantiate a client at this block.
|
||||||
pub async fn client(
|
pub async fn client(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<ClientAtBlock<T, OnlineClientAtBlock<T>>, OnlineClientAtBlockError> {
|
) -> Result<ClientAtBlock<T, OnlineClientAtBlockImpl<T>>, OnlineClientAtBlockError> {
|
||||||
self.client.at_block(self.block_ref.clone()).await
|
self.client.at_block(self.block_ref.clone()).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ impl PolkadotConfigBuilder {
|
|||||||
/// Set the metadata to be used for decoding blocks at the given spec versions.
|
/// Set the metadata to be used for decoding blocks at the given spec versions.
|
||||||
pub fn set_metadata_for_spec_versions(
|
pub fn set_metadata_for_spec_versions(
|
||||||
mut self,
|
mut self,
|
||||||
ranges: impl Iterator<Item = (u32, ArcMetadata)>,
|
ranges: impl IntoIterator<Item = (u32, ArcMetadata)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self = Self(self.0.set_metadata_for_spec_versions(ranges));
|
self = Self(self.0.set_metadata_for_spec_versions(ranges));
|
||||||
self
|
self
|
||||||
@@ -45,7 +45,7 @@ impl PolkadotConfigBuilder {
|
|||||||
/// to this configuration.
|
/// to this configuration.
|
||||||
pub fn set_spec_version_for_block_ranges(
|
pub fn set_spec_version_for_block_ranges(
|
||||||
mut self,
|
mut self,
|
||||||
ranges: impl Iterator<Item = SpecVersionForRange>,
|
ranges: impl IntoIterator<Item = SpecVersionForRange>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self = Self(self.0.set_spec_version_for_block_ranges(ranges));
|
self = Self(self.0.set_spec_version_for_block_ranges(ranges));
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ impl SubstrateConfigBuilder {
|
|||||||
/// Set the metadata to be used for decoding blocks at the given spec versions.
|
/// Set the metadata to be used for decoding blocks at the given spec versions.
|
||||||
pub fn set_metadata_for_spec_versions(
|
pub fn set_metadata_for_spec_versions(
|
||||||
self,
|
self,
|
||||||
ranges: impl Iterator<Item = (u32, ArcMetadata)>,
|
ranges: impl IntoIterator<Item = (u32, ArcMetadata)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut map = self.metadata_for_spec_version.lock().unwrap();
|
let mut map = self.metadata_for_spec_version.lock().unwrap();
|
||||||
for (spec_version, metadata) in ranges {
|
for (spec_version, metadata) in ranges.into_iter() {
|
||||||
map.insert(spec_version, metadata);
|
map.insert(spec_version, metadata);
|
||||||
}
|
}
|
||||||
drop(map);
|
drop(map);
|
||||||
@@ -74,10 +74,10 @@ impl SubstrateConfigBuilder {
|
|||||||
/// to this configuration.
|
/// to this configuration.
|
||||||
pub fn set_spec_version_for_block_ranges(
|
pub fn set_spec_version_for_block_ranges(
|
||||||
mut self,
|
mut self,
|
||||||
ranges: impl Iterator<Item = SpecVersionForRange>,
|
ranges: impl IntoIterator<Item = SpecVersionForRange>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut m = RangeMap::builder();
|
let mut m = RangeMap::builder();
|
||||||
for version_for_range in ranges {
|
for version_for_range in ranges.into_iter() {
|
||||||
let start = version_for_range.block_range.start;
|
let start = version_for_range.block_range.start;
|
||||||
let end = version_for_range.block_range.end;
|
let end = version_for_range.block_range.end;
|
||||||
let spec_version = version_for_range.spec_version;
|
let spec_version = version_for_range.spec_version;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
|
mod address;
|
||||||
|
|
||||||
use crate::client::OfflineClientAtBlockT;
|
use crate::client::OfflineClientAtBlockT;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::ConstantError;
|
use crate::error::ConstantError;
|
||||||
use address::Address;
|
|
||||||
use frame_decode::constants::ConstantTypeInfo;
|
use frame_decode::constants::ConstantTypeInfo;
|
||||||
use scale_decode::IntoVisitor;
|
use scale_decode::IntoVisitor;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub mod address;
|
pub use address::{Address, DynamicAddress, StaticAddress, dynamic};
|
||||||
|
|
||||||
/// A client for working with storage entries.
|
/// A client for working with storage entries.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
|
mod address;
|
||||||
|
|
||||||
use crate::client::OfflineClientAtBlockT;
|
use crate::client::OfflineClientAtBlockT;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::CustomValueError;
|
use crate::error::CustomValueError;
|
||||||
use crate::utils::Maybe;
|
use crate::utils::Maybe;
|
||||||
use address::Address;
|
|
||||||
use derive_where::derive_where;
|
use derive_where::derive_where;
|
||||||
use frame_decode::custom_values::CustomValueTypeInfo;
|
use frame_decode::custom_values::CustomValueTypeInfo;
|
||||||
use scale_decode::IntoVisitor;
|
use scale_decode::IntoVisitor;
|
||||||
|
|
||||||
pub mod address;
|
pub use address::{Address, DynamicAddress, StaticAddress, dynamic};
|
||||||
|
|
||||||
/// A client for accessing custom values stored in the metadata.
|
/// A client for accessing custom values stored in the metadata.
|
||||||
#[derive_where(Clone; Client)]
|
#[derive_where(Clone; Client)]
|
||||||
|
|||||||
@@ -4,13 +4,11 @@
|
|||||||
|
|
||||||
//! Construct addresses to access custom values with.
|
//! Construct addresses to access custom values with.
|
||||||
|
|
||||||
|
use crate::utils::{Maybe, NoMaybe};
|
||||||
use derive_where::derive_where;
|
use derive_where::derive_where;
|
||||||
use scale_decode::DecodeAsType;
|
use scale_decode::DecodeAsType;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// Use this with [`Address::IsDecodable`].
|
|
||||||
pub use crate::utils::{Maybe, No, NoMaybe};
|
|
||||||
|
|
||||||
/// This represents the address of a custom value in the metadata.
|
/// This represents the address of a custom value in the metadata.
|
||||||
/// Anything that implements it can be used to fetch custom values from the metadata.
|
/// Anything that implements it can be used to fetch custom values from the metadata.
|
||||||
/// The trait is implemented by [`str`] for dynamic lookup and [`StaticAddress`] for static queries.
|
/// The trait is implemented by [`str`] for dynamic lookup and [`StaticAddress`] for static queries.
|
||||||
|
|||||||
@@ -7,19 +7,20 @@
|
|||||||
pub use scale_value::{At, Value, value};
|
pub use scale_value::{At, Value, value};
|
||||||
|
|
||||||
// Submit dynamic transactions.
|
// Submit dynamic transactions.
|
||||||
pub use crate::transactions::payload::dynamic as transaction;
|
pub use crate::transactions::dynamic as transaction;
|
||||||
|
pub use crate::transactions::dynamic as tx;
|
||||||
|
|
||||||
// Lookup constants dynamically.
|
// Lookup constants dynamically.
|
||||||
pub use crate::constants::address::dynamic as constant;
|
pub use crate::constants::dynamic as constant;
|
||||||
|
|
||||||
// Lookup storage values dynamically.
|
// Lookup storage values dynamically.
|
||||||
pub use crate::storage::address::dynamic as storage;
|
pub use crate::storage::dynamic as storage;
|
||||||
|
|
||||||
// Execute runtime API function call dynamically.
|
// Execute runtime API function call dynamically.
|
||||||
pub use crate::runtime_apis::payload::dynamic as runtime_api_call;
|
pub use crate::runtime_apis::dynamic as runtime_api_call;
|
||||||
|
|
||||||
// Execute View Function API function call dynamically.
|
// Execute View Function API function call dynamically.
|
||||||
pub use crate::view_functions::payload::dynamic as view_function_call;
|
pub use crate::view_functions::dynamic as view_function_call;
|
||||||
|
|
||||||
/// Obtain a custom value from the metadata.
|
/// Obtain a custom value from the metadata.
|
||||||
pub use crate::custom_values::address::dynamic as custom_value;
|
pub use crate::custom_values::dynamic as custom_value;
|
||||||
|
|||||||
+8
-2
@@ -47,17 +47,23 @@ pub mod dynamic;
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod extrinsics;
|
pub mod extrinsics;
|
||||||
pub mod metadata;
|
|
||||||
pub mod runtime_apis;
|
pub mod runtime_apis;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod transactions;
|
pub mod transactions;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod view_functions;
|
pub mod view_functions;
|
||||||
|
|
||||||
|
// Re-export the [`subxt_metadata`] crate.
|
||||||
|
pub use subxt_metadata as metadata;
|
||||||
|
|
||||||
|
// A shorthand to match previous versions and the
|
||||||
|
// tx shorthand in other places.
|
||||||
|
pub use transactions as tx;
|
||||||
|
|
||||||
// Expose a few of the most common types at root,
|
// Expose a few of the most common types at root,
|
||||||
// but leave most types behind their respective modules.
|
// but leave most types behind their respective modules.
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
client::{OfflineClient, OnlineClient},
|
client::{OfflineClient, OfflineClientAtBlock, OnlineClient, OnlineClientAtBlock},
|
||||||
config::{Config, PolkadotConfig, SubstrateConfig},
|
config::{Config, PolkadotConfig, SubstrateConfig},
|
||||||
error::Error,
|
error::Error,
|
||||||
metadata::{ArcMetadata, Metadata},
|
metadata::{ArcMetadata, Metadata},
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
// Re-export everything from subxt-metadata here.
|
|
||||||
pub use subxt_metadata::*;
|
|
||||||
|
|
||||||
/// A cheaply clonable version of our [`Metadata`].
|
|
||||||
pub type ArcMetadata = Arc<Metadata>;
|
|
||||||
@@ -2,15 +2,16 @@
|
|||||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||||
// see LICENSE for license details.
|
// see LICENSE for license details.
|
||||||
|
|
||||||
|
mod payload;
|
||||||
|
|
||||||
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::RuntimeApiError;
|
use crate::error::RuntimeApiError;
|
||||||
use derive_where::derive_where;
|
use derive_where::derive_where;
|
||||||
use payload::Payload;
|
|
||||||
use scale_decode::IntoVisitor;
|
use scale_decode::IntoVisitor;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub mod payload;
|
pub use payload::{DynamicPayload, Payload, StaticPayload, dynamic};
|
||||||
|
|
||||||
/// Execute runtime API calls.
|
/// Execute runtime API calls.
|
||||||
#[derive_where(Clone; Client)]
|
#[derive_where(Clone; Client)]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
mod address;
|
||||||
mod prefix_of;
|
mod prefix_of;
|
||||||
mod storage_entry;
|
mod storage_entry;
|
||||||
mod storage_key;
|
mod storage_key;
|
||||||
@@ -8,18 +9,17 @@ use crate::backend::BackendExt;
|
|||||||
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::StorageError;
|
use crate::error::StorageError;
|
||||||
use address::Address;
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use frame_decode::helpers::Entry;
|
use frame_decode::helpers::Entry;
|
||||||
use frame_decode::storage::StorageEntryInfo;
|
use frame_decode::storage::StorageEntryInfo;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
pub use address::{Address, DynamicAddress, StaticAddress, dynamic};
|
||||||
pub use prefix_of::PrefixOf;
|
pub use prefix_of::PrefixOf;
|
||||||
pub use storage_entry::StorageEntry;
|
pub use storage_entry::StorageEntry;
|
||||||
pub use storage_key::{StorageKey, StorageKeyPart};
|
pub use storage_key::{StorageKey, StorageKeyPart};
|
||||||
pub use storage_key_value::StorageKeyValue;
|
pub use storage_key_value::StorageKeyValue;
|
||||||
pub use storage_value::StorageValue;
|
pub use storage_value::StorageValue;
|
||||||
pub mod address;
|
|
||||||
|
|
||||||
/// A client for working with storage entries.
|
/// A client for working with storage entries.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
mod account_nonce;
|
mod account_nonce;
|
||||||
mod default_params;
|
mod default_params;
|
||||||
|
mod payload;
|
||||||
mod signer;
|
mod signer;
|
||||||
mod transaction_progress;
|
mod transaction_progress;
|
||||||
mod validation_result;
|
mod validation_result;
|
||||||
|
|
||||||
pub mod payload;
|
|
||||||
|
|
||||||
use crate::backend::{BackendExt, TransactionStatus as BackendTransactionStatus};
|
use crate::backend::{BackendExt, TransactionStatus as BackendTransactionStatus};
|
||||||
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
||||||
use crate::config::extrinsic_params::Params;
|
use crate::config::extrinsic_params::Params;
|
||||||
@@ -20,7 +19,7 @@ use sp_crypto_hashing::blake2_256;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
pub use default_params::DefaultParams;
|
pub use default_params::DefaultParams;
|
||||||
pub use payload::Payload;
|
pub use payload::{DynamicPayload, Payload, StaticPayload, dynamic};
|
||||||
pub use signer::Signer;
|
pub use signer::Signer;
|
||||||
pub use transaction_progress::{TransactionProgress, TransactionStatus};
|
pub use transaction_progress::{TransactionProgress, TransactionStatus};
|
||||||
pub use validation_result::{
|
pub use validation_result::{
|
||||||
|
|||||||
@@ -2,15 +2,16 @@
|
|||||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||||
// see LICENSE for license details.
|
// see LICENSE for license details.
|
||||||
|
|
||||||
|
mod payload;
|
||||||
|
|
||||||
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::ViewFunctionError;
|
use crate::error::ViewFunctionError;
|
||||||
use derive_where::derive_where;
|
use derive_where::derive_where;
|
||||||
use payload::Payload;
|
|
||||||
use scale_decode::IntoVisitor;
|
use scale_decode::IntoVisitor;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub mod payload;
|
pub use payload::{DynamicPayload, Payload, StaticPayload, dynamic};
|
||||||
|
|
||||||
/// The name of the Runtime API call which can execute
|
/// The name of the Runtime API call which can execute
|
||||||
const CALL_NAME: &str = "RuntimeViewFunction_execute_view_function";
|
const CALL_NAME: &str = "RuntimeViewFunction_execute_view_function";
|
||||||
|
|||||||
@@ -193,4 +193,4 @@ mod test {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ mod error;
|
|||||||
#[cfg(feature = "url")]
|
#[cfg(feature = "url")]
|
||||||
mod url;
|
mod url;
|
||||||
#[cfg(feature = "url")]
|
#[cfg(feature = "url")]
|
||||||
pub use url::{from_url, from_url_blocking, MetadataVersion, Url};
|
pub use url::{MetadataVersion, Url, from_url, from_url_blocking};
|
||||||
|
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
//! Fetch metadata from a URL.
|
//! Fetch metadata from a URL.
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
core::client::ClientT, http_client::HttpClientBuilder, rpc_params, ws_client::WsClientBuilder,
|
core::client::ClientT, http_client::HttpClientBuilder, rpc_params, ws_client::WsClientBuilder,
|
||||||
};
|
};
|
||||||
@@ -44,7 +44,11 @@ impl std::str::FromStr for MetadataVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the metadata bytes from the provided URL.
|
/// Returns the metadata bytes from the provided URL.
|
||||||
pub async fn from_url(url: Url, version: MetadataVersion, at_block_hash: Option<&str>) -> Result<Vec<u8>, Error> {
|
pub async fn from_url(
|
||||||
|
url: Url,
|
||||||
|
version: MetadataVersion,
|
||||||
|
at_block_hash: Option<&str>,
|
||||||
|
) -> Result<Vec<u8>, Error> {
|
||||||
let bytes = match url.scheme() {
|
let bytes = match url.scheme() {
|
||||||
"http" | "https" => fetch_metadata_http(url, version, at_block_hash).await,
|
"http" | "https" => fetch_metadata_http(url, version, at_block_hash).await,
|
||||||
"ws" | "wss" => fetch_metadata_ws(url, version, at_block_hash).await,
|
"ws" | "wss" => fetch_metadata_ws(url, version, at_block_hash).await,
|
||||||
@@ -55,7 +59,11 @@ pub async fn from_url(url: Url, version: MetadataVersion, at_block_hash: Option<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the metadata bytes from the provided URL, blocking the current thread.
|
/// Returns the metadata bytes from the provided URL, blocking the current thread.
|
||||||
pub fn from_url_blocking(url: Url, version: MetadataVersion, at_block_hash: Option<&str>) -> Result<Vec<u8>, Error> {
|
pub fn from_url_blocking(
|
||||||
|
url: Url,
|
||||||
|
version: MetadataVersion,
|
||||||
|
at_block_hash: Option<&str>,
|
||||||
|
) -> Result<Vec<u8>, Error> {
|
||||||
tokio_block_on(from_url(url, version, at_block_hash))
|
tokio_block_on(from_url(url, version, at_block_hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +76,11 @@ fn tokio_block_on<T, Fut: std::future::Future<Output = T>>(fut: Fut) -> T {
|
|||||||
.block_on(fut)
|
.block_on(fut)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_metadata_ws(url: Url, version: MetadataVersion, at_block_hash: Option<&str>) -> Result<Vec<u8>, Error> {
|
async fn fetch_metadata_ws(
|
||||||
|
url: Url,
|
||||||
|
version: MetadataVersion,
|
||||||
|
at_block_hash: Option<&str>,
|
||||||
|
) -> Result<Vec<u8>, Error> {
|
||||||
let client = WsClientBuilder::default()
|
let client = WsClientBuilder::default()
|
||||||
.request_timeout(std::time::Duration::from_secs(180))
|
.request_timeout(std::time::Duration::from_secs(180))
|
||||||
.max_buffer_capacity_per_subscription(4096)
|
.max_buffer_capacity_per_subscription(4096)
|
||||||
@@ -78,7 +90,11 @@ async fn fetch_metadata_ws(url: Url, version: MetadataVersion, at_block_hash: Op
|
|||||||
fetch_metadata(client, version, at_block_hash).await
|
fetch_metadata(client, version, at_block_hash).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_metadata_http(url: Url, version: MetadataVersion, at_block_hash: Option<&str>) -> Result<Vec<u8>, Error> {
|
async fn fetch_metadata_http(
|
||||||
|
url: Url,
|
||||||
|
version: MetadataVersion,
|
||||||
|
at_block_hash: Option<&str>,
|
||||||
|
) -> Result<Vec<u8>, Error> {
|
||||||
let client = HttpClientBuilder::default()
|
let client = HttpClientBuilder::default()
|
||||||
.request_timeout(std::time::Duration::from_secs(180))
|
.request_timeout(std::time::Duration::from_secs(180))
|
||||||
.build(url)?;
|
.build(url)?;
|
||||||
@@ -87,12 +103,16 @@ async fn fetch_metadata_http(url: Url, version: MetadataVersion, at_block_hash:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The innermost call to fetch metadata:
|
/// The innermost call to fetch metadata:
|
||||||
async fn fetch_metadata(client: impl ClientT, version: MetadataVersion, at_block_hash: Option<&str>) -> Result<Vec<u8>, Error> {
|
async fn fetch_metadata(
|
||||||
|
client: impl ClientT,
|
||||||
|
version: MetadataVersion,
|
||||||
|
at_block_hash: Option<&str>,
|
||||||
|
) -> Result<Vec<u8>, Error> {
|
||||||
const UNSTABLE_METADATA_VERSION: u32 = u32::MAX;
|
const UNSTABLE_METADATA_VERSION: u32 = u32::MAX;
|
||||||
|
|
||||||
// Ensure always 0x prefix.
|
// Ensure always 0x prefix.
|
||||||
let at_block_hash = at_block_hash
|
let at_block_hash =
|
||||||
.map(|hash| format!("0x{}", hash.strip_prefix("0x").unwrap_or(hash)));
|
at_block_hash.map(|hash| format!("0x{}", hash.strip_prefix("0x").unwrap_or(hash)));
|
||||||
let at_block_hash = at_block_hash.as_deref();
|
let at_block_hash = at_block_hash.as_deref();
|
||||||
|
|
||||||
// Fetch available metadata versions. If error, revert to legacy metadata code.
|
// Fetch available metadata versions. If error, revert to legacy metadata code.
|
||||||
@@ -101,7 +121,10 @@ async fn fetch_metadata(client: impl ClientT, version: MetadataVersion, at_block
|
|||||||
at_block_hash: Option<&str>,
|
at_block_hash: Option<&str>,
|
||||||
) -> Result<Vec<u32>, Error> {
|
) -> Result<Vec<u32>, Error> {
|
||||||
let res: String = client
|
let res: String = client
|
||||||
.request("state_call", rpc_params!["Metadata_metadata_versions", "0x", at_block_hash])
|
.request(
|
||||||
|
"state_call",
|
||||||
|
rpc_params!["Metadata_metadata_versions", "0x", at_block_hash],
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let raw_bytes = hex::decode(res.trim_start_matches("0x"))?;
|
let raw_bytes = hex::decode(res.trim_start_matches("0x"))?;
|
||||||
Decode::decode(&mut &raw_bytes[..]).map_err(Into::into)
|
Decode::decode(&mut &raw_bytes[..]).map_err(Into::into)
|
||||||
@@ -170,7 +193,10 @@ async fn fetch_metadata(client: impl ClientT, version: MetadataVersion, at_block
|
|||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
// Fetch the metadata.
|
// Fetch the metadata.
|
||||||
let metadata_string: String = client
|
let metadata_string: String = client
|
||||||
.request("state_call", rpc_params!["Metadata_metadata", "0x", at_block_hash])
|
.request(
|
||||||
|
"state_call",
|
||||||
|
rpc_params!["Metadata_metadata", "0x", at_block_hash],
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Decode the metadata.
|
// Decode the metadata.
|
||||||
@@ -182,12 +208,15 @@ async fn fetch_metadata(client: impl ClientT, version: MetadataVersion, at_block
|
|||||||
match fetch_available_versions(&client, at_block_hash).await {
|
match fetch_available_versions(&client, at_block_hash).await {
|
||||||
Ok(supported_versions) => {
|
Ok(supported_versions) => {
|
||||||
fetch_inner(&client, version, supported_versions, at_block_hash).await
|
fetch_inner(&client, version, supported_versions, at_block_hash).await
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// The "new" interface failed. if the user is asking for V14 or the "latest"
|
// The "new" interface failed. if the user is asking for V14 or the "latest"
|
||||||
// metadata then try the legacy interface instead. Else, just return the
|
// metadata then try the legacy interface instead. Else, just return the
|
||||||
// reason for failure.
|
// reason for failure.
|
||||||
if matches!(version, MetadataVersion::Version(14) | MetadataVersion::Latest) {
|
if matches!(
|
||||||
|
version,
|
||||||
|
MetadataVersion::Version(14) | MetadataVersion::Latest
|
||||||
|
) {
|
||||||
fetch_inner_legacy(&client, at_block_hash).await
|
fetch_inner_legacy(&client, at_block_hash).await
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
|
|||||||
Reference in New Issue
Block a user