solana_block_decoder/transaction/
tx_status_meta.rs

1
2use {
3    crate::{
4        errors::{
5            conversion_error::ConversionError,
6        },
7        instruction::{
8            inner_instruction::{
9                InnerInstructions,
10            },
11        },
12        address::{
13            loaded_addresses::LoadedAddresses,
14        },
15        transaction::{
16            tx_token_balance::TransactionTokenBalance,
17            tx_return_data::TransactionReturnData,
18        },
19    },
20    solana_transaction_error::TransactionResult,
21    solana_transaction_status_client_types::{
22        UiTransactionStatusMeta,
23        Rewards,
24        option_serializer::OptionSerializer,
25    },
26    serde::{
27        Deserialize, Serialize,
28    },
29};
30
31
32#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
33pub struct TransactionStatusMeta {
34    pub status: TransactionResult<()>,
35    pub fee: u64,
36    pub pre_balances: Vec<u64>,
37    pub post_balances: Vec<u64>,
38    pub inner_instructions: Option<Vec<InnerInstructions>>,
39    pub log_messages: Option<Vec<String>>,
40    pub pre_token_balances: Option<Vec<TransactionTokenBalance>>,
41    pub post_token_balances: Option<Vec<TransactionTokenBalance>>,
42    pub rewards: Option<Rewards>,
43    pub loaded_addresses: LoadedAddresses,
44    pub return_data: Option<TransactionReturnData>,
45    pub compute_units_consumed: Option<u64>,
46}
47
48
49
50impl TryFrom<UiTransactionStatusMeta> for TransactionStatusMeta {
51    type Error = ConversionError;
52
53    fn try_from(meta: UiTransactionStatusMeta) -> Result<Self, Self::Error> {
54        let inner_instructions: Option<Vec<InnerInstructions>> = match meta.inner_instructions {
55            OptionSerializer::Some(ui_inner_instructions) => {
56                let inner_instructions_result: Result<Vec<_>, _> = ui_inner_instructions
57                    .into_iter()
58                    .map(|ui_inner_instruction| InnerInstructions::try_from(ui_inner_instruction))
59                    .collect();
60
61                match inner_instructions_result {
62                    Ok(inner_instructions) => Some(inner_instructions),
63                    Err(e) => return Err(e),
64                }
65            }
66            _ => None,
67        };
68
69        let pre_token_balances: Option<Vec<TransactionTokenBalance>> = match meta.pre_token_balances {
70            OptionSerializer::Some(ui_pre_token_balances) => {
71                let pre_token_balances: Vec<_> = ui_pre_token_balances
72                    .into_iter()
73                    .map(TransactionTokenBalance::from)
74                    .collect();
75
76                Some(pre_token_balances)
77            }
78            _ => None,
79        };
80
81        let post_token_balances: Option<Vec<TransactionTokenBalance>> = match meta.post_token_balances {
82            OptionSerializer::Some(ui_post_token_balances) => {
83                let post_token_balances: Vec<_> = ui_post_token_balances
84                    .into_iter()
85                    .map(TransactionTokenBalance::from)
86                    .collect();
87
88                Some(post_token_balances)
89            }
90            _ => None,
91        };
92
93        let return_data: Option<TransactionReturnData> = match meta.return_data {
94            OptionSerializer::Some(ui_return_data) => {
95                let return_data = TransactionReturnData::try_from(ui_return_data)?;
96                Some(return_data)
97            }
98            _ => None,
99        };
100
101        let loaded_addresses: LoadedAddresses = match &meta.loaded_addresses {
102            OptionSerializer::Some(ui_loaded_addresses) => {
103                match LoadedAddresses::try_from(ui_loaded_addresses) {
104                    Ok(loaded_addresses) => loaded_addresses,
105                    Err(_) => return Err(ConversionError::InvalidProgramId),
106                }
107            }
108            _ => return Err(ConversionError::InvalidProgramId),
109        };
110
111        let compute_units_consumed: Option<u64> = match meta.compute_units_consumed {
112            OptionSerializer::Some(cuc) => Some(cuc),
113            _ => None,
114        };
115
116        Ok(Self {
117            status: meta.status,
118            fee: meta.fee,
119            pre_balances: meta.pre_balances,
120            post_balances: meta.post_balances,
121            inner_instructions,
122            log_messages: match meta.log_messages {
123                OptionSerializer::Some(logs) => Some(logs),
124                _ => None,
125            },
126            pre_token_balances,
127            post_token_balances,
128            rewards: match meta.rewards {
129                OptionSerializer::Some(rewards) => Some(rewards),
130                _ => None,
131            },
132            loaded_addresses,
133            return_data,
134            compute_units_consumed,
135        })
136    }
137}
138
139
140impl From<TransactionStatusMeta> for solana_transaction_status_client_types::TransactionStatusMeta {
141    fn from(meta: TransactionStatusMeta) -> Self {
142        Self {
143            status: meta.status,
144            fee: meta.fee,
145            pre_balances: meta.pre_balances,
146            post_balances: meta.post_balances,
147            inner_instructions: meta.inner_instructions.map(|ii| ii.into_iter().map(Into::into).collect()),
148            log_messages: meta.log_messages,
149            pre_token_balances: meta.pre_token_balances.map(|tb| tb.into_iter().map(Into::into).collect()),
150            post_token_balances: meta.post_token_balances.map(|tb| tb.into_iter().map(Into::into).collect()),
151            rewards: meta.rewards,
152            loaded_addresses: meta.loaded_addresses.into(),
153            return_data: meta.return_data.map(Into::into),
154            compute_units_consumed: meta.compute_units_consumed,
155        }
156    }
157}