Skip to content

Conversation

@Y3drk
Copy link
Contributor

@Y3drk Y3drk commented Jan 9, 2026

Substantial PR → Copy shared components from ENSAdmin & ENSAwards


Reviewer Focus (Read This First)

What reviewers should focus on
  • Feel free to critique the overall structure of the package, that's where I went by my instinct the most
  • The vast majority of changes in this PR are just copy-pasting components from ENSAwards & ENSAdmin and adding the package's prefix to their styles
  • The only components with major alignments are packages/namehash-ui/src/components/identity/ResolveAndDisplayIdentity.tsx:ResolveAndDisplayIdentityProps and packages/namehash-ui/src/components/registrar-actions/RegistrarActionCard.tsx. I suggest reasoning about the changes made, focusing on differences in how each of our apps displays registrar-actions
  • Overall, this PR brings a lot of changes, but the related risk is low, as all of these components have not been replaced yet, just copied.

Problem & Motivation

Why this exists

What Changed (Concrete)

What actually changed
  1. Went through a preliminary list of components to move into the package
  2. For each of them, explored the possible differences between them in ENSAwards & ENSAdmin and decided whether the component should be copied or not. I also created a variant where a component could be moved, but that action was postponed either due to a low priority or potentially significant effort to refactor them and/or resolve differences between ensadmin and ensawards instances.
  3. Copied chosen components, applied the package's prefix to their styles, and performed some refactors to make them usable in both apps if needed.
  4. Adjusted package.json and README.md files accordingly.

Design & Planning

How this approach was chosen

Self-Review

What you caught yourself
  • I appreciate that the refactor of packages/namehash-ui/src/components/identity/ResolveAndDisplayIdentity.tsx:ResolveAndDisplayIdentityProps might seem weird (the addition of identityLinkDetails), but with how our registrar actions display is designed across our apps, I found it the best way to keep the code usable across both of them without any design changes. Feel free to attack it.
  • Bugs caught: None → planning a bughunting for when I actually apply the package in our apps.
  • Logic simplified: None (new code added, nothing changed outside the package)
  • Naming / terminology improved: -
  • Dead or unnecessary code removed (or why none was): None → will be removing the redundant components from ENSAdmin & ENSAwards once I successfully apply the package's components there.

Cross-Codebase Alignment


Downstream & Consumer Impact

Who this affects and how
  • Other than the namehash-ui itself, this PR shouldn't affect any of our apps, docs, or packages.
  • Public APIs affected: None
  • Docs updated: Only contains updates to namehash-ui/README.me
  • Naming decisions worth calling out: None

Testing Evidence

  • Testing performed: Only the CI tests that were run on the PR, plus a self-review of the code.
  • Known gaps: The components have not been applied anywhere yet, so I did not check whether some runtime errors occur or some layouts are broken, etc. → I want these "tests" to be a part of future PRs where I'll apply the package in our apps.
  • What reviewers have to reason about manually (and why): Any alignment refactor changes made to copied components → I plan to carefully review these in action as I apply the package in our apps in later PRs, as they seem fine in code when I review them now.
  • If this is wrong, what breaks first: The only thing possibly affected by mistakes made in this PR would be the namehash-ui package. I expect that nothing bad should happen, but even if it does, it won't affect any of our apps, as none of them use the package yet.

Scope Reductions

  • Follow-ups: See the preliminary components list🔁 postponed
  • Why they were deferred: In my opinion, all of the postponed components are worth including in the package, but doing that right now is not strictly necessary, cause for now they are only used in one of the apps. Also, for most of them, including them in the package would require a significant refactor to make them 'unified' / usable in both apps at once.

Risk Analysis

How this could go wrong
  • Assumptions this PR relies on: The copied components will retain their styles and runtime characteristics.
  • Likely failure modes: Runtime errors when trying to use the package's components and/or some broken layouts for these components (worth noting that the styling errors are highly unlikely to happen)
  • Blast radius if it breaks: Only the namehash-ui package
  • Risk areas: Only the namehash-ui package
  • Mitigations or rollback options: Do not use the package anywhere until the components are confirmed to work (my plan for my next PR is to include them in ENSAdmin and iron out any possible errors)
  • Named owner if this causes problems: @Y3drk

Pre-Review Checklist (Blocking)

  • I reviewed every line of this diff and understand it end-to-end
  • I'm prepared to defend this PR line-by-line in review
  • I'm comfortable being the on-call owner for this change
  • Relevant changesets are included (or explicitly not required)

@Y3drk Y3drk self-assigned this Jan 9, 2026
@Y3drk Y3drk added the ensnode-internal ensnode-internal related label Jan 9, 2026
@changeset-bot
Copy link

changeset-bot bot commented Jan 9, 2026

🦋 Changeset detected

Latest commit: cb8e5c1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 17 packages
Name Type
@namehash/namehash-ui Major
ensindexer Major
ensadmin Major
ensrainbow Major
ensapi Major
fallback-ensapi Major
@ensnode/datasources Major
@ensnode/ensrainbow-sdk Major
@ensnode/ponder-metadata Major
@ensnode/ensnode-schema Major
@ensnode/ensnode-react Major
@ensnode/ponder-subgraph Major
@ensnode/ensnode-sdk Major
@ensnode/shared-configs Major
@docs/ensnode Major
@docs/ensrainbow Major
@namehash/ens-referrals Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Jan 12, 2026 2:40pm
ensnode.io Ready Ready Preview, Comment Jan 12, 2026 2:40pm
ensrainbow.io Ready Ready Preview, Comment Jan 12, 2026 2:40pm

Copy link
Member

@lightwalker-eth lightwalker-eth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Y3drk Nice updates 👍 Reviewed and shared feedback. Please feel welcome to take the lead to merge when ready. Thanks!

```

Note: `@ensnode/ensnode-react` is necessary only for some components. It might happen that you won't need it.
Note: `@ensnode/ensnode-react` is necessary only for some components. It might happen that you won't need it. Same goes for `sonner` it's only necessary for `CopyButton` component.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is sonner only necessary for the CopyButton component? I assume this is for tooltips? Don't all our apps use tooltips and therefore don't all our apps require sonner?

"hooks": "@/hooks"
},
"iconLibrary": "lucide"
} No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like something is causing some files not to always include a newline character at the end automatically as part of our lint / auto-formatting steps?

```

Note: `@ensnode/ensnode-react` is necessary only for some components. It might happen that you won't need it.
Note: `@ensnode/ensnode-react` is necessary only for some components. It might happen that you won't need it. Same goes for `sonner` it's only necessary for `CopyButton` component.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be helpful here to identify how these packages are configured as peerDependencies?

"boring-avatars": "^2.0.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not have date-fns as a "workspace:*" dependency as configured in pnpm-workspace.yaml?

"@ensnode/ensnode-sdk": "workspace:*",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.8",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, so we need sonner on top of these other tooltip libraries?

* @returns complete block explorer URL for a specific address on a specific chainId,
* or null if the referenced chain doesn't have a known block explorer
*/
export const getBlockExplorerUrlForAddress = (chainId: ChainId, address: Address): URL | null => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const getBlockExplorerUrlForAddress = (chainId: ChainId, address: Address): URL | null => {
export const getBlockExplorerAddressDetailsUrl = (chainId: ChainId, address: Address): URL | null => {

* @returns default block explorer URL for the chain with the provided id,
* or null if the referenced chain doesn't have a known block explorer
*/
export const getChainBlockExplorerUrl = (chainId: ChainId): URL | null => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const getChainBlockExplorerUrl = (chainId: ChainId): URL | null => {
export const getBlockExplorerUrl = (chainId: ChainId): URL | null => {

}

/**
* Gets the base block explorer URL for a given chainId
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Gets the base block explorer URL for a given chainId
* Gets the "base" block explorer URL for a given ChainId

* @returns complete block explorer URL for a specific transaction hash on a specific chainId,
* or null if the referenced chain doesn't have a known block explorer
*/
export const getBlockExplorerUrlForTransactionHash = (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const getBlockExplorerUrlForTransactionHash = (
export const getBlockExplorerTransactionDetailsUrl = (

* @returns ENS Manager App URL for the provided namespace, or null if the provided namespace
* doesn't have a known ENS Manager App
*/
export function getEnsManagerAppUrl(namespaceId: ENSNamespaceId): URL | null {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function getEnsManagerAppUrl(namespaceId: ENSNamespaceId): URL | null {
export function getEnsManagerUrl(namespaceId: ENSNamespaceId): URL | null {

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

Labels

ensnode-internal ensnode-internal related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add AbsoluteTime to shared UI Components

3 participants