#[cfg(target_os = "solana")]
use hopper_runtime::{error::ProgramError, Address, ProgramResult};
#[cfg(target_os = "solana")]
use crate::constants::{ATA_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID};
#[cfg(target_os = "solana")]
#[inline(always)]
pub fn derive_ata(wallet: &Address, mint: &Address) -> (Address, u8) {
derive_ata_for_program(wallet, mint, &TOKEN_PROGRAM_ID)
}
#[cfg(target_os = "solana")]
#[inline(always)]
pub fn derive_ata_2022(wallet: &Address, mint: &Address) -> (Address, u8) {
derive_ata_for_program(wallet, mint, &TOKEN_2022_PROGRAM_ID)
}
#[cfg(target_os = "solana")]
#[inline(always)]
pub fn derive_ata_for_program(
wallet: &Address,
mint: &Address,
token_program_id: &Address,
) -> (Address, u8) {
let seeds: &[&[u8]] = &[wallet.as_ref(), token_program_id.as_ref(), mint.as_ref()];
Address::find_program_address(seeds, &ATA_PROGRAM_ID)
}
#[cfg(target_os = "solana")]
#[inline(always)]
pub fn verify_ata(account_key: &Address, wallet: &Address, mint: &Address) -> ProgramResult {
let (expected, _) = derive_ata(wallet, mint);
if *account_key != expected {
return Err(ProgramError::InvalidSeeds);
}
Ok(())
}
#[cfg(target_os = "solana")]
#[inline(always)]
pub fn verify_ata_2022(account_key: &Address, wallet: &Address, mint: &Address) -> ProgramResult {
let (expected, _) = derive_ata_2022(wallet, mint);
if *account_key != expected {
return Err(ProgramError::InvalidSeeds);
}
Ok(())
}
#[cfg(target_os = "solana")]
#[inline(always)]
pub fn verify_ata_any(account_key: &Address, wallet: &Address, mint: &Address) -> ProgramResult {
if verify_ata(account_key, wallet, mint).is_ok() {
return Ok(());
}
verify_ata_2022(account_key, wallet, mint)
}