checkpoint: sync to 22d7c01 — QR pairing, identity adoption, always-allow grants, hygiene (2026-09-12)

This commit is contained in:
Avi 2026-09-12 17:56:08 -05:00
commit 937fcc67cb

View file

@ -1,3 +1,88 @@
# Checkpoint — QR pairing, identity adoption, always-allow grants + hygiene (2026-09-12)
## Where things are
- Project: `/home/avi/Projects/Keynctr`
- Branch: `master` @ **`22d7c01`** ("chore(hygiene): ignore editor artifacts;
prettier SignerScreen"). Previous feature HEAD: `81b082f`.
- Working tree: clean for tracked files. Untracked intentionally NOT
committed: `COSMIC_THEME.md`, `KeynectrAppIconPossibility02.jpeg`,
`deferred/` (stays deferred). `.directory`, `.opencode/`, `.impeccable/`
are now gitignored. Dead stub `src/signer/nip46_external.rs` **deleted**
(was untracked, never declared in `signer/mod.rs`, superseded by
`nip46_client.rs`).
- Verification (all green at `22d7c01`): `cargo test` **201 unit + 2 e2e
passed / 0 failed**, `cargo clippy --all-targets` 0 warnings,
`cargo fmt --check` clean, `cargo build --release` green. Frontend:
`npm test` **116 passed (16 files)**, `npm run typecheck` clean,
`npm run lint` clean, `npm run format:check` clean,
`npm run electron:build` and `npm run build` green.
## What was completed since the last checkpoint (7 feature commits + hygiene)
- **QR pairing (`38499d4`)**: Keynctr is the NIP-46 *client*, Amber scans.
Signer screen mints a `nostrconnect://` pairing token (ephemeral key +
secret), renders it as a QR ("Show QR"), copy-link fallback, cancel.
Backend listens for the signer's connect request, echoes the secret
(anti-spoofing), persists the connection, adopts identity via
`get_public_key`. e2e covers scan -> secret echo -> identity -> sign ->
vault persistence with a fake QR scanner.
- **Electron allowlist (`c5004eb`)**: `nip46_pair_start` added to the
main-process renderer allowlist (was rejected with "not permitted").
- **Lazy signer handle (`dc58f38`)**: all `nip46_*` IPC handlers ensure the
client signer handle exists (fresh backend no longer answers "not
initialized" until the mode is re-saved).
- **Pairing diagnostics (`9cfab4b`)**: pairing start + session failures
logged to stderr (captured by Electron).
- **Real identity adoption (`3d5302f`)**: paired profiles get the signer's
kind-0 display name/picture/nip05 (best-effort, 3s-capped) instead of a
generic pairing label.
- **Instant Connected (`286bbca`)**: session flips to Connected as soon as
identity is verified/persisted; metadata lands in a background task that
never overrides a user-chosen label (fixes "Amber said yes but nothing
changed").
- **Always-allow grants (`81b082f`)**: standing per-(peer pubkey, method)
permission for external signer requests. Approvals gained an "Always
allow" option; grants listed with Revoke on the Signer screen; persist in
the encrypted vault (`src/vault.rs` grant storage).
- **Hygiene (`22d7c01`)**: gitignore editor artifacts, prettier-fix
`SignerScreen.tsx` (format:check had been failing since `81b082f`),
delete dead `nip46_external.rs` stub.
## Commits added (newest first)
- `22d7c01` chore(hygiene): ignore editor artifacts; prettier SignerScreen
- `81b082f` feat(signer): always-allow grants for external signer requests
- `286bbca` fix(signer): connect immediately after identity; fetch kind-0
metadata in background
- `3d5302f` feat(signer): adopt real display name/picture for paired NIP-46
identities
- `9cfab4b` chore(signer): log pairing start and session failures to stderr
- `dc58f38` fix(ipc): lazily initialize the NIP-46 client signer handle
- `c5004eb` fix(electron): allow nip46_pair_start through the renderer method
allowlist
- `38499d4` feat(signer): QR pairing — client-initiated nostrconnect:// flow
for Amber
## How to reproduce / exercise
- Dev loop (unchanged): `npx vite --port 5173` in `frontend/` FIRST, then
`NOSTR_GUI_DEV_URL=http://localhost:5173 KEYNCTR_ENABLE_GPU=1 npx electron .`.
- E2E: `cargo test --test nip46_e2e` (no network).
- GUI: Signer mode screen -> "Show QR" -> scan in Amber -> approve ->
identity + display name appear; sign a note; approval dialog offers
"Always allow"; revoke on the Signer screen.
## Outstanding / next steps
1. **On-device Amber verification** of everything above (QR pair + pasted
bunker://, identity/name/pic, sign + publish, always-allow grant, revoke,
re-prompt). Top item — never run against real Amber since `f917e5e`.
2. `publish_profile_metadata` (kind 0) still signs locally — reroute through
`Signing` for external profiles (P2).
3. Step 5 (KDF upgrade m=64MiB/t=3 + vault header versioning, gate
deprecated `RevealSecretKey`), Step 6 (undo preserves `ProfileSummary` ->
secret lost), Step 7 (Keynctr rename pass incl. `homepage` URL).
4. `wip/pairing-relay-widening` branch parked — needs an env seam before it
can merge (breaks e2e isolation as-is).
---
# Checkpoint — NIP-46 e2e test + bunker:// frontend support (2026-09-11) # Checkpoint — NIP-46 e2e test + bunker:// frontend support (2026-09-11)
## Where things are ## Where things are