49485a882c
- Add all missing workspace dependencies required by vendor crates - Include external crates: scale-*, sp-core, sc-chain-spec, kube, etc. - Include subxt dependencies: smoldot, web-time, wasm-bindgen, etc. - Regenerate umbrella crate with updated dependencies - Apply zepter std feature propagation fixes to vendor crates - Apply rustfmt formatting to vendor and pezframe files
105 lines
6.4 KiB
Rust
105 lines
6.4 KiB
Rust
// Copyright 2019-2025 Parity Technologies (UK) Ltd.
|
|
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
|
// see LICENSE for license details.
|
|
|
|
//! # Blocks
|
|
//!
|
|
//! The [blocks API](crate::blocks::BlocksClient) in Subxt unifies many of the other interfaces, and
|
|
//! allows you to:
|
|
//!
|
|
//! - Access information about specific blocks (see [`crate::blocks::BlocksClient::at()`] and
|
|
//! [`crate::blocks::BlocksClient::at_latest()`]).
|
|
//! - Subscribe to [all](crate::blocks::BlocksClient::subscribe_all()),
|
|
//! [best](crate::blocks::BlocksClient::subscribe_best()) or
|
|
//! [finalized](crate::blocks::BlocksClient::subscribe_finalized()) blocks as they are produced.
|
|
//! **Prefer to subscribe to finalized blocks unless you know what you're doing.**
|
|
//!
|
|
//! In either case, you'll end up with [`crate::blocks::Block`]'s, from which you can access various
|
|
//! information about the block, such a the [header](crate::blocks::Block::header()),
|
|
//! [block number](crate::blocks::Block::number()) and [body (the
|
|
//! extrinsics)](crate::blocks::Block::extrinsics()). [`crate::blocks::Block`]'s also provide
|
|
//! shortcuts to other Subxt APIs that will operate at the given block:
|
|
//!
|
|
//! - [storage](crate::blocks::Block::storage()),
|
|
//! - [events](crate::blocks::Block::events())
|
|
//! - [runtime APIs](crate::blocks::Block::runtime_api())
|
|
//!
|
|
//! 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.
|
|
//!
|
|
//! ## Decoding Extrinsics
|
|
//!
|
|
//! 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 transaction
|
|
//! 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 Pezkuwi network.
|
|
//! We statically decode them and access the [tip](crate::blocks::ExtrinsicTransactionExtensions::tip()) and
|
|
//! [account nonce](crate::blocks::ExtrinsicTransactionExtensions::nonce()) transaction 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::decode_as_fields()), 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 Pezkuwi network and retrieves their pallet name, variant name, data
|
|
//! fields and transaction extensions dynamically. Notice how we do not need to use code generation via the
|
|
//! subxt macro. The only fixed component we provide is the [PezkuwiConfig](crate::config::PezkuwiConfig).
|
|
//! Other than that it works in a chain-agnostic way:
|
|
//! ```rust,ignore
|
|
#![doc = include_str!("../../../examples/block_decoding_dynamic.rs")]
|
|
//! ```
|
|
//!
|
|
//! ## Decoding transaction extensions
|
|
//!
|
|
//! Extrinsics can contain transaction extensions. The transaction extensions can be different across chains.
|
|
//! The [Config](crate::Config) implementation for your chain defines which transaction 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 transaction extensions](crate::blocks::ExtrinsicDetails::transaction_extensions()).
|
|
//! These are only available on V4 signed extrinsics or V5 general extrinsics. You can try to
|
|
//! [find a specific transaction extension](crate::blocks::ExtrinsicTransactionExtensions::find), in the returned
|
|
//! [transaction extensions](crate::blocks::ExtrinsicTransactionExtensions).
|
|
//!
|
|
//! Subxt also provides utility functions to get the [tip](crate::blocks::ExtrinsicTransactionExtensions::tip()) and
|
|
//! the [account nonce](crate::blocks::ExtrinsicTransactionExtensions::nonce()) associated with an extrinsic, given
|
|
//! its transaction extensions. If you prefer to do things dynamically you can get the data of the transaction extension
|
|
//! as a [scale value](crate::blocks::ExtrinsicTransactionExtension::value()).
|