diff --git a/subxt/examples/block_decoding_static.rs b/subxt/examples/block_decoding_static.rs index 42eccc9c24..d997dc0e22 100644 --- a/subxt/examples/block_decoding_static.rs +++ b/subxt/examples/block_decoding_static.rs @@ -27,29 +27,28 @@ async fn main() -> Result<(), Box> { println!("Block #{block_number} ({block_hash}):"); let extrinsics = block.extrinsics().await?; - for ext in extrinsics.iter() { - let ext = ext?; - if let Ok(Some(transfer)) = ext.as_extrinsic::() { - let Some(extensions) = ext.signed_extensions() else { - panic!("TransferKeepAlive should be signed") - }; + for transfer in extrinsics.find::() { + let transfer = transfer?; - ext.address_bytes().unwrap(); - let addr_bytes = ext - .address_bytes() - .expect("TransferKeepAlive should be signed"); - let sender = MultiAddress::::decode(&mut &addr_bytes[..]) - .expect("Decoding should work"); - let sender = display_address(&sender); - let receiver = display_address(&transfer.dest); - let value = transfer.value; - let tip = extensions.tip().expect("Should have tip"); - let nonce = extensions.nonce().expect("Should have nonce"); + let Some(extensions) = transfer.details.signed_extensions() else { + panic!("TransferKeepAlive should be signed") + }; - println!( + let addr_bytes = transfer + .details + .address_bytes() + .expect("TransferKeepAlive should be signed"); + let sender = MultiAddress::::decode(&mut &addr_bytes[..]) + .expect("Decoding should work"); + let sender = display_address(&sender); + let receiver = display_address(&transfer.value.dest); + let value = transfer.value.value; + let tip = extensions.tip().expect("Should have tip"); + let nonce = extensions.nonce().expect("Should have nonce"); + + println!( " Transfer of {value} DOT:\n {sender} (Tip: {tip}, Nonce: {nonce}) ---> {receiver}", ); - } } } diff --git a/subxt/src/blocks/extrinsic_types.rs b/subxt/src/blocks/extrinsic_types.rs index 92f70d565c..333ee5bfe8 100644 --- a/subxt/src/blocks/extrinsic_types.rs +++ b/subxt/src/blocks/extrinsic_types.rs @@ -130,22 +130,30 @@ where /// Iterate through the extrinsics using metadata to dynamically decode and skip /// them, and return only those which should decode to the provided `E` type. /// If an error occurs, all subsequent iterations return `None`. - pub fn find(&self) -> impl Iterator> + '_ { - self.iter().filter_map(|e| { - e.and_then(|e| e.as_extrinsic::().map_err(Into::into)) - .transpose() + pub fn find( + &self, + ) -> impl Iterator, Error>> + '_ { + self.iter().filter_map(|res| match res { + Err(err) => Some(Err(err)), + Ok(details) => match details.as_extrinsic::() { + // Failed to decode extrinsic: + Err(err) => Some(Err(err)), + // Extrinsic for a different pallet / different call (skip): + Ok(None) => None, + Ok(Some(value)) => Some(Ok(FoundExtrinsic { details, value })), + }, }) } /// Iterate through the extrinsics using metadata to dynamically decode and skip /// them, and return the first extrinsic found which decodes to the provided `E` type. - pub fn find_first(&self) -> Result, Error> { + pub fn find_first(&self) -> Result>, Error> { self.find::().next().transpose() } /// Iterate through the extrinsics using metadata to dynamically decode and skip /// them, and return the last extrinsic found which decodes to the provided `Ev` type. - pub fn find_last(&self) -> Result, Error> { + pub fn find_last(&self) -> Result>, Error> { self.find::().last().transpose() } @@ -479,6 +487,12 @@ where } } +/// A Static Extrinsic found in a block coupled with it's details. +pub struct FoundExtrinsic { + pub details: ExtrinsicDetails, + pub value: E, +} + /// Details for the given extrinsic plucked from the metadata. pub struct ExtrinsicMetadataDetails<'a> { pub pallet: PalletMetadata<'a>,