Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/blueshift-gg/quasar/llms.txt

Use this file to discover all available pages before exploring further.

quasar-spl is the SPL Token companion crate for Quasar programs. It ships zero-copy account wrappers for Mint and Token accounts, a unified TokenCpi trait that works with both SPL Token and Token-2022, and a declarative #[account(init)] system that generates the correct CPI calls to create mints, token accounts, and associated token accounts without any heap allocation.

Adding quasar-spl

Add the crate to your program’s Cargo.toml:
[dependencies]
quasar-lang = { version = "0.0" }
quasar-spl  = { version = "0.0" }
Then import the prelude at the top of every instruction file:
use quasar_lang::prelude::*;
use quasar_spl::prelude::*;

What the Prelude Exports

use quasar_spl::prelude::* re-exports everything you need for day-to-day token programming:
ExportDescription
MintZero-copy SPL Token mint wrapper (Account<Mint> / InterfaceAccount<Mint>)
TokenZero-copy SPL Token account wrapper (Account<Token> / InterfaceAccount<Token>)
Mint2022Zero-copy Token-2022 mint wrapper (Account<Mint2022>)
Token2022Zero-copy Token-2022 account wrapper (Account<Token2022>)
TokenProgramProgram marker for SPL Token (Program<TokenProgram>)
Token2022ProgramProgram marker for Token-2022 (Program<Token2022Program>)
TokenInterfaceInterface marker accepting either program (Interface<TokenInterface>)
AssociatedTokenProgramProgram marker for the ATA program
TokenCpiTrait providing .transfer(), .mint_to(), .burn(), etc.
accounts::{ associated_token, mint, token, token_close, token_sweep }Behavior modules for #[account(...)] annotations
The prelude is defined in spl/src/prelude.rs and re-exports from the crate root:
use quasar_lang::prelude::*;
use quasar_spl::prelude::*;

Account Type Matrix

Quasar-spl provides four concrete account types and one interface type. Choose the right one based on whether you need to support one or both token programs:
WrapperOwner checkUnderlying dataUse when
Account<Token>SPL Token onlyTokenDataZc (165 bytes)Token accounts for SPL Token
Account<Mint>SPL Token onlyMintDataZc (82 bytes)Mints owned by SPL Token
Account<Token2022>Token-2022 onlyTokenDataZc (165 bytes)Token accounts for Token-2022
Account<Mint2022>Token-2022 onlyMintDataZc (82 bytes)Mints owned by Token-2022
InterfaceAccount<Token>SPL Token or Token-2022TokenDataZcAccounts accepted by either program
InterfaceAccount<Mint>SPL Token or Token-2022MintDataZcMints from either program
All wrappers provide zero-copy field access through their Deref target (TokenDataZc or MintDataZc). No deserialization occurs — the framework reinterprets account data in place.

Program Markers

Three program account types are provided. Each implements the TokenCpi trait so you can call CPI methods directly on the program field:
// SPL Token only
pub token_program: Program<TokenProgram>,

// Token-2022 only
pub token_program: Program<Token2022Program>,

// Either program — dispatches CPI to whichever program is passed
pub token_program: Interface<TokenInterface>,
Program<TokenProgram> verifies the account is the executable at TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA. Program<Token2022Program> verifies TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb. Interface<TokenInterface> accepts either address at runtime and dispatches the correct CPI call to whichever token program was supplied.

The TokenCpi Trait

TokenCpi is a single trait implemented by Program<TokenProgram>, Program<Token2022Program>, and Interface<TokenInterface>. Every method returns a CpiCall that you finalize with .invoke() or .invoke_signed(&seeds):
// Transfer tokens — works the same regardless of which program marker you use
self.token_program
    .transfer(&self.from, &self.to, &self.authority, amount)
    .invoke()?;

// Mint new tokens
self.token_program
    .mint_to(&self.mint, &self.to, &self.authority, amount)
    .invoke()?;

// Burn tokens
self.token_program
    .burn(&self.from, &self.mint, &self.authority, amount)
    .invoke()?;

// Close a token account and reclaim its lamports
self.token_program
    .close_account(&self.vault, &self.destination, &self.authority)
    .invoke_signed(&seeds)?;
The full method list on TokenCpi is: transfer, transfer_checked, mint_to, burn, approve, revoke, close_account, sync_native, initialize_account3, and initialize_mint2.

Built-in Init Support

The #[account(init, ...)] attribute on any Account<Token>, Account<Mint>, or Account<Token2022> field triggers an automatic CPI sequence during account deserialization. No manual system_program.create_account call is needed. Initialize a mint:
#[account(mut,
    init,
    mint(decimals = 6, authority = mint_authority, freeze_authority = None, token_program = token_program),
)]
pub mint: Account<Mint>,
Initialize a token account:
#[account(mut,
    init,
    token(mint = mint, authority = payer, token_program = token_program),
)]
pub token_account: Account<Token>,
Initialize an associated token account (idempotent):
#[account(mut,
    init(idempotent),
    associated_token(authority = wallet, mint = mint, token_program = token_program,
                     system_program = system_program, ata_program = ata_program),
)]
pub ata: Account<Token>,
The init(idempotent) variant uses CreateIdempotent under the hood so the instruction is safe to re-run if the ATA already exists.

Program Addresses

Three well-known addresses are exported from the crate root:
use quasar_spl::{SPL_TOKEN_ID, TOKEN_2022_ID, ATA_PROGRAM_ID};
ConstantAddress
SPL_TOKEN_IDTokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
TOKEN_2022_IDTokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
ATA_PROGRAM_IDATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL

SPL Token

Mint and Token zero-copy wrappers, TokenCpi methods, init patterns, and escrow examples for SPL Token programs.

Token-2022

Token-2022 account types, Interface<TokenInterface> for multi-program support, and migration guidance.

Build docs developers (and LLMs) love