use crate::common::{
fast_fn::create_associated_token_account_idempotent_fast,
seed::{
create_associated_token_account_use_seed,
get_associated_token_address_with_program_id_use_seed,
},
spl_token::close_account,
};
use smallvec::SmallVec;
use solana_sdk::{instruction::Instruction, instruction::AccountMeta, pubkey::Pubkey};
use solana_system_interface::instruction as system_instruction;
#[inline]
pub fn handle_wsol(payer: &Pubkey, amount_in: u64) -> SmallVec<[Instruction; 3]> {
let wsol_token_account =
crate::common::fast_fn::get_associated_token_address_with_program_id_fast(
&payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
);
let mut insts = SmallVec::<[Instruction; 3]>::new();
insts.extend(create_associated_token_account_idempotent_fast(
&payer,
&payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
));
insts.extend([
system_instruction::transfer(&payer, &wsol_token_account, amount_in),
Instruction {
program_id: crate::constants::TOKEN_PROGRAM,
accounts: vec![AccountMeta::new(wsol_token_account, false)],
data: vec![17],
},
]);
insts
}
pub fn close_wsol(payer: &Pubkey) -> Vec<Instruction> {
use std::sync::Arc;
let wsol_token_account =
crate::common::fast_fn::get_associated_token_address_with_program_id_fast(
&payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
);
let arc_instructions = crate::common::fast_fn::get_cached_instructions(
crate::common::fast_fn::InstructionCacheKey::CloseWsolAccount {
payer: *payer,
wsol_token_account,
},
|| {
vec![close_account(
&crate::constants::TOKEN_PROGRAM,
&wsol_token_account,
&payer,
&payer,
&[],
)
.unwrap()]
},
);
Arc::try_unwrap(arc_instructions).unwrap_or_else(|arc| (*arc).clone())
}
#[inline]
pub fn create_wsol_ata(payer: &Pubkey) -> Vec<Instruction> {
create_associated_token_account_idempotent_fast(
&payer,
&payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
)
}
#[inline]
pub fn wrap_sol_only(payer: &Pubkey, amount_in: u64) -> SmallVec<[Instruction; 2]> {
let wsol_token_account =
crate::common::fast_fn::get_associated_token_address_with_program_id_fast(
&payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
);
let mut insts = SmallVec::<[Instruction; 2]>::new();
insts.extend([
system_instruction::transfer(&payer, &wsol_token_account, amount_in),
Instruction {
program_id: crate::constants::TOKEN_PROGRAM,
accounts: vec![AccountMeta::new(wsol_token_account, false)],
data: vec![17],
},
]);
insts
}
pub fn wrap_wsol_to_sol(payer: &Pubkey, amount: u64) -> Result<Vec<Instruction>, anyhow::Error> {
let mut instructions = Vec::new();
let seed_account_instructions = create_associated_token_account_use_seed(
payer,
payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
)?;
instructions.extend(seed_account_instructions);
let seed_ata_address = get_associated_token_address_with_program_id_use_seed(
payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
)?;
let user_wsol_ata = crate::common::fast_fn::get_associated_token_address_with_program_id_fast(
payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
);
let transfer_instruction = crate::common::spl_token::transfer(
&crate::constants::TOKEN_PROGRAM,
&user_wsol_ata,
&seed_ata_address,
payer,
amount,
&[],
)?;
instructions.push(transfer_instruction);
let close_instruction =
close_account(&crate::constants::TOKEN_PROGRAM, &seed_ata_address, payer, payer, &[])?;
instructions.push(close_instruction);
Ok(instructions)
}
pub fn wrap_wsol_to_sol_without_create(
payer: &Pubkey,
amount: u64,
) -> Result<Vec<Instruction>, anyhow::Error> {
let mut instructions = Vec::new();
let seed_ata_address = get_associated_token_address_with_program_id_use_seed(
payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
)?;
let user_wsol_ata = crate::common::fast_fn::get_associated_token_address_with_program_id_fast(
payer,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
);
let transfer_instruction = crate::common::spl_token::transfer(
&crate::constants::TOKEN_PROGRAM,
&user_wsol_ata,
&seed_ata_address,
payer,
amount,
&[],
)?;
instructions.push(transfer_instruction);
let close_instruction =
close_account(&crate::constants::TOKEN_PROGRAM, &seed_ata_address, payer, payer, &[])?;
instructions.push(close_instruction);
Ok(instructions)
}