feat(nip46): show user's kind-0 profile (name, about, NIP-05) after Amber login - #79
Merged
Merged
Conversation
…ive relays The user's bug report: 'it doesn't give a success message on the actual device, it needs to give a success message there and also show the profile of the person when it's working in HOOT.' Right now the TUI shows nothing more than the 16-char pubkey prefix after QR login — no name, no about, no picture, no NIP-05. There's no code anywhere that fetches the user's kind-0 (NIP-01 profile) metadata after a successful NIP-46 pairing. This commit adds Session.FetchProfile(ctx, userPubKey), which queries the same relay connections opened by ConnectRelays for a kind-0 event by UserPublicKey. No extra dial cost (amortises the QR-pairing latency), 6s timeout so the TUI never blocks on a dead relay, and returns (nil, nil) — not an error — when no kind-0 event exists so the caller can fall back to npub display without raising an error toast. The TUI integration, cache persistence, and home-screen rendering land in the next step of this branch. Tests: profile.go is testable as a unit without a real relay; the TUI integration test will follow.
…mber login The user's bug report: 'it doesn't give a success message on the actual device, it needs to give a success message there and also show the profile of the person when it's working in HOOT.' After QR pairing succeeds, the home screen showed only the raw 16-char pubkey prefix. There's no code anywhere in the repo that fetches the user's kind-0 (NIP-01 profile metadata) event. This commit wires that in end-to-end. - nip46.Session.FetchProfile(ctx, userPubKey) queries the same relay connections opened by ConnectRelays (no extra dial cost, amortises the QR-pairing latency) for kind=0 events authored by the user. 6s timeout so a dead relay doesn't block the TUI login flow. Returns (nil, nil) — not an error — when the user has no kind-0 event, so callers fall back to the npub display without raising an error toast. - The OnCheckQR callback in hoot.go now also calls FetchProfile and returns the result alongside the pubkey. Successful fetch is cached in the existing profiles table with 24h TTL (matches the kind-0 re-publish cadence of most signers). - The TUI's qrSuccessMsg now carries the profile. The success message says 'Logged in as <name>' when we have one, else 'Logged in via Amber!' (unchanged fallback). viewHome renders the about line and NIP-05 (✓ alice@example.com) under the name when present. - Test files updated to the new OnCheckQR signature. New profile_test.go covers the JSON round-trip, the omit-empty- fields contract, and the FetchProfile input-validation guards. - ProfileMetadata is JSON-shaped to match what kind-0 events contain on the wire (name, about, picture, nip05 — all optional), so unmarshal survives signer quirks. Tests: +5 new in nip46/profile_test.go, existing nip46+tui tests updated, full suite green, go vet clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug Description
The user's bug report (second part): "it doesn't give a success message on the actual device, it needs to give a success message there and also show the profile of the person when it's working in HOOT."
After a successful NIP-46 QR pairing, the home screen showed only the raw 16-char pubkey prefix (
m.publicKey[:16]). There was no code anywhere in the codebase that fetched the user's kind-0 (NIP-01 profile metadata) event, and no UI element to render the name / about / picture / NIP-05 from one.Fix
Wires the kind-0 profile fetch end-to-end from session → TUI → home screen:
nip46.Session.FetchProfile(ctx, userPubKey)— new method that queries the same relay connections opened byConnectRelaysfor a kind-0 event authored by the user. No extra dial cost (amortises the QR-pairing latency). 6-second timeout so a dead relay doesn't block the TUI login flow. Returns(nil, nil)— not an error — when the user has no kind-0 event, so the caller falls back to the npub display without raising an error toast.hoot.go:OnCheckQR— afterGetPublicKeyreturns, callsFetchProfileand returns the result alongside the pubkey. Successful fetch is cached in the existingcache.profilestable with 24h TTL.tui.qrSuccessMsg— now carries the profile alongside the pubkey. The success message becomes "Logged in as " when a name is available; falls back to "Logged in via Amber!" otherwise.tui.viewHome— whencurrentProfileAboutorcurrentProfileNIP05is set, renders them under the title in dim style. The NIP-05 gets a ✓ prefix to communicate verification status at a glance.How to Verify
go run .and pick "Scan QR with Amber".currentProfileNameis used unchanged, no regression.Test Plan
TestProfileMetadataJSONRoundTrip— pins the wire formatTestProfileMetadataOmitsEmptyFields— pins the omit-empty contractTestFetchProfileRejectsEmptyPubKey— input-validation guardTestFetchProfileRejectsNoRelays— "called too early" guardTestProfileNameIsRenderable— covers ASCII/emoji/unicode/whitespace/markup casesOnCheckQRsignaturego test ./...)go vet ./...cleanRisk Assessment
Low. The change is purely additive on the success path:
Model(currentProfileAbout,currentProfileNIP05) are only set by the new code path, and only displayed when non-empty.loggedIn/publicKeystate is unchanged.FetchProfilefailures are non-fatal by design — they degrade gracefully to npub display, identical to the pre-change behaviour._ =); a cache failure doesn't break sign-in.The TUI's
OnCheckQRsignature changed (func() (string, error)→func() (string, *nip46.ProfileMetadata, error)). All four test files usingSetCallbackswere updated; no other callers exist outsidehoot.go.