Skip to main content

Overview

This guide covers the fundamental token operations you’ll need in Anchor programs:
  • Creating token accounts
  • Minting new tokens
  • Transferring tokens between accounts
  • Using Program Derived Addresses (PDAs) as authorities
All examples use the token_interface module, which works with both the Token Program and Token-2022 Program.

Creating Token Accounts

Before tokens can be held, you must create a token account. Anchor provides two approaches: Associated Token Accounts (ATAs) are the standard way to create token accounts for users:
Key points:
  • Uses associated_token constraints
  • Address is deterministically derived from owner + mint
  • Requires the AssociatedToken program
  • Use init_if_needed to handle existing accounts (requires init-if-needed feature)

Custom Token Accounts with PDAs

For program-controlled accounts, use custom PDAs:
Key points:
  • Uses token constraints instead of associated_token
  • Requires seeds and bump for PDA derivation
  • Can set the PDA as its own authority for program-controlled transfers

Minting Tokens

Minting creates new token supply. Only the mint authority can mint tokens.

Basic Minting

Important: The amount should account for decimals. If the mint has 6 decimals, minting 1,000,000 base units equals 1 token.

Minting with PDA Authority

When the mint authority is a PDA, your program must sign with the PDA’s seeds:
Key points:
  • Use ctx.bumps.<account_name> to access the bump seed
  • Call .with_signer() on the CPI context with the seeds
  • The PDA must be set as the mint authority when creating the mint

Transferring Tokens

Transfers move tokens from one token account to another. Use transfer_checked for safety.

Basic Transfer

Key points:
  • transfer_checked verifies the mint and decimals for safety
  • The authority must own the source token account
  • Both token accounts must be for the same mint

Transfer from Program-Controlled Account

When transferring from a PDA-owned account, use PDA signing:

Complete Example

Here’s a complete example showing mint creation, token account creation, minting, and transferring:
lib.rs

Common Patterns

Checking Token Balances

Validating Mint and Owner

Burning Tokens

Best Practices

  1. Use transfer_checked over transfer - It validates mint and decimals
  2. Use init_if_needed for ATAs - Handles existing accounts gracefully (requires feature flag)
  3. Store bump seeds - Use ctx.bumps.<account> instead of recomputing
  4. Use InterfaceAccount and Interface - Works with both token programs
  5. Validate token account relationships - Check mint and owner match expectations
  6. Handle decimals correctly - Remember amounts are in base units

Next Steps