Digital Dreamer

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.

  1. User connects a devnet Solana wallet (Phantom) in the browser.
  2. Veiled SDK generates and verifies a Noir ZK proof locally for the chosen requirements.
  3. The user signs the verification result; only this signature and a nullifier are sent to the on-chain Anchor program.
  4. The program verifies the Ed25519 signature, stores the nullifier, and confirms authentication.
  5. 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.