Project
Veiled
OAuth-level privacy for Web3 — authenticate on Solana without exposing your wallet address, balance, or transaction history.
Role
Sole developer – ZK circuits, Solana program, SDK, and demo app.
Tech stack
TypeScript, Noir, Anchor, Rust, Solana, SvelteKit, Bun, Hono, TailwindCSS, Helius, Quicknode
Project type
Fullstack Solana ZK system – circuits, on-chain program, SDK, and demo application.
Highlights
100x cheaper than on-chain ZK verification, 30x faster auth, zero backend required.
Overview
Today, “Sign in with Solana” leaks your entire financial identity: wallet address, full balance, NFTs, and transaction history. Veiled fixes this by bringing OAuth-style privacy to Solana – dApps can verify that you own a wallet and meet certain eligibility criteria, but never see your actual address or portfolio.
The problem
Every Solana dApp currently learns far more than it needs – from balances and DeFi positions to complete NFT collections. This breaks basic privacy expectations and enables wallet profiling, targeted phishing, and cross-site tracking.
The solution
Veiled uses Noir-based zero-knowledge proofs and an Anchor program to let users prove facts like “I own a wallet”, “my SOL balance is above X”, or “I own an NFT from this collection” – without revealing which wallet, how much SOL, or which NFT.
Key achievements
- 100x cost reduction vs naive on-chain ZK verification (<$0.01 per auth).
- Sub-second on-chain confirmation by verifying only an Ed25519 signature, not the ZK proof itself.
- Pure client-side proof generation (no backend service required for developers to integrate Veiled).
How Veiled works
Veiled splits verification into two parts: heavy ZK proof work happens entirely in the browser using Noir and UltraHonk WASM, while the on-chain program on Solana verifies a lightweight Ed25519 signature over the proof result and registers a nullifier to prevent replay.
- User connects a devnet Solana wallet (Phantom) in the browser.
- Veiled SDK generates and verifies a Noir ZK proof locally for the chosen requirements.
- The user signs the verification result; only this signature and a nullifier are sent to the on-chain Anchor program.
- The program verifies the Ed25519 signature, stores the nullifier, and confirms authentication.
- The dApp receives an anonymous, domain-scoped ID instead of the raw wallet address.
Selected use cases
I designed Veiled around concrete Solana use cases where privacy is missing but eligibility still matters.
- NFT-gated communities – prove you own an NFT from a collection without revealing which token or what else is in your wallet.
- DeFi access control – gate features by balance range instead of exposing exact net worth.
- Anonymous DAO voting – cast verifiable votes using a nullifier-based identity that cannot be traced back to a wallet.
- Cross-game identity – share a persistent player identity across games without sharing the underlying wallet.
Architecture & stack
Veiled combines Noir circuits, an Anchor program, and a TypeScript SDK into a cohesive system that is easy for Solana dApps to integrate.
Components
- Noir circuits for wallet ownership, balance range, and NFT ownership proofs.
- Anchor 0.32.1 Solana program with nullifier registry and Ed25519 verification.
- TypeScript SDK (`@veiled/core`) for browser integrations.
- SvelteKit + TailwindCSS demo app to showcase the flows.
Infra & tooling
- Bun + Hono for backend utilities and local tooling.
- Helius Secure URLs for balance queries without exposing API keys.
- Quicknode for NFT metadata queries where needed.
- Vercel deployment for the demo app.
Challenges & what I learned
- Noir / backend version alignment. Early prototypes hit “unreachable” WASM panics due to subtle mismatches between nargo, noir_js, and UltraHonk versions; I fixed this with strict version pinning, runtime validation, and better error surfacing in the SDK.
- Designing for Solana’s BPF limits. I had to replace dynamic allocations with fixed-size arrays and carefully control stack usage in the Anchor program to stay within compute and memory bounds while still enforcing domain-scoped nullifiers.
- Balancing theory with DX. A lot of ZK literature focuses on protocols, not integration. I spent significant effort designing an API that feels like OAuth – a few lines of TypeScript – while hiding the complexity of circuits, backends, and RPC configuration.
If I iterate further, I plan to add SPL token balance proofs, harden wallet adapter support beyond Phantom, and publish a stable v1.0 of the SDK with stricter API contracts and framework-specific components (React, Svelte, Vue).
Demo & gallery
The live demo walks through traditional “Connect Wallet” flows side-by-side with Veiled, highlighting how much data is over-shared today and what is preserved when you switch to ZK-based authentication.