Privacy-First Donations on Solana
Stealth Link enables creators, developers, and privacy-conscious users to receive SOL donations publicly on Twitter/X without revealing their wallet balance or transaction history. It bridges the viral distribution of Solana Blinks with the ZK-privacy of Light Protocol.
In the Web3 creator economy, accepting public donations means doxxing your wallet.
- Public Donations: Put your SOL address in your bio and everyone sees your balance, trade history, and net worth
- The "Anon" Dilemma: Privacy-focused users can't accept tips because it links their persona to their financial identity
- Existing Tools: Current solutions (Blink generators, tip jars) offer zero on-chain privacy
A Stealth Link (e.g., stealth.link/donate/ariel.stealth) unfurls as a native Blink on Twitter/X. When a supporter donates:
- Frontend: The Blink constructs a transaction using Light Protocol
- On-Chain: SOL is shielded (compressed) into a private UTXO owned by the creator
- Result: Explorer shows
Donor β Light Protocol Pool. The creator's personal wallet never receives a public transfer
The creator manages funds via a private Dashboard where they can view their shielded balance and unshield (withdraw) to any fresh wallet when needed - breaking the on-chain link entirely.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TWITTER/X β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β BLINK PREVIEW β β
β β ββββββββββββ β β
β β β π₯· Icon β Donate to @creator β β
β β ββββββββββββ Support privately via Stealth Link β β
β β β β
β β [0.1 SOL] [0.5 SOL] [1 SOL] [Custom] β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STEALTH LINK API β
β β
β GET /api/actions/donate/[username] β Blink metadata β
β POST /api/actions/donate/[username] β Create shield transaction β
β β
β Resolves: .sol domains, .stealth handles, raw pubkeys β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LIGHT PROTOCOL (ZK COMPRESSION) β
β β
β LightSystemProgram.compress() β
β ββββββββββββ ββββββββββββββββ βββββββββββββββββββ β
β β Donor βββββΆβ Light Pool βββββΆβ Shielded UTXO β β
β β Wallet β β (Public) β β (Private Owner) β β
β ββββββββββββ ββββββββββββββββ βββββββββββββββββββ β
β β
β PUBLIC EXPLORER: "Donor β Light Protocol" β
β ACTUAL STATE: Creator owns compressed SOL β
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CREATOR DASHBOARD β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Shielded Balance: 2.5 SOL β β
β β β β
β β [Unshield to Connected Wallet] β β
β β [Unshield to Fresh Address: _____________ ] β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β LightSystemProgram.decompress() β Any destination wallet β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
When a donor sends SOL through a Stealth Link:
// Blink API constructs this transaction
const ix = await LightSystemProgram.compress({
payer: donorPubkey,
toAddress: creatorPubkey,
lamports: amountLamports,
outputStateTree: stateTree, // V1 tree for compatibility
});The SOL enters Light Protocol's compression pool. The creator's ownership is recorded as a compressed account - invisible on standard explorers.
Creators withdraw from the Dashboard:
// Fetch creator's compressed accounts via Helius ZK-RPC
const accounts = await rpc.getCompressedAccountsByOwner(creatorPubkey);
// Decompress to any destination (fresh wallet for max privacy)
const ix = await LightSystemProgram.decompress({
payer: creatorPubkey,
toAddress: destinationPubkey, // Can be any wallet
lamports: totalBalance,
inputCompressedAccounts: accounts,
});On-chain Anchor program maps human-readable handles to wallets:
#[account]
pub struct RegistryEntry {
pub handle: String, // "ariel"
pub authority: Pubkey, // Wallet owner
pub bump: u8,
}
// PDA: seeds = ["stealth", handle.as_bytes()]| Component | Technology | Purpose |
|---|---|---|
| Privacy Engine | Light Protocol | ZK Compression for shielded SOL transfers |
| Distribution | Solana Blinks | Native Twitter/X integration |
| Indexing | Helius | ZK-enabled RPC for compressed state |
| Framework | Next.js 14 | App Router for API + Dashboard |
| Registry | Anchor Program | On-chain handle β wallet mapping |
- Node.js 18+
- Helius API Key (Get one here)
git clone https://github.com/mindsend-datatech/solana-stealth.git
cd solana-stealth
npm installCreate .env.local:
NEXT_PUBLIC_HELIUS_RPC_URL=https://devnet.helius-rpc.com/?api-key=YOUR_HELIUS_KEYnpm run dev- Open
http://localhost:3000/api/actions/donate/YOUR_WALLETto see the Blink JSON - Use dial.to to preview how the Blink renders
- Register a
.stealthhandle athttp://localhost:3000/register
Light Protocol has V1 and V2 state trees. We explicitly select V1 trees because:
- V2 trees require additional account permissions during decompression
- V1 provides stable, well-tested behavior for our use case
// Only use V1 trees (treeType: 1)
const outputStateTree = stateTrees.find(t => t.treeType === 1);Maximum privacy requires breaking the on-chain link. The Dashboard allows unshielding to any destination:
- Shield funds arrive at Light Pool β Creator's compressed account
- Creator unshields to a fresh wallet address (not their main wallet)
- No on-chain connection between donor, creator identity, and final funds
See ROADMAP.md for detailed status and plans.
Completed:
- Registration page for
.stealthhandles - Blink API with .sol/.stealth/pubkey resolution
- Dashboard with shielded balance display
- Unshield to connected wallet
- Unshield to fresh wallet (privacy mode)
- RPC error handling with retry
Planned:
- Gas relayer for donor privacy
- Meta-address support (one-time stealth addresses)
- SPL token support (USDC, BONK)
MIT
Built with support from:
- Light Protocol - ZK Compression infrastructure
- Helius - ZK-enabled RPC indexing
- Dialect - Blink specification and tooling