solmail_program/state/
credits.rs1use crate::error::SolMailError;
2
3pub const USER_CREDITS_SIZE: usize = 49;
5
6#[repr(C, packed)]
8#[derive(Clone, Copy, Debug)]
9pub struct UserCredits {
10 pub owner: [u8; 32],
12 pub sol_balance: u64,
14 pub usdc_balance: u64,
16 pub bump: u8,
18}
19
20const _: () = assert!(core::mem::size_of::<UserCredits>() == USER_CREDITS_SIZE);
21
22impl UserCredits {
23 pub fn from_bytes(data: &[u8]) -> Result<&Self, SolMailError> {
25 if data.len() < USER_CREDITS_SIZE {
26 return Err(SolMailError::InvalidInstructionData);
27 }
28 Ok(unsafe { &*(data.as_ptr() as *const Self) })
30 }
31
32 pub fn from_bytes_mut(data: &mut [u8]) -> Result<&mut Self, SolMailError> {
34 if data.len() < USER_CREDITS_SIZE {
35 return Err(SolMailError::InvalidInstructionData);
36 }
37 Ok(unsafe { &mut *(data.as_mut_ptr() as *mut Self) })
39 }
40
41 pub fn add_sol(&mut self, amount: u64) -> Result<(), SolMailError> {
43 self.sol_balance = self
44 .sol_balance
45 .checked_add(amount)
46 .ok_or(SolMailError::Overflow)?;
47 Ok(())
48 }
49
50 pub fn sub_sol(&mut self, amount: u64) -> Result<(), SolMailError> {
52 if self.sol_balance < amount {
53 return Err(SolMailError::InsufficientFunds);
54 }
55 self.sol_balance -= amount;
56 Ok(())
57 }
58
59 pub fn add_usdc(&mut self, amount: u64) -> Result<(), SolMailError> {
61 self.usdc_balance = self
62 .usdc_balance
63 .checked_add(amount)
64 .ok_or(SolMailError::Overflow)?;
65 Ok(())
66 }
67
68 pub fn sub_usdc(&mut self, amount: u64) -> Result<(), SolMailError> {
70 if self.usdc_balance < amount {
71 return Err(SolMailError::InsufficientFunds);
72 }
73 self.usdc_balance -= amount;
74 Ok(())
75 }
76}