DRIPDRIP
Drip Private (ZK)
Zero-Knowledge

Drip 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.

What it proves

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.

How it works

01

Payer toggles Private Mode

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).

02

Commitment is registered on-chain

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.

03

Receiver generates a proof locally

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.

04

Receiver shares a proof code

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.

05

Anyone verifies on the /verify page

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.

Key properties

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.

On-chain verification

Verification happens inside a Soroban contract using Stellar Protocol 23 BN254 host functions. No off-chain oracle or trusted party is involved.

Local proof generation

The Noir circuit runs entirely in the browser via Barretenberg (bb.js). The private inputs (amount, salt) never leave the receiver's device.

Selective disclosure

The receiver chooses what threshold to prove, to whom, and when. The same stream can generate different proofs for different verifiers.

Verifier contract API

Deployed at CCUOR6VPMCFDOU7MODZGOI2K264YR3LNRSQ4LMJ37LGTZCTOAHSXWNV5 on Stellar Testnet.

register_commitmentpayer

Stores the Pedersen commitment for a stream. Verifies caller is the stream payer via cross-contract read.

verify_income_proofread-only

Verifies a 14592-byte UltraHonk proof against the registered commitment and threshold. Returns true or false.

has_commitmentread-only

Returns whether a commitment exists for a stream. Drives the Private badge in the dashboard.

get_commitmentread-only

Returns the 32-byte registered commitment for a given stream ID.

Honest limitations

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.