oil_api/state/
whitelist.rs1use serde::{Deserialize, Serialize};
2use solana_program::program_error::ProgramError;
3use solana_program::log::sol_log;
4use steel::*;
5
6use crate::consts::WHITELIST;
7use super::OilAccount;
8
9#[repr(C)]
11#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
12pub struct Whitelist {
13 pub code_hash: [u8; 32],
15
16 pub usage_count: u64,
18}
19
20impl Whitelist {
21 pub fn pda(code_hash: [u8; 32]) -> (Pubkey, u8) {
23 use crate::ID;
24 Pubkey::find_program_address(&[WHITELIST, &code_hash], &ID)
25 }
26
27 pub fn validate_premine_code<'a>(
29 is_premine: bool,
30 has_access_code: bool,
31 access_code_hash: [u8; 32],
32 whitelist_info_opt: Option<&AccountInfo<'a>>,
33 ) -> Result<(), ProgramError> {
34 if is_premine {
35 if !has_access_code {
36 return Err(ProgramError::InvalidArgument); }
38
39 let whitelist_info = whitelist_info_opt.ok_or(ProgramError::NotEnoughAccountKeys)?;
41
42 let (whitelist_pda, _) = Self::pda(access_code_hash);
44 whitelist_info.has_address(&whitelist_pda)?;
45
46 if whitelist_info.data_is_empty() {
48 return Err(ProgramError::InvalidArgument); }
50
51 let whitelist = whitelist_info.as_account::<Whitelist>(&crate::ID)?;
53 if whitelist.code_hash != access_code_hash {
54 return Err(ProgramError::InvalidArgument); }
56
57 let whitelist_mut = whitelist_info.as_account_mut::<Whitelist>(&crate::ID)?;
59 whitelist_mut.usage_count = whitelist_mut.usage_count.saturating_add(1);
60
61 sol_log(&format!(
62 "Pre-mine: access code validated, usage_count={}",
63 whitelist_mut.usage_count
64 ));
65 } else if has_access_code {
66 sol_log("Access code provided but pre-mine is not active - ignoring");
68 }
69
70 Ok(())
71 }
72}
73
74account!(OilAccount, Whitelist);