Something went wrong. Try again.
Cairns help you find your way in a trail.
Something went wrong. Try again.
Go 96%
Dockerfile 2%
HTML 2%
README.md
Park Passport #
Mobile-first PWA for GPS-verified National Park stamps. Identity and data live on AT Protocol.
Stack #
| Layer | Technology |
|---|---|
| Frontend | React Native / mobile-first PWA |
| Backend | Go |
| Identity | AT Protocol / Bluesky OAuth |
| User data | User's own AT Protocol PDS |
| Park data | NPS Public API + bundled GeoJSON |
| Credentials | W3C Verifiable Credentials 2.0 |
Architecture #
The backend issues signed W3C VCs but stores nothing. All stamp records and VC blobs live on the user's PDS.
Client Verification Service User PDS
│ │ │
├─ { did, parkId, coords } ────►│ │
│ ├─ check GeoJSON boundary │
│ ├─ sign VC (EdDSA) │
│ ├─ write VC blob ─────────►│
│◄─ vcRef (CID) ────────────────│ │
│ │
├─ write app.parkpassport.stamp record ───────────────────►│
Stamp Record (app.parkpassport.stamp) #
parkId string
visitedAt datetime
verificationMethod "gps" | "exif" | "passport-import"
vcRef blob ref (CID of VC blob in PDS blob store)
photoRef blob ref (optional)
Verifiable Credential Structure #
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiableCredential", "NationalParkStamp"],
"issuer": "did:web:verify.parkpassport.app",
"validFrom": "2026-03-22T14:30:00Z",
"credentialSubject": {
"id": "did:plc:abc123",
"parkId": "acadia",
"parkName": "Acadia National Park",
"visitedAt": "2026-03-22T14:30:00Z",
"verificationMethod": "gps"
},
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"verificationMethod": "did:web:verify.parkpassport.app#key-1",
"proofValue": "..."
}
}
Stamps are independently verifiable: fetch the VC blob from the user's PDS, fetch the issuer public key from https://verify.parkpassport.app/.well-known/did.json, verify the EdDSA signature.
Stamp Issuance Flow (GPS) #
- Client requests device GPS coordinates
- Client sends
{ did, parkId, coords, authToken }to verification service - Service checks coords against bundled park GeoJSON boundary
- Service signs a W3C VC 2.0 and writes it as a blob to the user's PDS
- Service returns
vcRef(blob CID) - Client writes
app.parkpassport.stamprecord to PDS repo withvcRef
Key Endpoints #
| Endpoint | Purpose |
|---|---|
POST /stamp |
Issue a signed VC for a GPS-verified park visit |
GET /.well-known/did.json |
Issuer DID document with public key |
Data Sources #
- NPS Public API — park metadata (requires free API key from nps.gov/subjects/developer)
- NPS GeoJSON — park boundary polygons from
services1.arcgis.com/fBc8EJBxQRMcHlei/arcgis/rest/services/; bundled at build time for the MVP park
Infrastructure #
- Verification service: Cloudflare Workers
- Issuer DID:
did:web:verify.parkpassport.app - User data: user's existing Bluesky PDS