1pub mod explorer;
2pub mod pubkey;
3pub mod thread;
4
5use std::fmt::{Debug, Display, Formatter};
6
7use anchor_lang::{prelude::Pubkey, prelude::*, AnchorDeserialize};
8use base64;
9
10#[derive(AnchorDeserialize, AnchorSerialize, Clone, Debug)]
12pub struct CrateInfo {
13 pub spec: String,
15 pub blob: String,
17}
18
19impl Display for CrateInfo {
20 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
21 write!(f, "spec:{} blob:{}", self.spec, self.blob)
22 }
23}
24
25pub trait ProgramLogsDeserializable {
27 fn try_from_program_logs(
28 program_logs: Vec<String>,
29 program_id: &Pubkey,
30 ) -> std::result::Result<Self, ErrorCode>
31 where
32 Self: Sized;
33}
34
35impl<T> ProgramLogsDeserializable for T
36where
37 T: AnchorDeserialize,
38{
39 fn try_from_program_logs(
40 program_logs: Vec<String>,
41 program_id: &Pubkey,
42 ) -> std::result::Result<T, ErrorCode> {
43 let preimage = format!("Program return: {} ", program_id.to_string());
47
48 let get_return_data_base64 = program_logs
50 .iter()
51 .find(|&s| s.starts_with(&preimage))
52 .ok_or(ErrorCode::AccountDidNotDeserialize)?
53 .strip_prefix(&preimage)
54 .ok_or(ErrorCode::AccountDidNotDeserialize)?;
55
56 let decoded = base64::decode(get_return_data_base64)
57 .map_err(|_err| ErrorCode::AccountDidNotDeserialize)?;
58
59 T::try_from_slice(&decoded).map_err(|_err| ErrorCode::AccountDidNotDeserialize)
60 }
61}