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