defituna_client/utils/
token.rs

1use solana_program::instruction::Instruction;
2use solana_program::pubkey::Pubkey;
3use solana_program::system_instruction::transfer;
4use spl_associated_token_account::get_associated_token_address_with_program_id;
5use spl_associated_token_account::instruction::create_associated_token_account_idempotent;
6use spl_token_2022::instruction::{close_account, sync_native};
7
8pub struct CreateATAInstructions {
9    pub create: Vec<Instruction>,
10    pub cleanup: Vec<Instruction>,
11}
12
13pub fn get_create_ata_instructions(mint: &Pubkey, owner: &Pubkey, payer: &Pubkey, token_program_id: &Pubkey, amount: u64) -> CreateATAInstructions {
14    let mut create_instructions = vec![];
15    let mut cleanup_instructions = vec![];
16
17    let owner_ata = get_associated_token_address_with_program_id(&owner, mint, token_program_id);
18
19    create_instructions.push(create_associated_token_account_idempotent(payer, owner, mint, token_program_id));
20
21    if *mint == spl_token::native_mint::ID {
22        if amount > 0 {
23            create_instructions.push(transfer(&owner, &owner_ata, amount));
24            create_instructions.push(sync_native(token_program_id, &owner_ata).unwrap());
25        }
26
27        // Close WSOL account on the cleanup stage if the token account belongs to the payer.
28        if owner == payer {
29            cleanup_instructions.push(close_account(token_program_id, &owner_ata, owner, owner, &[]).unwrap());
30        }
31    }
32
33    CreateATAInstructions {
34        create: create_instructions,
35        cleanup: cleanup_instructions,
36    }
37}