Token-2022 In Depth
Token-2022 (Token Extensions) is the Solana token program that keeps the familiar mint, account, and transfer model of classic SPL Token while allowing optional extensions to attach extra fields and rules at initialization.
It is not a new chain and not a silent upgrade of the classic program. It is a different program ID with a compatible base layout, larger accounts when extensions are enabled, and client and venue compatibility that varies by extension.
This page is the umbrella for token-2022-extensions: how Token-2022 relates to classic Token, how the extension model works, what the major extensions mean for product and code, and how migration actually happens.
Summary
- Token-2022 (
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) is a superset token program: same base mint and token-account concepts as classic SPL Token (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA), plus a type-length-value (TLV) extension region for fees, hooks, metadata, soulbound rules, yield display, and confidential amounts. - Insight: Choosing Token-2022 is a product and integration decision, not only a CLI flag. Wrong program ID in ATA derivation, missing hook accounts, ignoring withheld fees, or assuming classic balances under confidential or interest-bearing mints breaks wallets, DEXs, and vaults.
- Key Concepts: classic SPL Token, Token-2022 program ID, mint extension, account extension, TLV layout, metadata / metadata pointer, transfer hook, permanent delegate, non-transferable, interest-bearing, default account state, confidential transfer, token_interface, migration (new mint).
- When to Use: You need on-mint policy or data that classic Token cannot express, or your stack standardizes on Token-2022 for new mints with a verified support matrix.
- Limitations/Trade-offs: Not every wallet, router, or indexer supports every extension. Extensions at init are often permanent product commitments. Confidential and hook-heavy paths raise CU, client complexity, and compliance cost.
- Related Topics: Token-2022 basics, transfer fees and hooks, metadata, permanent delegate and non-transferable, interest-bearing and default account state, confidential transfers, and migrating from SPL Token.
Foundations
Classic SPL Token versus Token-2022
Classic SPL Token is the long-standing program most wallets and DEXs assume by default. Its mint and token account layouts are fixed: supply, decimals, authorities, balances, delegates, frozen state. Policy beyond that lives in separate programs (marketplaces, Metaplex metadata PDAs, custom transfer wrappers).
Token-2022 keeps that base layout at the front of the account and appends extension data. Without extensions, a Token-2022 mint behaves much like a classic mint for mint, burn, and transfer, but:
- Mint and ATAs are owned by the Token-2022 program, not classic Token.
- ATA addresses depend on the token program ID passed into derivation.
- Clients must encode instructions against Token-2022 (or dual-aware interfaces), not assume
Tokenkeg....
There is no shared upgrade path that flips an existing classic mint into Token-2022. Same brand, new program means new mint, new ATAs, and an operational holder and liquidity migration.
The extension model
Extensions are optional modules initialized when the mint and/or token account is created (or, for some account extensions, when the account is configured). They live in a TLV region after the base SPL fields.
Practical rules:
- Pick at birth. Many mint extensions cannot be stripped later. Enabling transfer fee, non-transferable, or permanent delegate is a permanent product commitment for that mint.
- Mint versus account scope. Fee config, hook program id, metadata pointer, permanent delegate, and interest rate authority sit on the mint. Withheld fees, confidential balances, and some flags sit on token accounts.
- Rent and size scale. More extension data means larger accounts and higher rent-exempt minimums.
- Clients must be extension-aware. Prefer
jsonParsedwhere supported, official Token-2022 codecs, or DAS for reads; still branch on program ID for writes.
| Family | Intent | Typical pain if ignored |
|---|---|---|
| Transfer fee | Withhold bps (and max) on transfers | Wrong UX amounts; fees never harvested |
| Transfer hook | CPI custom program on transfer | Missing extra accounts; failed txs |
| Metadata / pointer | Name, symbol, URI on or beside mint | Blank branding in non-aware wallets |
| Permanent delegate | Fixed authority can always move tokens | Undisclosed seizure power |
| Non-transferable | Block ordinary transfers (soulbound) | Failed sells; DEX listing impossible |
| Interest-bearing | Rate-based balance growth display | Stale amount UI |
| Default account state | New accounts start frozen or initialized | Surprise freeze until thaw |
| Confidential transfer | ZK-hidden amounts | Wrong public amount; unsupported wallets |
Metadata and metadata pointer
Token metadata embeds name, symbol, and URI in mint extension data so simple fungibles do not need a Metaplex Token Metadata PDA for basic branding. Metadata pointer stores a pubkey that points at an external metadata account when you want metadata off the mint itself.
URI usually references off-chain JSON (image, description); prefer immutable storage over mutable HTTP hosts. Explorers and DAS increasingly index Token-2022 metadata, but some wallets still expect Metaplex for NFT-like assets. On-mint metadata does not by itself make an NFT.
Detail: Metadata & Metadata Pointer.
Transfer hooks (concept)
A transfer hook mint stores a custom program id. On every transfer (and related move), Token-2022 invokes that program so policy runs atomically with the token move: allowlists, royalty ledgers, compliance checks, accounting.
The hook program must implement the interface Token-2022 expects and stay minimal (CU is shared with the transfer). Clients must resolve and pass extra accounts the hook requires; missing accounts is the most common integration failure. Prefer the built-in transfer fee extension when the only need is basis-point revenue.
Detail: Transfer Hooks. Fees: Transfer Fees.
Permanent delegate and non-transferable
Permanent delegate embeds a pubkey on the mint that can transfer tokens without the usual per-account delegate approval from the holder. It is strong issuer control for reclaim paths, and a serious trust disclosure for users.
Non-transferable marks the mint so standard transfers fail. Tokens are effectively soulbound after issue (credentials, badges, non-tradable access). Mint and burn may still apply under authorities you configure. Secondary markets and AMM pools are the wrong product surface.
Often combined with default account state frozen so new accounts cannot move funds until a freeze authority thaws after KYC or claim flow.
Detail: Permanent Delegate & Non-Transferable.
Interest-bearing, default account state, and confidential transfers
Interest-bearing stores a rate (and rate authority) on the mint. Displayed or effective balances grow according to Token-2022's time-based formula without an external lending vault for simple savings-style product math. UIs must refresh with extension-aware reads.
Default account state sets whether new token accounts start initialized or frozen. Frozen-by-default is a compliance and airdrop pattern: creation succeeds, transfers wait on thaw.
Confidential transfers use zero-knowledge proofs so amounts can rest and move in encrypted form while the program still enforces conservation of value. The classic public amount field is not the full economic picture once value is deposited into confidential state. Proof generation is client-side and wallet or RPC support is narrower than plain transfers.
Details: Interest-Bearing & Default Account State, Confidential Transfers.
Migration considerations
Migrating from classic SPL Token means: design the Token-2022 mint and extension set; confirm wallet, DEX, custody, and indexer support; snapshot holders (and LP positions); create the new mint and airdrop or claim into Token-2022 ATAs; dual-run both mints; then sunset legacy deposits.
There is no on-chain "upgrade this mint" instruction across programs. Programs that accept arbitrary user mints should use token_interface (Anchor) or equivalent dual paths so classic and Token-2022 can coexist during transition.
Detail: Migrating from SPL Token.
Mechanics & Interactions
End-to-end, a Token-2022 asset touches three layers:
Mint init (program ID Token-2022 + extension TLV)
|
v
Token accounts / ATAs (same program ID in derivation)
|
v
Instructions (transfer, mint, freeze, harvest, hook CPI, confidential proofs)
|
v
Clients, wallets, routers, vaults (branch on owner + extensions)
Program ID is the first branch. Before building ATA PDAs or transfer instructions, read the mint account's owner. If it is Token-2022, every subsequent builder, CPI target, and package must match.
ATA derivation includes the token program. With a new Token-2022 mint you always get new ATAs. Passing the wrong tokenProgram yields a wrong address and silent empty-account bugs.
Extension interactions compound. Transfer fee plus hook means fee math and hook accounts both apply. Non-transferable plus permanent delegate blocks user transfer while the delegate may still move value. Default frozen plus thaw authority creates accounts that cannot transfer until thaw. Confidential plus public deposit or withdraw needs multi-step UI state (public, pending, confidential).
Anchor dual mint programs. Prefer InterfaceAccount + TokenInterface over classic-only Token constraints when vaults list external or user-chosen mints.
CLI and stack. With Solana CLI 3.0.10, point spl-token at Token-2022 via --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb. Local work on Agave 4.1.1-class validators, Surfpool, or LiteSVM still requires correct program and extension init order. @solana/kit 7.0.0 supplies typed RPC and codecs; detect owner via getAccountInfo, then encode with Token-2022-aware helpers.
Advanced Considerations & Applications
Choosing Token-2022 at all
Default to classic SPL Token when you need maximum venue compatibility and no extension is required. Choose Token-2022 when an extension is a hard product requirement and you have verified support. Shipping Token-2022 only because it is newer is how launches strand liquidity.
Extension set as threat model
Treat mint init as a security and legal document:
- Permanent delegate and freeze authority are seizure and gating powers; prefer multisig or governance and clear disclosure.
- Transfer hooks expand trusted code on every transfer; audit the hook like production code.
- Confidential transfers change what outsiders and risk systems can observe; align with compliance before mainnet.
- Interest rate authority can change displayed yield parameters; document ownership and update process.
Client and venue matrix before mainnet
For each enabled extension, verify target wallets (display, send, ATA create, fee net amounts), DEX or router routes and hook extra accounts, custody deposit support, indexer or DAS balance semantics, and your own program paths (token_interface, fee harvest, hook metas). Smoke-test small amounts on devnet and mainnet before large liquidity.
Operational load
Transfer fees need harvest or crank paths so withheld tokens reach treasury. Hooks need versioned extra-account resolvers in every client path. Interest-bearing needs UI refresh policy. Confidential needs key custody and proof generation architecture (worker, server, or specialized wallet).
Greenfield is one mint and one ATA tree. Migration is dual mint registry, dual pools, dual analytics, and a communication plan. Budget engineering for dual-run; it usually outlasts airdrop day.
Common Misconceptions
- "Token-2022 replaces classic Token for every mint." Classic Token remains widely supported. Token-2022 is opt-in per mint via a different program.
- "I can upgrade my classic mint in place." You cannot. New mint, new ATAs, holder and liquidity migration.
- "Without extensions, program ID does not matter." It always matters for ownership, ATA derivation, and instruction encoding.
- "Metadata extension is Metaplex." Related branding goals, different account models.
- "Transfer hooks are free policy." They cost CU, extra accounts, and full client support; simple fees should use the fee extension.
- "Permanent delegate is just another optional admin." It can move holder tokens under extension rules; treat it as high trust.
- "Non-transferable tokens can still list on a DEX." Ordinary transfers fail; pools are the wrong fit.
- "The public amount is always total wealth under confidential mints." Confidential balances are not fully reflected in the public amount once deposited.
- "token_interface is optional for multi-mint vaults." Classic-only constraints reject Token-2022 deposits.
FAQs
What is Token-2022 in one sentence?
A separate Solana token program that preserves classic mint and account concepts while allowing optional TLV extensions for fees, hooks, metadata, policy, yield display, and confidential amounts.
What is the Token-2022 program ID?
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb. Classic SPL Token remains TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA.
When should a new fungible use Token-2022?
When you need a specific extension classic Token cannot provide and you have verified wallet, DEX, and custody support for that set; otherwise classic Token maximizes compatibility.
Can I add extensions after the mint is created?
Generally you configure extensions at mint and account initialization. Plan the set before mainnet; do not assume later feature flags.
How do ATAs differ for Token-2022?
ATA derivation includes the token program id. Always pass Token-2022's program id when deriving and creating accounts for Token-2022 mints.
What is a transfer hook versus a transfer fee?
A transfer fee withholds basis points inside Token-2022. A transfer hook CPI-calls a custom program for arbitrary policy and requires extra accounts from every client.
Are non-transferable tokens the same as frozen accounts?
No. Frozen is an account state that can be thawed. Non-transferable is a mint-level rule that blocks ordinary transfers for that mint's tokens.
What does permanent delegate allow?
A fixed authority on the mint can move tokens without the usual holder-approved delegate pattern. Disclose it and secure the key with multisig or governance when used.
Do confidential transfers hide parties or only amounts?
The extension family is centered on amount privacy via ZK proofs and encrypted balances; do not assume full identity privacy on a public L1 without a broader design.
How do I support classic and Token-2022 in one Anchor program?
Use anchor-spl token_interface types (InterfaceAccount, TokenInterface) and branch clients on mint owner program id.
How do holders migrate from classic Token?
Operationally: snapshot, new Token-2022 mint, airdrop or claim into new ATAs, dual-run, then sunset. There is no single upgrade instruction.
Where should I go next in this section?
Start with Token-2022 Basics for concrete CLI and client steps, then the extension pages under Related for metadata, policy, yield, confidential transfers, and migration.
Related
- Token-2022 Basics - program id, ATAs, CLI mint/transfer, token_interface
- Metadata & Metadata Pointer - on-mint branding and pointer accounts
- Permanent Delegate & Non-Transferable - issuer control and soulbound mints
- Interest-Bearing & Default Account State - rate display and freeze-by-default accounts
- Confidential Transfers - ZK amounts, deposit/withdraw, client proofs
- Migrating from SPL Token - dual program support and holder cutover
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, and @solana/kit 7.0.0.