Light Protocol: compressed token mint, transfer, decompress logoLight Protocol: compressed token mint, transfer, decompress
Create a mint with an interface PDA, mint compressed balances, send them, then compress or decompress when you need a normal ATA. Photon RPC required.
devrels.xyz/a/271Light Protocol compressed tokens are SPL and Token-2022 balances stored as hashes in a Merkle tree. You mint them, send them, then compress or decompress when a wallet or program needs a normal associated token account. Phantom and Backpack already display the compressed side.
A compressed token account costs about 5,000 lamports to create. A regular ATA is about 2 million. Trees, proofs, and Photon live in the ZK Compression overview. This page is the token path.
Install and RPC
The JS SDK talks to a Photon-enabled endpoint. createRpc() with no args hits local light test-validator. On devnet or mainnet pass a Helius URL (the ZK Compression product page issues the key).
npm install @lightprotocol/stateless.js@^0.23.0 \
@lightprotocol/compressed-token@^0.23.0
npm install -g @lightprotocol/zk-compression-cli
light test-validatorimport { createRpc } from "@lightprotocol/stateless.js"
const rpc = createRpc() // local validator
// const rpc = createRpc("https://devnet.helius-rpc.com?api-key=" + process.env.API_KEY)
await rpc.getIndexerHealth(await rpc.getSlot()) // "Ok"The four calls
Every mint needs an SPL interface PDA (also called a token pool). createMint makes a new mint with that PDA. Existing SPL mints use createTokenPool or createSplInterface. Without it, mint and compress fail with TokenPool not found.
| Call | What it does |
|---|---|
createMint / mintTo | New SPL mint plus interface PDA, then mint compressed balances to one or many owners. No ATA on the recipient. |
transfer | Spends sender compressed accounts and writes new outputs for sender and recipient. Max four compressed accounts per transaction. Split large spends. |
compress | Moves a precise amount from an ATA to a compressed owner (can be someone else). For a full account plus rent reclaim, use compressSplTokenAccount. |
decompress | Writes compressed balance back onto an ATA. Create that ATA first. |
Mint, send, then round-trip
Amounts are base units. Nine decimals means 1_000_000_000 is one token. mintTo accepts a single pubkey or parallel arrays of recipients and amounts.
import { createRpc } from "@lightprotocol/stateless.js"
import {
createMint,
mintTo,
transfer,
compress,
decompress,
} from "@lightprotocol/compressed-token"
import { createAssociatedTokenAccount } from "@solana/spl-token"
const rpc = createRpc(RPC_URL)
const { mint } = await createMint(rpc, payer, payer.publicKey, 9)
await mintTo(rpc, payer, mint, sender.publicKey, payer, 1_000_000_000)
await transfer(
rpc,
payer,
mint,
500_000_000,
sender,
recipient.publicKey,
)
const splAta = await createAssociatedTokenAccount(
rpc,
payer,
mint,
sender.publicKey,
)
await decompress(rpc, payer, mint, 250_000_000, sender, splAta)
await compress(
rpc,
payer,
mint,
100_000_000,
sender,
splAta,
sender.publicKey,
)CLI: light create-mint, then light mint-to and light transfer with --mint, --to, --amount.
Before a transfer, sum rpc.getCompressedTokenAccountsByOwner(owner, { mint }). Compressed transfers do not mutate one account in place. They nullify inputs and append outputs, so many small leftovers can blow the four-account cap. Merge when that happens.
When this is the right tool
Airdrops, rewards, and long-tail holder accounts are the fit. You skip rent on every empty ATA. A compressed transfer spends more compute (proof verify plus hashing, on the order of a few hundred thousand CU) and needs Photon plus a prover. Keep hot AMM vaults and every-block accounts on regular SPL.
Program cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m. Each mint supports up to four interface PDAs. Extra pools via addTokenPools raise per-block write-lock capacity when many compress/decompress txs hit the same mint.
People and links
| Who / what | Where |
|---|---|
| Docs | zkcompression.com/compressed-tokens |
| Cookbook | Lightprotocol/examples-zk-compression |
| X | @LightProtocol · @swen_sjn |
| GitHub | Lightprotocol/light-protocol |
| Related | ZK Compression overview · cNFTs |
Keep reading
State compression gave Solana cheap NFTs. ZK Compression generalises the idea to arbitrary accounts and tokens — ~100× cheaper, secured by a constant-size validity proof verified on-chain. The catch is compute. A developer's-eye view, and the cNFT distinction everyone gets wrong.
min_balance = (128 + data) * lamports_per_byte. Step 1 target 6333. Token instruction WithdrawExcessLamports. Mainnet rent sysvar still 6960.
Bonding-curve internet round, USDC in, SPL out. MCP: npx -y @star-factory/launch-cli mcp serve.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
