mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 14:41:11 +00:00
More examples and get compiling with deny(missing_docs)
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
//! Subscribe to blocks.
|
||||
use subxt::dynamic::Value;
|
||||
use subxt::{Error, OnlineClient, PolkadotConfig};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
|
||||
mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
// Create a new API client, configured to talk to Polkadot nodes.
|
||||
let config = PolkadotConfig::new();
|
||||
let api = OnlineClient::new(config).await?;
|
||||
|
||||
// Stream the finalized blocks. See the OnlineClient docs for how to
|
||||
// stream best blocks or all new blocks.
|
||||
let mut blocks = api.stream_blocks().await?;
|
||||
|
||||
while let Some(block) = blocks.next().await {
|
||||
let block = block?;
|
||||
|
||||
let block_number = block.number();
|
||||
let block_hash = block.hash();
|
||||
|
||||
println!("Block #{block_number}:");
|
||||
println!(" Hash: {block_hash}");
|
||||
println!(" Extrinsics:");
|
||||
|
||||
// Create a client to work at this block. From here you have the
|
||||
// same interface as `api.block(block.hash()).await`.
|
||||
let at_block = block.at().await?;
|
||||
|
||||
// Here we'll obtain and display the extrinsics:
|
||||
let extrinsics = at_block.extrinsics().fetch().await?;
|
||||
for ext in extrinsics.iter() {
|
||||
let ext = ext?;
|
||||
|
||||
let idx = ext.index();
|
||||
let pallet_name = ext.pallet_name();
|
||||
let call_name = ext.call_name();
|
||||
let bytes_hex = format!("0x{}", hex::encode(ext.bytes()));
|
||||
let events = ext.events().await?;
|
||||
|
||||
// See the API docs for more ways to decode extrinsics:
|
||||
let decoded_ext = ext.decode_call_data_as::<polkadot::Call>()?;
|
||||
|
||||
println!(" #{idx}: {pallet_name}.{call_name}:");
|
||||
println!(" Bytes: {bytes_hex}");
|
||||
println!(" Decoded: {decoded_ext:?}");
|
||||
|
||||
for evt in events.iter() {
|
||||
println!(" Events:");
|
||||
let evt = evt?;
|
||||
let event_idx = evt.event_index();
|
||||
let pallet_name = evt.pallet_name();
|
||||
let event_name = evt.event_name();
|
||||
let event_values = evt.decode_fields_unchecked_as::<Value>()?;
|
||||
|
||||
println!(" #{event_idx}: {pallet_name}.{event_name}");
|
||||
println!(" {event_values}");
|
||||
}
|
||||
|
||||
if let Some(transaction_extensions) = ext.transaction_extensions() {
|
||||
println!(" Transaction Extensions:");
|
||||
for transaction_extension in transaction_extensions.iter() {
|
||||
let name = transaction_extension.name();
|
||||
let value = transaction_extension.decode_unchecked_as::<Value>()?;
|
||||
println!(" {name}: {value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//! Working with historic blocks.
|
||||
use subxt::dynamic::Value;
|
||||
use subxt::{Error, OnlineClient, PolkadotConfig};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
// Point at an archive node since we want to obtain old blocks.
|
||||
let config = PolkadotConfig::new();
|
||||
let api = OnlineClient::from_url(config, "wss://rpc.polkadot.io").await?;
|
||||
|
||||
for block_number in 1234567u32.. {
|
||||
let at_block = api.at_block(block_number).await?;
|
||||
|
||||
let block_number = at_block.block_number();
|
||||
let block_hash = at_block.block_hash();
|
||||
|
||||
println!("Block #{block_number}:");
|
||||
println!(" Hash: {block_hash}");
|
||||
println!(" Extrinsics:");
|
||||
|
||||
// Here we'll obtain and display the extrinsics:
|
||||
let extrinsics = at_block.extrinsics().fetch().await?;
|
||||
for ext in extrinsics.iter() {
|
||||
let ext = ext?;
|
||||
|
||||
let idx = ext.index();
|
||||
let pallet_name = ext.pallet_name();
|
||||
let call_name = ext.call_name();
|
||||
let bytes_hex = format!("0x{}", hex::encode(ext.bytes()));
|
||||
let events = ext.events().await?;
|
||||
|
||||
// See the API docs for more ways to decode extrinsics. Here, since we're
|
||||
// accessing a historic block, we don't use any generated types to help us.
|
||||
let decoded_ext = ext.decode_call_data_fields_unchecked_as::<Value>()?;
|
||||
|
||||
println!(" #{idx}: {pallet_name}.{call_name}:");
|
||||
println!(" Bytes: {bytes_hex}");
|
||||
println!(" Decoded: {decoded_ext}");
|
||||
|
||||
for evt in events.iter() {
|
||||
println!(" Events:");
|
||||
let evt = evt?;
|
||||
let event_idx = evt.event_index();
|
||||
let pallet_name = evt.pallet_name();
|
||||
let event_name = evt.event_name();
|
||||
let event_values = evt.decode_fields_unchecked_as::<Value>()?;
|
||||
|
||||
println!(" #{event_idx}: {pallet_name}.{event_name}");
|
||||
println!(" {event_values}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//! Fetching and iterating over storage entries.
|
||||
use subxt::dynamic::Value;
|
||||
use subxt::utils::AccountId32;
|
||||
use subxt::{Error, OnlineClient, PolkadotConfig};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
|
||||
mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
let config = PolkadotConfig::new();
|
||||
let api = OnlineClient::new(config).await?;
|
||||
let at_block = api.at_current_block().await?;
|
||||
|
||||
// Here we use a statically generated address to fetch the storage entry, which
|
||||
// gives us type information for future actions on it.
|
||||
let account_balances = at_block
|
||||
.storage()
|
||||
.entry(polkadot::storage().system().account())?;
|
||||
|
||||
// We can see the default value for this entry at this block, if one exists.
|
||||
if let Some(default_value) = account_balances.default_value() {
|
||||
let default_balance_info = default_value.decode_as::<Value>()?;
|
||||
println!("Default balance info: {default_balance_info}");
|
||||
}
|
||||
|
||||
// We can fetch a specific account balance by its key, like so (here I just picked a random key
|
||||
// I knew to exist from iterating over storage entries):
|
||||
let account_id = {
|
||||
let hex = "9a4d0faa2ba8c3cc5711852960940793acf55bf195b6eecf88fa78e961d0ce4a";
|
||||
let bytes: [u8; 32] = hex::decode(hex).unwrap().try_into().unwrap();
|
||||
AccountId32::from(bytes)
|
||||
};
|
||||
let entry = account_balances.fetch((account_id,)).await?;
|
||||
|
||||
// We can decode the value into our generic `Value` type, which can
|
||||
// represent any SCALE-encoded value, like so:
|
||||
let _balance_info = entry.decode_as::<Value>()?;
|
||||
|
||||
// Or we can decode into a known shape. Any type implementing DecodeAsType can
|
||||
// be used here to extract fields you're interested in, or we can use the generated
|
||||
// type which already implements this:
|
||||
type AccountInfo = polkadot::system::storage::account::output::Output;
|
||||
let balance_info = entry.decode_as::<AccountInfo>()?;
|
||||
|
||||
println!(
|
||||
"Single balance info from {account_id} => free: {} reserved: {} frozen: {} flags: {:?}",
|
||||
balance_info.data.free,
|
||||
balance_info.data.reserved,
|
||||
balance_info.data.frozen,
|
||||
balance_info.data.flags,
|
||||
);
|
||||
|
||||
// Or we can iterate over all of the account balances and print them out. Here we provide an
|
||||
// empty tuple, indicating that we want to iterate over everything and not only things under a certain key
|
||||
// (in the case of account balances, there is only one key anyway, but other storage entries may map from
|
||||
// several keys to a value, and for those we can choose which depth we iterate at by providing as many keys
|
||||
// as we want and leaving the rest).
|
||||
let mut all_balances = account_balances.iter(()).await?;
|
||||
while let Some(entry) = all_balances.next().await {
|
||||
let entry = entry?;
|
||||
let key = entry.key()?;
|
||||
|
||||
// Because we provided a statically typed Address when we originally obtained this
|
||||
// storage entry (ie `polkadot::storage().system().account()`), we can statically
|
||||
// decode the key into its well typed constituent parts:
|
||||
let key_parts = key.decode()?;
|
||||
println!("Account ID: {}", key_parts.0);
|
||||
|
||||
// Alternately, if we don't have type information available (or just want to decode
|
||||
// into some different type), we can do something like this instead:
|
||||
let account_id = key
|
||||
.part(0)
|
||||
.unwrap()
|
||||
.decode_as::<AccountId32>()?
|
||||
.expect("We expect this key to decode into a 32 byte AccountId");
|
||||
|
||||
// Decode these values into our generic scale_value::Value type. Less efficient than
|
||||
// defining a static type as above, but easier for the sake of the example.
|
||||
let balance_info = entry.value().decode_as::<scale_value::Value>()?;
|
||||
println!(" {account_id} => {balance_info}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
#![allow(missing_docs)]
|
||||
//! Construct and submit a transaction.
|
||||
use subxt::{Error, OnlineClient, PolkadotConfig};
|
||||
use subxt_signer::sr25519::dev;
|
||||
|
||||
// Generate an interface that we can use from the node's metadata.
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
|
||||
pub mod polkadot {}
|
||||
mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
Reference in New Issue
Block a user