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> {
let api = OnlineClient::<PolkadotConfig>::new().await?;
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:");
let at_block = block.at().await?;
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?;
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}");
}
}
}
if let Some(ext) = extrinsics.find_first::<polkadot::para_inherent::calls::Enter>() {
let ext = ext?;
println!("ParaInherent.Enter");
println!(" backed_candidated: {:?}", ext.data.backed_candidates);
println!(" disputes: {:?}", ext.data.disputes);
}
}
Ok(())
}