Skip to content

docs(example): ensnode-react#1999

Draft
notrab wants to merge 10 commits into
mainfrom
ensnode-react-example
Draft

docs(example): ensnode-react#1999
notrab wants to merge 10 commits into
mainfrom
ensnode-react-example

Conversation

@notrab
Copy link
Copy Markdown
Member

@notrab notrab commented Apr 27, 2026

Todo

  • Indexing Status

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • What changed (1-3 bullets, no essays).

Why

  • Why this change exists. Link to related GitHub issues where relevant.

Testing

  • How this was tested.
  • If you didn't test it, say why.

Notes for Reviewer (Optional)

  • Anything non-obvious or worth a heads-up.

Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

Copilot AI review requested due to automatic review settings April 27, 2026 06:37
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 27, 2026

⚠️ No Changeset found

Latest commit: 1e386f1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 27, 2026

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

Project Deployment Actions Updated (UTC)
enskit-react-example.ensnode.io Ready Ready Preview, Comment May 12, 2026 3:44pm
ensnode-enskit-react-example Ready Ready Preview, Comment May 12, 2026 3:44pm
3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped May 12, 2026 3:44pm
ensnode.io Skipped Skipped May 12, 2026 3:44pm
ensrainbow.io Skipped Skipped May 12, 2026 3:44pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Review Change Stack

Warning

Rate limit exceeded

@notrab has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 31 minutes and 57 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 41ba0565-c46f-464b-8f1e-7aa20db658bf

📥 Commits

Reviewing files that changed from the base of the PR and between 2d8f70a and 1e386f1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/ensnode-react/example/README.md
  • packages/ensnode-react/example/src/config.ts
  • pnpm-workspace.yaml
📝 Walkthrough

Walkthrough

This PR introduces a new minimal React example application within the ensnode-react package. The example demonstrates primary name resolution using the @ensnode/ensnode-react library, with ENSNode connectivity monitoring, configurable endpoints via environment variables, and a form for resolving addresses to their primary names on ENSIP-19-compatible chains.

Changes

ENSNode React Example Application

Layer / File(s) Summary
Project setup and build configuration
packages/ensnode-react/example/package.json, packages/ensnode-react/example/tsconfig.json, packages/ensnode-react/example/vite.config.ts, packages/ensnode-react/example/index.html, packages/ensnode-react/example/README.md, packages/ensnode-react/example/LICENSE
Establishes a Vite+React monorepo example with ESM modules, strict TypeScript, React JSX transform, dev scripts for dev/build/preview/typecheck, workspace dependencies on @ensnode packages, and documentation for running and configuring the example.
Environment configuration
packages/ensnode-react/example/src/config.ts, packages/ensnode-react/example/src/vite-env.d.ts
Parses VITE_ENSNODE_URL and VITE_ENS_NAMESPACE environment variables with defaults (Mainnet alpha endpoint and Mainnet namespace), exports typed URL and ENSNamespaceId constants, and augments import.meta.env with TypeScript types for both variables.
Connection error classification
packages/ensnode-react/example/src/lib/classify-connection-error.ts
Utility that converts unknown errors into a structured ConnectionFailure type with kind (network/application/unsupported-namespace) and message, distinguishing TypeError as network failures and other errors as application failures.
Connection status and access control
packages/ensnode-react/example/src/components/IndexingStatusBadge.tsx, packages/ensnode-react/example/src/components/RequireActiveConnection.tsx
IndexingStatusBadge polls and displays worst-case indexing distance and snapshot age via useIndexingStatus(); RequireActiveConnection gates child rendering on active connection, correct namespace, and loading state, using classifyConnectionError to show network vs application failures.
Primary name resolution example
packages/ensnode-react/example/src/PrimaryNameView.tsx
Component accepting user EVM addresses and deriving available ENSIP-19 chains from the namespace (default EVM chain, ENS root chain, plus reverse-resolver chains); normalizes input, triggers usePrimaryName with accelerate: true, and displays loading, error, or resolved primary name output.
App component and React DOM initialization
packages/ensnode-react/example/src/App.tsx, packages/ensnode-react/example/src/main.tsx
App component initializes EnsNodeProvider with configured ENSNODE_URL, renders page layout with header, IndexingStatusBadge, RequireActiveConnection guard, and PrimaryNameView; main.tsx bootstraps React at #root element.

Sequence Diagram

sequenceDiagram
  participant User
  participant App
  participant RequireActiveConnection
  participant IndexingStatusBadge
  participant PrimaryNameView
  participant usePrimaryName as usePrimaryName Hook
  
  User->>App: Load application
  App->>RequireActiveConnection: Check ENSNode connection
  RequireActiveConnection->>IndexingStatusBadge: Request indexing status
  IndexingStatusBadge-->>RequireActiveConnection: Return status (loading/error/ok)
  RequireActiveConnection-->>App: Gate content (loading/error/ready)
  App->>PrimaryNameView: Render form
  User->>PrimaryNameView: Submit address & chain
  PrimaryNameView->>usePrimaryName: Resolve primary name
  usePrimaryName-->>PrimaryNameView: Return result (loading/error/data)
  PrimaryNameView-->>User: Display name or error
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • namehash/ensnode#1888: Updates example apps to use the VITE_ENSNODE_URL environment variable for configurable ENSNode endpoints
  • namehash/ensnode#1332: Alters indexing-status response shapes and real-time projection logic that the IndexingStatusBadge component consumes

Suggested labels

javascript

Poem

🐇 A new example hops to life,
With forms to resolve names so bright,
ENSNode chains all tied just right,
Status badges show the light—
React hooks save the day! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete: the Summary, Why, Testing, and Notes for Reviewer sections contain only template placeholders with no actual content filled in. Pre-Review Checklist items are unchecked. Fill in all required sections: provide 1-3 bullet points summarizing what was added, explain why this example is needed, document testing approach, and complete the pre-review checklist.
Docstring Coverage ⚠️ Warning Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'docs(example): ensnode-react' is vague and generic, using the conventional prefix but lacking specificity about what was actually added or changed in the example. Clarify the title to be more descriptive, e.g., 'docs(example): add ensnode-react example app' or 'feat(example): ensnode-react minimal example with primary name resolution'.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ensnode-react-example

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new minimal Vite + React example app under examples/ensnode-react-example to demonstrate using @ensnode/ensnode-react (specifically EnsNodeProvider + usePrimaryName) against a configurable ENSNode URL.

Changes:

  • Introduces a new examples/ensnode-react-example workspace package with Vite/TS config and minimal UI.
  • Demonstrates primary-name resolution via usePrimaryName, defaulting to https://api.alpha.ensnode.io with VITE_ENSNODE_URL override.
  • Updates pnpm-lock.yaml to include the new example importer and its dependencies.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds lockfile entries for the new example workspace importer and its resolved deps.
examples/ensnode-react-example/package.json Defines the example workspace package, scripts, and dependencies.
examples/ensnode-react-example/vite.config.ts Minimal Vite config enabling React plugin.
examples/ensnode-react-example/tsconfig.json TypeScript configuration for the example source.
examples/ensnode-react-example/index.html HTML entrypoint with #root mount point.
examples/ensnode-react-example/src/main.tsx React 19 createRoot bootstrap rendering <App />.
examples/ensnode-react-example/src/App.tsx Sets up EnsNodeProvider with URL-configurable options and renders the demo view.
examples/ensnode-react-example/src/PrimaryNameView.tsx Implements the address input + usePrimaryName query UI.
examples/ensnode-react-example/src/vite-env.d.ts Adds Vite client type references.
examples/ensnode-react-example/README.md Documents usage and environment configuration.
examples/ensnode-react-example/LICENSE Adds MIT license for the example package.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +26 to +30
<form
onSubmit={(event) => {
event.preventDefault();
setAddress(input as Address);
}}
Comment on lines +32 to +38
<input
type="text"
value={input}
onChange={(event) => setInput(event.target.value)}
placeholder="0x..."
style={{ width: "28rem" }}
/>
Comment thread packages/ensnode-react/example/package.json
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/ensnode-react-example/src/PrimaryNameView.tsx`:
- Around line 26-40: Validate the input before calling setAddress: replace the
blind type assertion setAddress(input as Address) with a check using viem's
isAddress (available via `@ensnode/ensnode-sdk`) and only call setAddress when
isAddress(input) is true; if invalid, prevent submission and surface feedback to
the user (e.g., set an error state and render a message) so the PrimaryNameView
form's onSubmit handler and related state (input, setInput, setAddress) validate
addresses rather than forwarding arbitrary text to usePrimaryName.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b70c8436-76c7-4a36-9d60-753f45611930

📥 Commits

Reviewing files that changed from the base of the PR and between aa26180 and feba95e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • examples/ensnode-react-example/LICENSE
  • examples/ensnode-react-example/README.md
  • examples/ensnode-react-example/index.html
  • examples/ensnode-react-example/package.json
  • examples/ensnode-react-example/src/App.tsx
  • examples/ensnode-react-example/src/PrimaryNameView.tsx
  • examples/ensnode-react-example/src/main.tsx
  • examples/ensnode-react-example/src/vite-env.d.ts
  • examples/ensnode-react-example/tsconfig.json
  • examples/ensnode-react-example/vite.config.ts

Comment thread examples/ensnode-react-example/src/PrimaryNameView.tsx Outdated
Copy link
Copy Markdown
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.

@notrab Thanks for getting started on this PR. Noted how this was only a draft. Shared some suggestions with feedback.

@@ -0,0 +1,20 @@
# ensnode-react Example
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's super logical to put the ensnode-react-example inside examples/ensnode-react-example/ within the monorepo.

The context we have right now though is an unusual one. This ensnode-react-example app is important for us to ship right now for the purpose of internally refining how ensnode-react works so that we can make a plan for how best to integrate it into enskit. But at this time I don't think we want to be promoting the ensnode-react package. Therefore we also don't want to be promoting any example apps for ensnode-react.

I don't feel good about putting this app inside the root examples directory at this time. Could you please share your advice on a temporary alternative? For example, I'm thinking we stick it under docs temporarily.

These are all temporary steps, but everything we're doing here right now is very important. We need to have a maximally clear narrative to promote for how to integrate with ENSNode and that answer is enskit not ensnode-react. We therefore should take some special actions here now.

We also need to promote enskit integrations now and not later after we figure out how we want to integrate ensnode-react into enskit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@lightwalker-eth I'd suggest we move it from the root examples directory, but place it inside the ensnode-react folder. Having it inside a docs folder just feels weird.

Once merged, and we work to remove ensnode-react, we can move the example to the correct folder once later when we come to delete the package.

wdyt

Comment thread packages/ensnode-react/example/package.json
@@ -0,0 +1,28 @@
{
"name": "@ensnode/ensnode-react-example",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@notrab Can you please take the lead to wire up Vercel so that this example app can automatically get all the Vercel stuff working?


import { usePrimaryName } from "@ensnode/ensnode-react";

const DEFAULT_ADDRESS: Address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // vitalik.eth
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All address values we use in this app should use NormalizedAddress as imported from enssdk. You also need to call a utility function such as asNormalizedAddress on this hardcoded address string.

<form
onSubmit={(event) => {
event.preventDefault();
setAddress(input as Address);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@notrab I need to stop seeing code like this. Ever. It completely goes against our culture as a team and company. I'm going completely crazy at how many times I have to repeat the related ideas. There's so many problems in this 1 line of code I'm not going to spend the time to explain them all over and over again.

<code>ensnode-react</code> Example App
</h1>
<p>
Connected to <code>{ENSNODE_URL}</code>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For this example app to achieve its goals, we need it to implement more critical ideas:

  1. How is it guaranteeing that it was able to successfully connect to the provided ENSNode?
  2. If for some reason it was unable to connect to the provided ENSNode, how is this case being gracefully handled? All the meaningfully distinct edge cases should have explicit handling. I don't want to see just a single "error connecting". I want more detailed error recognition such that you can disambiguate an error connecting (network-level error) from an unsupported ENSNode error (application-level error) where the config returned by the connected ENSNode is either not fetched or deserialized successfully.
  3. How is this app managing the latest indexing status projection / snapshot asynchronously in the background? I want to see a UI component for this in the example app similar to what's implemented for this inside the ENSAdmin UI (the little info icon).
  4. How is this app navigating the vital question of ENS Namespace? There's 2 options for this:
    1. Option 1: The example app hardcodes its own ENS Namespace configuration (ex: mainnet) and then upon connecting to an ENSNode instance, verifies that its config matches the expected namespace. If it doesn't, the example app should refuse the connection.
    2. Option 2: The example app doesn't hardcode any ENS Namespace configuration. Instead, it waits to connect to an ENSNode instance and then makes use of the whatever namespace that ENSNode instance's config is using.

I believe that Option 1 is the direction that 99% of our customers will want to use as there are benefits to knowing the ENS namespace even before a successful connection to ENSNode is established. Therefore this example app should implement Option 1.

That means this example app should also read an ENS namespace as an environment variable that defaults to mainnet.

import { usePrimaryName } from "@ensnode/ensnode-react";

const DEFAULT_ADDRESS: Address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // vitalik.eth
const MAINNET: ChainId = 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This form shouldn't hardcode the chainId this way and also make reference to ENSIP-19 (which is multichain).

We should reference what we've already built for this idea before in ENSAdmin.

CleanShot 2026-05-04 at 14 20 16

@@ -0,0 +1,20 @@
# ensnode-react Example

A minimal React app demonstrating how to use `@ensnode/ensnode-react` to resolve
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please see my other comments with key ideas that should be included here for the key goals of this example app:

  1. The bigger comment I shared several lines above in this file.
  2. The bigger comment I shared in examples/ensnode-react-example/src/App.tsx

I want to see this example app being an absolute A+ flawless bulletproof example of how an example app should manage the connection details with an ENSNode instance. This includes negotiating the connection itself, and the related validation and graceful / specialized error handling for that. It also includes maintaining an ongoing indexing status projection.

@vercel vercel Bot temporarily deployed to Preview – ensnode.io May 11, 2026 07:46 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 11, 2026 07:46 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 11, 2026 07:46 Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/ensnode-react-example/src/config.ts`:
- Line 9: The thrown Error message contains a typo "VITE_ENSNODE_ULR" — update
the string in the throw new Error(...) call to "VITE_ENSNODE_URL" so the message
correctly reflects the environment variable name (change the literal inside the
throw new Error in the validation logic that currently reads VITE_ENSNODE_ULR).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e40c2267-a853-4a10-a4c8-d0d641d63305

📥 Commits

Reviewing files that changed from the base of the PR and between feba95e and bf92c54.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • examples/ensnode-react-example/package.json
  • examples/ensnode-react-example/src/App.tsx
  • examples/ensnode-react-example/src/PrimaryNameView.tsx
  • examples/ensnode-react-example/src/components/IndexingStatusBadge.tsx
  • examples/ensnode-react-example/src/components/RequireActiveConnection.tsx
  • examples/ensnode-react-example/src/config.ts
  • examples/ensnode-react-example/src/lib/classify-connection-error.ts
  • examples/ensnode-react-example/src/vite-env.d.ts

try {
return new URL(value);
} catch {
throw new Error(`VITE_ENSNODE_ULR must be a valid URL. Got: '${value}'.`);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix typo in error message.

The error message says VITE_ENSNODE_ULR but should be VITE_ENSNODE_URL (missing the 'O'). This typo would confuse users trying to debug configuration issues.

🐛 Proposed fix
-    throw new Error(`VITE_ENSNODE_ULR must be a valid URL. Got: '${value}'.`);
+    throw new Error(`VITE_ENSNODE_URL must be a valid URL. Got: '${value}'.`);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
throw new Error(`VITE_ENSNODE_ULR must be a valid URL. Got: '${value}'.`);
throw new Error(`VITE_ENSNODE_URL must be a valid URL. Got: '${value}'.`);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/ensnode-react-example/src/config.ts` at line 9, The thrown Error
message contains a typo "VITE_ENSNODE_ULR" — update the string in the throw new
Error(...) call to "VITE_ENSNODE_URL" so the message correctly reflects the
environment variable name (change the literal inside the throw new Error in the
validation logic that currently reads VITE_ENSNODE_ULR).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 15 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

try {
return new URL(value);
} catch {
throw new Error(`VITE_ENSNODE_ULR must be a valid URL. Got: '${value}'.`);
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 11, 2026 08:02 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensnode.io May 11, 2026 08:02 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 11, 2026 08:02 Inactive
Copilot AI review requested due to automatic review settings May 11, 2026 08:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

accelerate: true,
});

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
Comment on lines +2 to +13
import { ENSNamespaceSchema, makeUrlSchema } from "@ensnode/ensnode-sdk/internal";

// TODO: potential internal to be made public
const DEFAULT_ENSNODE_URL = "https://api.alpha.ensnode.io";

export const ENSNODE_URL: URL = makeUrlSchema("VITE_ENSNODE_URL").parse(
import.meta.env.VITE_ENSNODE_URL ?? DEFAULT_ENSNODE_URL,
);

export const EXPECTED_NAMESPACE: ENSNamespaceId = ENSNamespaceSchema.parse(
import.meta.env.VITE_ENS_NAMESPACE ?? ENSNamespaceIds.Mainnet,
);
Comment on lines +1 to +5
{
"name": "@ensnode/ensnode-react-example",
"private": true,
"version": "0.0.1",
"license": "MIT",
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ensnode-react/example/README.md`:
- Around line 16-20: Update the README example to show overriding both
environment variables used by the example: add a sample command demonstrating
setting VITE_ENSNODE_URL together with VITE_ENS_NAMESPACE (the variable
referenced in the example config). Mention both variables in the same one-line
shell example so users can run something like setting VITE_ENSNODE_URL and
VITE_ENS_NAMESPACE before starting the dev script, and include a brief note that
mismatched namespaces can cause namespace errors.

In `@packages/ensnode-react/example/src/components/RequireActiveConnection.tsx`:
- Around line 9-11: Replace the interface declaration for
RequireActiveConnectionProps with a type alias to follow the TSX guideline:
change "interface RequireActiveConnectionProps { children: ReactNode }" to a
type alias "type RequireActiveConnectionProps = { children: ReactNode }" and
ensure the component still references RequireActiveConnectionProps (e.g., in the
RequireActiveConnection function/component signature) so the prop type is used
exactly once and documented on the type alias.

In `@packages/ensnode-react/example/src/config.ts`:
- Around line 2-8: The example imports makeUrlSchema from the internal
entrypoint which isn't published; update the example to avoid /internal: either
re-export makeUrlSchema from the public SDK entrypoint and import that, or
replace its usage in ENSNODE_URL with a local Zod-based URL validation (e.g.,
use z.string().url() to parse/validate import.meta.env.VITE_ENSNODE_URL ??
DEFAULT_ENSNODE_URL) and remove the internal import; adjust references to
makeUrlSchema and ENSNODE_URL accordingly so the example works for external
consumers.

In `@packages/ensnode-react/example/src/lib/classify-connection-error.ts`:
- Around line 1-27: The declared union type ConnectionFailureKind includes
"unsupported-namespace" but classifyConnectionError never returns it; remove the
unused variant from ConnectionFailureKind so the type matches actual outputs
(leave ConnectionFailure and classifyConnectionError unchanged), and update any
callers/types expecting "unsupported-namespace" accordingly; reference symbols:
ConnectionFailureKind, ConnectionFailure, classifyConnectionError.

In `@packages/ensnode-react/example/src/PrimaryNameView.tsx`:
- Around line 31-34: Replace the interface declaration "interface ChainOption"
with a type alias "type ChainOption = { id: DefaultableChainId; label: string }"
and move any invariant documentation comments (the single-source-of-truth
invariant text) onto that type alias; ensure DefaultableChainId remains
referenced as the id type and remove the now-redundant interface declaration so
the invariant is documented exactly once on the alias.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4f43ce0d-7781-4c4e-b5db-b9f47c977414

📥 Commits

Reviewing files that changed from the base of the PR and between bf92c54 and 2d8f70a.

📒 Files selected for processing (14)
  • packages/ensnode-react/example/LICENSE
  • packages/ensnode-react/example/README.md
  • packages/ensnode-react/example/index.html
  • packages/ensnode-react/example/package.json
  • packages/ensnode-react/example/src/App.tsx
  • packages/ensnode-react/example/src/PrimaryNameView.tsx
  • packages/ensnode-react/example/src/components/IndexingStatusBadge.tsx
  • packages/ensnode-react/example/src/components/RequireActiveConnection.tsx
  • packages/ensnode-react/example/src/config.ts
  • packages/ensnode-react/example/src/lib/classify-connection-error.ts
  • packages/ensnode-react/example/src/main.tsx
  • packages/ensnode-react/example/src/vite-env.d.ts
  • packages/ensnode-react/example/tsconfig.json
  • packages/ensnode-react/example/vite.config.ts

Comment thread packages/ensnode-react/example/README.md Outdated
Comment on lines +9 to +11
interface RequireActiveConnectionProps {
children: ReactNode;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use a type alias for props to match TS/TSX guideline requirements.

Switch this props declaration from interface to type.

Proposed change
-interface RequireActiveConnectionProps {
-  children: ReactNode;
-}
+type RequireActiveConnectionProps = {
+  children: ReactNode;
+};

As per coding guidelines, "**/*.{ts,tsx}: Use type aliases to document invariants; each invariant MUST be documented exactly once on its type alias".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface RequireActiveConnectionProps {
children: ReactNode;
}
type RequireActiveConnectionProps = {
children: ReactNode;
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ensnode-react/example/src/components/RequireActiveConnection.tsx`
around lines 9 - 11, Replace the interface declaration for
RequireActiveConnectionProps with a type alias to follow the TSX guideline:
change "interface RequireActiveConnectionProps { children: ReactNode }" to a
type alias "type RequireActiveConnectionProps = { children: ReactNode }" and
ensure the component still references RequireActiveConnectionProps (e.g., in the
RequireActiveConnection function/component signature) so the prop type is used
exactly once and documented on the type alias.

Comment on lines +2 to +8
import { ENSNamespaceSchema, makeUrlSchema } from "@ensnode/ensnode-sdk/internal";

// TODO: potential internal to be made public
const DEFAULT_ENSNODE_URL = "https://api.alpha.ensnode.io";

export const ENSNODE_URL: URL = makeUrlSchema("VITE_ENSNODE_URL").parse(
import.meta.env.VITE_ENSNODE_URL ?? DEFAULT_ENSNODE_URL,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Is @ensnode/ensnode-sdk/internaldocumented as a stable public import path for external/example apps, and what is the recommended public alternative tomakeUrlSchema?

💡 Result:

I couldn’t find any authoritative documentation (package README/docs, npm entrypoint docs, or repo docs) that explicitly states that @ensnode/ensnode-sdk/internal is a stable, supported public import path for external/example apps. Recommended public alternative to makeUrlSchema: Not enough evidence found. The sources retrieved do not mention makeUrlSchema, nor an exported public replacement for it, so I can’t responsibly name an alternative. What I did find: the package’s public API is documented via the main @ensnode/ensnode-sdk entrypoint usage (e.g., importing ENSNodeClient from “@ensnode/ensnode-sdk”) on npm, but nothing in the retrieved material links that to makeUrlSchema or to an approved public alternative for internal imports. [1][2] If you paste the relevant snippet that uses makeUrlSchema (and the package version you’re targeting), I can pinpoint the correct exported replacement and verify whether an internal path is involved.

Citations:


🏁 Script executed:

# First, find the ensnode-sdk package location and its exports
find . -name "package.json" -path "*ensnode-sdk*" | head -5

Repository: namehash/ensnode

Length of output: 96


🏁 Script executed:

# Look for the SDK structure
fd -t d "ensnode-sdk" | grep -v node_modules

Repository: namehash/ensnode

Length of output: 82


🏁 Script executed:

# Check the main index/exports of ensnode-sdk
git ls-files | grep -E "(ensnode-sdk|@ensnode)" | grep -v node_modules | head -20

Repository: namehash/ensnode

Length of output: 982


🏁 Script executed:

# Search for makeUrlSchema definition and all its usages
rg "makeUrlSchema" --no-heading -B 2 -A 2

Repository: namehash/ensnode

Length of output: 6191


🏁 Script executed:

cat packages/ensnode-sdk/package.json

Repository: namehash/ensnode

Length of output: 1702


🏁 Script executed:

# Check what's exported from the main index
ls -la packages/ensnode-sdk/src/index.ts 2>/dev/null || echo "Not found"
cat packages/ensnode-sdk/src/index.ts 2>/dev/null || echo "File does not exist"

Repository: namehash/ensnode

Length of output: 1654


🏁 Script executed:

# Look for internal/index.ts
ls -la packages/ensnode-sdk/src/internal/ 2>/dev/null || echo "Internal dir not found"
find packages/ensnode-sdk/src -name "internal*" -o -name "index.ts" | head -10

Repository: namehash/ensnode

Length of output: 580


🏁 Script executed:

cat packages/ensnode-sdk/src/internal.ts

Repository: namehash/ensnode

Length of output: 2542


🏁 Script executed:

# Also check the zod-schemas file to understand makeUrlSchema better
head -50 packages/ensnode-sdk/src/shared/zod-schemas.ts

Repository: namehash/ensnode

Length of output: 1314


Remove /internal dependency from example code; makeUrlSchema is not available to external SDK consumers.

The /internal entrypoint is explicitly designed for monorepo-only use and is not included in the published npm package. External developers cannot replicate this example. Either:

  1. Export makeUrlSchema from the public SDK entrypoint (or a dedicated public utilities export), or
  2. Implement URL validation locally in the example using plain Zod (e.g., z.string().url())

The TODO comment acknowledges this is a known issue requiring resolution before shipping.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ensnode-react/example/src/config.ts` around lines 2 - 8, The example
imports makeUrlSchema from the internal entrypoint which isn't published; update
the example to avoid /internal: either re-export makeUrlSchema from the public
SDK entrypoint and import that, or replace its usage in ENSNODE_URL with a local
Zod-based URL validation (e.g., use z.string().url() to parse/validate
import.meta.env.VITE_ENSNODE_URL ?? DEFAULT_ENSNODE_URL) and remove the internal
import; adjust references to makeUrlSchema and ENSNODE_URL accordingly so the
example works for external consumers.

Comment on lines +1 to +27
export type ConnectionFailureKind = "network" | "application" | "unsupported-namespace";

export interface ConnectionFailure {
kind: ConnectionFailureKind;
message: string;
}

// TODO: abstract out
export function classifyConnectionError(error: unknown): ConnectionFailure {
if (error instanceof TypeError) {
return {
kind: "network",
message:
"Could not reach the ENSNode instance. " +
"Check the URL, your network, and that the server allows CORS from this origin.",
};
}

if (error instanceof Error) {
return { kind: "application", message: error.message };
}

return {
kind: "application",
message: "Unknown error connecting to ENSNode.",
};
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Align ConnectionFailureKind with actual classifier outputs.

"unsupported-namespace" is declared but never returned by classifyConnectionError, which makes the contract misleading. Either add a classification path for it or remove it from this type.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ensnode-react/example/src/lib/classify-connection-error.ts` around
lines 1 - 27, The declared union type ConnectionFailureKind includes
"unsupported-namespace" but classifyConnectionError never returns it; remove the
unused variant from ConnectionFailureKind so the type matches actual outputs
(leave ConnectionFailure and classifyConnectionError unchanged), and update any
callers/types expecting "unsupported-namespace" accordingly; reference symbols:
ConnectionFailureKind, ConnectionFailure, classifyConnectionError.

Comment on lines +31 to +34
interface ChainOption {
id: DefaultableChainId;
label: string;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Replace interface ChainOption with a type alias and document invariant once.

This should use a type alias per repo TS/TSX rules; keep any invariant documentation on that alias only.

Proposed change
-interface ChainOption {
-  id: DefaultableChainId;
-  label: string;
-}
+type ChainOption = {
+  /** ENSIP-19 chain selector value (defaultable or concrete chain id). */
+  id: DefaultableChainId;
+  label: string;
+};

As per coding guidelines, "**/*.{ts,tsx}: Use type aliases to document invariants; each invariant MUST be documented exactly once on its type alias".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface ChainOption {
id: DefaultableChainId;
label: string;
}
type ChainOption = {
/** ENSIP-19 chain selector value (defaultable or concrete chain id). */
id: DefaultableChainId;
label: string;
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ensnode-react/example/src/PrimaryNameView.tsx` around lines 31 - 34,
Replace the interface declaration "interface ChainOption" with a type alias
"type ChainOption = { id: DefaultableChainId; label: string }" and move any
invariant documentation comments (the single-source-of-truth invariant text)
onto that type alias; ensure DefaultableChainId remains referenced as the id
type and remove the now-redundant interface declaration so the invariant is
documented exactly once on the alias.

Comment thread pnpm-workspace.yaml
- examples/*
- packages/*
# TODO: remove once we can move into `examples` folder enskit-example
- packages/ensnode-react/example
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No way around this unless we changed packages/* to packages/**, but I preferred keeping the blast radius here small.

2. **Disambiguated error handling.** Connection failures are classified as `network`
(fetch / DNS / CORS), `application` (bad response, or `responseCode === "error"`),
or `unsupported-namespace`. See
[`classify-connection-error.ts`](./src/lib/classify-connection-error.ts) and
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

need to better format these, leave it with me.

Comment thread packages/ensnode-react/example/README.md Outdated
Copilot AI review requested due to automatic review settings May 12, 2026 15:43
@vercel vercel Bot temporarily deployed to Preview – ensnode.io May 12, 2026 15:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 12, 2026 15:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 12, 2026 15:43 Inactive
Comment thread packages/ensnode-react/example/README.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 16 changed files in this pull request and generated 8 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment on lines +80 to +82
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
try {
@@ -0,0 +1,48 @@
# `ensnode-react` Example

> [!IMPORTANT] > **For React integrations with ENSNode, use [`enskit`](../../enskit), not `ensnode-react`.**
> [!IMPORTANT] > **For React integrations with ENSNode, use [`enskit`](../../enskit), not `ensnode-react`.**
> See the [`enskit` React example](../../../examples/enskit-react-example).
>
> This app is internaldocumentation for refining `ensnode-react` before its functionality
Comment on lines +4 to +9
// TODO: potential internal to be made public
const DEFAULT_ENSNODE_URL = "https://api.alpha.green.ensnode.io";

export const ENSNODE_URL: URL = makeUrlSchema("VITE_ENSNODE_URL").parse(
import.meta.env.VITE_ENSNODE_URL ?? DEFAULT_ENSNODE_URL,
);
Comment on lines +2 to +11
import { ENSNamespaceSchema, makeUrlSchema } from "@ensnode/ensnode-sdk/internal";

// TODO: potential internal to be made public
const DEFAULT_ENSNODE_URL = "https://api.alpha.green.ensnode.io";

export const ENSNODE_URL: URL = makeUrlSchema("VITE_ENSNODE_URL").parse(
import.meta.env.VITE_ENSNODE_URL ?? DEFAULT_ENSNODE_URL,
);

export const EXPECTED_NAMESPACE: ENSNamespaceId = ENSNamespaceSchema.parse(
Comment thread pnpm-workspace.yaml
Comment on lines +6 to +7
# TODO: remove once we can move into `examples` folder enskit-example
- packages/ensnode-react/example
Comment thread pnpm-workspace.yaml
- docs/*
- examples/*
- packages/*
# TODO: remove once we can move into `examples` folder enskit-example
Comment on lines +1 to +10
export type ConnectionFailureKind = "network" | "application" | "unsupported-namespace";

export interface ConnectionFailure {
kind: ConnectionFailureKind;
message: string;
}

// TODO: abstract out
export function classifyConnectionError(error: unknown): ConnectionFailure {
if (error instanceof TypeError) {
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.

3 participants