English · Français · Documentation · Integration guide
Mobile photo capture and signed receipt verification
Use the headless TypeScript engine with your own interface and workflow. Add the supplied Web Component, the ASP.NET Core reference API or the React demo as needed. The receipt verifier works on its own, without calling a server.
CaptureProof is a working reference implementation. It binds exact accepted file bytes and declared business context. It does not attest physical camera origin, object authenticity, absence of AI or independently trusted time.
| Your goal | Start here | What you can replace |
|---|---|---|
| Build your own capture screen | @captureproof/capture-web/headless |
Interface, steps, navigation and transport |
| Embed a ready-made capture control | <capture-proof> |
Surrounding application and transport |
| Capture locally, without signed receipts | capture-only |
Your interface and handling of the resulting JPEGs |
| Issue signed receipts in your workflow | CaptureTransport + compatible backend |
Backend implementation and business authorization |
| Verify an existing receipt and files | @captureproof/receipt-verifier |
Your application and trusted public key source |
| Explore the complete QR journey | React demo + reference .NET API | Demo screens, identity integration and business rules |
The engine has no React dependency. The headless entry point does not load the supplied UI. Your backend can use another language if it implements the transport and receipt contracts; the server remains responsible for authorization, quotas and accepted bytes.
import { CaptureController } from '@captureproof/capture-web/headless';
const capture = new CaptureController({
mode: 'capture-only',
policy: {
minPhotos: 1,
maxPhotos: 3,
maxBytesPerPhoto: 5 * 1024 * 1024,
sessionTtlSeconds: 600,
},
});
capture.addEventListener('change', () => renderYourScreen(capture.snapshot));
startButton.onclick = () => void capture.startCamera(videoElement);
shutterButton.onclick = () => void capture.capture();
finishButton.onclick = () => void capture.finalize();
// On leaving your capture screen: capture.dispose();renderYourScreen, the buttons and the video element belong to your application. Capture runs in a supported mobile browser over trusted HTTPS and starts after an explicit user action. The integration guide covers completion events, custom transports, retries, lifecycle cleanup and signed receipts.
Prerequisites: Node.js 24, .NET SDK 10.0.402 and the ASP.NET Core 10.0.13 runtime. Exact dependency versions are locked.
npm ci
npm run buildOn Windows:
pwsh -File scripts/install-dotnet.ps1 # optional local SDK installation
pwsh -File scripts/start-demo.ps1On Linux:
ASPNETCORE_ENVIRONMENT=Development \
ASPNETCORE_URLS=http://localhost:5080 \
CaptureProof__DataDirectory="$PWD/.data/demo" \
dotnet run --no-launch-profile --project src/CaptureProof.ApiOpen the local demo. This loopback HTTP address is for desktop development. A real phone needs a shared, trusted HTTPS origin: follow the mobile HTTPS guide. The default QR origin, https://localhost:7443, cannot reach your computer from another device.
For frontend development, keep the API running and use npm run dev in a second terminal. The React demo uses port 5173 and proxies the API on port 5080.
The packages are not published to the npm registry. Build and create local archives:
npm ci
npm run build
node scripts/package-npm.mjsThen, in your own project, install the archive you need:
npm install /path/to/CaptureProof/artifacts/captureproof-capture-web-0.1.0.tgz
# Or install captureproof-receipt-verifier-0.1.0.tgz independently.See the capture package, verifier package and integration guide for complete contracts and examples.
- Build your integration: integration, architecture, HTTP protocol, receipt format.
- Operate the reference API: HTTPS, configuration and Docker, backup and restore.
- Assess the guarantees: threat model, validation record, security reporting, dependencies.
- Contribute or adapt: contribution guide, Apache-2.0 license, French documentation.
The validation record distinguishes automated checks, observed device tests and remaining gaps. Real user journeys have been exercised on iPhone/Safari and Xiaomi/Mi Browser, including Wi-Fi recovery and a short screen lock with a pending photo on the Xiaomi. Exact device and browser versions were not recorded; Chrome Android has not been tested on a physical device.
npm run typecheck
npm run lint
npm run build
dotnet restore CaptureProof.slnx --locked-mode
dotnet test CaptureProof.slnx --no-restore
npm test
npx playwright install chromium
npm run test:e2e
npm run audit:publicFor the two .NET-to-TypeScript fixture checks, follow the environment setup in the testing guide, or run pwsh -File scripts/interop.ps1. A skipped fixture test is not a passed interoperability check.
Apache-2.0. You can adapt the modules, build your own interface and integrate them into your products under that license. Keep the applicable license and dependency notices.
The reference demo uses anonymous, browser-scoped identities and temporary storage with a default retention of 24 hours. Production integration requires your own identity and business authorization. Pending JPEGs stay in page memory and can be lost when the page is closed, reloaded or evicted. See security and operational limits before exposing the reference API publicly.