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