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)
|
# Checkpoint — first live Amber pairing succeeded; subscription race fixed (2026-09-23)
|
||||||
|
|
||||||
## Where things are
|
## Where things are
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue