fix: Convert vendor/pezkuwi-subxt from submodule to regular directory

This commit is contained in:
2025-12-19 16:45:24 +03:00
parent 9a52edf0df
commit fdd023c499
393 changed files with 154124 additions and 1 deletions
+103
View File
@@ -0,0 +1,103 @@
// 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 Polkadot 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 Polkadot 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 [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 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()).
//!
+55
View File
@@ -0,0 +1,55 @@
// 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.
//! # Constants
//!
//! There are various constants stored in a node; the types and values of these are defined in a
//! runtime, and can only change when the runtime is updated. Much like [`super::storage`], we can
//! query these using Subxt by taking the following steps:
//!
//! 1. [Constructing a constant query](#constructing-a-query).
//! 2. [Submitting the query to get back the associated value](#submitting-it).
//!
//! ## Constructing a constant query
//!
//! We can use the statically generated interface to build constant queries:
//!
//! ```rust,no_run,standalone_crate
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")]
//! pub mod polkadot {}
//!
//! let constant_query = polkadot::constants().system().block_length();
//! ```
//!
//! Alternately, we can dynamically construct a constant query. A dynamic query needs the return
//! type to be specified, where we can use [`crate::dynamic::Value`] if unsure:
//!
//! ```rust,no_run,standalone_crate
//! use subxt::dynamic::Value;
//!
//! let storage_query = subxt::dynamic::constant::<Value>("System", "BlockLength");
//! ```
//!
//! ## Submitting it
//!
//! Call [`crate::constants::ConstantsClient::at()`] to return and decode the constant into the
//! type given by the address, or [`crate::constants::ConstantsClient::bytes_at()`] to return the
//! raw bytes for some constant.
//!
//! Constant values are pulled directly out of the node metadata which Subxt has
//! already acquired, and so this function requires no network access and is available from a
//! [`crate::OfflineClient`].
//!
//! Here's an example using a static query:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/constants_static.rs")]
//! ```
//!
//! And here's one using a dynamic query:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/constants_dynamic.rs")]
//! ```
//!
@@ -0,0 +1,69 @@
// 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.
//! # Custom Values
//!
//! Substrate-based chains can expose custom values in their metadata.
//! Each of these values:
//!
//! - can be accessed by a unique __name__.
//! - refers to a concrete __type__ stored in the metadata.
//! - contains a scale encoded __value__ of that type.
//!
//! ## Getting a custom value
//!
//! First, you must construct an address to access a custom value. This can be either:
//! - a raw [`str`] which assumes the return type to be the dynamic [`crate::dynamic::Value`] type,
//! - created via [`dynamic`](crate::custom_values::dynamic) function whereby you set the return type
//! that you want back,
//! - created via statically generated addresses as part of the `#[subxt]` macro which define the return type.
//!
//! With an address, use [`at`](crate::custom_values::CustomValuesClient::at) to access and decode specific values, and
//! [`bytes_at`](crate::custom_values::CustomValuesClient::bytes_at) to access the raw bytes.
//!
//! ## Examples
//!
//! Dynamically accessing a custom value using a [`str`] to select which one:
//!
//! ```rust,ignore
//! use subxt::{OnlineClient, PolkadotConfig, ext::scale_decode::DecodeAsType};
//! use subxt::dynamic::Value;
//!
//! let api = OnlineClient::<PolkadotConfig>::new().await?;
//! let custom_value_client = api.custom_values();
//! let foo: Value = custom_value_client.at("foo")?;
//! ```
//!
//! Use the [`dynamic`](crate::custom_values::dynamic) function to select the return type:
//!
//! ```rust,ignore
//! use subxt::{OnlineClient, PolkadotConfig, ext::scale_decode::DecodeAsType};
//!
//! #[derive(Decode, DecodeAsType, Debug)]
//! struct Foo {
//! n: u8,
//! b: bool,
//! }
//!
//! let api = OnlineClient::<PolkadotConfig>::new().await?;
//! let custom_value_client = api.custom_values();
//! let custom_value_addr = subxt::custom_values::dynamic::<Foo>("foo");
//! let foo: Foo = custom_value_client.at(&custom_value_addr)?;
//! ```
//!
//! Alternatively we also provide a statically generated api for custom values:
//!
//! ```rust,ignore
//! #[subxt::subxt(runtime_metadata_path = "some_metadata.scale")]
//! pub mod interface {}
//!
//! let static_address = interface::custom().foo();
//!
//! let api = OnlineClient::<PolkadotConfig>::new().await?;
//! let custom_value_client = api.custom_values();
//!
//! // Now the `at()` function already decodes the value into the Foo type:
//! let foo = custom_value_client.at(&static_address)?;
//! ```
//!
+49
View File
@@ -0,0 +1,49 @@
// 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.
//! # Events
//!
//! In the process of adding extrinsics to a block, they are executed. When extrinsics are executed,
//! they normally produce events describing what's happening (at the very least, an event dictating whether
//! the extrinsic has succeeded or failed). The node may also emit some events of its own as the block is
//! processed.
//!
//! Events live in a single location in node storage which is overwritten at each block. Normal nodes tend to
//! keep a snapshot of the state at a small number of previous blocks, so you can sometimes access
//! older events by using [`crate::events::EventsClient::at()`] and providing an older block hash.
//!
//! When we submit transactions using Subxt, methods like [`crate::tx::TxProgress::wait_for_finalized_success()`]
//! return [`crate::blocks::ExtrinsicEvents`], which can be used to iterate and inspect the events produced
//! by that transaction being executed. We can also access _all_ of the events produced in a single block using one
//! of these two interfaces:
//!
//! ```rust,no_run,standalone_crate
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use subxt::client::OnlineClient;
//! use subxt::config::PolkadotConfig;
//!
//! // Create client:
//! let client = OnlineClient::<PolkadotConfig>::new().await?;
//!
//! // Get events from the latest block (use .at() to specify a block hash):
//! let events = client.blocks().at_latest().await?.events().await?;
//! // We can use this shorthand too:
//! let events = client.events().at_latest().await?;
//! # Ok(())
//! # }
//! ```
//!
//! Once we've loaded our events, we can iterate all events or search for specific events via
//! methods like [`crate::events::Events::iter()`] and [`crate::events::Events::find()`]. See
//! [`crate::events::Events`] and [`crate::events::EventDetails`] for more information.
//!
//! ## Example
//!
//! Here's an example which puts this all together:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/events.rs")]
//! ```
//!
@@ -0,0 +1,51 @@
// 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.
//! # Light Client
//!
//! The light client based interface uses _Smoldot_ to connect to a _chain_, rather than an individual
//! node. This means that you don't have to trust a specific node when interacting with some chain.
//!
//! This feature is currently unstable. Use the `unstable-light-client` feature flag to enable it.
//! To use this in WASM environments, enable the `web` feature flag and disable the "native" one.
//!
//! To connect to a blockchain network, the Light Client requires a trusted sync state of the network,
//! known as a _chain spec_. One way to obtain this is by making a `sync_state_genSyncSpec` RPC call to a
//! trusted node belonging to the chain that you wish to interact with.
//!
//! Subxt exposes a utility method to obtain the chain spec: [`crate::utils::fetch_chainspec_from_rpc_node()`].
//! Alternately, you can manually make an RPC call to `sync_state_genSyncSpec` like do (assuming a node running
//! locally on port 9933):
//!
//! ```bash
//! curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "sync_state_genSyncSpec", "params":[true]}' http://localhost:9933/ | jq .result > chain_spec.json
//! ```
//!
//! ## Examples
//!
//! ### Basic Example
//!
//! This basic example uses some already-known chain specs to connect to a relay chain and parachain
//! and stream information about their finalized blocks:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/light_client_basic.rs")]
//! ```
//!
//! ### Connecting to a local node
//!
//! This example connects to a local chain and submits a transaction. To run this, you first need
//! to have a local polkadot node running using the following command:
//!
//! ```text
//! polkadot --dev --node-key 0000000000000000000000000000000000000000000000000000000000000001
//! ```
//!
//! Then, the following code will download a chain spec from this local node, alter the bootnodes
//! to point only to the local node, and then submit a transaction through it.
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/light_client_local_node.rs")]
//! ```
//!
+27
View File
@@ -0,0 +1,27 @@
// 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.
//! This modules contains examples of using Subxt; follow the links for more:
//!
//! - [Transactions](transactions)
//! - [Storage](storage)
//! - [Events](events)
//! - [Constants](constants)
//! - [Blocks](blocks)
//! - [Runtime APIs](runtime_apis)
//! - [Unstable Light Client](light_client)
//! - [Custom Values](custom_values)
//! - [RPC calls](rpc)
//!
//! Alternately, [go back](super).
pub mod blocks;
pub mod constants;
pub mod custom_values;
pub mod events;
pub mod light_client;
pub mod rpc;
pub mod runtime_apis;
pub mod storage;
pub mod transactions;
+22
View File
@@ -0,0 +1,22 @@
// 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.
//! # RPC calls
//!
//! The RPC interface is provided by the [`pezkuwi_subxt_rpcs`] crate but re-exposed here. We have:
//!
//! - [`crate::backend::rpc::RpcClient`] and [`crate::backend::rpc::RpcClientT`]: the underlying type and trait
//! which provides a basic RPC client.
//! - [`crate::backend::legacy::rpc_methods`] and [`crate::backend::chain_head::rpc_methods`]: RPc methods that
//! can be instantiated with an RPC client.
//!
//! See [`pezkuwi_subxt_rpcs`] or [`crate::ext::pezkuwi_subxt_rpcs`] for more.
//!
//! # Example
//!
//! Here's an example which calls some legacy JSON-RPC methods, and reuses the same connection to run a full Subxt client
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/rpc_legacy.rs")]
//! ```
@@ -0,0 +1,80 @@
// 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.
//! # Runtime API interface
//!
//! The Runtime API interface allows Subxt to call runtime APIs exposed by certain pallets in order
//! to obtain information. Much like [`super::storage`] and [`super::transactions`], Making a runtime
//! call to a node and getting the response back takes the following steps:
//!
//! 1. [Constructing a runtime call](#constructing-a-runtime-call)
//! 2. [Submitting it to get back the response](#submitting-it)
//!
//! **Note:** Runtime APIs are only available when using V15 metadata, which is currently unstable.
//! You'll need to use `subxt metadata --version unstable` command to download the unstable V15 metadata,
//! and activate the `unstable-metadata` feature in Subxt for it to also use this metadata from a node. The
//! metadata format is unstable because it may change and break compatibility with Subxt at any moment, so
//! use at your own risk.
//!
//! ## Constructing a runtime call
//!
//! We can use the statically generated interface to build runtime calls:
//!
//! ```rust,no_run,standalone_crate
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
//! pub mod polkadot {}
//!
//! let runtime_call = polkadot::apis().metadata().metadata_versions();
//! ```
//!
//! Alternately, we can dynamically construct a runtime call. The input type can be a tuple or
//! vec or valid types implementing [`scale_encode::EncodeAsType`], and the output can be anything
//! implementing [`scale_decode::DecodeAsType`]:
//!
//! ```rust,no_run
//! use subxt::dynamic::Value;
//!
//! let runtime_call = subxt::dynamic::runtime_api_call::<(), Vec<u32>>(
//! "Metadata",
//! "metadata_versions",
//! ()
//! );
//! ```
//!
//! All valid runtime calls implement [`crate::runtime_api::Payload`], a trait which
//! describes how to encode the runtime call arguments and what return type to decode from the
//! response.
//!
//! ## Submitting it
//!
//! Runtime calls can be handed to [`crate::runtime_api::RuntimeApi::call()`], which will submit
//! them and hand back the associated response.
//!
//! ### Making a static Runtime API call
//!
//! The easiest way to make a runtime API call is to use the statically generated interface.
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/runtime_apis_static.rs")]
//! ```
//!
//! ### Making a dynamic Runtime API call
//!
//! If you'd prefer to construct the call at runtime, you can do this using the
//! [`crate::dynamic::runtime_api_call`] method.
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/runtime_apis_dynamic.rs")]
//! ```
//!
//! ### Making a raw call
//!
//! This is generally discouraged in favour of one of the above, but may be necessary (especially if
//! the node you're talking to does not yet serve V15 metadata). Here, you must manually encode
//! the argument bytes and manually provide a type for the response bytes to be decoded into.
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/runtime_apis_raw.rs")]
//! ```
//!
+82
View File
@@ -0,0 +1,82 @@
// 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.
//! # Storage
//!
//! A Substrate based chain can be seen as a key/value database which starts off at some initial
//! state, and is modified by the extrinsics in each block. This database is referred to as the
//! node storage. With Subxt, you can query this key/value storage with the following steps:
//!
//! 1. [Constructing a storage query](#constructing-a-storage-query).
//! 2. [Submitting the query to get back the associated entry](#submitting-it).
//! 3. [Fetching](#fetching-storage-entries) or [iterating](#iterating-storage-entries) over that
//! entry to retrieve the value or values within it.
//!
//! ## Constructing a storage query
//!
//! We can use the statically generated interface to build storage queries:
//!
//! ```rust,no_run,standalone_crate
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
//! pub mod polkadot {}
//!
//! let storage_query = polkadot::storage().system().account();
//! ```
//!
//! Alternately, we can dynamically construct a storage query. A dynamic query needs the input
//! and return value types to be specified, where we can use [`crate::dynamic::Value`] if unsure.
//!
//! ```rust,no_run,standalone_crate
//! use subxt::dynamic::Value;
//!
//! let storage_query = subxt::dynamic::storage::<(Value,), Value>("System", "Account");
//! ```
//!
//! ## Submitting it
//!
//! Storage queries can be handed to various functions in [`crate::storage::StorageClientAt`] in order to
//! obtain the associated values (also referred to as storage entries) back.
//!
//! The core API here is [`crate::storage::StorageClientAt::entry()`], which takes a query and looks up the
//! corresponding storage entry, from which you can then fetch or iterate over the values contained within.
//! [`crate::storage::StorageClientAt::fetch()`] and [`crate::storage::StorageClientAt::iter()`] are shorthand
//! for this.
//!
//! When you wish to manually query some entry, [`crate::storage::StorageClientAt::fetch_raw()`] exists to take
//! in raw bytes pointing at some storage value, and return the value bytes if possible. [`crate::storage::StorageClientAt::storage_version()`]
//! and [`crate::storage::StorageClientAt::runtime_wasm_code()`] use this to retrieve the version of some storage API
//! and the current Runtime WASM blob respectively.
//!
//! ### Fetching storage entries
//!
//! The simplest way to access storage entries is to construct a query and then call either
//! [`crate::storage::StorageClientAt::fetch()`]:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/storage_fetch.rs")]
//! ```
//!
//! For completeness, below is an example using a dynamic query instead. Dynamic queries can define the types that
//! they wish to accept inputs and decode the return value into ([`crate::dynamic::Value`] can be used here anywhere we
//! are not sure of the specific types).
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/storage_fetch_dynamic.rs")]
//! ```
//!
//! ### Iterating storage entries
//!
//! Many storage entries are maps of values; as well as fetching individual values, it's possible to
//! iterate over all of the values stored at that location:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/storage_iterating.rs")]
//! ```
//!
//! Here's the same logic but using dynamically constructed values instead:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/storage_iterating_dynamic.rs")]
//! ```
//!
@@ -0,0 +1,202 @@
// 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.
//! # Transactions
//!
//! A transaction is an extrinsic that's signed (ie it originates from a given address). The purpose
//! of extrinsics is to modify the node storage in a deterministic way, and so being able to submit
//! transactions to a node is one of the core features of Subxt.
//!
//! > Note: the documentation tends to use the terms _extrinsic_ and _transaction_ interchangeably;
//! > An extrinsic is some data that can be added to a block, and is either signed (a _transaction_)
//! > or unsigned (an _inherent_). Subxt can construct either, but overwhelmingly you'll need to
//! > sign the payload you'd like to submit.
//!
//! Submitting a transaction to a node consists of the following steps:
//!
//! 1. [Constructing a transaction payload to submit](#constructing-a-transaction-payload).
//! 2. [Signing it](#signing-it).
//! 3. [Submitting it (optionally with some additional parameters)](#submitting-it).
//!
//! We'll look at each of these steps in turn.
//!
//! ## Constructing a transaction payload
//!
//! We can use the statically generated interface to build transaction payloads:
//!
//! ```rust,no_run,standalone_crate
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
//! pub mod polkadot {}
//!
//! let remark = "Hello there".as_bytes().to_vec();
//! let tx_payload = polkadot::tx().system().remark(remark);
//! ```
//!
//! > If you're not sure what types to import and use to build a given payload, you can use the
//! > `subxt` CLI tool to generate the interface by using something like `subxt codegen | rustfmt >
//! > interface.rs`, to see what types and things are available (or even just to use directly
//! > instead of the [`#[subxt]`](crate::subxt) macro).
//!
//! Alternately, we can dynamically construct a transaction payload. This will not be type checked or
//! validated until it's submitted:
//!
//! ```rust,no_run,standalone_crate
//! use subxt::dynamic::Value;
//!
//! let tx_payload = subxt::dynamic::tx("System", "remark", vec![
//! Value::from_bytes("Hello there")
//! ]);
//! ```
//!
//! The [`crate::dynamic::Value`] type is a dynamic type much like a `serde_json::Value` but instead
//! represents any type of data that can be SCALE encoded or decoded. It can be serialized,
//! deserialized and parsed from/to strings.
//!
//! A valid transaction payload is just something that implements the [`crate::tx::Payload`] trait;
//! you can implement this trait on your own custom types if the built-in ones are not suitable for
//! your needs.
//!
//! ## Signing it
//!
//! You'll normally need to sign an extrinsic to prove that it originated from an account that you
//! control. To do this, you will typically first create a [`crate::tx::Signer`] instance, which tells
//! Subxt who the extrinsic is from, and takes care of signing the relevant details to prove this.
//!
//! There are two main ways to create a compatible signer instance:
//! 1. The `pezkuwi_subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`]
//! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled).
//! 2. Alternately, implement your own [`crate::tx::Signer`] instance by wrapping it in a new type pattern.
//!
//! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via
//! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or
//! need additional signing algorithms that `pezkuwi_subxt_signer` doesn't support, and don't care about WASM
//! compatibility.
//!
//! Because 2 is more complex and require more code, we'll focus on 1 here.
//! For 2, see the example in `subxt/examples/substrate_compat_signer.rs` how
//! you can integrate things like sp_core's signer in subxt.
//!
//! Let's go through how to create a signer using the `pezkuwi_subxt_signer` crate:
//!
//! ```rust,standalone_crate
//! use subxt::config::PolkadotConfig;
//! use std::str::FromStr;
//!
//! use pezkuwi_subxt_signer::{SecretUri, sr25519};
//!
//! // Get hold of a `Signer` for a test account:
//! let alice = sr25519::dev::alice();
//!
//! // Or generate a keypair, here from an SURI:
//! let uri = SecretUri::from_str("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password")
//! .expect("valid URI");
//! let keypair = sr25519::Keypair::from_uri(&uri)
//! .expect("valid keypair");
//!```
//!
//! After initializing the signer, let's also go through how to create a transaction and sign it:
//!
//! ```rust,no_run,standalone_crate
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use subxt::client::OnlineClient;
//! use subxt::config::PolkadotConfig;
//! use subxt::dynamic::Value;
//!
//! // Create client:
//! let client = OnlineClient::<PolkadotConfig>::new().await?;
//!
//! // Create a dummy tx payload to sign:
//! let payload = subxt::dynamic::tx("System", "remark", vec![
//! Value::from_bytes("Hello there")
//! ]);
//!
//! // Construct the tx but don't sign it. The account nonce here defaults to 0.
//! // You can use `create_partial` to fetch the correct nonce.
//! let mut partial_tx = client.tx().create_partial_offline(
//! &payload,
//! Default::default()
//! )?;
//!
//! // Fetch the payload that needs to be signed:
//! let signer_payload = partial_tx.signer_payload();
//!
//! // ... At this point, we can hand off the `signer_payload` to be signed externally.
//! // Ultimately we need to be given back a `signature` (or really, anything
//! // that can be SCALE encoded) and an `address`:
//! let signature;
//! let account_id;
//! # use subxt::tx::Signer;
//! # let signer = pezkuwi_subxt_signer::sr25519::dev::alice();
//! # signature = signer.sign(&signer_payload).into();
//! # account_id = signer.public_key().to_account_id();
//!
//! // Now we can build an tx, which one can call `submit` or `submit_and_watch`
//! // on to submit to a node and optionally watch the status.
//! let tx = partial_tx.sign_with_account_and_signature(
//! &account_id,
//! &signature
//! );
//! # Ok(())
//! # }
//! ```
//!
//! ## Submitting it
//!
//! Once we have signed the transaction, we need to submit it.
//!
//! ### The high level API
//!
//! The highest level approach to doing this is to call
//! [`crate::tx::TxClient::sign_and_submit_then_watch_default`]. This hands back a
//! [`crate::tx::TxProgress`] struct which will monitor the transaction status. We can then call
//! [`crate::tx::TxProgress::wait_for_finalized_success()`] to wait for this transaction to make it
//! into a finalized block, check for an `ExtrinsicSuccess` event, and then hand back the events for
//! inspection. This looks like:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/tx_basic.rs")]
//! ```
//!
//! ### Providing transaction parameters
//!
//! If you'd like to provide parameters (such as mortality) to the transaction, you can use
//! [`crate::tx::TxClient::sign_and_submit_then_watch`] instead:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/tx_with_params.rs")]
//! ```
//!
//! This example doesn't wait for the transaction to be included in a block; it just submits it and
//! hopes for the best!
//!
//! ### Boxing transaction payloads
//!
//! Transaction payloads can be boxed so that they all share a common type and can be stored together.
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/tx_boxed.rs")]
//! ```
//!
//! ### Custom handling of transaction status updates
//!
//! If you'd like more control or visibility over exactly which status updates are being emitted for
//! the transaction, you can monitor them as they are emitted and react however you choose:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/tx_status_stream.rs")]
//! ```
//!
//! ### Signing transactions externally
//!
//! Subxt also allows you to get hold of the signer payload and hand that off to something else to be
//! signed. The signature can then be provided back to Subxt to build the final transaction to submit:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/tx_partial.rs")]
//! ```
//!
//! Take a look at the API docs for [`crate::tx::TxProgress`], [`crate::tx::TxStatus`] and
//! [`crate::tx::TxInBlock`] for more options.
//!