Skip to main content
The Compressed Token program implements an SPL Token-compatible interface for compressed tokens. It supports both compressed tokens (stored in Merkle trees) and CToken accounts (decompressed but not SPL tokens).

Program ID

cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m

Overview

The Compressed Token program enables rent-free token operations through ZK compression while maintaining full compatibility with SPL Token interfaces. Tokens can exist in two forms:
  • Compressed Tokens: Stored as leaves in Merkle trees (rent-free)
  • CToken Accounts: Decompressed Solana accounts (SPL-compatible layout)

Key Features

SPL Compatible

Matches SPL Token instruction interface

Token-2022 Extensions

Supports metadata, transfer fees, and more

Compression/Decompression

Seamlessly move between compressed and decompressed

Rent Management

Compressible extension for rent reclamation

Account Types

Compressed Token (TokenData)

Compressed token account stored in a Merkle tree.
mint
Pubkey
required
Compressed mint address
owner
Pubkey
required
Token account owner
amount
u64
required
Token balance
delegate
Option<Pubkey>
Optional delegate authority
state
AccountState
required
Account state: Initialized, Frozen, or Uninitialized
tlv
Vec<u8>
Type-length-value encoded extensions (for Token-2022 compatibility)
Discriminator:
  • V1: [2, 0, 0, 0, 0, 0, 0, 0] (little-endian, Poseidon hashed)
  • V2: [0, 0, 0, 0, 0, 0, 0, 3] (big-endian, Poseidon hashed)
  • ShaFlat: [0, 0, 0, 0, 0, 0, 0, 4] (big-endian, SHA-256 truncated)
Source: program-libs/token-interface/src/state/compressed_token/token_data.rs

CToken Account (Decompressed)

Solana account with SPL Token-compatible layout.
mint
Pubkey
required
Mint address (compressed or decompressed)
owner
Pubkey
required
Account owner
amount
u64
required
Token balance
delegate
Option<Pubkey>
Optional delegate
state
AccountState
required
Initialized, Frozen, or Uninitialized
is_native
Option<u64>
Native token amount (not supported)
delegated_amount
u64
Amount delegated to delegate
close_authority
Option<Pubkey>
Authority that can close the account
extensions
Vec<ExtensionStruct>
Token-2022 extensions:
  • Compressible: Rent management data
  • PausableAccount: Pausable account marker
  • PermanentDelegate: Permanent delegate marker
  • TransferHook: Transfer hook configuration
  • TransferFee: Transfer fee configuration
Associated Token Account Seeds: [owner, program_id, mint] Source: program-libs/token-interface/src/state/ctoken/ctoken_struct.rs

Compressed Mint

Mint account for compressed tokens.
mint_authority
Option<Pubkey>
Authority that can mint tokens
supply
u64
required
Total supply of tokens minted
decimals
u8
required
Number of decimals
is_initialized
bool
required
Whether mint is initialized
freeze_authority
Option<Pubkey>
Authority that can freeze accounts
metadata
Option<TokenMetadata>
Optional Token-2022 metadata extension:
  • name: Token name
  • symbol: Token symbol
  • uri: Metadata URI
Source: program-libs/token-interface/src/state/mint/compressed_mint.rs

Instruction Reference

Token Account Management

Creates a regular CToken account.Accounts:
  • fee_payer (signer, writable)
  • authority (signer)
  • token_account (writable): Account to create
  • mint: Mint account
  • compressible_config: Optional config for compressible extension
  • rent_recipient: Optional rent sponsor
  • system_program
Parameters:
  • compressible: Whether to add Compressible extension
Source: programs/compressed-token/program/src/ctoken/create.rs
Creates an associated token account (deterministic address).Derivation: Seeds [owner, program_id, mint]Source: programs/compressed-token/program/src/ctoken/create_ata.rs
Creates ATA, succeeds if already exists.Use Case: Safe to call multiple timesSource: programs/compressed-token/program/src/ctoken/create_ata.rs
Closes a CToken account.Process:
  1. Requires zero balance
  2. Returns rent exemption to rent recipient (if compressible)
  3. Returns remaining lamports to destination
Source: programs/compressed-token/program/src/ctoken/close/

Transfer Operations

Batch transfer instruction supporting multiple operations.Modes:
  • Compress: Convert SPL/CToken to compressed token
  • Decompress: Convert compressed token to CToken
  • CompressAndClose: Compress CToken and close account
  • Transfer: Standard compressed token transfer
Parameters:
  • inputs: Input compressed tokens (to spend)
  • outputs: Output compressed tokens (to create)
  • mint_indices: Multi-mint support (map outputs to mints)
  • compression_indices: Map compression operations to inputs
  • proof: ZK proof for state transitions
Multi-Mint: Supports multiple mints in single transaction with sum checks per mintSource: programs/compressed-token/program/src/compressed_token/transfer2/
Transfer between CToken accounts (decompressed).Accounts:
  • source (writable): Source CToken account
  • destination (writable): Destination CToken account
  • authority (signer): Source owner or delegate
Parameters:
  • amount: Amount to transfer
Source: programs/compressed-token/program/src/ctoken/transfer/default.rs
Transfer with decimals validation.Additional Parameter:
  • decimals: Must match mint decimals
Source: programs/compressed-token/program/src/ctoken/transfer/checked.rs

Mint Operations

Batch instruction for mint management and minting.Actions:
  • CreateCompressedMint: Create new compressed mint
  • MintTo: Mint to compressed token
  • MintToCToken: Mint to CToken account
  • UpdateMintAuthority: Change mint authority
  • UpdateFreezeAuthority: Change freeze authority
  • UpdateMetadataField: Update metadata (name, symbol, URI)
  • UpdateMetadataAuthority: Change metadata authority
  • RemoveMetadataKey: Remove metadata field
  • DecompressMint: Convert compressed mint to SPL mint
  • CompressAndCloseCMint: Compress mint and close CToken
Source: programs/compressed-token/program/src/compressed_token/mint_action/
Mint tokens to CToken account.Accounts:
  • mint (writable): Mint account
  • destination (writable): CToken account
  • authority (signer): Mint authority
Parameters:
  • amount: Amount to mint
Source: programs/compressed-token/program/src/ctoken/mint_to.rs
Mint with decimals validation.Additional Parameter:
  • decimals: Must match mint
Source: programs/compressed-token/program/src/ctoken/mint_to.rs

Burn Operations

Burn tokens from CToken account.Accounts:
  • token_account (writable): Account to burn from
  • mint (writable): Mint to decrease supply
  • authority (signer): Owner or delegate
Parameters:
  • amount: Amount to burn
Source: programs/compressed-token/program/src/ctoken/burn.rs
Burn with decimals validation.Source: programs/compressed-token/program/src/ctoken/burn.rs

Delegate Operations

Approve a delegate on CToken account.Accounts:
  • token_account (writable): Account to delegate
  • delegate: Delegate address
  • owner (signer): Account owner
Parameters:
  • amount: Amount to delegate
Source: programs/compressed-token/program/src/ctoken/approve_revoke.rs
Revoke delegate from CToken account.Source: programs/compressed-token/program/src/ctoken/approve_revoke.rs

Freeze Operations

Freeze a CToken account.Accounts:
  • token_account (writable): Account to freeze
  • mint: Mint account
  • authority (signer): Freeze authority
Effect: Sets account state to Frozen, preventing transfersSource: programs/compressed-token/program/src/ctoken/freeze_thaw.rs
Thaw a frozen CToken account.Effect: Sets account state back to InitializedSource: programs/compressed-token/program/src/ctoken/freeze_thaw.rs

Rent Management (Compressible Extension)

Claims rent from expired compressible accounts.Accounts:
  • rent_recipient (writable): Receives claimed rent
  • token_account (writable): Compressible account to claim from
  • compressible_config: Config with expiry settings
  • rent_authority: Optional authority for claiming
Requirements:
  • Account must be compressible (is_compressible() returns true)
  • Config must not be inactive
Process:
  1. Checks if account is expired based on config
  2. Transfers rent exemption to rent recipient
  3. Closes the account
Source: programs/compressed-token/program/src/compressible/claim.rs
Withdraws funds from rent recipient pool.Accounts:
  • rent_recipient (writable): Rent recipient account
  • destination (writable): Withdrawal destination
  • compressible_config: Associated config
  • rent_sponsor (signer): Must match config
Parameters:
  • amount: Amount to withdraw
Source: programs/compressed-token/program/src/compressible/withdraw_funding_pool.rs

Token-2022 Extensions

The Compressed Token program supports these Token-2022 extensions:

TokenMetadata

Name, symbol, URI for mints

Compressible

Custom extension for rent management

TransferFee

Configurable transfer fees

TransferHook

Custom transfer validation

PausableAccount

Account can be paused

PermanentDelegate

Permanent delegate authority
Extension Validation: All extensions are validated for compatibility across compression/decompression operations. Source: programs/compressed-token/program/src/extensions/

Usage Examples

Creating a Compressed Token

import { createMint, mintTo } from '@lightprotocol/compressed-token';
import { Rpc } from '@lightprotocol/stateless.js';

const rpc: Rpc = createRpc(rpcEndpoint, proverEndpoint);

// Create compressed mint
const { mint, transactionSignature } = await createMint(
  rpc,
  payer,
  mintAuthority.publicKey,
  9, // decimals
);

console.log(`Mint created: ${mint}`);

// Mint compressed tokens
const mintToResult = await mintTo(
  rpc,
  payer,
  mint,
  destination,
  mintAuthority,
  1_000_000_000, // 1 token (with 9 decimals)
);

Transferring Compressed Tokens

import { transfer } from '@lightprotocol/compressed-token';

const transferResult = await transfer(
  rpc,
  payer,
  mint,
  500_000_000, // 0.5 tokens
  owner,
  recipient.publicKey,
);

console.log(`Transfer signature: ${transferResult.transactionSignature}`);

Compressing SPL Tokens

import { compress } from '@lightprotocol/compressed-token';
import { getAssociatedTokenAddress } from '@solana/spl-token';

// Get SPL token account
const tokenAccount = await getAssociatedTokenAddress(
  mint,
  owner.publicKey,
);

// Compress SPL tokens to compressed tokens
const compressResult = await compress(
  rpc,
  payer,
  mint,
  1_000_000_000, // amount to compress
  owner,
  tokenAccount,
);

Decompressing to CToken Account

import { decompress } from '@lightprotocol/compressed-token';

// Decompress compressed tokens to CToken account
const decompressResult = await decompress(
  rpc,
  payer,
  mint,
  500_000_000, // amount to decompress
  owner,
  recipientCTokenAccount,
);

Error Codes

CodeNameDescription
4000MintMismatchToken accounts have different mints
4001InsufficientFundsInsufficient balance for operation
4002InvalidMintMint account invalid or uninitialized
4003OwnerMismatchAuthority doesn’t match owner
4004AccountFrozenAccount is frozen
4005InvalidDelegateDelegate not authorized
4006MintDecimalsMismatchDecimals don’t match mint
4007SumCheckFailedInput/output amounts don’t match
4008InvalidExtensionToken-2022 extension validation failed
4009CompressibleConfigInactiveConfig is inactive
4010NotCompressibleAccount not eligible for compression
Source:
  • programs/compressed-token/anchor/src/lib.rs (ErrorCode enum)
  • program-libs/token-interface/src/error.rs (CTokenError enum)

Source Code

View the full source code on GitHub:

Next Steps

Token Quickstart

Build your first compressed token app

Registry Program

Learn about protocol configuration

Build docs developers (and LLMs) love