light_sdk/
token.rs

1use light_compressed_account::compressed_account::CompressedAccountWithMerkleContext;
2use light_hasher::{sha256::Sha256BE, HasherError};
3
4use crate::{AnchorDeserialize, AnchorSerialize, Pubkey};
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq, AnchorDeserialize, AnchorSerialize, Default)]
7#[repr(u8)]
8pub enum AccountState {
9    #[default]
10    Initialized,
11    Frozen,
12}
13// TODO: extract token data from program into into a separate crate, import it and remove this file.
14#[derive(Debug, PartialEq, Eq, AnchorDeserialize, AnchorSerialize, Clone, Default)]
15pub struct TokenData {
16    /// The mint associated with this account
17    pub mint: Pubkey,
18    /// The owner of this account.
19    pub owner: Pubkey,
20    /// The amount of tokens this account holds.
21    pub amount: u64,
22    /// If `delegate` is `Some` then `delegated_amount` represents
23    /// the amount authorized by the delegate
24    pub delegate: Option<Pubkey>,
25    /// The account's state
26    pub state: AccountState,
27    /// Placeholder for TokenExtension tlv data (unimplemented)
28    pub tlv: Option<Vec<u8>>,
29}
30
31impl TokenData {
32    /// TokenDataVersion 3
33    /// CompressedAccount Discriminator [0,0,0,0,0,0,0,4]
34    #[inline(always)]
35    pub fn hash_sha_flat(&self) -> Result<[u8; 32], HasherError> {
36        use light_hasher::Hasher;
37        let bytes = self.try_to_vec().map_err(|_| HasherError::BorshError)?;
38        Sha256BE::hash(bytes.as_slice())
39    }
40}
41#[derive(Debug, Clone, PartialEq)]
42pub struct TokenDataWithMerkleContext {
43    pub token_data: TokenData,
44    pub compressed_account: CompressedAccountWithMerkleContext,
45}
46
47impl TokenDataWithMerkleContext {
48    /// Only works for sha flat hash
49    pub fn hash(&self) -> Result<[u8; 32], HasherError> {
50        if let Some(data) = self.compressed_account.compressed_account.data.as_ref() {
51            match data.discriminator {
52                [0, 0, 0, 0, 0, 0, 0, 4] => self.token_data.hash_sha_flat(),
53                _ => Err(HasherError::EmptyInput),
54            }
55        } else {
56            Err(HasherError::EmptyInput)
57        }
58    }
59}