Skip to main content
Every new token account created under a mint starts in a specified state, such as frozen, requiring the freeze authority to thaw accounts before holders can transact.
Set the compression_only flag when creating token accounts for this mint. Use transferInterface for transfers as usual.

Key Parameters

DefaultAccountState is configured with two parameters:
ParameterDescription
stateThe initial AccountState for new token accounts. Set to Frozen to require approval before transacting.
freezeAuthorityAuthority that can thaw frozen accounts and update the default state. Required when the default state is Frozen.
When a new token account is created for this mint, the token program automatically sets its state to the configured default. If the default is Frozen, the account cannot send or receive tokens until the freeze authority thaws it.

Use DefaultAccountState With Light Token

Install the agent skill:
npx skills add https://zkcompression.com
See the AI tools guide for dedicated skills.
npm install @lightprotocol/compressed-token@beta \
            @lightprotocol/stateless.js@beta \
            @solana/spl-token
Snippets below assume rpc, payer, mint, owner, recipient, and amount are defined. See the full examples for runnable setup.
import { createRpc } from "@lightprotocol/stateless.js";

const rpc = createRpc(RPC_ENDPOINT);

Create a Token-2022 Mint With Default Account State

import {
    Keypair,
    SystemProgram,
    Transaction,
    sendAndConfirmTransaction,
} from "@solana/web3.js";
import { createRpc } from "@lightprotocol/stateless.js";
import { LightTokenProgram } from "@lightprotocol/compressed-token";
import {
    TOKEN_2022_PROGRAM_ID,
    ExtensionType,
    getMintLen,
    createInitializeMint2Instruction,
    createInitializeDefaultAccountStateInstruction,
    AccountState,
} from "@solana/spl-token";

const rpc = createRpc(RPC_ENDPOINT);

const mintKeypair = Keypair.generate();
const decimals = 9;

// Calculate space for mint + DefaultAccountState extension
const mintLen = getMintLen([ExtensionType.DefaultAccountState]);
const rentExemptBalance =
    await rpc.getMinimumBalanceForRentExemption(mintLen);

// Create account
const createAccountIx = SystemProgram.createAccount({
    fromPubkey: payer.publicKey,
    lamports: rentExemptBalance,
    newAccountPubkey: mintKeypair.publicKey,
    programId: TOKEN_2022_PROGRAM_ID,
    space: mintLen,
});

// Initialize DefaultAccountState extension
const initDefaultAccountStateIx = createInitializeDefaultAccountStateInstruction(
    mintKeypair.publicKey,
    AccountState.Frozen,
    TOKEN_2022_PROGRAM_ID,
);

// Initialize mint
const initMintIx = createInitializeMint2Instruction(
    mintKeypair.publicKey,
    decimals,
    payer.publicKey, // mint authority
    payer.publicKey, // freeze authority (required for frozen default state)
    TOKEN_2022_PROGRAM_ID,
);

// Register interface PDA with Light Token
const createSplInterfaceIx = await LightTokenProgram.createSplInterface({
    feePayer: payer.publicKey,
    mint: mintKeypair.publicKey,
    tokenProgramId: TOKEN_2022_PROGRAM_ID,
});

const tx = new Transaction().add(
    createAccountIx,
    initDefaultAccountStateIx,
    initMintIx,
    createSplInterfaceIx
);

const signature = await sendAndConfirmTransaction(rpc, tx, [
    payer,
    mintKeypair,
]);

Create Interface PDA for Existing Mint

If you already have a Token-2022 mint with DefaultAccountState, create an interface PDA with Light Token.
import { LightTokenProgram } from "@lightprotocol/compressed-token";
import { TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";

const createSplInterfaceIx = await LightTokenProgram.createSplInterface({
    feePayer: payer.publicKey,
    mint: mintKeypair.publicKey,
    tokenProgramId: TOKEN_2022_PROGRAM_ID,
});

Transfer interface

Wrap and unwrap


Didn’t find what you were looking for?

Reach out! Telegram | email | Discord