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.
- Program ID:
4ffj6hEnx6cqp4ToMALExqk6QwPNSbZyr8ro9yW1Qvok - Anchor:
0.30.1 - Solana:
1.18.17 - IDL:
distributor/merkle-distributor/idl/merkle_distributor.json
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
| Instruction | Caller | Purpose |
|---|---|---|
new_distributor | streamer (or operator) | Create distributor PDA + token vault |
set_enable_slot | admin | Gate when claims become active |
new_claim | viewer | Claim unlocked tokens with their proof |
claim_locked | viewer | Claim vested portion if vesting is configured |
clawback | streamer | Reclaim unclaimed tokens after clawback_start_ts |
set_clawback_receiver | admin | Update the clawback recipient |
set_admin | admin | Hand 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/predictablemint= the SPL mint being distributedversion=u64index, 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.