subxt_core/blocks/
extrinsic_transaction_extensions.rs1use crate::config::TransactionExtension;
6use crate::config::transaction_extensions::{
7 ChargeAssetTxPayment, ChargeTransactionPayment, CheckNonce,
8};
9use crate::dynamic::Value;
10use crate::{Metadata, config::Config, error::Error};
11use frame_decode::extrinsics::ExtrinsicExtensions;
12use scale_decode::DecodeAsType;
13
14#[derive(Debug, Clone)]
16pub struct ExtrinsicTransactionExtensions<'a, T: Config> {
17 bytes: &'a [u8],
18 metadata: &'a Metadata,
19 decoded_info: &'a ExtrinsicExtensions<'static, u32>,
20 _marker: core::marker::PhantomData<T>,
21}
22
23impl<'a, T: Config> ExtrinsicTransactionExtensions<'a, T> {
24 pub(crate) fn new(
25 bytes: &'a [u8],
26 metadata: &'a Metadata,
27 decoded_info: &'a ExtrinsicExtensions<'static, u32>,
28 ) -> Self {
29 Self {
30 bytes,
31 metadata,
32 decoded_info,
33 _marker: core::marker::PhantomData,
34 }
35 }
36
37 pub fn iter(&self) -> impl Iterator<Item = ExtrinsicTransactionExtension<'a, T>> + use<'a, T> {
39 self.decoded_info
40 .iter()
41 .map(|s| ExtrinsicTransactionExtension {
42 bytes: &self.bytes[s.range()],
43 ty_id: *s.ty(),
44 identifier: s.name(),
45 metadata: self.metadata,
46 _marker: core::marker::PhantomData,
47 })
48 }
49
50 pub fn find<S: TransactionExtension<T>>(&self) -> Result<Option<S::Decoded>, Error> {
54 for ext in self.iter() {
55 match ext.as_signed_extension::<S>() {
56 Ok(Some(e)) => return Ok(Some(e)),
58 Ok(None) => continue,
60 Err(e) => return Err(e),
62 }
63 }
64 Ok(None)
65 }
66
67 pub fn tip(&self) -> Option<u128> {
72 self.find::<ChargeTransactionPayment>()
74 .ok()
75 .flatten()
76 .map(|e| e.tip())
77 .or_else(|| {
78 self.find::<ChargeAssetTxPayment<T>>()
79 .ok()
80 .flatten()
81 .map(|e| e.tip())
82 })
83 }
84
85 pub fn nonce(&self) -> Option<u64> {
89 self.find::<CheckNonce>().ok()?
90 }
91}
92
93#[derive(Debug, Clone)]
95pub struct ExtrinsicTransactionExtension<'a, T: Config> {
96 bytes: &'a [u8],
97 ty_id: u32,
98 identifier: &'a str,
99 metadata: &'a Metadata,
100 _marker: core::marker::PhantomData<T>,
101}
102
103impl<'a, T: Config> ExtrinsicTransactionExtension<'a, T> {
104 pub fn bytes(&self) -> &'a [u8] {
106 self.bytes
107 }
108
109 pub fn name(&self) -> &'a str {
111 self.identifier
112 }
113
114 pub fn type_id(&self) -> u32 {
116 self.ty_id
117 }
118
119 pub fn value(&self) -> Result<Value<u32>, Error> {
121 let value = scale_value::scale::decode_as_type(
122 &mut &self.bytes[..],
123 self.ty_id,
124 self.metadata.types(),
125 )?;
126 Ok(value)
127 }
128
129 pub fn as_signed_extension<S: TransactionExtension<T>>(
133 &self,
134 ) -> Result<Option<S::Decoded>, Error> {
135 if !S::matches(self.identifier, self.ty_id, self.metadata.types()) {
136 return Ok(None);
137 }
138 self.as_type::<S::Decoded>().map(Some)
139 }
140
141 fn as_type<E: DecodeAsType>(&self) -> Result<E, Error> {
142 let value = E::decode_as_type(&mut &self.bytes[..], self.ty_id, self.metadata.types())?;
143 Ok(value)
144 }
145}