Skip to main content

yellowstone_shield_parser/
accounts.rs

1use solana_pubkey::Pubkey;
2use yellowstone_shield_client::{accounts, PolicyTrait};
3pub use yellowstone_shield_client::{types::PermissionStrategy, ID};
4
5#[derive(Debug, Clone)]
6pub struct Policy {
7    pub strategy: PermissionStrategy,
8    pub identities: Vec<Pubkey>,
9}
10
11impl Policy {
12    pub fn new(strategy: PermissionStrategy, identities: Vec<Pubkey>) -> Self {
13        Self {
14            strategy,
15            identities,
16        }
17    }
18}
19
20/// Shield Program State
21#[allow(clippy::large_enum_variant, dead_code)]
22#[derive(Debug, Clone)]
23pub enum ShieldProgramState {
24    Policy(u64, Pubkey, Policy),
25}
26
27impl ShieldProgramState {
28    pub fn try_parse_account_data(
29        slot: u64,
30        pubkey: Pubkey,
31        owner: &Pubkey,
32        data: &[u8],
33        expected_program_id: Option<&Pubkey>,
34    ) -> Result<Self, String> {
35        let expected_id = expected_program_id.unwrap_or(&ID);
36        if owner != expected_id {
37            return Err(format!(
38                "Invalid owner: expected {}, got {}",
39                expected_id, owner
40            ));
41        }
42
43        if data.is_empty() {
44            return Err("Data is empty".to_owned());
45        }
46
47        let (strategy, identities) = match data[0] {
48            0 => {
49                let policy = accounts::Policy::from_bytes(data).map_err(|e| e.to_string())?;
50                let strategy = policy.try_strategy().map_err(|e| e.to_string())?;
51                let identities = accounts::Policy::try_deserialize_identities(data)
52                    .map_err(|e| e.to_string())?;
53                (strategy, identities)
54            }
55            1 => {
56                let policy = accounts::PolicyV2::from_bytes(data).map_err(|e| e.to_string())?;
57                let strategy = policy.try_strategy().map_err(|e| e.to_string())?;
58                let identities = accounts::PolicyV2::try_deserialize_identities(data)
59                    .map_err(|e| e.to_string())?;
60                (strategy, identities)
61            }
62            _ => return Err("Unsupported data type".to_owned()),
63        };
64
65        let policy = Policy::new(strategy, identities);
66        Ok(ShieldProgramState::Policy(slot, pubkey, policy))
67    }
68}
69
70pub fn parse_account(
71    slot: u64,
72    pubkey: Pubkey,
73    owner: &Pubkey,
74    data: &[u8],
75    expected_program_id: Option<&Pubkey>,
76) -> Result<ShieldProgramState, String> {
77    ShieldProgramState::try_parse_account_data(slot, pubkey, owner, data, expected_program_id)
78}