How Passport works
One account is one contract on the Midnight ledger. No seed phrase exists anywhere: each device holds a secret derived from its passkey, the chain holds only hashes and proofs, and losing every device does not lose the account. This page shows the whole system on one screen, walks the account lifecycle in six steps, and ends with what the October demo puts on a screen.
The whole system on one screen
The left side is yours: devices, people you trust, and paper. The right side is the public ledger: readable by anyone, forever. Everything Passport does is the discipline of that dashed line. The snapshot below is a healthy account mid-life; every annotation says why that field is safe to publish.
Six steps, one account
The life of an account, in order. Each card ends with exactly what crossed the line to the chain, because that boundary is the whole design.
Create
Your first device establishes a signing key and deploys the account with a bootstrap commitment and public encryption key. The reference supports JubJub and k256; open PR #175 adds authenticator-held P-256 signing under a bounded WebAuthn profile. Guardian recovery is configured through a separate session ceremony.
Add a device
A second device makes its own passkey and secret. Any already-enrolled device authorises the addition with a proof, and the newcomer’s commitment is enrolled at the current epoch. There is no primary device: all devices are equals.
Receive
Anyone may fund the account, no authority required. Night lands in the public balance. A shielded token lands as a sealed commitment: an observer learns that something arrived, but not the amount and not the token type. The belief that contract-held shielded coins must be public was proven wrong on a real node; the private pattern is the standard.
Spend
The device signs a challenge binding the account, operation, inputs and authorisation counter. The circuit verifies that signature against an enrolled device entry before moving funds and advancing the counter. A delegated prover receives the one-call signature and required witnesses, never the device signing key.
Delegate
The account enrols a dApp’s independent signing key with bounded operations, asset, amount and expiry. Scope fields use salted commitments; the circuit checks their openings on use. Revocation ends that grant’s spending authority. Viewing access is separate: a reader cannot be made to forget a secret already shared with it.
Recover
Guardians retain their own keys but no per-account shares. A quorum reconstructs the session secret off-chain. In the merged reference tranche, recovery and successor signatures authorise a two-phase flow with a veto window. Finalisation installs a fresh device and advances the epoch, retiring old devices and grants at the same account address. A separate wrapped viewing key restores visibility; wallet transport and multi-session cryptographic review remain.
Why we can claim this works
The reference implementation carries executable custody, authorisation, grant and recovery evidence. The dated status report identifies merged work, open feature PRs and remaining integration/review obligations.
Contract-held shielded coins do not have to expose amount or token type; the widely copied vault recipe did so as a bookkeeping choice (and silently lost change, a defect found and fixed along the way). The validated private pattern is normative in MIP-0012.
Every authorised circuit performs the same check through a single helper circuit, instantiated with in-circuit JubJub Schnorr per MIP-0013. One epoch bump retires every device and grant at once, which is exactly what recovery relies on.
BUSS guardians derive shares on demand from long-lived keys. The reference adds session artifacts, a wrapped viewing secret and a two-phase signature gate. The contract tranche is merged; the upstream proposal and multi-session review remain open.
Demo release status · 1 October
Latest release: v5.2, published 29 September. The app has its own release history and pinned contract builds. The reference lifecycle above and open PRs #175–#177 are not a claim that every feature is deployed in the demo.
- Released changesv5.2 adds installation guidance across browsers. Its history includes fresh-device recovery, viewing-key persistence with sign-in metadata, chain-derived activity and per-payment passkey approval (demo #111–#114).
- Live sitesStaging and production both expose service-worker build
362ee84c685ebb8b, matching the v5.2 prefix. Release notes say production stays on v5.0; reconcile that discrepancy. - Deployment recordThe v5.2 release workflow failed at Vercel project resolution, before build/test/deploy. Demo #125 tracks reconciliation. This audit checked HTTP responses, not a new account journey.
- Open delivery workPush notifications (#123, off until configured and real delivery untested), provider recovery UX (#121), app builder (#120) and bridge integration. PWA/E2E checks are skipped on #120/#121/#123; bridge #26–#28/#31 have failing typecheck/unit checks.
- SDK integrationSDK #24 proposes realignment and deliverables; review is pending. New reference signing, caller pins and viewing envelopes require explicit integration and release validation.
Original six-phase planning baseline
Historical May–October milestones, retained for context. Their dates and earlier completion labels are not a current release checklist; use the release observations above for development status.
Original demo planning picks
Historical baseline, not the deployed configuration. These choices document the earlier managed-signing plan and its proposed migration. Current source, release and integration evidence is linked above. Click any ID to open its design space.
| ID | Component | Alt | Note |
|---|