gemachain_storage_proto/
lib.rs

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}