ZK Compression Airdrop

ZK Compression Airdrop
A Next.js application for distributing SPL tokens using ZK Compression - making token airdrops ~5000x cheaper than regular SPL tokens.
Features
- ZK Compressed Tokens: Rent-free token accounts stored in Merkle trees
- Cost Efficient: ~5000x cheaper than standard SPL tokens
- Direct Minting: Simple authority-based distribution (no merkle proofs needed)
- Batch Processing: Configurable batch sizes for optimal transaction handling
- Wallet Integration: Connect with Phantom, Solflare, and other Solana wallets
Tech Stack
- Framework: Next.js 15 with App Router
- Styling: Tailwind CSS + Shadcn UI
- Solana SDK: Gill + Wallet UI components
- ZK Compression: @lightprotocol/compressed-token + stateless.js
Prerequisites
- Node.js (v22 or higher)
- npm (recommended) or npm
- Solana Wallet with devnet SOL
- Helius RPC API Key (free tier works) - Get one here
Why Helius? ZK Compression requires special Photon indexer nodes to query compressed accounts and generate validity proofs. Helius runs these indexers for free on devnet. Regular Solana RPC nodes can't parse compressed account data stored in Merkle trees.
Quick Start
1. Install Dependencies
npm install2. Set Up Environment Variables
Create a .env.local file in the project root:
# Helius RPC endpoint (required for ZK compression)
RPC_ENDPOINT=https://devnet.helius-rpc.com?api-key=YOUR_HELIUS_API_KEY
# Your wallet's private key (Base58 encoded) - KEEP THIS SECRET!
DEV_WALLET=your_base58_private_key_hereImportant:
- Get your Helius API key from https://dev.helius.xyz/
- To get your Base58 private key from Phantom: Settings → Show Private Key → Copy
DEV_WALLETworks for both scripts and frontend (via next.config.ts)- Never commit your
.env.localfile!
3. Get Devnet SOL
Make sure your wallet has some devnet SOL:
solana airdrop 2 YOUR_WALLET_ADDRESS --url devnetOr use the Solana Faucet.
4. Run Complete Airdrop Setup
This single command will:
- Generate test wallet recipients
- Create a compressed token mint
- Generate the airdrop recipients list
npm run airdrop:setup5. Start the Development Server
npm run devOpen http://localhost:3000 and execute the airdrop!
Manual Setup (Optional)
If you want to run the setup steps individually:
# Generate test wallets for recipients
npm run airdrop:wallets
# Create a new compressed token mint
npm run airdrop:mint
# Generate recipients list from test wallets
npm airdrop:recipientsHow It Works
1. Compressed Token Mint
Creates an SPL token registered with Light Protocol's compression program. The token pool enables rent-free compressed accounts.
2. Test Wallets
Generates Solana keypairs that will receive the airdrop tokens. In production, you'd load real recipient addresses.
3. Airdrop Execution
The mint authority calls mintTo() in batches, directly minting compressed tokens to recipients. No merkle proofs needed - the authority can mint directly.
4. Batching
Splits recipients across multiple transactions to stay within transaction size limits. Configurable via UI slider (max 50 per batch).
Project Structure
├── scripts/
│ ├── create-compressed-mint.ts # Create compressed token mint
│ ├── generate-test-wallets.ts # Generate recipient wallets
│ └── generate-recipients.ts # Prepare airdrop data
├── src/
│ ├── app/
│ │ └── page.tsx # Main airdrop UI
│ ├── components/
│ │ ├── airdrop/ # Airdrop UI components
│ │ │ ├── airdrop-executor.tsx # Main orchestrator
│ │ │ ├── airdrop-stats.tsx # Display token info
│ │ │ ├── airdrop-progress.tsx # Progress tracking
│ │ │ ├── airdrop-controls.tsx # Batch controls
│ │ │ └── airdrop-alerts.tsx # Status alerts
│ │ └── ui/ # Shadcn components
│ ├── hooks/
│ │ └── use-airdrop.ts # Airdrop execution hook
│ └── lib/
│ └── airdrop.ts # Core airdrop logicUnderstanding ZK Compression
What's Different?
Standard SPL Tokens:
- Each token account costs ~0.002 SOL rent
- 1000 recipients = ~2 SOL in rent fees
- Visible on standard explorers
ZK Compressed Tokens:
- Token accounts stored in Merkle trees
- About 5000x cheaper (no rent!)
- 1000 recipients = ~0.0004 SOL
- Requires ZK Compression indexer to query
Why Transactions Don't Appear on Solscan
Compressed token accounts are stored in on-chain Merkle trees, not as individual accounts. Standard explorers can't decode this data structure. To query compressed accounts:
- Mint address on Solana Explorer (shows the mint, not individual accounts)
- Photon RPC with special methods like
getCompressedTokenAccountsByOwner - RPC providers that run Photon indexers (Helius or run your own)
Customization
Change Token Details
Edit scripts/create-compressed-mint.ts:
const decimals = 9 // Token decimals
const config = {
name: 'My Airdrop Token',
symbol: 'AIRDROP',
// ... rest of config
}Change Recipient Amounts
Edit scripts/generate-recipients.ts:
return wallets.map((w, i) => ({
address: address(w.address),
amount: 100 * (i + 1), // Customize amounts here
}))Adjust Max Batch Size
Edit src/components/airdrop/airdrop-executor.tsx:
maxBatchSize={Math.min(airdropData.recipients.length, 50)} // Change 50 to your maxScripts Reference
| Script | Description |
|---|---|
npm airdrop:setup |
Complete setup: wallets + mint + recipients |
npm airdrop:wallets |
Generate test wallet recipients |
npm airdrop:mint |
Create compressed token mint |
npm airdrop:recipients |
Generate airdrop recipients list |
npm dev |
Start development server |
npm build |
Build for production |
Troubleshooting
"RPC_ENDPOINT environment variable not set"
Make sure you've created .env.local and added your Helius RPC endpoint.
"DEV_WALLET environment variable not set"
Add your Base58 private key to DEV_WALLET in .env.local. It's exposed to both scripts and frontend via next.config.ts.
"401 Unauthorized: Invalid API key"
Your Helius API key is incorrect. Get a new one from https://dev.helius.xyz/
"Wallet not authorized"
The connected wallet must match the mint authority. Connect the wallet whose private key is in DEV_WALLET.
"Transaction not found on Solscan"
This is expected! Compressed tokens use Merkle trees. Check the mint address on Solana Explorer instead.
Production Deployment
- Update recipient list: Replace test wallets with real addresses
- Secure your keys: Use environment variables, never commit keys
- Use mainnet RPC: Update
RPC_ENDPOINTto Helius mainnet - Test thoroughly: Always test on devnet first
- Monitor transactions: Keep track of successful/failed mints
Resources
- ZK Compression Documentation
- Photon Indexer (Terminology)
- ZK Compression RPC Methods
- Run Your Own Indexer
- Light Protocol GitHub
- Gill SDK
- Solana Wallet UI
License
This project is based on the gill-next-tailwind template from the Solana Foundation.
