vtc-service 0.11.44

Service for Verifiable Trust Communities
// Render a DID as its name, with the identifier still visible.
//
// One component so every table, dialog and detail pane in the console agrees
// on what a principal looks like. Drop-in for the `<code className="truncate"
// title={did}>{did}</code>` pattern the plugins used before.
//
// Two rules it enforces, both from `vta_sdk::display_name`:
//
//   * **The DID is never hidden.** A name the operator cannot cross-check
//     against an identifier is a name they cannot audit — and these screens
//     are where ACL grants get approved and members admitted. The name leads,
//     the abbreviated DID follows, the full DID is in the tooltip.
//
//   * **An unverified name is marked.** `alsoKnownAs` is self-asserted, so a
//     name that has not round-tripped carries its `[unverified]` suffix and a
//     warning style. Seeing that a DID *claims* to be `mybank.com/@treasury`
//     is useful; being told it *is* would be a lie.

import { shortenDid } from "@/lib/format";
import { isTrusted, type NameBook } from "@/lib/names";

interface NamedDidProps {
  book: NameBook;
  did: string;
  /** Omit the abbreviated DID and show the name alone. Only for places that
   *  render the DID separately in the same row — never to save space. */
  nameOnly?: boolean;
  className?: string;
}

export function NamedDid({ book, did, nameOnly, className }: NamedDidProps) {
  const entry = book.get(did);
  const name = book.nameOf(did);

  if (!name) {
    return (
      <code className={`truncate ${className ?? ""}`} title={did}>
        {shortenDid(did)}
      </code>
    );
  }

  const untrusted = entry && !isTrusted(entry.source);

  return (
    <span className={`named-did ${className ?? ""}`} title={did}>
      <span className={untrusted ? "named-did-name unverified" : "named-did-name"}>
        {name}
      </span>
      {!nameOnly && <code className="named-did-id">{shortenDid(did)}</code>}
    </span>
  );
}