Zero-knowledge
The proof reveals nothing about the stream amount beyond the fact that it meets or exceeds the threshold. The exact number stays private.
Drip Private lets a stream receiver prove they earn at least X XLM per month — without revealing the exact stream amount. The proof is generated locally in the browser and verified on-chain by a Soroban smart contract using Stellar's native BN254 host functions.
A Drip Private income proof answers one question: does this stream pay at least [threshold] XLM per month? The answer is yes or no — verified on-chain. The exact amount is never revealed.
This is useful for employment verification, loan applications, proof of income for services, or any situation where someone needs to prove a minimum earning without exposing private financial data.
When creating a stream, the payer turns on Private Mode. After the stream is created, the Drip Private modal generates a random salt and computes a Pedersen commitment: pedersen_hash(amount, salt).
The payer signs a register_commitment transaction through Freighter. The commitment (a 32-byte hash) is stored in the drip_zk_verifier Soroban contract. The stream amount is never stored in the verifier — only the hash.
The stream receiver opens the proof drawer (amount and salt auto-fill from localStorage or an optional link), enters the threshold to prove, and clicks Generate Proof. Noir.js and Barretenberg (bb.js) run in the browser — no data leaves the device. The proof takes ~5–10 seconds and is 14592 bytes. The proof button is receiver-only.
Under Share with a verifier, the receiver copies a compact share code (or downloads a .json) bundling the proof, stream ID, and threshold. The amount and salt are never included, so the code is safe to send to anyone — alongside the /verify link.
A third party — no wallet, no Drip account — opens /verify, pastes the share code, and clicks Verify on Stellar. The page runs a read-only verify_income_proof simulation (funding a throwaway Friendbot account for the source). Stellar's BN254 host functions check the UltraHonk proof on-chain and return Income Verified or Not Verified — without revealing the amount.
The proof reveals nothing about the stream amount beyond the fact that it meets or exceeds the threshold. The exact number stays private.
Verification happens inside a Soroban contract using Stellar Protocol 23 BN254 host functions. No off-chain oracle or trusted party is involved.
The Noir circuit runs entirely in the browser via Barretenberg (bb.js). The private inputs (amount, salt) never leave the receiver's device.
The receiver chooses what threshold to prove, to whom, and when. The same stream can generate different proofs for different verifiers.
Deployed at CCUOR6VPMCFDOU7MODZGOI2K264YR3LNRSQ4LMJ37LGTZCTOAHSXWNV5 on Stellar Testnet.
register_commitmentpayerStores the Pedersen commitment for a stream. Verifies caller is the stream payer via cross-contract read.
verify_income_proofread-onlyVerifies a 14592-byte UltraHonk proof against the registered commitment and threshold. Returns true or false.
has_commitmentread-onlyReturns whether a commitment exists for a stream. Drives the Private badge in the dashboard.
get_commitmentread-onlyReturns the 32-byte registered commitment for a given stream ID.
The drip_stream contract stores the stream amount in cleartext — Drip Private adds the ZK layer on top of it. The proof hides the amount from third-party verifiers, but the payer and receiver can still see it on-chain. Full end-to-end confidentiality would require a streaming contract that never stores the cleartext amount.