Token-2022 Best Practices
Rules for choosing Token-2022 extensions and shipping compatible clients on Agave 4.1.1.
How to Use This List
- Apply A before enabling any extension at mint init
- Review B before shipping wallet or DEX integration
- Use C for on-chain programs accepting arbitrary tokens
A - Extension Selection
- Enable only extensions you need. Immutable extensions are permanent product commitments.
- Prefer transfer fee over hook for simple bps revenue. Hooks add client account resolution complexity.
- Avoid confidential transfers unless legal and wallet path confirmed. Ecosystem support is narrower.
- Document soulbound/non-transferable clearly. Users must not expect secondary market liquidity.
- Plan migration as new mint. No upgrade path from classic SPL Token.
B - Client Integration
- Detect mint owner program ID before every instruction.
Tokenkeg...vsTokenzQd...branches all builders. - Pass token program to ATA derivation.
findAssociatedTokenPdarequires correcttokenProgram. - Fetch and attach hook extra accounts. Missing accounts fail transfers silently in poorly built txs.
- Show transfer fee net amounts. Display gross, fee, and recipient receive before user signs.
- Test swaps on target DEX with small amount. Router Token-2022 support is mint-specific.
- Use DAS for portfolio metadata. Pair with correct program ID in custom parsers.
C - On-Chain Programs
- Use
token_interfacefor vaults listing external tokens. ClassicTokenconstraint rejects Token-2022 deposits. - Validate extension implications in README. e.g., non-transferable tokens break withdrawal markets.
- Keep hook programs minimal. Heavy logic on every transfer blows CU limits.
- Automate fee harvest cranks. Withheld fees do not reach treasury without harvest instructions.
- Do not assume
amountfield for confidential balances. Indexers need extension-aware parsers.
FAQs
Should new fungibles use Token-2022?
Only when an extension provides hard requirement - else classic Token maximizes compatibility.
Most common extension mistake?
Enabling transfer hooks without SDK support for extra accounts in all client paths.
How to test extensions?
Devnet mint + Surfpool 0.12.0 + target wallet/DEX smoke tests before mainnet.
token_interface required?
Yes for DeFi programs accepting arbitrary user-selected mints.
Can I mix Metaplex NFTs and Token-2022 fungible?
Yes - different standards for different asset types in same app.
Immutable metadata pitfalls?
Verify immutability flags at mint init - wrong URI permanent without upgrade path.
Freeze + default frozen confusion?
Default frozen affects new accounts; freeze authority still required for thaw.
Indexer guidance?
Parse TLV extensions or use DAS; do not assume 165-byte accounts only.
When to migrate from classic?
When extension benefit outweighs liquidity and wallet friction of new mint.
Program ID constant?
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb on all clusters.
Related
- Token-2022 Basics - overview
- Migrating from SPL Token - cutover plan
- Transfer Hooks - advanced policy
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.