use solana_program::program_error::ProgramError;
use solana_program::program::invoke;
use solana_program::sysvar::clock::Clock;
use spl_associated_token_account::instruction::create_associated_token_account_idempotent;
use steel::*;
use crate::state::Config;
#[macro_export]
macro_rules! extract_accounts {
($iter:expr, [$($var:ident),*]) => {
$(
let $var = $iter.next().unwrap();
)*
};
}
pub fn create_or_validate_wrapped_sol_ata<'a>(
ata_info: &AccountInfo<'a>,
owner_info: &AccountInfo<'a>,
mint_info: &AccountInfo<'a>,
payer_info: &AccountInfo<'a>,
system_program: &AccountInfo<'a>,
token_program: &AccountInfo<'a>,
ata_program: &AccountInfo<'a>,
_log_message: Option<&str>,
) -> Result<(), ProgramError> {
ata_info.is_writable()?;
let is_empty = ata_info.data_is_empty();
let is_owned_by_token_program = !is_empty && ata_info.has_owner(token_program.key).is_ok();
if is_owned_by_token_program {
ata_info.as_associated_token_account(owner_info.key, mint_info.key).map(|_| ())
} else if is_empty {
let create_ix = create_associated_token_account_idempotent(
payer_info.key,
owner_info.key,
mint_info.key,
token_program.key,
);
invoke(
&create_ix,
&[
payer_info.clone(),
ata_info.clone(),
owner_info.clone(),
mint_info.clone(),
system_program.clone(),
token_program.clone(),
ata_program.clone(),
],
)?;
ata_info.as_associated_token_account(owner_info.key, mint_info.key)?;
Ok(())
} else {
ata_info.as_associated_token_account(owner_info.key, mint_info.key).map(|_| ())
}
}
pub fn is_premine_active(config: &Config, clock: &Clock) -> bool {
config.tge_timestamp > 0 && clock.unix_timestamp < config.tge_timestamp
}
pub fn generate_random_mask(num_squares: u64, r: &[u8]) -> [bool; 25] {
let mut new_mask = [false; 25];
let mut selected = 0;
for i in 0..25 {
let rand_byte = r[i];
let remaining_needed = num_squares - selected;
let remaining_positions = 25 - i;
if remaining_needed > 0 && (rand_byte as u64) * (remaining_positions as u64) < (remaining_needed * 256) {
new_mask[i] = true;
selected += 1;
}
}
new_mask
}