Skip to content

feat(desktop): canonical <PubKey> component — hover to view/copy full keys, owner "you" labels#1589

Merged
wesbillman merged 5 commits into
mainfrom
pinky/pubkey-component
Jul 7, 2026
Merged

feat(desktop): canonical <PubKey> component — hover to view/copy full keys, owner "you" labels#1589
wesbillman merged 5 commits into
mainfrom
pinky/pubkey-component

Conversation

@wesbillman

@wesbillman wesbillman commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

What

Make public keys viewable and copyable everywhere they appear, fix the two #showing-ids-instead-of-names dialog bugs, and consolidate pubkey truncation into one canonical path.

  • Canonical <PubKey> component (desktop/src/shared/ui/PubKey.tsx): compact renders the truncated form and opens a popover (hover with grace delays, or click/tap) showing the full npub + hex with one-click copy for each; full renders the whole npub inline for security-decision surfaces (bech32 checksum beats eyeballing hex).
  • Profile panel: the Public key row now renders the compact <PubKey> — hover to view/copy — instead of a silent hex-copy row.
  • New-DM dialog fixes: hovering an agent row no longer swaps the name for a truncated hex pubkey (the full npub is added as a line below), and owned by <hex> now resolves to owned by you / owner name. Same "you" fix applied to the members-sidebar add-member search.
  • One truncation helper: all display truncation goes through truncatePubkey (8+4) in shared/lib/pubkey.ts; the four drifted helpers and ~30 ad-hoc slice() sites are deleted, with a CI guard (check-pubkey-truncation) to keep it that way.
  • Helper consolidation: the three drifted formatOwnerLabel copies (useMentions, New-DM dialog, MembersSidebar) collapse into profile/lib/identity.ts with a primitive signature; safeNpub is shared from shared/lib/nostrUtils.ts.
  • Workflow/text surfaces: template filter emits the full npub instead of a grindable truncated prefix; agent-profile fallback names likewise.

Why

Truncated pubkey prefixes are forgeable by vanity grinding, and the only place you could see (let alone copy) a full key was the profile panel — which itself only copied silently. Meanwhile truncation had fragmented into five formats across four helpers.

Screenshots

Profile panel — hover the Public key row opens the copy popover (npub + hex, copy either):

Profile panel hover popover

New-DM agent row — name stays on hover, full npub added below, "owned by you":

New-DM agent row hover

New-DM selection — full npub verification line with copy:

New-DM full npub

Copy popover from the full-variant copy button:

Copy popover

Members sidebar:

Members sidebar

Testing

  • Unit suite 1974/1974, typecheck/biome/file-size/pubkey-truncation guards green
  • New e2e screenshot spec (4/4) covering the popover, New-DM hover/owner-label, and inline-npub surfaces
  • Full smoke suite: 396 pass / 1 skip / 2 fail — both failures reproduce on clean main (channels.spec.ts:876, custom-emoji.spec.ts:375), verified in a throwaway main worktree

wesbillman and others added 5 commits July 7, 2026 09:48
Truncated pubkey prefixes are forgeable by vanity grinding, and display
truncation had fragmented into five formats across four helpers plus
~30 ad-hoc slice() sites — while only the profile panel offered any way
to see the full key.

- Add `<PubKey>` (desktop/src/shared/ui/PubKey.tsx): `compact` renders
  the canonical truncated form and opens a click/tap popover with the
  full npub + hex and one-click copy for each; `full` renders the whole
  npub inline (bech32 checksum beats eyeballing hex) for
  security-decision surfaces.
- Consolidate all truncation into one canonical `truncatePubkey`
  (8+4, unicode ellipsis) in shared/lib/pubkey.ts; delete the duplicate
  helpers (identity.ts, memberUtils formatPubkey, agentUi 8+6,
  huddleChannelName ASCII form, RepoListItem truncateHex, shortenNpub)
  and migrate every ad-hoc slice() display site.
- Wire the full-key variant into the blessed decision surfaces:
  channel member invite, relay member rows, member-removal confirm,
  managed-agent row + RespondTo allowlist, new-DM recipient list,
  mention autocomplete (full npub shown inline on display-name
  collisions), and key-import previews now show the untruncated npub.
- Add `check-pubkey-truncation` guard (core + desktop/web wrappers,
  wired into `pnpm check`) so hand-rolled pubkey truncation can't
  fragment again; allowlist documents the genuine non-display uses.

Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
…faces

Truncated pubkey prefixes are grindable with vanity-key tools, so any
text surface that identifies a party by a shortened key is forgeable.

- Workflow template filter: add `| npub` (full bech32 npub from a hex
  pubkey; non-pubkey values pass through unchanged) and make
  `truncate_pubkey` a legacy alias with the same full-npub output. No
  existing workflows use the old filter (all channels audited).
- Agent profile conversion: the fallback display name for kind:10100
  events without a display_name is now the full npub instead of the
  first 8 hex chars.

Part of the pubkey-display effort; the rendered-UI half is the shared
PubKey component (separate PR).

Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Captures the canonical <PubKey> compact popover (full npub + hex with
copy-either) and the inline-full-npub decision surfaces (new-DM verify
list, members sidebar) as screenshot evidence for the pubkey-display
work. Registered in the smoke testMatch.

Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
…wner-label helper

- Profile panel Public key row renders the compact <PubKey> (view/copy
  full npub + hex) instead of a silent hex-copy row
- Compact <PubKey> opens on hover with a close-grace delay; click/tap
  kept for touch
- New DM dialog: hovering an agent row no longer swaps the name for a
  truncated hex pubkey — the full npub appears as an added line
- "owned by <hex>" now resolves to "you" for self-owned agents in the
  New DM dialog and channel Add-members search
- Consolidate the three drifted formatOwnerLabel copies into
  profile/lib/identity.ts and share safeNpub from shared/lib/nostrUtils

Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
The name-collision npub in the mention autocomplete rendered the full
64+-char npub inline on every duplicate name — a wall of text Wes flagged.
Show the canonical truncated form instead, with the full npub in a native
title tooltip for careful disambiguation.

Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
@wesbillman wesbillman merged commit 777babf into main Jul 7, 2026
29 checks passed
@wesbillman wesbillman deleted the pinky/pubkey-component branch July 7, 2026 20:35
tellaho added a commit that referenced this pull request Jul 7, 2026
…ivity

* origin/main:
  feat(desktop): restart-required badge from spawn-time config hash (#1602)
  feat(desktop): boot-time reconcile of managed agents to relay events (#1601)
  feat(desktop): canonical <PubKey> component — hover to view/copy full keys, owner "you" labels (#1589)

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tlongwell-block pushed a commit that referenced this pull request Jul 7, 2026
* origin/main:
  docs(readme): add Getting started section routing install paths (#1606)
  fix(desktop): restrict shared-agent sync to dev data dirs (#1597)
  feat(desktop): restart-required badge from spawn-time config hash (#1602)
  feat(desktop): boot-time reconcile of managed agents to relay events (#1601)
  feat(desktop): canonical <PubKey> component — hover to view/copy full keys, owner "you" labels (#1589)
  fix(desktop): hydrate reactions for Inbox context messages (#1596)
  fix: cleanup old screenshots that my agents committed (#1598)
  chore(release): release Buzz Desktop version 0.3.46 (#1585)
  fix(desktop): preserve agent model/provider when persona snapshot fields are blank (#1583)
  feat(acp,desktop): identify and reap stale agent harness processes (#1582)
  feat(desktop): active-draft badge, send-from-drafts confirm dialog, thread-deleted state (#1581)
  fix(desktop): treat baked build env vars as satisfying required agent config (#1580)
  feat(desktop): add "Copy image" to image right-click context menu (#1579)
  fix(nest): use buzz-dev symlink name for dev builds (#1587)
  fix(composer): address image-editor follow-up nits on #1491 (#1565)
  fix(desktop): render black static boot screen (#1570)
  feat(agents): group activity tool bursts (#1571)
  feat(desktop): aggregated overview rail, commit detail page, and full breadcrumbs (#1573)
  fix(desktop): fetch profiles for reaction actors and thread-reply authors (#1550)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant