mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 15:11:03 +00:00
Improve Signed Extension and Block Decoding Examples/Book (#1357)
* asset hub example and book adjustment * formatting * recursive derives * polkadot monitor example and book adjustments * formatting * adjust docs and examples, add dynamic example * james suggestions * fmt * chore(subxt/src): typo fix (#1370) * rpcmethods * followstr * mod and else * Weekly Cronjob fetching artifacts and generating polkadot.rs file. (#1352) * github CI action cronjob * add commit message * fix the CI yml files * binary crate for CI script with substrate-runner * update the CI script * correct the artifacts script * remove bash script --------- Co-authored-by: James Wilson <james@jsdw.me> Co-authored-by: Pan chao <152830401+Pan-chao@users.noreply.github.com>
This commit is contained in:
@@ -152,3 +152,15 @@
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str ! ("../../../examples/setup_config_custom.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! ### Using a type from the metadata as a config parameter
|
||||
//!
|
||||
//! You can also use types that are generated from chain metadata as type parameters of the Config trait.
|
||||
//! Just make sure all trait bounds are satisfied. This can often be achieved by using custom derives with the subxt macro.
|
||||
//! For example, the AssetHub Parachain expects tips to include a `MultiLocation`, which is a type we can draw from the metadata.
|
||||
//!
|
||||
//! This example shows what using the `MultiLocation` struct as part of your config would look like in subxt:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str ! ("../../../examples/setup_config_assethub.rs")]
|
||||
//! ```
|
||||
|
||||
@@ -27,13 +27,72 @@
|
||||
//! Aside from these links to other Subxt APIs, the main thing that we can do here is iterate over and
|
||||
//! decode the extrinsics in a block body.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ## Decoding Extrinsics
|
||||
//!
|
||||
//! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and iterate over
|
||||
//! the extrinsics stored within it. From there, you can decode the extrinsics and access various details,
|
||||
//! including the associated events:
|
||||
//! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and [iterate over
|
||||
//! the extrinsics](crate::blocks::Extrinsics::iter()) stored within it. The extrinsics yielded are of type
|
||||
//! [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), which is just a blob of bytes that also stores which
|
||||
//! pallet and call in that pallet it belongs to. It also contains information about signed extensions that
|
||||
//! have been used for submitting this extrinsic.
|
||||
//!
|
||||
//! To use the extrinsic, you probably want to decode it into a concrete Rust type. These Rust types representing
|
||||
//! extrinsics from different pallets can be generated from metadata using the subxt macro or the CLI tool.
|
||||
//!
|
||||
//! When decoding the extrinsic into a static type you have two options:
|
||||
//!
|
||||
//! ### Statically decode the extrinsics into [the root extrinsic type](crate::blocks::ExtrinsicDetails::as_root_extrinsic())
|
||||
//!
|
||||
//! The root extrinsic type generated by subxt is a Rust enum with one variant for each pallet. Each of these
|
||||
//! variants has a field that is another enum whose variants cover all calls of the respective pallet.
|
||||
//! If the extrinsic bytes are valid and your metadata matches the chain's metadata, decoding the bytes of an extrinsic into
|
||||
//! this root extrinsic type should always succeed.
|
||||
//!
|
||||
//! This example shows how to subscribe to blocks and decode the extrinsics in each block into the root extrinsic type.
|
||||
//! Once we get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), we can decode it statically or dynamically.
|
||||
//! We can also access details about the extrinsic, including the associated events and signed extensions.
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../examples/blocks_subscribing.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! ### Statically decode the extrinsic into [a specific pallet call](crate::blocks::ExtrinsicDetails::as_extrinsic())
|
||||
//!
|
||||
//! This is useful if you are expecting a specific extrinsic to be part of some block. If the extrinsic you try to decode
|
||||
//! is a different extrinsic, an `Ok(None)` value is returned from [`as_extrinsic::<T>()`](crate::blocks::ExtrinsicDetails::as_extrinsic());
|
||||
//!
|
||||
//! If you are only interested in finding specific extrinsics in a block, you can also [iterate over all of them](crate::blocks::Extrinsics::find),
|
||||
//! get only [the first one](crate::blocks::Extrinsics::find_first), or [the last one](crate::blocks::Extrinsics::find_last).
|
||||
//!
|
||||
//! The following example monitors `TransferKeepAlive` extrinsics on the Polkadot network.
|
||||
//! We statically decode them and access the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and [account nonce](crate::blocks::ExtrinsicSignedExtensions::nonce()) signed extensions.
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../examples/block_decoding_static.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! ### Dynamically decode the extrinsic
|
||||
//!
|
||||
//! Sometimes you might use subxt with metadata that is not known at compile time. In this case, you do not have access to a statically generated
|
||||
//! interface module that contains the relevant Rust types. You can [decode ExtrinsicDetails dynamically](crate::blocks::ExtrinsicDetails::field_values()),
|
||||
//! which gives you access to it's fields as a [scale value composite](scale_value::Composite).
|
||||
//! The following example looks for signed extrinsics on the Polkadot network and retrieves their pallet name, variant name, data fields and signed extensions dynamically.
|
||||
//! Notice how we do not need to use code generation via the subxt macro. The only fixed component we provide is the [PolkadotConfig](crate::config::PolkadotConfig).
|
||||
//! Other than that it works in a chain-agnostic way:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../examples/block_decoding_dynamic.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! ## Decoding signed extensions
|
||||
//!
|
||||
//! Extrinsics can contain signed extensions. The signed extensions can be different across chains.
|
||||
//! The [Config](crate::Config) implementation for your chain defines which signed extensions you expect.
|
||||
//! Once you get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails) for an extrinsic you are interested in,
|
||||
//! you can try to [get its signed extensions](crate::blocks::ExtrinsicDetails::signed_extensions()).
|
||||
//! These are only available on signed extrinsics. You can try to [find a specific signed extension](crate::blocks::ExtrinsicSignedExtensions::find),
|
||||
//! in the returned [signed extensions](crate::blocks::ExtrinsicSignedExtensions).
|
||||
//!
|
||||
//! Subxt also provides utility functions to get the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and the
|
||||
//! [account nonce](crate::blocks::ExtrinsicSignedExtensions::tip()) associated with an extrinsic, given its signed extensions.
|
||||
//! If you prefer to do things dynamically you can get the data of the signed extension as a [scale value](crate::blocks::ExtrinsicSignedExtension::value()).
|
||||
//!
|
||||
|
||||
Reference in New Issue
Block a user