Archived, October 2026. This is the February 2026 hackathon prototype, kept for reference only. Don't deploy it or use it for real evidence: an October 2026 security audit found it publishes where and when recordings were made and can silently lose footage. Witness is being rebuilt from scratch as a native Android app in a new repository.
Privacy-Preserving Evidence Capture with Web of Trust
An open-source personal safety toolkit that enables secure video evidence capture, encrypted storage, and anonymous verification through trusted contacts.
Hackathon Project: This is in active development with rapid iteration. No backward compatibility guarantees.
Evidence is only as credible as the witnesses who can vouch for it. Witness Protocol lets you:
- Record video that encrypts and uploads to IPFS in real-time (10-second chunks)
- Share evidence with trusted contacts via wallet-based cryptographic identity
- Enable trusted contacts to verify and attest to evidence anonymously (ZK proofs)
- Prove content integrity with on-chain merkle roots
- Maintain privacy: content stays encrypted, attestor identities stay hidden
Phases 0-7 Complete (v1.0.0):
- ✅ Privy authentication with embedded wallet
- ✅ Kernel ERC-4337 smart account (gasless transactions via Pimlico)
- ✅ AES-256-GCM encryption with wallet-derived keys
- ✅ Group creation and QR code-based trusted contact sync
- ✅ IPFS content upload via Pinata
- ✅ On-chain content registration with merkle roots
- ✅ Content discovery and decryption for group members
- ✅ Anonymous attestations using Semaphore V4 ZK proofs
Possible Next Directions:
- Matrix server as data streaming, caching, processing, and notification layer
- zkDID and credential linking (without account linking) for attestations
- Native iOS and Android App
- Numbers Protocol Deployment for enhanced data provenance
Live Demo: https://witness.squirrlylabs.xyz
/
├── witness-pwa/ # Main PWA application
│ ├── src/
│ │ ├── services/ # Core services (auth, encryption, storage, etc.)
│ │ ├── modals/ # UI modals (login, groups, content detail)
│ │ └── app.js # Main application controller
│ ├── public/ # Static assets + manifest
│ └── package.json
│
├── contracts/ # Smart contracts (Foundry)
│ ├── src/
│ │ └── WitnessRegistry.sol
│ ├── script/
│ │ └── DeployWitnessRegistry.s.sol
│ └── broadcast/ # Deployment artifacts
│
├── docs/
│ ├── architecture/ # System architecture & design
│ ├── front-end/ # UI/UX documentation
│ ├── planning/ # Vision and architecture specs
│ ├── research/ # Technology research notes
│ └── testing/ # Test plans and results
│
├── deploy.sh # Automated deployment script
├── .env # Environment configuration
├── CLAUDE.md # Project context for Claude Code
└── README.md
| Component | Technology | Purpose |
|---|---|---|
| Frontend | Vite + Vanilla JS | PWA with service worker |
| Authentication | Privy (@privy-io/js-sdk-core) |
Email/social login + embedded wallet |
| Smart Account | Kernel + Permissionless | ERC-4337 account abstraction |
| Gas Sponsorship | Pimlico | Paymaster for gasless transactions |
| Blockchain | Base Sepolia | L2 testnet (~2s block times) |
| Storage | IPFS via Pinata | Decentralized content storage |
| Encryption | Web Crypto API | AES-256-GCM with HKDF key derivation |
| ZK Proofs | Semaphore V4 | Anonymous group membership attestations |
| Ethereum Client | viem | Lightweight Ethereum interaction |
| Local DB | Dexie (IndexedDB) | Client-side persistence |
| QR Codes | qrcode + html5-qrcode | Group invite generation/scanning |
- Node.js 18+ and npm
- Accounts/API keys:
-
Clone and install:
git clone https://github.com/yourusername/witness.git cd witness/witness-pwa npm install -
Configure environment:
cp .env.example .env # Edit .env with your API keys -
Contract setup (required for on-chain features):
The app requires a deployed WitnessRegistry contract. You can either:
- Use the existing contract: The default config points to our deployed contract on Base Sepolia (
0x99b952eba38d1a0d681d258a61be2ee17b49c992) - Deploy your own: See Smart Contract section below
Important: Set
VITE_CONTRACT_DEPLOYED_BLOCKin your.envto the block number when the contract was deployed. This limits how much blockchain history the RPC must scan for events—without it, queries start from block 0 and will be slow or fail.Without a valid contract, user registration, group creation, content commits, and attestations will fail.
- Use the existing contract: The default config points to our deployed contract on Base Sepolia (
-
Run dev server:
npm run dev # Open http://localhost:5173Camera APIs require localhost or HTTPS to function.
cd witness-pwa
npm run build
# Output: dist/Server: Hetzner VPS (46.62.231.168) Domain: https://witness.squirrlylabs.xyz Web Server: nginx with Let's Encrypt SSL
Deploy latest build:
rsync -avz witness-pwa/dist/ root@46.62.231.168:/var/www/witness/Service worker updates propagate automatically. For PWA home screen apps, users may need to delete and re-add the app to see major updates.
WitnessRegistry.sol on Base Sepolia:
- User registration with on-chain identity
- Group management (parallel Semaphore groups for ZK attestations)
- Content commitment (merkle roots + manifest CIDs)
- Anonymous attestation verification
Deployed Address: 0x99b952eba38d1a0d681d258a61be2ee17b49c992
From project root:
cd contracts && export $(grep -v '^#' ../.env | grep -v '^$' | xargs) && \
forge script script/DeployWitnessRegistry.s.sol:DeployWitnessRegistry \
--rpc-url base-sepolia --broadcast --verify -vvvvSee CLAUDE.md for detailed deployment instructions.
- Architecture Overview - System design and component interaction
- Architecture v3 (Vision) - Full hackathon architecture
- Anonymous Attestations - ZK proof system using Semaphore
- Encryption & Key Derivation - Cryptographic design
- Content Storage - IPFS + on-chain architecture
- Technical Decisions & Limitations - Current constraints
- Create Account: Email/social login via Privy → embedded wallet → Kernel smart account
- Create or Join Group: Generate QR invite or scan one to join a trusted contact group
- Record Evidence: Video chunks encrypt and upload to IPFS in real-time, merkle root commits on-chain
- Share & Verify: Group members decrypt content, verify integrity, and attest anonymously using ZK proofs
- Privacy Preserved: Content stays encrypted, attestor identities hidden, only attestation count is public
The system uses two-layer privacy:
| Layer | Purpose | What's Public | What's Private |
|---|---|---|---|
| Access Control | Who can decrypt | Group membership (addresses) | Content (encrypted) |
| Attestations | Verification proofs | Attestation count | Who attested (ZK proofs) |
This allows public proof that "N people verified this content" while maintaining complete anonymity for attestors.
- WebM format: Not supported for saving to Photos (only Files app)
- MediaRecorder: Only
video/mp4format supported - Service Worker: PWA updates require home screen app deletion/re-add
This is a hackathon project with rapid iteration. See Technical Decisions & Limitations for current constraints.
This project is in active hackathon development. If you're interested in contributing:
- See CLAUDE.md for development guidelines and project context
- Review Architecture docs to understand the system
- Check the Issues for open tasks
Contact me at: beau@squirrlylabs.xyz
MIT