safe_token_2022/
generic_token_account.rs1use {
4 crate::state::AccountState,
5 solana_program::pubkey::{Pubkey, PUBKEY_BYTES},
6};
7
8const SAFE_TOKEN_ACCOUNT_MINT_OFFSET: usize = 0;
9const SAFE_TOKEN_ACCOUNT_OWNER_OFFSET: usize = 32;
10
11pub trait GenericTokenAccount {
14 fn valid_account_data(account_data: &[u8]) -> bool;
16
17 fn unpack_account_owner_unchecked(account_data: &[u8]) -> &Pubkey {
19 Self::unpack_pubkey_unchecked(account_data, SAFE_TOKEN_ACCOUNT_OWNER_OFFSET)
20 }
21
22 fn unpack_account_mint_unchecked(account_data: &[u8]) -> &Pubkey {
24 Self::unpack_pubkey_unchecked(account_data, SAFE_TOKEN_ACCOUNT_MINT_OFFSET)
25 }
26
27 fn unpack_pubkey_unchecked(account_data: &[u8], offset: usize) -> &Pubkey {
30 bytemuck::from_bytes(&account_data[offset..offset + PUBKEY_BYTES])
31 }
32
33 fn unpack_account_owner(account_data: &[u8]) -> Option<&Pubkey> {
35 if Self::valid_account_data(account_data) {
36 Some(Self::unpack_account_owner_unchecked(account_data))
37 } else {
38 None
39 }
40 }
41
42 fn unpack_account_mint(account_data: &[u8]) -> Option<&Pubkey> {
44 if Self::valid_account_data(account_data) {
45 Some(Self::unpack_account_mint_unchecked(account_data))
46 } else {
47 None
48 }
49 }
50}
51
52pub const ACCOUNT_INITIALIZED_INDEX: usize = 108;
54
55pub fn is_initialized_account(account_data: &[u8]) -> bool {
58 *account_data
59 .get(ACCOUNT_INITIALIZED_INDEX)
60 .unwrap_or(&(AccountState::Uninitialized as u8))
61 != AccountState::Uninitialized as u8
62}