Proof of Concept for Handle Pay's passkey-based onboarding system.
- Usecase selection
- Username validation & reservation
- TTL-based reservation system (30 minutes)
- WebAuthn passkey registration
- Biometric login (Face ID, Touch ID, Windows Hello)
- JWT-based session management
- Frontend: Next.js 14, React, TailwindCSS
- Authentication: @simplewebauthn/browser
- Backend API: NestJS (separate repository)
- Install dependencies:
npm install- Configure environment:
Create
.env.local(see.env.example):
NEXT_PUBLIC_API_URL=http://localhost:3001/api/v1
NEXT_PUBLIC_REQUEST_SIGNATURE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"- Configure request signing keys (required — backend enforces
x-signatureon most routes):
Generate a P-256 key pair:
openssl ecparam -name prime256v1 -genkey -noout -out request-signature-private.pem
openssl ec -in request-signature-private.pem -pubout -out request-signature-public.pemSet in handle-pay-backend/.env:
REQUEST_SIGNATURE_PUBLIC_KEY="<contents of request-signature-public.pem>"Set in passkey-nextjs-poc/.env.local:
NEXT_PUBLIC_REQUEST_SIGNATURE_PRIVATE_KEY="<contents of request-signature-private.pem>"Use \n escapes for newlines in .env files (same convention as the mobile app).
- Run development server:
npm run dev- Open browser:
http://localhost:3002
- Navigate to
/phase1/onboarding - Select a usecase
- Check username availability
- Reserve username and save the token
- Navigate to
/phase2/passkey-test - Enter reservation token from Phase 1
- Create passkey with biometric authentication
- Test login with existing passkey
Note: Passkeys work best with HTTPS. For local testing, use browser's built-in authenticator (not password managers like Proton Pass).
vercel --prodSet environment variables:
NEXT_PUBLIC_API_URL: Your backend API URLNEXT_PUBLIC_REQUEST_SIGNATURE_PRIVATE_KEY: PEM private key matching backendREQUEST_SIGNATURE_PUBLIC_KEY
This PoC requires the Handle Pay backend running. See main repository for backend setup.
Private - Handle Pay Project