From 4b2b85fcdcb4785615e74e03584c03f67a49ad6f Mon Sep 17 00:00:00 2001 From: real-venus Date: Fri, 17 Jul 2026 05:32:34 -0700 Subject: [PATCH] feat(ui): surface the owning coldkey on the validator detail page (#6427) validatorDetailQuery already normalizes `coldkey` into ValidatorDetail, but the page only ever read it to decide whether the connected wallet owns this validator (the gate on the take modal). A visitor had no way to tell which account operates a hotkey: the identity chip shows self-declared operator identity, which is declared on the coldkey but never shows the coldkey itself, and the raw address appeared nowhere. Render it beside the hotkey it belongs to, public and unconditional -- no owner gating, since this is chain-public data every visitor can already read from the API. Use AccountAddress rather than a hand-rolled Link: it is the app's shared ss58 treatment (accounts link + entity hover preview + copy button) and its own contract notes /accounts/$ss58 resolves any ss58 whether hotkey or coldkey, so a coldkey needs no special case. Its `fallback` covers the null the query normalizes an absent coldkey to, so the empty case renders "Not reported" rather than a dead link. `break-all` on the value so the full 48-char address wraps at 375px instead of escaping the viewport -- the hotkey above it is shown in full too, and a truncated owner address would defeat the point of surfacing it. --- apps/ui/src/routes/validators.$hotkey.tsx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/apps/ui/src/routes/validators.$hotkey.tsx b/apps/ui/src/routes/validators.$hotkey.tsx index 78ee16347..6faa844d4 100644 --- a/apps/ui/src/routes/validators.$hotkey.tsx +++ b/apps/ui/src/routes/validators.$hotkey.tsx @@ -7,6 +7,7 @@ import { Boxes, Coins, Gauge, Percent, TriangleAlert, Users, Zap } from "lucide- import { useWallet } from "@/hooks/use-wallet"; import { AppShell } from "@/components/metagraphed/app-shell"; import { EmptyState, PageHeading, Skeleton, StaleBanner } from "@/components/metagraphed/states"; +import { AccountAddress } from "@/components/metagraphed/account-address"; import { ApiSourceFooter } from "@/components/metagraphed/api-source-footer"; import { EndpointSnippet } from "@/components/metagraphed/endpoint-snippet"; import { QueryErrorBoundary } from "@/components/metagraphed/error-boundary"; @@ -291,6 +292,27 @@ function ValidatorDetail({ hotkey }: { hotkey: string }) { + {/* #6427: the payload already carries the owning coldkey -- it was + only ever read for the owner check that gates the take modal, so + a visitor had no way to see which account operates this hotkey. + Public and unconditional, beside the hotkey it belongs to. + AccountAddress is the app's shared ss58 treatment (accounts link + + hover preview + copy) and covers a coldkey as readily as a + hotkey; its `fallback` handles the null the API normalizes an + absent coldkey to. `break-all` so the full 48-char address wraps + on a 375px viewport instead of escaping it. */} + + + Coldkey + + + Not reported} + /> + + } actions={