DEV Community

BunHead
BunHead

Posted on

I built a browser-based proof-of-presence tool

Six months of tinkering produced IRLid — two people meet, scan each other's QR codes, get a cryptographically signed receipt proving co-location within 12 metres. No app, no accounts, no biometrics, no central server. Just ECDSA P-256 and a bit of GPS, running entirely in the browser via Web Crypto API.

The 4am Bug

Shipped v3 last week. Thought it was done. Four hours later — every receipt showing 23% verified instead of 100%.

Root cause: GPS coordinates were being stripped server-side before returning to the client. But the ECDSA signature was computed with those coordinates. Strip them → client can't recompute the original hash → signature check fails. Every. Single. Receipt.

Obvious in hindsight. Not obvious at 4am.

The Deeper Lesson: Canonical Serialisation

Moved from JSON.stringify() to canonical() for payload hashing before ECDSA signing. JSON property order isn't guaranteed across environments — same object, different hash, broken signature.

New: Embeddable Widget

Any site can embed IRLid as a human-verification step — one iframe, postMessage API, no SDK. Think reCAPTCHA but you prove you've met a real human. Demo: https://irlid.co.uk/demo-login.html

Honest Limitations

GPS is self-reported. Cooperative trust model only — not proof-of-presence to a sceptical third party. Documented honestly in PROTOCOL.md on GitHub.

https://irlid.co.uk

Top comments (0)