Skip to content

fix(login): identity preview on primary splash, lenient hex parsing#303

Open
dmnyc wants to merge 1 commit into
mainfrom
fix/login-preview-and-hex-parsing
Open

fix(login): identity preview on primary splash, lenient hex parsing#303
dmnyc wants to merge 1 commit into
mainfrom
fix/login-preview-and-hex-parsing

Conversation

@dmnyc

@dmnyc dmnyc commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #226 (hex private-key login appears to fail despite the error message saying hex is supported) and #227 (account preview missing from the primary login screen).

Changes

Identity preview shared across both login surfaces. The splash sheet (NostrLoginSheet in SplashView.swift) and the secondary login (LoginView for Add Account) were separate implementations; only the secondary one rendered a live avatar + display name + nip05 preview. Extracted the preview into a new NsecIdentityPreview SwiftUI view that owns its own debounced relay lookup, and now both surfaces use it.

Lenient hex parsing. NostrKey.parseNsec already supported a raw 64-char hex private key but rejected anything with a 0x / 0X prefix or internal whitespace — keys copied from wallets or terminals often arrive in those shapes and were silently failing. Both are now stripped before the length check.

Tighter error wording. Both screens previously said "Invalid key. Enter an nsec or hex private key." which gave the user no signal about why a hex paste failed. Reworded to spell out the accepted formats explicitly.

Splash layout refinements (came out of testing the new preview):

  • Sheet detent bumped from .medium to a custom .height(500) so the ostrich isn't crowded against the top and the preview card fits between input + Log In without clipping the lower controls. .large stays as a secondary detent.
  • Description line shortened to "Your key never leaves the device." with .fixedSize(vertical: true) so it never truncates with an ellipsis.
  • Federated identity buttons (Apple, Google) stay tight at 8pt; the Nostr button gets a 16pt gap below them so it reads as its own choice rather than a third entry in the federated list.

Test plan

  • First-time launch: paste an nsec on the splash sheet → preview card appears with avatar / display name / nip05
  • Same flow via Add Account: behavior matches
  • Hex private key (64 chars) logs in successfully
  • Hex with 0x prefix logs in successfully
  • Hex with surrounding / internal whitespace logs in successfully
  • Invalid key → error reads "Couldn't read that key. Paste an nsec ("nsec1…")…"
  • Splash sheet opens at a height that shows the discovery grid above without clipping any controls
  • Description text on splash never shows an ellipsis

Closes #226. Closes #227.

…tighter error

Two related login bugs from #226 + #227.

#227 — identity preview missing from primary login. The splash sheet
`NostrLoginSheet` and the secondary `LoginView` (Add Account) used
to be separate implementations; only `LoginView` rendered a live
avatar + display name + nip05 preview from the pasted nsec. Extract
the preview into a shared `NsecIdentityPreview` SwiftUI view that
owns its own debounced relay lookup, and use it from both surfaces.

#226 — hex private key login fails despite the error message saying
hex is supported. The path actually worked end-to-end, but
`parseNsec` only accepted a literal 64-char string with no prefix
and no internal whitespace. Keys copied from wallets or terminals
often arrive with a leading `0x` / `0X` prefix or surrounding spaces
and silently failed validation. `parseNsec` now strips both before
the length check.

Also:
- Splash error wording rewritten so the user can tell which formats
  the field accepts ("nsec (\"nsec1…\"), npub / nprofile to browse
  watch-only, or a 64-character hex private key") and the `LoginView`
  variant tracks.
- Splash sheet detent bumped from `.medium` to a custom `.height(500)`
  so the ostrich isn't crowded against the top edge and the new
  preview card fits between the input and the Log In button without
  clipping the lower controls. `.large` stays as a secondary detent.
- Splash description line shortened from two sentences to one and
  pinned with `.fixedSize(vertical: true)` so it never truncates
  with an ellipsis at narrow widths.
- Splash button stack regrouped: the two federated identity options
  (Apple, Google) stay tight at 8pt; the Nostr button gets a 16pt
  gap below them so it reads as its own choice rather than a third
  entry in the federated list.

Closes #226. Closes #227.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant