trident_explorer/
account.rs1use crate::output::pretty_lamports_to_sol;
2use console::style;
3use serde::Serialize;
4use solana_sdk::{account::Account, pubkey::Pubkey};
5use std::fmt;
6
7#[derive(Serialize)]
8pub struct KeyedAccount {
9 pub pubkey: Pubkey,
10 pub account: Account,
11}
12
13pub struct AccountFieldVisibility {
14 lamports: bool,
15 data: bool,
16 owner: bool,
17 executable: bool,
18 rent_epoch: bool,
19}
20
21impl AccountFieldVisibility {
22 pub fn new_all_enabled() -> Self {
23 Self {
24 lamports: true,
25 data: true,
26 owner: true,
27 executable: true,
28 rent_epoch: true,
29 }
30 }
31
32 pub fn new_all_disabled() -> Self {
33 Self {
34 lamports: false,
35 data: false,
36 owner: false,
37 executable: false,
38 rent_epoch: false,
39 }
40 }
41
42 pub fn lamports(&self) -> bool {
43 self.lamports
44 }
45
46 pub fn enable_lamports(&mut self) -> &mut Self {
47 self.lamports = true;
48 self
49 }
50
51 pub fn disable_lamports(&mut self) -> &mut Self {
52 self.lamports = false;
53 self
54 }
55
56 pub fn data(&self) -> bool {
57 self.data
58 }
59
60 pub fn enable_data(&mut self) -> &mut Self {
61 self.data = true;
62 self
63 }
64
65 pub fn disable_data(&mut self) -> &mut Self {
66 self.data = false;
67 self
68 }
69
70 pub fn owner(&self) -> bool {
71 self.owner
72 }
73
74 pub fn enable_owner(&mut self) -> &mut Self {
75 self.owner = true;
76 self
77 }
78
79 pub fn disable_owner(&mut self) -> &mut Self {
80 self.owner = false;
81 self
82 }
83
84 pub fn executable(&self) -> bool {
85 self.executable
86 }
87
88 pub fn enable_executable(&mut self) -> &mut Self {
89 self.executable = true;
90 self
91 }
92
93 pub fn disable_executable(&mut self) -> &mut Self {
94 self.executable = false;
95 self
96 }
97
98 pub fn rent_epoch(&self) -> bool {
99 self.rent_epoch
100 }
101
102 pub fn enable_rent_epoch(&mut self) -> &mut Self {
103 self.rent_epoch = true;
104 self
105 }
106
107 pub fn disable_rent_epoch(&mut self) -> &mut Self {
108 self.rent_epoch = false;
109 self
110 }
111}
112
113#[derive(Serialize)]
114pub struct DisplayAccount {
115 #[serde(skip_serializing_if = "Option::is_none")]
116 pub lamports: Option<u64>,
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub data: Option<String>,
119 #[serde(skip_serializing_if = "Option::is_none")]
120 pub owner: Option<String>,
121 #[serde(skip_serializing_if = "Option::is_none")]
122 pub executable: Option<bool>,
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub rent_epoch: Option<u64>,
125}
126
127#[derive(Serialize)]
128pub struct DisplayKeyedAccount {
129 pub pubkey: String,
130 pub account: DisplayAccount,
131}
132
133impl DisplayKeyedAccount {
134 pub fn from_keyed_account(
135 keyed_account: &KeyedAccount,
136 visibility: &AccountFieldVisibility,
137 ) -> Self {
138 Self {
139 pubkey: keyed_account.pubkey.to_string(),
140 account: DisplayAccount {
141 lamports: if visibility.lamports {
142 Some(keyed_account.account.lamports)
143 } else {
144 None
145 },
146 data: if visibility.data {
147 Some(base64::encode(&keyed_account.account.data))
148 } else {
149 None
150 },
151 owner: if visibility.owner {
152 Some(keyed_account.account.owner.to_string())
153 } else {
154 None
155 },
156 executable: if visibility.executable {
157 Some(keyed_account.account.executable)
158 } else {
159 None
160 },
161 rent_epoch: if visibility.rent_epoch {
162 Some(keyed_account.account.rent_epoch)
163 } else {
164 None
165 },
166 },
167 }
168 }
169}
170
171impl fmt::Display for DisplayKeyedAccount {
172 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
173 writeln!(
174 f,
175 "========================================================"
176 )?;
177 writeln!(f, "{} {}", style("Public Key:").bold(), self.pubkey)?;
178 writeln!(
179 f,
180 "========================================================"
181 )?;
182
183 if let Some(lamports) = self.account.lamports {
184 writeln!(f)?;
185 write!(
186 f,
187 "{} {} (◎ {})",
188 style("Lamports:").bold(),
189 lamports,
190 pretty_lamports_to_sol(lamports)
191 )?;
192 }
193 if let Some(data) = &self.account.data {
194 writeln!(f)?;
195 if data.is_empty() {
196 write!(f, "{} [Empty]", style("Data:").bold())?;
197 } else {
198 write!(f, "{} [Hexdump below]", style("Data:").bold())?;
199 }
200 }
201 if let Some(owner) = &self.account.owner {
202 writeln!(f)?;
203 write!(f, "{} {}", style("Owner").bold(), owner)?;
204 }
205 if let Some(executable) = self.account.executable {
206 writeln!(f)?;
207 write!(f, "{} {}", style("Executable:").bold(), executable)?;
208 }
209 if let Some(rent_epoch) = self.account.rent_epoch {
210 writeln!(f)?;
211 write!(f, "{} {}", style("Rent Epoch:").bold(), rent_epoch)?;
212 }
213
214 Ok(())
215 }
216}