Files
pezkuwi-subxt/historic/examples/extrinsics.rs
T
James Wilson 3aabd6dc09 Add subxt-historic crate for accesing historic (non head-of-chain) blocks (#2040)
* WIP subxt-historic

* WIP subxt-historic

* WIP subxt-historic; flesh out basic foundations

* WIP filling in extrinsic decoding functionality

* iter and decode transaction extensions

* Fill in the Online/OfflineClient APIs and move more things to be part of the chain Config

* WIP storage

* clippy, fmt, finish extrinsics example

* prep for 0.0.1 release to claim crate name

* fix README link

* fmt

* WIP thinking about storage APIs

* WIP working out storage APIs

* Storage plain value fetching first pass

* WIP storage: first pass iterating over values done

* First apss finishing storage APIs

* fmt and clippy

* Create a storage example showing fetch and iteration

* Bump to frame-decode 0.9.0

* Bump subxt-historic to 0.0.3 for preview release

* Remove unused deps

* fix import

* clippy

* doc fixes

* tweak CI and fix some cargo hack findings

* Update README: subxt-historic is prerelease
2025-08-26 17:56:21 +01:00

84 lines
3.1 KiB
Rust

#![allow(missing_docs)]
use subxt_historic::{Error, OnlineClient, PolkadotConfig};
#[tokio::main]
async fn main() -> Result<(), Error> {
// Configuration for the Polkadot relay chain.
let config = PolkadotConfig::new();
// Create an online client for the Polkadot relay chain, pointed at a Polkadot archive node.
let client = OnlineClient::from_url(config, "wss://rpc.polkadot.io").await?;
// Iterate through some randomly selected old blocks to show how to fetch and decode extrinsics.
for block_number in 123456.. {
println!("=== Block {block_number} ===");
// Point the client at a specific block number. By default this will download and cache
// metadata for the required spec version (so it's cheaper to instantiate again), if it
// hasn't already, and borrow the relevant legacy types from the client.
let client_at_block = client.at(block_number).await?;
// Fetch the extrinsics at that block.
let extrinsics = client_at_block.extrinsics().fetch().await?;
// Now, we have various operations to work with them. Here we print out various details
// about each extrinsic.
for extrinsic in extrinsics.iter() {
println!(
"{}.{}",
extrinsic.call().pallet_name(),
extrinsic.call().name()
);
if let Some(signature) = extrinsic.signature_bytes() {
println!(" Signature: 0x{}", hex::encode(signature));
}
println!(" Call Data:");
// We can decode each of the fields (in this example we decode everything into a
// scale_value::Value type, which can represent any SCALE encoded data, but if you
// have an idea of the type then you can try to decode into that type instead):
for field in extrinsic.call().fields().iter() {
println!(
" {}: {}",
field.name(),
field.decode::<scale_value::Value>().unwrap()
);
}
// Or, all of them at once:
println!(
" All: {}",
extrinsic
.call()
.fields()
.decode::<scale_value::Composite<_>>()
.unwrap()
);
// We can also look at things like the transaction extensions:
if let Some(extensions) = extrinsic.transaction_extensions() {
println!(" Transaction Extensions:");
// We can decode each of them:
for extension in extensions.iter() {
println!(
" {}: {}",
extension.name(),
extension.decode::<scale_value::Value>().unwrap()
);
}
// Or all of them at once:
println!(
" All: {}",
extensions.decode::<scale_value::Composite<_>>().unwrap()
);
}
}
}
Ok(())
}