1use {
2 serde::{Deserialize, Serialize},
3 gemachain_account_decoder::{
4 parse_token::{real_number_string_trimmed, UiTokenAmount},
5 StringAmount,
6 },
7 gemachain_sdk::{deserialize_utils::default_on_eof, transaction::Result},
8 gemachain_transaction_status::{
9 InnerInstructions, Reward, RewardType, TransactionStatusMeta, TransactionTokenBalance,
10 },
11 std::str::FromStr,
12};
13
14pub mod convert;
15
16pub type StoredExtendedRewards = Vec<StoredExtendedReward>;
17
18#[derive(Serialize, Deserialize)]
19pub struct StoredExtendedReward {
20 pubkey: String,
21 carats: i64,
22 #[serde(deserialize_with = "default_on_eof")]
23 post_balance: u64,
24 #[serde(deserialize_with = "default_on_eof")]
25 reward_type: Option<RewardType>,
26 #[serde(deserialize_with = "default_on_eof")]
27 commission: Option<u8>,
28}
29
30impl From<StoredExtendedReward> for Reward {
31 fn from(value: StoredExtendedReward) -> Self {
32 let StoredExtendedReward {
33 pubkey,
34 carats,
35 post_balance,
36 reward_type,
37 commission,
38 } = value;
39 Self {
40 pubkey,
41 carats,
42 post_balance,
43 reward_type,
44 commission,
45 }
46 }
47}
48
49impl From<Reward> for StoredExtendedReward {
50 fn from(value: Reward) -> Self {
51 let Reward {
52 pubkey,
53 carats,
54 post_balance,
55 reward_type,
56 commission,
57 } = value;
58 Self {
59 pubkey,
60 carats,
61 post_balance,
62 reward_type,
63 commission,
64 }
65 }
66}
67
68#[derive(Serialize, Deserialize)]
69pub struct StoredTokenAmount {
70 pub ui_amount: f64,
71 pub decimals: u8,
72 pub amount: StringAmount,
73}
74
75impl From<StoredTokenAmount> for UiTokenAmount {
76 fn from(value: StoredTokenAmount) -> Self {
77 let StoredTokenAmount {
78 ui_amount,
79 decimals,
80 amount,
81 } = value;
82 let ui_amount_string =
83 real_number_string_trimmed(u64::from_str(&amount).unwrap_or(0), decimals);
84 Self {
85 ui_amount: Some(ui_amount),
86 decimals,
87 amount,
88 ui_amount_string,
89 }
90 }
91}
92
93impl From<UiTokenAmount> for StoredTokenAmount {
94 fn from(value: UiTokenAmount) -> Self {
95 let UiTokenAmount {
96 ui_amount,
97 decimals,
98 amount,
99 ..
100 } = value;
101 Self {
102 ui_amount: ui_amount.unwrap_or(0.0),
103 decimals,
104 amount,
105 }
106 }
107}
108
109#[derive(Serialize, Deserialize)]
110pub struct StoredTransactionTokenBalance {
111 pub account_index: u8,
112 pub mint: String,
113 pub ui_token_amount: StoredTokenAmount,
114}
115
116impl From<StoredTransactionTokenBalance> for TransactionTokenBalance {
117 fn from(value: StoredTransactionTokenBalance) -> Self {
118 let StoredTransactionTokenBalance {
119 account_index,
120 mint,
121 ui_token_amount,
122 } = value;
123 Self {
124 account_index,
125 mint,
126 ui_token_amount: ui_token_amount.into(),
127 }
128 }
129}
130
131impl From<TransactionTokenBalance> for StoredTransactionTokenBalance {
132 fn from(value: TransactionTokenBalance) -> Self {
133 let TransactionTokenBalance {
134 account_index,
135 mint,
136 ui_token_amount,
137 } = value;
138 Self {
139 account_index,
140 mint,
141 ui_token_amount: ui_token_amount.into(),
142 }
143 }
144}
145
146#[derive(Serialize, Deserialize)]
147pub struct StoredTransactionStatusMeta {
148 pub status: Result<()>,
149 pub fee: u64,
150 pub pre_balances: Vec<u64>,
151 pub post_balances: Vec<u64>,
152 #[serde(deserialize_with = "default_on_eof")]
153 pub inner_instructions: Option<Vec<InnerInstructions>>,
154 #[serde(deserialize_with = "default_on_eof")]
155 pub log_messages: Option<Vec<String>>,
156 #[serde(deserialize_with = "default_on_eof")]
157 pub pre_token_balances: Option<Vec<StoredTransactionTokenBalance>>,
158 #[serde(deserialize_with = "default_on_eof")]
159 pub post_token_balances: Option<Vec<StoredTransactionTokenBalance>>,
160 #[serde(deserialize_with = "default_on_eof")]
161 pub rewards: Option<Vec<StoredExtendedReward>>,
162}
163
164impl From<StoredTransactionStatusMeta> for TransactionStatusMeta {
165 fn from(value: StoredTransactionStatusMeta) -> Self {
166 let StoredTransactionStatusMeta {
167 status,
168 fee,
169 pre_balances,
170 post_balances,
171 inner_instructions,
172 log_messages,
173 pre_token_balances,
174 post_token_balances,
175 rewards,
176 } = value;
177 Self {
178 status,
179 fee,
180 pre_balances,
181 post_balances,
182 inner_instructions,
183 log_messages,
184 pre_token_balances: pre_token_balances
185 .map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
186 post_token_balances: post_token_balances
187 .map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
188 rewards: rewards
189 .map(|rewards| rewards.into_iter().map(|reward| reward.into()).collect()),
190 }
191 }
192}
193
194impl From<TransactionStatusMeta> for StoredTransactionStatusMeta {
195 fn from(value: TransactionStatusMeta) -> Self {
196 let TransactionStatusMeta {
197 status,
198 fee,
199 pre_balances,
200 post_balances,
201 inner_instructions,
202 log_messages,
203 pre_token_balances,
204 post_token_balances,
205 rewards,
206 } = value;
207 Self {
208 status,
209 fee,
210 pre_balances,
211 post_balances,
212 inner_instructions,
213 log_messages,
214 pre_token_balances: pre_token_balances
215 .map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
216 post_token_balances: post_token_balances
217 .map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
218 rewards: rewards
219 .map(|rewards| rewards.into_iter().map(|reward| reward.into()).collect()),
220 }
221 }
222}