solana_block_decoder/transaction/
tx_status_meta.rs1
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 pub cost_units: Option<u64>,
47}
48
49
50
51impl TryFrom<UiTransactionStatusMeta> for TransactionStatusMeta {
52 type Error = ConversionError;
53
54 fn try_from(meta: UiTransactionStatusMeta) -> Result<Self, Self::Error> {
55 let inner_instructions: Option<Vec<InnerInstructions>> = match meta.inner_instructions {
56 OptionSerializer::Some(ui_inner_instructions) => {
57 let inner_instructions_result: Result<Vec<_>, _> = ui_inner_instructions
58 .into_iter()
59 .map(|ui_inner_instruction| InnerInstructions::try_from(ui_inner_instruction))
60 .collect();
61
62 match inner_instructions_result {
63 Ok(inner_instructions) => Some(inner_instructions),
64 Err(e) => return Err(e),
65 }
66 }
67 _ => None,
68 };
69
70 let pre_token_balances: Option<Vec<TransactionTokenBalance>> = match meta.pre_token_balances {
71 OptionSerializer::Some(ui_pre_token_balances) => {
72 let pre_token_balances: Vec<_> = ui_pre_token_balances
73 .into_iter()
74 .map(TransactionTokenBalance::from)
75 .collect();
76
77 Some(pre_token_balances)
78 }
79 _ => None,
80 };
81
82 let post_token_balances: Option<Vec<TransactionTokenBalance>> = match meta.post_token_balances {
83 OptionSerializer::Some(ui_post_token_balances) => {
84 let post_token_balances: Vec<_> = ui_post_token_balances
85 .into_iter()
86 .map(TransactionTokenBalance::from)
87 .collect();
88
89 Some(post_token_balances)
90 }
91 _ => None,
92 };
93
94 let return_data: Option<TransactionReturnData> = match meta.return_data {
95 OptionSerializer::Some(ui_return_data) => {
96 let return_data = TransactionReturnData::try_from(ui_return_data)?;
97 Some(return_data)
98 }
99 _ => None,
100 };
101
102 let loaded_addresses: LoadedAddresses = match &meta.loaded_addresses {
103 OptionSerializer::Some(ui_loaded_addresses) => {
104 match LoadedAddresses::try_from(ui_loaded_addresses) {
105 Ok(loaded_addresses) => loaded_addresses,
106 Err(_) => return Err(ConversionError::InvalidProgramId),
107 }
108 }
109 _ => return Err(ConversionError::InvalidProgramId),
110 };
111
112 let compute_units_consumed: Option<u64> = match meta.compute_units_consumed {
113 OptionSerializer::Some(cuc) => Some(cuc),
114 _ => None,
115 };
116
117 Ok(Self {
118 status: meta.status.map_err(Into::into),
119 fee: meta.fee,
120 pre_balances: meta.pre_balances,
121 post_balances: meta.post_balances,
122 inner_instructions,
123 log_messages: match meta.log_messages {
124 OptionSerializer::Some(logs) => Some(logs),
125 _ => None,
126 },
127 pre_token_balances,
128 post_token_balances,
129 rewards: match meta.rewards {
130 OptionSerializer::Some(rewards) => Some(rewards),
131 _ => None,
132 },
133 loaded_addresses,
134 return_data,
135 compute_units_consumed,
136 cost_units: match meta.cost_units {
137 OptionSerializer::Some(cost_units) => Some(cost_units),
138 _ => None,
139 },
140 })
141 }
142}
143
144
145impl From<TransactionStatusMeta> for solana_transaction_status_client_types::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 cost_units: meta.cost_units,
161 }
162 }
163}