docs(checkpoint): sync to 8f055f7 - NIP-46 spec fix, handshake trace, visible errors (2026-09-23)
This commit is contained in:
parent
8f055f71bf
commit
5456835cde
1 changed files with 95 additions and 0 deletions
|
|
@ -1,3 +1,98 @@
|
|||
# Checkpoint — NIP-46 handshake debugged: connect-params spec fix + full [NIP46] trace + visible errors (2026-09-23)
|
||||
|
||||
## Where things are
|
||||
- Project: `/home/avi/Projects/Keynctr`
|
||||
- Branch: `master` @ **`8f055f7`** ("fix(nip46): spec-correct connect params,
|
||||
full-handshake [NIP46] trace, visible handshake errors"). Previous:
|
||||
`2bc6321` (identity-RPC retry), `9cfc1cf` (relay-accept trace).
|
||||
- Working tree: clean for tracked files. Untracked intentionally NOT
|
||||
committed: `COSMIC_THEME.md`, `KeynectrAppIconPossibility02.jpeg`,
|
||||
`deferred/` (stays deferred).
|
||||
- Release binary: **rebuilt at `8f055f7`** — Electron spawns this one.
|
||||
|
||||
## What was completed this session
|
||||
1. **Spec-verified the whole signer flow against NIP-46** (20-point checklist
|
||||
in the session brief). URI generation, keypair handling, subscribe-before-
|
||||
publish, relay URL encoding, kind-24133 listen, NIP-44 decrypt, secret
|
||||
validation, identity-via-`get_public_key`, account-state update and UI
|
||||
polling were all traced file-by-file (`nip46_client.rs`, `ipc.rs`,
|
||||
`SignerModeScreen.tsx`, `relays.rs`, `nip46_e2e.rs`).
|
||||
2. **Found + fixed the definitive paste-flow (`bunker://`) bug (`8f055f7`)**:
|
||||
`run_handshake` sent `connect` params as `[client_pubkey, secret]`, but
|
||||
NIP-46 (and rust-nostr's own `NostrConnectRequest::Connect` codec) require
|
||||
`[<remote-signer-pubkey>, <optional_secret>]`. Strict signers answer a
|
||||
malformed connect with silence, stalling the handshake with zero feedback.
|
||||
New pure helper `connect_params(peer, secret)` + 2 unit tests (one
|
||||
round-trips through the library codec).
|
||||
3. **Client keypair is now always ephemeral** in `connect()` (was: reused the
|
||||
vault's local secret key when unlocked). Per NIP-46 the client keypair is
|
||||
disposable and must never be confused with the user's identity or a vault
|
||||
key. QR flow already did this; both flows now agree.
|
||||
4. **Full `[NIP46]` diagnostic trace** across both flows (console stderr, in
|
||||
addition to the existing `pairing-trace.log` forensics): keypair gen,
|
||||
client pubkey, secret presence (NEVER values), relay connecting/connected,
|
||||
subscription created/registered (filter + id), URI generated, every inbound
|
||||
24133 (author, tags, decrypt OK/real-error, method, secret PASS/FAIL,
|
||||
remote pubkey), every RPC publish/timeout/response-routing decision
|
||||
(including stale/duplicate ids), relay-health pre-check before each
|
||||
`get_public_key` retry (fails fast with a useful error when no relay is
|
||||
connected), user pubkey, account-state update, UI-state update.
|
||||
5. **Failures are visible now, not silent**: `fail()` keeps the FIRST
|
||||
(specific) error instead of letting the demux exit overwrite it with
|
||||
generic "Connect handshake failed"; `SignerModeScreen` renders
|
||||
`status.error` as an alert in both the pairing and the idle/paste branches
|
||||
and shows a "Connection request sent — approve it in Amber" hint while a
|
||||
paste-URI connect is in flight. No fake Connected state anywhere:
|
||||
`Connected` still requires `get_public_key` to resolve the identity.
|
||||
6. **Tests**: new strict-Amber e2e
|
||||
(`nip46_bunker_connect_params_match_spec_against_strict_amber`) — fake
|
||||
signer rejects `connect` unless params[0] is its own pubkey, then serves
|
||||
identity + sign like Amber; asserts the REAL user pubkey lands in the
|
||||
vault as a secretless row AND becomes the active profile. Verified RED on
|
||||
the old param order, GREEN on the fix. New `SignerModeScreen.test.tsx`
|
||||
(3 tests: QR waiting hint, connecting hint, failed-handshake error
|
||||
visible) + `nip46_*` dispatch in `fakeBackend.ts`. Also widened the e2e
|
||||
`VAULT_ENV_LOCK` to whole-test bodies (data_dir() re-reads process-global
|
||||
XDG_DATA_HOME on every save — one cross-write flake seen under full-suite
|
||||
parallelism) with targeted `await_holding_lock` allows.
|
||||
- Verification (all green at `8f055f7`): `cargo test` **211 unit + 4 e2e
|
||||
passed / 0 failed**, `cargo clippy --all-targets` 0 warnings,
|
||||
`cargo fmt --check` clean, `cargo build --release` green; frontend
|
||||
`npm test` **119 passed (17 files)**, `typecheck`, `lint`, `format:check`,
|
||||
`electron:build`, `build` clean.
|
||||
|
||||
## Commits added (newest first)
|
||||
- `8f055f7` fix(nip46): spec-correct connect params, full-handshake [NIP46]
|
||||
trace, visible handshake errors
|
||||
|
||||
## How to resume / reproduce
|
||||
- Dev loop: `cd frontend && npx vite --port 5173` then
|
||||
`NOSTR_GUI_DEV_URL=http://localhost:5173 KEYNCTR_ENABLE_GPU=1 npx electron .`
|
||||
(release binary already rebuilt at `8f055f7`).
|
||||
- **Live Amber re-scan (still the decisive test)**: Signer Mode → Show QR →
|
||||
scan in Amber → approve, **keep Amber open in the foreground**. Watch
|
||||
terminal/backend console for the `[NIP46]` lines in order (see "Expected
|
||||
logs" in the session report) and `~/Tools/keynctr-debug/pairing-trace.log`.
|
||||
- E2E: `cargo test --test nip46_e2e` (4 tests, no network).
|
||||
- Frontend: `cd frontend && npm test -- SignerModeScreen`.
|
||||
|
||||
## Outstanding / next steps
|
||||
1. **Live Amber re-scan against `8f055f7`** — the QR flow's `get_public_key`
|
||||
silence (5 scans × 4 attempts, publishes accepted by primal+nos.lol, zero
|
||||
responses) is downstream of our publish: either Amber never receives our
|
||||
request (e.g. its subscription fails, NIP-42 AUTH on those relays from
|
||||
mobile, or the app was backgrounded) or it receives and never answers.
|
||||
The new demux logs distinguish these live: zero inbound lines during the
|
||||
retries ⇒ Amber-side; inbound-but-dropped lines ⇒ our filter/decrypt.
|
||||
2. If the live trace shows zero inbound during retries, next step is a relay
|
||||
experiment (add a no-auth REQ relay to the pairing set) and/or confirming
|
||||
Amber stays foregrounded with network.
|
||||
3. `publish_profile_metadata` (kind 0) still signs locally — reroute through
|
||||
`Signing` for external profiles (P2, pre-existing).
|
||||
4. Step 5 (KDF upgrade), Step 7 (rename pass incl. `homepage` URL).
|
||||
|
||||
---
|
||||
|
||||
# Checkpoint — first live Amber pairing succeeded; subscription race fixed (2026-09-23)
|
||||
|
||||
## Where things are
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue