1pub mod account;
2pub mod explorer;
3pub mod pubkey;
4pub mod pyth;
5pub mod space;
6pub mod thread;
7
8use std::fmt::{Debug, Display, Formatter};
9
10use anchor_lang::{prelude::Pubkey, prelude::*, AnchorDeserialize};
11use base64::{engine::general_purpose::STANDARD, Engine};
12
13pub use sablier_macros::MinSpace;
14pub use space::Space;
15
16#[derive(AnchorDeserialize, AnchorSerialize, Clone, Debug)]
18pub struct CrateInfo {
19 pub spec: String,
21 pub blob: String,
23}
24
25impl Display for CrateInfo {
26 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
27 write!(f, "spec:{} blob:{}", self.spec, self.blob)
28 }
29}
30
31pub trait ProgramLogsDeserializable {
33 fn try_from_program_logs(
34 program_logs: Vec<String>,
35 program_id: &Pubkey,
36 ) -> std::result::Result<Self, ErrorCode>
37 where
38 Self: Sized;
39}
40
41impl<T> ProgramLogsDeserializable for T
42where
43 T: AnchorDeserialize,
44{
45 fn try_from_program_logs(
46 program_logs: Vec<String>,
47 program_id: &Pubkey,
48 ) -> std::result::Result<T, ErrorCode> {
49 let preimage = format!("Program return: {} ", program_id);
53
54 let get_return_data_base64 = program_logs
56 .iter()
57 .find(|&s| s.starts_with(&preimage))
58 .ok_or(ErrorCode::AccountDidNotDeserialize)?
59 .strip_prefix(&preimage)
60 .ok_or(ErrorCode::AccountDidNotDeserialize)?;
61
62 let decoded = STANDARD
63 .decode(get_return_data_base64)
64 .map_err(|_err| ErrorCode::AccountDidNotDeserialize)?;
65
66 T::try_from_slice(&decoded).map_err(|_err| ErrorCode::AccountDidNotDeserialize)
67 }
68}