Prove what you hold.Keep your address.
Sign in and ZProof reads your balance on Solana once. If it clears your threshold, we sign a card that says only “held ≥ 100 SOL at slot …” — no address, no exact amount. Anyone can check the signature in their browser, or offline against our published key.
A sample card. Tilt it — the foil is decoration; the signature is the security.
Make a proof card in one check
Pick what to prove and for how long. We read your balance once at the moment you press the button. Below the threshold? Nothing is signed and nothing is stored.
Preview — the real card appears here after the check.
Your cards
signed outCards are listed by a keyed hash of your wallet — the cards themselves don't contain it.
Verify a card
Paste a ZProof link or card id. The signature is checked in your browser against the issuer key; the server only tells you whether it was revoked.
Issuer key G7ZCWn7GNZ9WNZr44UgBrcjAQ75kr1ccXhbiTPTD3AaA · key id e27dadfb · issuer.json
A receipt for “enough”
Allowlists, OTC desks, communities and lenders often want to know you hold enough — not which wallet is yours or exactly how much is in it. ZProof answers only the question they asked.
- For holders who want to show “≥ 1,000 USDC” or “≥ 10 SOL” without handing over an address that reveals their whole history.
- For verifiers who need a yes/no they can check themselves: a signature, a threshold, a timestamp, an expiry.
- No exact balance. The card states a floor you choose. Your real balance is never printed or stored.
- Honest about trust. It's an attestation by this server, not a zero-knowledge proof — the page says exactly what we see.
Every mark on the card means something
The artwork is drawn live in your browser. The facts on it come from the signed bytes — the same bytes any verifier checks.
The claim
“≥ amount + asset” — the threshold you chose, in whole tokens. Never your real balance.
Where an address would be
The hatched bar is literal: there is no address field in the card format. Nothing to redact, nothing to leak.
Checked at slot · issued · valid until
The Solana slot our balance read came from (confirmed commitment), when it was signed, and when it stops being valid.
Card id · issuer key id
A random 128-bit id (for revocation lookups) and the first 4 bytes of SHA-256 of the issuer's public key.
Holographic seal + QR
The seal is decoration that shifts with your pointer. The QR carries the whole signed card, so a phone can verify it — the signature is the real security.
Live-presentable mark
Shown when the card carries a device key from the requesting browser, so the holder can prove possession on the spot.
One balance read, one signature
No background polling: the Solana RPC is called only when someone requests a card (one call) — verifying costs nothing.
Sign in
Your wallet signs a one-time text (free). We keep the session in memory for an hour — never on disk.
Your walletRead
Solana mainnetgetBalancefor SOL, orgetTokenAccountsByOwnerfor a token, at confirmed commitment. Liquid balance only.Sign
If balance ≥ threshold we build a ZPF1 card (no address) and sign it with our Ed25519 issuer key. We store a keyed hash of your address for revocation.
ZProof serverVerify
Anyone opens
Anyone/v/<id>: their browser checks the signature against the issuer key, then asks us only “revoked?”. Offline works too.
What a card proves
That a wallet which signed in to ZProof held at least the threshold at the stated slot, according to this server's read of Solana mainnet.
What it doesn't
That the funds are still there, that they weren't counted for another card after a transfer, or who the holder is. Staked SOL and DeFi positions don't count.
Revocation
You can revoke your cards; the operator can revoke cards with abusive labels. Online checks see it instantly. Offline checks can't — they rely on expiry.
Small enough to audit
Ed25519 cards
A compact binary format (ZPF1) signed with a domain-separated Ed25519 signature. ~200 bytes + 64-byte signature.
Two verifiers
WebCrypto Ed25519 where the browser supports it, otherwise a built-in RFC 8032 verifier in plain JavaScript (zcard.js).
Live guilloché
The hero is a WebGL fragment shader drawing counter-phased rosettes; the card art is a 2D canvas with a CSS foil and tilt.
Zero-dependency Node
No npm packages. Hand-written Solana encodings, wallet sign-in via node:crypto, strict CSP with nonces, no analytics. One vendored QR encoder (MIT).
Free to prove. More with a burn.
Making and verifying cards is free. Premium is unlocked by burning the coin.
Free
- SOL, USDC, USDT, JUP and BONK at preset thresholds
- Cards valid for 24 hours or 7 days
- Up to 10 active cards per wallet
- QR + link + PNG download, live presentation
- Revoke any of your cards
- Verification is always free, for anyone
Unlock with the coin
- Any SPL / Token-2022 token, by mint address
- Any threshold, to the token's full precision
- Longer validity: 30 or 90 days
- Branded cards: a printed label and six card themes
- Up to 200 active cards
The coin is burned, not paid
In ZProof the coin does one thing: burn-to-unlock. You destroy tokens from your own wallet in your own transaction; the server reads the burn back from the chain and starts your premium pass. Nobody receives the tokens.
The coin is coming soon. Every free feature works without it.
Burning destroys tokens permanently. It gives no return, revenue share or financial right. The free version stays free.
Premium pass
Burn 50,000 tokens of the coin for 30 days of premium. Passes stack.
Burn ledger
| Wallet | Amount | When | Tx |
|---|---|---|---|
| No burns yet. | |||
Each row links to its transaction on Solscan. “Burned on-chain in total” is the initial supply minus the current supply, so it also counts burns made outside this app.
You trust this server's check
ZProof is an attestation, not a zero-knowledge proof. Our server sees your address when it reads your balance and vouches for the result with its signature. If you don't trust the operator to check honestly, a ZProof card shouldn't convince you either.
What we can see
- Your wallet address while you're signed in (in memory, up to 1 hour) and during the balance read.
- Our RPC provider sees the balance query for your address — that's how Solana data is read.
- Per card: a keyed hash of your address (HMAC-SHA256 with a server secret) so you can list and revoke your cards. Whoever runs the server could test a known address against it.
- If you unlock premium, your wallet is stored with your pass — burns are public on Solana anyway.
- Who verifies which card id — only in in-memory rate limits; never logged.
What we never do
- Put your address or exact balance in a card, or store your balance anywhere.
- Write sessions to disk, log IPs, run analytics or load third-party scripts.
- Ask for a seed phrase or private key. Signing in is a free message signature.
- Move funds. The only transaction we ever build is an optional burn, shown in full before you sign.
- Keep cards forever: records are deleted 30 days after a card expires.
Linkability, honestly
A card can't name you, but context can narrow things down: “≥ 5,000,000 of a token only three wallets hold” is close to an address. Pick a threshold many wallets meet, and avoid issuing many cards with different thresholds at the same time.
Labels & reports
Premium labels are printed on public verify pages, so every card page has a Report button. The operator can revoke cards with abusive or impersonating labels. No illegal content, impersonation or scams.
Questions, plainly answered
Is this a zero-knowledge proof?
No. It's a signed statement from this server: “we read this wallet's balance at slot N and it was at least X.” Verifiers trust our check and our key. What it gives you is minimal disclosure: the card contains no address and no exact amount.
Can a verifier find my wallet from the card?
Not from the card's contents — there's no address in it. But a very high threshold on a rarely-held token, or many cards at different thresholds, can narrow the set of possible wallets. Choose round thresholds that many holders meet.
What if I move my funds after getting a card?
The card is true for the slot it names, not forever. Verifiers decide how fresh is fresh enough; short validity (24 h) is the honest choice for anything time-sensitive.
Could someone else show my card?
A card is a bearer document: whoever has the link can show it. If you bind it to your browser, you can “present live” — a QR re-signed every 20 seconds by your device — which a screenshot can't fake for more than two minutes.
Which balance counts?
For SOL: the liquid SOL in the wallet (staked SOL and DeFi deposits don't count). For tokens: the sum of the wallet's token accounts for that mint, excluding frozen accounts. One wallet per card.
Can I verify without trusting your website?
Yes. Download the issuer key once; the card link's #c= part is the full signed card. The verifier code is a single readable file (zcard.js) and works offline. Only revocation needs us.
What happens when I burn the coin?
Your wallet signs a transaction that destroys 50,000 tokens (an SPL burn) plus a memo. We read it back from the chain and start or extend your premium pass by 30 days. It gives no return or financial right.