@styxstack/whisperdrop-sdk
v1.0.2
Published
TypeScript SDK for WhisperDrop - Privacy-Preserving Airdrops on Solana
Maintainers
Readme
@styx-stack/whisperdrop-sdk
TypeScript SDK for WhisperDrop - Privacy-Preserving Airdrops on Solana.
Features
- 🔒 Privacy-Preserving - Recipient lists never published on-chain
- 🌳 Merkle Proofs - Efficient verification for 1M+ recipients
- 🎫 Token Gating - SPL, Token-2022, NFT, and cNFT support
- ⏰ Time-Locked - Automatic expiry with reclaim
- ⚡ Ultra-Efficient - ~5K compute units per claim
Installation
npm install @styx-stack/whisperdrop-sdk @solana/web3.jsQuick Start
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import {
WhisperDrop,
buildMerkleTree,
generateCampaignId,
generateNonce,
GateType
} from '@styx-stack/whisperdrop-sdk';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const whisperdrop = new WhisperDrop(connection);
// 1. Create allocations
const allocations = [
{ recipient: new PublicKey('...'), amount: 1000n, nonce: generateNonce() },
{ recipient: new PublicKey('...'), amount: 2000n, nonce: generateNonce() },
// ... up to 1M+ recipients
];
// 2. Build Merkle tree
const campaignId = generateCampaignId();
const { root, proofs } = buildMerkleTree(campaignId, allocations);
// 3. Initialize campaign with Token-2022 gating
const { campaignPDA, escrowPDA } = await whisperdrop.initCampaign(
authority,
tokenMint,
{
campaignId,
merkleRoot: root,
expiryUnix: BigInt(Date.now() / 1000 + 86400 * 30), // 30 days
gateType: GateType.Token22Holder,
gateMint: membershipToken, // Require Token-2022 token to claim
}
);
// 4. Recipients claim with proof
const proof = proofs.get(recipient.publicKey.toBase58())!;
await whisperdrop.claim(
payer,
recipient,
campaignPDA,
allocation,
proof,
recipientATA,
gateTokenAccount // Token-2022 token account
);Token Gating
WhisperDrop supports selective claiming based on multiple token standards:
SPL Token (Original Token Program)
// Require any amount of SPL token
{ gateType: GateType.SplTokenHolder, gateMint: tokenMint }
// Require minimum balance
{ gateType: GateType.SplMinBalance, gateMint: tokenMint, gateAmount: 1000_000_000n }Token-2022 (Token Extensions)
// Require any amount of Token-2022 token
{ gateType: GateType.Token22Holder, gateMint: token22Mint }
// Require minimum balance
{ gateType: GateType.Token22MinBalance, gateMint: token22Mint, gateAmount: 500_000_000n }NFT (Metaplex Standard)
// Require specific NFT
{ gateType: GateType.NftHolder, gateMint: nftMint }
// Require NFT from collection
{ gateType: GateType.NftCollection, gateMint: collectionMint }cNFT (Compressed NFT via Bubblegum)
// Require specific cNFT (asset ID as mint)
{ gateType: GateType.CnftHolder, gateMint: assetId }
// Require cNFT from collection
{ gateType: GateType.CnftCollection, gateMint: collectionId }GateType.NftCollection
Must hold an NFT from a specific collection (future: Metaplex verification).
API Reference
WhisperDrop Class
const wd = new WhisperDrop(connection, programId?);initCampaign(authority, mint, config)
Initialize a new airdrop campaign.
claim(payer, recipient, campaignPDA, allocation, proof, recipientATA, gateTokenAccount?)
Claim tokens with Merkle proof.
reclaim(authority, campaignPDA, authorityATA)
Reclaim remaining tokens after expiry.
hasClaimed(campaignPDA, recipient)
Check if recipient has already claimed.
getCampaign(campaignPDA)
Get campaign state.
Merkle Tree Utilities
import {
buildMerkleTree,
verifyMerkleProof,
computeLeafHash,
computeNodeHash,
} from '@styx-stack/whisperdrop-sdk';PDA Derivation
import {
deriveCampaignPDA,
deriveEscrowPDA,
deriveNullifierPDA,
} from '@styx-stack/whisperdrop-sdk';Program IDs
| Network | Program ID |
|---------|------------|
| Mainnet | GhstFNnEbixAGQgLnWg1nWetJQgGfSUMhnxdBA6hWu5e |
| Devnet | BPM5VuX9YrG7CgueWGxtqQZBQwMTacc315ppWCtTCJ5q |
Use Cases
1. NFT Holder Airdrops
Airdrop tokens only to holders of your NFT collection.
2. Staker Rewards
Distribute rewards to users who stake above a threshold.
3. Community Rewards
Private distribution to community members without revealing the list.
4. Retroactive Airdrops
Reward early users without publishing their addresses.
Security
- Nullifiers prevent double-claiming
- Time-locked reclaim protects unclaimed funds
- Immutable Merkle root ensures allocation integrity
- PDA escrow for secure token custody
License
Apache-2.0
Built by @moonmanquark at Bluefoot Labs
