1
use bytemuck::{Pod, Zeroable};
2

            
3
use crate::error::ClientError;
4

            
5
#[cfg(feature = "on-chain")]
6
use {
7
    solana_program::account_info::AccountInfo, solana_program::program_memory::sol_memcpy,
8
    solana_program::pubkey::Pubkey,
9
};
10

            
11
#[cfg(not(feature = "on-chain"))]
12
use solana_sdk::pubkey::Pubkey;
13

            
14
#[repr(C)]
15
#[derive(Pod, Copy, Clone, Zeroable)]
16
pub struct ClaimStateV1 {
17
    pub claimer: [u8; 32],
18
    pub claimed_at: u64,
19
    pub block_commitment: u64,
20
}
21

            
22
pub struct ClaimStateHolder {
23
    data: Vec<u8>,
24
}
25

            
26
impl ClaimStateHolder {
27
    pub fn new(data: Vec<u8>) -> Self {
28
        Self {
29
            data: data.try_into().unwrap(),
30
        }
31
    }
32

            
33
    pub fn claim(&self) -> Result<&ClaimStateV1, ClientError> {
34
        bytemuck::try_from_bytes(&self.data).map_err(|_| ClientError::InvalidClaimAccount)
35
    }
36
}
37

            
38
impl ClaimStateV1 {
39
    pub fn load_claim(ca_data: &mut [u8]) -> Result<&Self, ClientError> {
40
        bytemuck::try_from_bytes::<ClaimStateV1>(ca_data)
41
            .map_err(|_| ClientError::InvalidClaimAccount)
42
    }
43

            
44
    pub fn load_claim_owned(ca_data: &[u8]) -> Result<Self, ClientError> {
45
        bytemuck::try_pod_read_unaligned::<ClaimStateV1>(ca_data)
46
            .map_err(|_| ClientError::InvalidClaimAccount)
47
    }
48

            
49
    pub fn from_claim_ix(claimer: &Pubkey, slot: u64, block_commitment: u64) -> Self {
50
        ClaimStateV1 {
51
            claimer: claimer.to_bytes(),
52
            claimed_at: slot,
53
            block_commitment,
54
        }
55
    }
56

            
57
    #[cfg(feature = "on-chain")]
58
    pub fn save_claim(claim: &Self, ca: &AccountInfo) {
59
        let claim_data = bytemuck::bytes_of(claim);
60
        sol_memcpy(&mut ca.data.borrow_mut(), claim_data, claim_data.len());
61
    }
62
}