Skip to main content

Merkle distributor program

BitView reuses a battle-tested merkle distributor program (forked from the Jito / Jupiter implementation, audited by Neodyme and OtterSec — reports in distributor/audit/). The program is intentionally unchanged so the audits keep applying.

Why merkle?

A naive airdrop sends one transaction per recipient. With thousands of viewers that is gas-prohibitive on most chains and rent-prohibitive on Solana. A merkle distributor lets you publish a single 32-byte root on-chain. Each recipient claims by submitting their leaf + proof; the program verifies and pays them out from a single vault. Cost is amortized to the claimers themselves.

Instructions used by BitView

InstructionCallerPurpose
new_distributorstreamer (or operator)Create distributor PDA + token vault
set_enable_slotadminGate when claims become active
new_claimviewerClaim unlocked tokens with their proof
claim_lockedviewerClaim vested portion if vesting is configured
clawbackstreamerReclaim unclaimed tokens after clawback_start_ts
set_clawback_receiveradminUpdate the clawback recipient
set_adminadminHand over admin authority

PDA derivation

distributor_pda = pda([b"MerkleDistributor", base, mint, version_le], program_id)
claim_status_pda = pda([b"ClaimStatus", claimant, distributor_pda], program_id)

Where:

  • base = a per-tree base pubkey, kept secret/predictable
  • mint = the SPL mint being distributed
  • version = u64 index, lets one mint host multiple trees if needed

Flow timeline

streamer wallet backend viewer wallet
│ │ │
│── create SPL mint ────────┼───────────────────────────────▶│
│── new_distributor ────────┼───────────────────────────────▶│
│── fund vault ─────────────┼───────────────────────────────▶│
│── POST /distributions/ │ │
│ register ──────────────▶│ │
│ │── start accrual loop │
│ │ for channel │
│ │ │
│ │── (after duration) │
│ │── POST /finalize ──────────────│
│ │ │
admin/operator ── new merkle root ─────────────────────────────────▶ on-chain
set_enable_slot │
│ │ │
│ │ │── claim_proof ──▶
│ │◀── proof JSON ─────────────────│
│ │ │
│ │ │── new_claim ────▶ on-chain

Vesting and clawback

The distributor supports linear vesting (start_vesting_ts → end_vesting_ts) and a clawback after clawback_start_ts. BitView's default tier is no-vesting (claim immediately at finalize), but the program supports both, so a streamer can configure "earn now, claim over 30 days" if desired.