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