Account Types
Anchor account wrapper types encode common validation rules. Pick the strictest type that matches your threat model, then add attribute constraints for relationships.
Search across all documentation pages
Anchor account wrapper types encode common validation rules. Pick the strictest type that matches your threat model, then add attribute constraints for relationships.
#[derive(Accounts)]
pub struct Example<'info> {
pub payer: Signer<'info>,
pub data: Account<'info, MyState>,
pub sys: SystemAccount<'info>,
pub token_prog: Program<'info, Token>,
/// CHECK: validated in handler
pub oracle: UncheckedAccount<'info>,
}When to reach for this: You choose types for a new accounts struct field.
#[derive(Accounts)]
pub struct Deposit<'info> {
#[account(mut)]
pub user: Signer<'info>,
#[account(
mut,
associated_token::mint = mint,
associated_token::authority = user,
)]
pub user_ata: Account<'info, TokenAccount>,
pub mint: Account<'info, Mint>,
pub token_program: Program<'info, Token>,
pub associated_token_program: Program<'info, AssociatedToken>,
}What this demonstrates:
Signer requires a transaction signatureAccount<T> checks owner and deserializes with discriminatorProgram<T> pins program IDs for CPI targetsUncheckedAccount skips automatic safety checks| Type | Automatic checks |
|---|---|
Signer<'info> | is_signer |
Account<'info, T> | Owner, discriminator, deserialize T |
InterfaceAccount<'info, T> | Token-2022 / interface owners |
Program<'info, T> | Program ID for T |
SystemAccount<'info> | System program owner |
UncheckedAccount<'info> | None |
Use AccountLoader<'info, T> for zero-copy accounts and Interface<'info, T> for token interfaces in 0.32.
mut when persisting changes.Program<Token> etc.InterfaceAccount with TokenInterface.invoke_signed or CPI with_signer.| Alternative | Use When | Don't Use When |
|---|---|---|
| AccountLoader | Large zero-copy state | Small Borsh structs |
| InterfaceAccount | Token-2022 mints/ATAs | Legacy SPL only |
| remaining_accounts | Dynamic sets | Fixed instruction layout |
0.32.1 for anchor-lang, Anchor CLI, and examples in this section.
Yes. Solana CLI 3.0.10 handles keypairs, airdrops, and solana program inspection.
target/idl/<program>.json in your workspace.
Yes, but every unchecked field needs explicit constraints or handler checks.
Use anchor test with Surfpool 0.12.0 or LiteSVM 0.6.x in CI.
Anchor account discriminator; do not strip it when sizing space.
Yes, or publish on-chain IDL so clients have a canonical source.
Run with logs; Anchor prints constraint name and account index.
Yes. This stack targets Agave validators with Solana CLI 3.0.10.
See sibling articles linked in Related for deeper account types topics.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026