Token-2022 ships more than a dozen extensions. Most guides list all of them with equal weight, which is useless when you are deciding whether a token is safe to trade.
★Sorted by what they do to your code, the list is much shorter.★
The Four That Change Your Transaction
| Extension | What breaks if you ignore it |
|---|---|
| ★Transfer fee★ | ★Minimum output check reverts, every time★ |
| ★Transfer hook★ | ★Missing accounts, extra compute, extra CPI level★ |
| ★Non-transferable★ | ★You cannot sell — position is trapped★ |
| ★Default account state★ | ★New accounts arrive frozen and unusable★ |
These are the ones worth engineering for. Everything else on the list either affects display or is invisible to a trading bot.
Default account state deserves the attention it rarely gets. A mint configured with frozen as the default means every token account created for it is unusable until a freeze authority thaws it. ★Your buy lands, the account exists, the balance is there, and you cannot move it.★
The Three That Change What Is Possible
Permanent delegate. An address that can transfer or burn from any account holding this token, without the owner's signature. ★Someone else can take your position at any time.★ It is a legitimate mechanism for regulated assets and an obvious hazard everywhere else.
Mint close authority. The mint can be closed. Not usually a trading concern, but it signals the token is not designed to be permanent.
Interest-bearing. ★Display only.★ It changes the shown amount without changing the raw balance, so uiAmount drifts from amount. Do your arithmetic in raw units, as you should be doing anyway.
Reading the Extensions on a Mint
import { getMint, getExtensionTypes } from "@solana/spl-token";
const info = await connection.getAccountInfo(mintAddress);
if (!info.owner.equals(TOKEN_2022_PROGRAM_ID)) {
// ★Classic mint — no extensions possible. Stop here.★
return { extensions: [] };
}
const mint = await getMint(connection, mintAddress, "confirmed", TOKEN_2022_PROGRAM_ID);
const types = getExtensionTypes(mint.tlvData);
★The owner check first is not just an optimisation.★ Calling getMint with the Token-2022 program on a classic mint fails, so the check is what makes the rest of the code safe to run.
Extensions are stored as TLV data after the base 165 bytes, which is why extended accounts are larger and why a dataSize: 165 filter silently misses them.
If your extension handling is correct and transactions still miss, a free BoltTx key is one line to test the submission path.
A Screening Function
const BLOCKING = new Set([
ExtensionType.NonTransferable,
ExtensionType.PermanentDelegate,
]);
const NEEDS_HANDLING = new Set([
ExtensionType.TransferFeeConfig,
ExtensionType.TransferHook,
ExtensionType.DefaultAccountState,
]);
function screen(types) {
const blocking = types.filter((t) => BLOCKING.has(t));
const handling = types.filter((t) => NEEDS_HANDLING.has(t));
return {
tradeable: blocking.length === 0,
blocking,
handling, // ★must adjust code, not skip★
};
}
★The distinction between "blocking" and "needs handling" is the useful one.★ A transfer fee is not a reason to skip a token — it is a reason to adjust your slippage math. A permanent delegate is a different category entirely, because no amount of correct code protects you from it.
Authorities Matter More Than Current State
★A configuration you screen today can change tomorrow.★
| Authority | What it can do later |
|---|---|
| Transfer fee config | ★Raise the fee★ |
| Transfer hook | ★Point at different code★ |
| Freeze | ★Freeze your account★ |
| Permanent delegate | ★Take your tokens★ |
| Mint | Inflate supply |
Check whether each authority is set to null, not just what the current value is. A zero transfer fee with a live config authority is a fee that can appear at any epoch boundary — and the revert it causes will look sudden and inexplicable.
// ★Null authority means the setting is frozen forever.★
const feeCfg = getTransferFeeConfig(mint);
const canChange = feeCfg != null && feeCfg.transferFeeConfigAuthority != null;
★This is the same reasoning as checking mint authority for inflation risk★ — you are asking what someone can still do, not what they have done.
What This Costs at Screening Time
For a launch sniper, every check is latency you cannot spend.
One account fetch answers the first question. The mint's owner tells you whether any of this applies, and for most tokens it does not.
Extensions come from the same fetch. The TLV data is in the mint account you already read, so parsing them costs no additional round trip.
★So the practical cost is one read you were probably making anyway.★ What it does not cover is the hook's behaviour, which requires simulation — and that is the expensive part, which is why hooked tokens are usually worth skipping in a speed-sensitive strategy.
What Landing Looks Like
Real transactions through our delivery nodes: median confirmation 336ms — under one slot.
★An extension-related failure lands and reverts, costing the base fee.★ Screening moves that cost from production to a single account read, which is the whole argument for doing it.
Where BoltTx Fits
We handle submission. Which extensions a token carries, and how you handle them, are decided entirely in your instruction construction.
Submissions route through our own delivery nodes in four regions with stake-weighted routing and no public mempool exposure, so a transaction is not observable in transit before it lands. We never modify transaction contents, which includes never altering amounts or accounts.
You sign locally. We never hold funds and never sign. The tip travels inside the transaction, paid on chain from your own wallet, and reverts with the transaction if it fails, because that is how Solana handles atomic transactions. You pay only on transactions that reach the chain.
Get a free API key. No monthly fee:
const connection = new Connection("https://la.bolttx.io/?api-key=YOUR_KEY");
FAQ
What are Solana token extensions? Optional features a Token-2022 mint can carry, stored as TLV data after the base account layout. They range from transfer fees to hooks to display-only features like interest accrual.
Which token extensions affect trading bots? Transfer fee, transfer hook, non-transferable, and default account state change how you build transactions. Permanent delegate changes whether you should hold the token at all.
How do I list the extensions on a mint?
Check the mint's owner is the Token-2022 program, fetch it with getMint, then call getExtensionTypes on its TLV data. The owner check must come first or getMint fails.
What is the non-transferable extension? A mint setting that prevents transfers entirely. If you acquire such a token, you cannot sell it, which makes it a blocking condition rather than something to handle.
What is a permanent delegate? An address that can transfer or burn tokens from any account without the owner's signature. It is legitimate for regulated assets and a serious hazard for anything else.
What does default account state do? It sets whether newly created token accounts start frozen. With frozen as the default, your buy lands and the balance exists, but you cannot move it until a freeze authority thaws it.
Does the interest-bearing extension change my balance?
No, only the displayed amount. The raw amount is unchanged, so uiAmount drifts from it. Keeping arithmetic in raw units avoids the discrepancy entirely.
Why does getMint fail on some mints? Probably because you passed the Token-2022 program ID for a classic mint. Read the mint account's owner first and branch on it before calling any Token-2022 helper.
Why does my dataSize filter miss extended accounts? Extensions are stored after the base 165 bytes, making the accounts larger. A filter on exactly 165 excludes every extended account silently.
Should I check authorities or just current settings? Both, but authorities matter more. A zero fee with a live config authority can become a real fee at any epoch boundary, and the resulting revert appears without warning.
How do I know if a setting is permanent? The corresponding authority is null. A null authority means nobody can change that configuration again, which is the only real guarantee available.
Which extensions should make me skip a token entirely? Non-transferable and permanent delegate. Neither can be handled with better code, since one prevents selling and the other lets someone else take the position.
Does screening extensions slow down a sniper? Barely. The mint's owner and its extension data come from one account read you are likely making anyway. Only hook behaviour requires simulation, which is genuinely expensive.
Can extensions be added after a mint is created? Extensions are set at mint creation, but their parameters can change if the relevant authority still exists. That is why authority checks matter more than a snapshot of current values.
Do all extensions cost extra rent? Any extension that stores data increases the account size, which raises the rent-exempt minimum with it. Query the requirement using the actual data length rather than assuming.
How do I handle a token with a transfer fee and a hook together? Adjust the minimum output for the fee, use the hook-aware instruction builder for the accounts, and simulate to size compute. The two are independent and both must be handled.
Related Reading
- Token-2022 Transfer Fees
- Solana Transfer Hooks
- Token-2022 vs SPL Token
- Solana Account Data Parsing
- Solana Transaction Landing