Camera companion PWA for attestto-desktop — your phone becomes the document and selfie capture device. Images travel over local WiFi via WebSocket. No server, no cloud, no PII transmitted outside your local network.
Attestto Mobile is a Progressive Web App deployed at mobile.attestto.com. It solves a specific problem: desktop webcams are terrible for identity document capture. A phone camera is much better. This app turns your phone into a dedicated camera for the Attestto desktop app, all over your local network.
graph LR
Desktop["attestto-desktop<br/>Electron app<br/>Local WebSocket server<br/>Shows QR code"]
Mobile["attestto-mobile<br/>Vue 3 PWA<br/>Camera capture<br/>WebSocket client"]
Network["Local Network<br/>WiFi<br/>WebSocket over TCP"]
Desktop -->|QR code<br/>ws://192.168.1.X:PORT/ws/SESSION| Mobile
Mobile -->|image: base64 JPEG<br/>ack, complete, error| Desktop
Mobile -.->|uses| Network
Flow:
- Desktop generates QR code with WebSocket URL
- Phone scans QR → opens this PWA with the URL
- PWA connects to desktop via WebSocket
- User captures document front, back, selfie
- Each image sent as base64 JPEG to desktop
- Desktop acknowledges each step; PWA advances
- Done → prompt to install PWA to home screen
- Node.js 18+
- pnpm
- HTTPS (required for
getUserMedia— GitHub Pages provides this, or uselocalhost:5173in dev)
pnpm install
pnpm dev # Starts on https://localhost:5173- Open https://localhost:5173 (note: HTTPS required for camera access)
- Click to open the QR reader
- Scan a QR code (or paste a WebSocket URL to test)
- Capture: phone → document front → document back → selfie
Build and deploy:
pnpm build # Creates dist/ for GitHub PagesDeployed automatically on push to main via .github/workflows/deploy.yml.
Step 1 — Document front Card frame overlay. User aligns document within the frame. Tap to capture, or use auto-capture if supported.
Step 2 — Document back Same card frame overlay.
Step 3 — Selfie + passive liveness Face oval overlay. Blink detection (passive liveness check — no active user prompts).
If camera access is blocked, file input fallback is available at each step.
After all 3 steps: success screen with prompt to install PWA to home screen.
All messages are JSON over WebSocket. The QR code URL format:
https://mobile.attestto.com/capture?ws=ws://192.168.1.X:PORT/ws/SESSION_ID
The PWA extracts ws= from the query string and connects immediately.
Message types:
// Phone → Desktop
{
type: 'image',
step: 'front' | 'back' | 'selfie',
data: '<base64 JPEG string>', // URL-safe base64
}
// Desktop → Phone
{
type: 'ack',
step: 'front' | 'back' | 'selfie',
}
// Desktop → Phone (all steps complete)
{
type: 'complete',
}
// Desktop → Phone (error, stop capture)
{
type: 'error',
message: 'description of error',
}- Vue 3 + TypeScript — Reactive, type-safe UI
- Vite + vite-plugin-pwa — Fast dev, installable PWA
- Tailwind CSS — Utility styling
- WebSocket — Real-time connection to desktop (
ws://) - WebAPI
getUserMedia— Camera access - GitHub Pages — HTTPS deployment (required for
getUserMedia)
- Images are captured locally on your phone
- Images travel directly to your own desktop over your local WiFi
- No intermediate server, no cloud storage, no PII leaves your home network
- All processing (OCR, liveness detection, credential storage) happens on your desktop
| Repo | Role | Relationship |
|---|---|---|
attestto-desktop |
Electron station | Receives images from this PWA, runs OCR and liveness checks |
attestto-app |
Citizen wallet | Where users manage credentials captured via this PWA |
This repo ships a llms.txt context file — a machine-readable summary of the API, data structures, and integration patterns designed to be read by AI coding assistants.
Use the attestto-dev-mcp server to give your LLM active access to the ecosystem:
cd ../attestto-dev-mcp
npm install && npm run buildThen add it to your Claude / Cursor / Windsurf config and ask:
"Explore the Attestto ecosystem and help me extend [this component]"
We recommend Claude Pro (5× usage vs free) or higher. Long context and Vue 3 / WebSocket expertise handle this codebase well. The MCP server works with any LLM that supports tool use.
Quick start: Ask your LLM to read
llms.txtin this repo, then describe what you want to build. It will find the right archetype, generate boilerplate, and walk you through the first run.
pnpm install # Install dependencies
pnpm dev # Start dev server with HTTPS
pnpm build # Build for deployment
pnpm lint # ESLint + Prettier
pnpm test # vitestContributions welcome. All code Apache 2.0.
Apache 2.0 — Use it, fork it, deploy it.
Built by Attestto as Public Digital Infrastructure for Costa Rica and beyond.