Quasar
SPL Tokens

Associated Token Accounts

Deterministic token accounts derived from wallet + mint.

ATAs are deterministic token accounts derived from a wallet address and a mint (seeds: [wallet, token_program, mint], program: ATA program). Quasar provides declarative initialization, address validation, and derivation helpers.

Declarative Initialization

Use init with associated_token::mint and associated_token::authority to create an ATA. This invokes the ATA program's Create instruction via CPI:

use quasar_spl::{AssociatedToken, AssociatedTokenProgram, Mint, Token};

#[derive(Accounts)]
pub struct InitAta<'info> {
    pub payer: &'info mut Signer,
    #[account(init, associated_token::mint = mint, associated_token::authority = wallet)]
    pub ata: &'info mut Account<AssociatedToken>,
    pub wallet: &'info Signer,
    pub mint: &'info Account<Mint>,
    pub token_program: &'info Program<Token>,
    pub system_program: &'info Program<System>,
    pub ata_program: &'info Program<AssociatedTokenProgram>,
}

Use init_if_needed to create only if the account doesn't exist yet. If it does, Quasar validates that the mint and authority match:

#[account(init_if_needed, associated_token::mint = mint, associated_token::authority = wallet)]
pub ata: &'info mut Account<AssociatedToken>,

associated_token vs token attributes

associated_token::* creates an ATA at the deterministic PDA address (via the ATA program). token::* creates a generic token account (via InitializeAccount3). Use associated_token::* when you need the canonical ATA address.

Validation Without Init

To validate an existing ATA without creating it, use associated_token::* without init:

#[account(associated_token::mint = mint, associated_token::authority = wallet)]
pub ata: &'info Account<AssociatedToken>,

This derives the expected address, checks that the account matches, and validates the token data.

Address Derivation

For computing ATA addresses in instruction logic:

use quasar_spl::get_associated_token_address;

let (ata_address, bump) = get_associated_token_address(&wallet, &mint);

For a specific token program (e.g., Token-2022):

use quasar_spl::get_associated_token_address_with_program;

let (ata_address, bump) = get_associated_token_address_with_program(&wallet, &mint, &token_program_id);

For const contexts:

use quasar_spl::get_associated_token_address_const;

const ATA: (Address, u8) = get_associated_token_address_const(&WALLET, &MINT);

Closing ATAs

ATAs are regular token accounts -- close them with TokenClose:

self.ata.close(self.token_program, self.destination, self.authority).invoke()?;

On this page