Getting Started

Introduction

Cloak SDK is a privacy protocol for Solana that enables stealth addresses, relayer-based sender privacy, and zero-knowledge proofs for hidden payment amounts.

Deployed on Solana Devnet
Program: AaJF9TTgTPqRTuXfnQnVvBihpYwYUAYroW984foWyVJ

What are stealth addresses?

Stealth addresses are a cryptographic technique that enables unlinkable payments on public blockchains. Every time someone sends you SOL, the payment goes to a unique, one-time address that only you can detect and spend from.

Unlike regular wallet addresses where your entire transaction history is publicly visible, stealth addresses ensure that no outside observer can determine that two payments went to the same person.

The privacy stack

Cloak v1.0 provides three layers of privacy:

Stealth Addresses

ECDH-derived one-time addresses. The receiver's identity is hidden — no one can link payments to the same recipient.

Relayer Privacy

Submit transactions through a relayer server to hide the sender's wallet address. The relayer pays rent, the user only signs the transfer.

Hidden Amounts

Pedersen commitments with Groth16 zk-SNARK proofs on BN254 hide the payment amount. Verifiers can confirm validity without knowing the value.

How it works

  1. Receiver generates a stealth meta-address (spending + viewing keypairs) and shares the public portion.
  2. Sender uses ECDH with the receiver's public meta-address to derive a unique one-time stealth address and an ephemeral keypair.
  3. Sender transfers SOL to the stealth address and publishes the ephemeral public key on-chain via an Anchor announcement PDA.
  4. Receiver scans announcement PDAs, uses their viewing key to detect which payments are addressed to them, then derives the spending key to claim the funds.

Quick example

main.rs
rust
use cloak_sdk::{
    StealthMetaAddress, PublicMetaAddress,
    StealthPayment, StealthKeypair, Scanner,
};

// Receiver: generate identity
let meta = StealthMetaAddress::generate();
let public_addr = meta.to_public_string();

// Sender: create stealth payment
let recipient = PublicMetaAddress::from_string(&public_addr)?;
let payment = StealthPayment::create(&recipient, 1_000_000_000)?;
// → payment.stealth_address (where to send SOL)
// → payment.ephemeral_pubkey (publish on-chain)

// Receiver: detect and spend
let keypair = StealthKeypair::derive(&meta, &payment.ephemeral_pubkey)?;
let solana_kp = keypair.to_solana_keypair()?;
// Sign transactions with solana_kp

On-chain program

Cloak includes an Anchor program deployed on Solana Devnet with 6 instructions:

InstructionDescription
initializeCreate the global announcement counter PDA
send_stealthTransfer SOL + create announcement PDA
send_stealth_relayedRelayer pays rent, user signs transfer (sender privacy)
send_stealth_privateHidden amount with Pedersen commitment + Groth16 proof
announcePublish ephemeral key without transferring SOL
close_announcementReclaim rent from processed announcements