Skip to content

WIP: Merge ENSApi /api/config endpoint into /api/indexing-status endpoint#1671

Draft
tk-o wants to merge 19 commits intomainfrom
ensapi-merge-config-with-indexing-status
Draft

WIP: Merge ENSApi /api/config endpoint into /api/indexing-status endpoint#1671
tk-o wants to merge 19 commits intomainfrom
ensapi-merge-config-with-indexing-status

Conversation

@tk-o
Copy link
Contributor

@tk-o tk-o commented Feb 24, 2026

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • Merges ENSApi /api/config endpoint into /api/indexing-status endpoint
  • Updates ENSNode SDK data model for ENSApi Indexing Status API
    • Follows up with updates in ENSNode React o use the updated data model
    • Follows up with updates in ENSAdmin to apply data model changes from ENSNode SDK and ENSNode React
  • Updates ENSAdmin to reference new data model.

Why

  • We need to consolidate ENSApi endpoints to simplify client operations. Clients shouldn't be forced to fetch ENSApi Config and Indexing Status independently. This makes handling UI variants more complex. We aim for simplicity.

Testing

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

Notes for Reviewer (Optional)


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)

tk-o added 4 commits February 24, 2026 10:24
Include `config` field of `EnsApiPublicConfig` type.
Merge `/api/config` endpoint into `/api/indexing-status`. The former endpoint got deleted, while the later includes the `config: EnsApiPublicConfig` object in the response.
Use `EnsIndexerClient` to fetch indexing status.
New names will match `EnsApiProvider*` pattern.
Copilot AI review requested due to automatic review settings February 24, 2026 10:07
@vercel
Copy link
Contributor

vercel bot commented Feb 24, 2026

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

Project Deployment Actions Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Mar 2, 2026 5:39pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
ensnode.io Skipped Skipped Mar 2, 2026 5:39pm
ensrainbow.io Skipped Skipped Mar 2, 2026 5:39pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Replaces ENSNode-centric provider/hooks with EnsApi variants, adds useEnsApiConfig, embeds public config into indexing-status responses, renames clients/types to EnsApi/EnsIndexer, and updates hooks, serializers, schemas, mocks, provider/context, and UI consumers accordingly. (50 words)

Changes

Cohort / File(s) Summary
New config hook
apps/ensadmin/src/components/config/useEnsApiConfig.ts
Adds useEnsApiConfig that composes provider options and useIndexingStatusWithSwr, exposing the Ens API public config via a react-query result enabled when indexing status is ready.
Indexing-status SWR & cache
apps/ensadmin/src/components/indexing-status/use-indexing-status-with-swr.ts, apps/ensapi/src/cache/indexing-status.cache.ts, apps/ensapi/src/handlers/ensnode-api.ts
Switches to EnsApi* request/response types; caches composite { crossChainIndexingStatusSnapshot, config }; indexing-status Ok responses now include config; client renamed to EnsIndexerClient.
Provider / Context / Types rename
packages/ensnode-react/src/provider.tsx, packages/ensnode-react/src/context.ts, packages/ensnode-react/src/types.ts, packages/ensnode-react/README.md
Renames ENSNode* → EnsApi* (Provider, Context, ProviderOptions), replaces config with options, updates default client/options to EnsApiClient, and updates docs/examples.
Hooks & query builders migration
packages/ensnode-react/src/hooks/*, packages/ensnode-react/src/utils/query.ts
Removes legacy useENSNodeConfig/useENSNodeSDKConfig; adds useEnsApiProviderOptions; updates many hooks and query builders to accept EnsApiProviderOptions and use EnsApiClient; removes createConfigQueryOptions.
SDK indexing-status types & serialization
packages/ensnode-sdk/src/ensapi/api/indexing-status/*, packages/ensnode-sdk/src/ensapi/config/deserialize.ts
Extends EnsApiIndexingStatusResponseOk with config: EnsApiPublicConfig, updates (de)serialization, zod schemas, serialized types, and exports buildUnvalidatedEnsApiPublicConfig.
UI consumers & admin changes
apps/ensadmin/src/components/connection/cards/ensnode-info.tsx, apps/ensadmin/src/components/connections/require-active-connection.tsx, apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx, apps/ensadmin/src/components/layout-wrapper.tsx
Consumers switched to useEnsApiConfig and SelectedEnsApiProvider; updated prop types to EnsApiPublicConfig, adjusted loading/error flows, and improved invalid-connection rendering.
Registrar / namespace / active hooks
apps/ensadmin/src/components/registrar-actions/use-stateful-fetch-registrar-actions.ts, apps/ensadmin/src/hooks/active/use-active-connection.tsx, apps/ensadmin/src/hooks/async/use-namespace.ts, packages/ensnode-react/src/hooks/useResolvedIdentity.ts, packages/namehash-ui/src/components/identity/ResolveAndDisplayIdentity.tsx
Removed dependency on ENSNode config; now read namespace/config from indexing-status config; useResolvedIdentity accepts namespace parameter; mock callers pass namespaceId.
Mocks & tests updated
apps/ensadmin/src/app/mock/*, packages/ensnode-sdk/src/ensapi/client.test.ts
Mocks and tests updated to include serialized config in indexing-status responses and to return full EnsApiIndexingStatusResponseOk objects.
Exports & cleanup
packages/ensnode-react/src/hooks/index.ts, packages/ensnode-react/src/hooks/useENSNodeConfig.ts (removed), packages/ensnode-react/src/hooks/useENSNodeSDKConfig.ts (removed), packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts
Removed legacy hook files/exports, added useEnsApiProviderOptions, updated re-exports.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(200,220,255,0.5)
    participant UI as UI Component
    participant Hook as useEnsApiConfig
    participant Provider as EnsApiProvider
    participant SWR as useIndexingStatusWithSwr
    participant API as EnsIndexer API
  end

  UI->>Hook: call useEnsApiConfig()
  Hook->>Provider: resolve provider options (useEnsApiProviderOptions)
  Hook->>SWR: subscribe (enabled when indexing status is success)
  SWR->>API: fetch /indexing-status
  API-->>SWR: respond { realtimeProjection, config }
  SWR-->>Hook: provide indexingStatus.data (includes config)
  Hook-->>UI: return query result containing ensApiPublicConfig
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Suggested labels

ensnode-sdk

Poem

🐰
I hopped through contexts, options in paw,
Swapped ENSNode roots for EnsApi law,
Config tucked inside the indexing tune,
Providers renamed — code hops to the moon,
A cheerful rabbit dances: patch — hurrah!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description follows the template with Summary, Why, Testing, and Notes sections. However, the Testing section is incomplete (contains only placeholder text). Complete the Testing section by describing how this change was tested or explaining why testing was not performed.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: merging ENSApi endpoints to consolidate config into indexing-status.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ensapi-merge-config-with-indexing-status

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
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

Consolidates ENSApi metadata fetching by embedding the former /api/config payload into the /api/indexing-status response, and propagates the updated data model through the ENSNode SDK, @ensnode/ensnode-react, and ENSAdmin consumers.

Changes:

  • ENSApi /indexing-status now returns { realtimeProjection, config } and the standalone /config route is removed.
  • ENSNode SDK updates indexing-status response types + (de)serialization + Zod schemas to include config.
  • ENSNode React + ENSAdmin update provider/options naming and migrate config consumption to come from indexing-status.

Reviewed changes

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

Show a summary per file
File Description
packages/namehash-ui/src/components/identity/ResolveAndDisplayIdentity.tsx Passes namespace explicitly into useResolvedIdentity.
packages/ensnode-sdk/src/ensapi/config/deserialize.ts Exposes config unvalidated builder for reuse by indexing-status deserializer.
packages/ensnode-sdk/src/ensapi/api/indexing-status/zod-schemas.ts Adds config to OK schema + serialized OK schema.
packages/ensnode-sdk/src/ensapi/api/indexing-status/serialized-response.ts Adds serialized config to serialized OK response type.
packages/ensnode-sdk/src/ensapi/api/indexing-status/serialize.ts Serializes config into indexing-status OK responses.
packages/ensnode-sdk/src/ensapi/api/indexing-status/response.ts Adds config: EnsApiPublicConfig to indexing-status OK response type.
packages/ensnode-sdk/src/ensapi/api/indexing-status/deserialize.ts Deserializes config from the indexing-status response.
packages/ensnode-react/src/utils/query.ts Switches to EnsApiClient + removes separate config query helpers/keys.
packages/ensnode-react/src/types.ts Renames provider config types to EnsApi-oriented types and adds namespace param to resolved-identity hook params.
packages/ensnode-react/src/provider.tsx Renames provider to EnsApiProvider and helper to createEnsApiOptions.
packages/ensnode-react/src/hooks/useResolvedIdentity.ts Stops deriving namespace from config fetch; accepts namespace directly.
packages/ensnode-react/src/hooks/useRegistrarActions.ts Migrates hooks to use provider “options” via useEnsApiProviderOptions.
packages/ensnode-react/src/hooks/useRecords.ts Migrates hooks to use provider “options” via useEnsApiProviderOptions.
packages/ensnode-react/src/hooks/usePrimaryNames.ts Migrates hooks to use provider “options” via useEnsApiProviderOptions.
packages/ensnode-react/src/hooks/usePrimaryName.ts Migrates hooks to use provider “options” via useEnsApiProviderOptions.
packages/ensnode-react/src/hooks/useNameTokens.ts Migrates hooks to use provider “options” via useEnsApiProviderOptions.
packages/ensnode-react/src/hooks/useIndexingStatus.ts Updates request/response types to EnsApi-prefixed indexing-status types.
packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts New hook replacing useENSNodeSDKConfig for resolving provider options.
packages/ensnode-react/src/hooks/useENSNodeSDKConfig.ts Removed legacy config hook.
packages/ensnode-react/src/hooks/useENSNodeConfig.ts Removed legacy config-fetch hook.
packages/ensnode-react/src/hooks/index.ts Updates public hook exports to new options hook.
packages/ensnode-react/src/context.ts Renames context to EnsApiContext and updates types.
packages/ensnode-react/README.md Updates docs/examples for new provider/options naming (incomplete).
apps/ensapi/src/handlers/ensnode-api.ts Removes /config endpoint and injects config into /indexing-status responses.
apps/ensapi/src/cache/indexing-status.cache.ts Updates ENSApi’s ENSIndexer client usage/type names.
apps/ensadmin/src/hooks/async/use-namespace.ts Switches namespace derivation to new ENSApi config hook.
apps/ensadmin/src/hooks/active/use-active-connection.tsx Uses new ENSApi config hook for active connection invariant.
apps/ensadmin/src/components/registrar-actions/use-stateful-fetch-registrar-actions.ts Uses indexing-status’ embedded config to gate registrar actions support.
apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx Migrates selected connection provider to EnsApiProvider + createEnsApiOptions.
apps/ensadmin/src/components/layout-wrapper.tsx Updates layout to use renamed selected provider component.
apps/ensadmin/src/components/indexing-status/use-indexing-status-with-swr.ts SWR caching updated to cache both snapshot + config and reproject over time.
apps/ensadmin/src/components/connections/require-active-connection.tsx Uses ENSApi config hook and updates user-facing error copy.
apps/ensadmin/src/components/connection/cards/ensnode-info.tsx Migrates config display to new ENSApi config hook and updated types.
apps/ensadmin/src/components/config/useEnsApiConfig.ts New hook to expose config from indexing-status-derived data.
Comments suppressed due to low confidence (2)

packages/ensnode-sdk/src/ensapi/api/indexing-status/zod-schemas.ts:17

  • The type imports from ./response and ./serialized-response are unused in this module (they're only referenced in JSDoc). With Biome's recommended rules enabled, this will fail lint due to unused imports; remove these imports or use them in code (e.g., via satisfies where appropriate).
    apps/ensapi/src/handlers/ensnode-api.ts:29
  • This route now returns both indexing status and the ENSApi public config (via the new config field), but the OpenAPI summary/description still describe it as only returning an indexing status snapshot from ENSIndexer. Update these strings to reflect the new combined payload so generated docs stay accurate.
  describeRoute({
    tags: ["Meta"],
    summary: "Get ENSIndexer Indexing Status",
    description: "Returns the indexing status snapshot most recently captured from ENSIndexer",
    responses: {

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

return useQuery({
enabled: indexingStatus.isSuccess,
queryKey: ["swr", ensApiProviderOptions.client.url.href, "config"],
queryFn: async () => indexingStatus.data?.config, // enabled flag ensures this is only called when indexingStatus.data is available
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

queryFn can currently return undefined because of the optional chain (indexingStatus.data?.config). Since enabled gates on indexingStatus.isSuccess, you can (and should) return indexingStatus.data.config directly (or throw if unexpectedly missing) to keep the query typed as always returning a config object.

Suggested change
queryFn: async () => indexingStatus.data?.config, // enabled flag ensures this is only called when indexingStatus.data is available
queryFn: async () => {
if (!indexingStatus.data || !indexingStatus.data.config) {
throw new Error("Indexing status config is unavailable despite isSuccess being true.");
}
return indexingStatus.data.config;
},

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestion:

The mock page creates an IndexingStatusResponseOk object without the required config property, causing a TypeScript build error

Fix on Vercel

Copy link
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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (9)
packages/ensnode-sdk/src/ensapi/config/deserialize.ts (1)

12-19: ⚠️ Potential issue | 🟡 Minor

Remove redundant JSDoc return tag.

The summary already covers the return value.

🧹 Suggested change
- * `@return` An unvalidated {`@link` EnsApiPublicConfig} object.

As per coding guidelines: Do not add JSDoc @returns tags that merely restate the method summary; remove redundancy during PR review.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-sdk/src/ensapi/config/deserialize.ts` around lines 12 - 19,
Remove the redundant JSDoc `@return/`@returns tag from the comment block above
buildUnvalidatedEnsApiPublicConfig; keep the existing summary and `@param`
description but delete the line that restates the return value so the
documentation is not duplicative.
packages/ensnode-react/README.md (2)

127-143: ⚠️ Potential issue | 🟡 Minor

Update API reference to use options and EnsApi types.

The interface and props list still reference config/ENSNodeConfig, which no longer match the EnsApiProvider surface.

✏️ Suggested doc update
- The provider component that supplies ENSNode configuration to all child components.
+ The provider component that supplies EnsApi provider options to all child components.

 interface EnsApiProviderProps {
-  config: ENSNodeConfig;
+  options: EnsApiProviderOptions;
   queryClient?: QueryClient;
   queryClientOptions?: QueryClientOptions;
 }

- `config`: ENSNode configuration object
+ `options`: EnsApi provider options
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/README.md` around lines 127 - 143, Update the
EnsApiProvider API docs to match the new surface: replace references to the old
EnsApiProviderProps/config/ENSNodeConfig with the current props using options
and EnsApi types; specifically, document the props as something like options:
EnsApiOptions (or options) and api?: EnsApi (or api) / queryClient? /
queryClientOptions? as applicable to the actual component signature, and update
the Props list bullets to reference options and EnsApi types instead of
config/ENSNodeConfig so the README aligns with the EnsApiProvider
implementation.

233-251: ⚠️ Potential issue | 🟡 Minor

Advanced usage snippets still pass config; switch to options.

These examples should mirror the new provider API.

✏️ Suggested doc update
-<EnsApiProvider
-  config={config}
+<EnsApiProvider
+  options={options}
   queryClientOptions={{
     defaultOptions: {
       queries: {
         staleTime: 1000 * 60 * 10, // 10 minutes
         gcTime: 1000 * 60 * 60, // 1 hour
         retry: 5,
       },
     },
   }}
 >
   <App />
 </EnsApiProvider>

 ...

-  <EnsApiProvider config={config} queryClient={queryClient}>
+  <EnsApiProvider options={options} queryClient={queryClient}>
     <App />
   </EnsApiProvider>

Also applies to: 271-274

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/README.md` around lines 233 - 251, The README examples
use the old prop name `config` for EnsApiProvider; update them to use the new
`options` prop instead. Find the EnsApiProvider usage examples (including the
snippet that mirrors advanced usage and the later similar snippet) and replace
`config={config}` with `options={options}` (and update any variable names or
surrounding text to match `options` if necessary) so the docs reflect the new
provider API.
packages/ensnode-react/src/hooks/usePrimaryName.ts (1)

15-16: ⚠️ Potential issue | 🟡 Minor

Remove redundant JSDoc return tag.

The summary already explains what the hook returns.

🧹 Suggested change
- * `@returns` Query result with resolved primary name

As per coding guidelines: Do not add JSDoc @returns tags that merely restate the method summary; remove redundancy during PR review.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/hooks/usePrimaryName.ts` around lines 15 - 16, The
JSDoc for the usePrimaryName hook contains a redundant `@returns` tag that
restates the summary; edit the JSDoc above the usePrimaryName function in
packages/ensnode-react/src/hooks/usePrimaryName.ts and remove the `@returns` line
so only the descriptive summary remains, leaving parameter tags (e.g., `@param`
parameters) intact.
packages/ensnode-react/src/hooks/useResolvedIdentity.ts (1)

26-27: ⚠️ Potential issue | 🟡 Minor

Align JSDoc param name with namespace.

The docs still reference namespaceId.

✏️ Suggested doc fix
- * `@param` parameters.namespaceId - The {`@link` ENSNamespaceId} that `identity.chainId` should be interpreted
+ * `@param` parameters.namespace - The {`@link` ENSNamespaceId} that `identity.chainId` should be interpreted

Also applies to: 41-41

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/hooks/useResolvedIdentity.ts` around lines 26 -
27, Update the JSDoc for useResolvedIdentity to use the correct parameter name
"namespace" (not "namespaceId"); locate the docblocks mentioning
"parameters.namespaceId" (around the comment for
getResolvePrimaryNameChainIdParam usage) and replace them with
"parameters.namespace" so the param name aligns with the actual function
signature and do the same for the second occurrence referenced at line ~41.
packages/ensnode-react/src/provider.tsx (1)

97-106: 🧹 Nitpick | 🔵 Trivial

Minor: EnsApiClient.defaultOptions() called twice.

Both the URL fallback and the spread invoke defaultOptions(). Consider calling it once:

♻️ Suggested refactor
 export function createEnsApiOptions(options?: { url?: string | URL }): EnsApiProviderOptions {
+  const defaults = EnsApiClient.defaultOptions();
-  const url = options?.url ? new URL(options.url) : EnsApiClient.defaultOptions().url;
+  const url = options?.url ? new URL(options.url) : defaults.url;

   return {
     client: {
-      ...EnsApiClient.defaultOptions(),
+      ...defaults,
       url,
     },
   };
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/provider.tsx` around lines 97 - 106,
createEnsApiOptions calls EnsApiClient.defaultOptions() twice; assign the result
to a local variable (e.g., defaults = EnsApiClient.defaultOptions()), use
defaults.url as the fallback when building url (options?.url ? new
URL(options.url) : defaults.url), and then spread defaults into the returned
client ({ ...defaults, url }) so defaultOptions is invoked only once; update the
function createEnsApiOptions accordingly.
packages/ensnode-sdk/src/ensapi/api/indexing-status/deserialize.ts (1)

27-33: ⚠️ Potential issue | 🟠 Major

Ok responses missing config will now fail deserialization.

Test fixtures in client.test.ts (lines 142–143 and 200–201) omit the config field despite being typed as SerializedEnsApiIndexingStatusResponseOk. Since the serialized schema requires config, deserializing these fixtures will throw an error. Either add config to all existing Ok response payloads/fixtures, or make the field optional in the serialized schema if backward compatibility is required.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-sdk/src/ensapi/api/indexing-status/deserialize.ts` around
lines 27 - 33, The deserializer assumes serializedResponse.config always exists
and will throw for existing test fixtures missing config (type
SerializedEnsApiIndexingStatusResponseOk). Fix by making config optional at
deserialization: in deserialize.ts check for serializedResponse.config and only
call buildUnvalidatedEnsApiPublicConfig when present (e.g., config:
serializedResponse.config ?
buildUnvalidatedEnsApiPublicConfig(serializedResponse.config) : undefined), and
update the serialized type (SerializedEnsApiIndexingStatusResponseOk) or schema
to mark config as optional for backward compatibility; alternatively, add the
missing config objects to the test fixtures in client.test.ts to match the
required schema.
apps/ensadmin/src/hooks/active/use-active-connection.tsx (1)

5-17: ⚠️ Potential issue | 🟡 Minor

Stale @returns qualifier after the hook migration.

useEnsApiConfig().data is EnsApiPublicConfig — which includes version and theGraphFallback in addition to ensIndexerPublicConfig. The parenthetical (currently only the ENSIndexer config) is now inaccurate and should be updated (or removed per the guideline against redundant @returns tags).

✏️ Suggested update
- * `@returns` The active ENSNode connection (currently only the ENSIndexer config)
+ * `@returns` The active ENSApi public configuration (version, theGraphFallback, ensIndexerPublicConfig)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensadmin/src/hooks/active/use-active-connection.tsx` around lines 5 -
17, The JSDoc `@returns` is stale: update the comment for the hook
(use-active-connection / the hook that returns useEnsApiConfig().data) so it
accurately describes that the hook returns an EnsApiPublicConfig (including
version and theGraphFallback as well as ensIndexerPublicConfig) instead of
saying "(currently only the ENSIndexer config)"; either remove the parenthetical
or replace it with a concise phrase like "includes version, theGraphFallback,
and ensIndexerPublicConfig" and ensure the `@returns` line matches the actual
returned type from useEnsApiConfig().data.
packages/ensnode-react/src/utils/query.ts (1)

69-165: 🧹 Nitpick | 🔵 Trivial

Optional: rename config parameter to options across all query builder functions.

The parameter was named config when the type was ENSNodeSDKConfig, but now it's EnsApiProviderOptions. Keeping the old name is mildly confusing — hook callers consistently name the same value providerOptions, while the builders call it config. Renaming to options here would close that gap.

♻️ Example diff (applies to all seven builder functions)
 export function createRecordsQueryOptions<SELECTION extends ResolverRecordsSelection>(
-  config: EnsApiProviderOptions,
+  options: EnsApiProviderOptions,
   args: ResolveRecordsRequest<SELECTION>,
 ) {
   return {
     enabled: true,
-    queryKey: queryKeys.records(config.client.url.href, args),
+    queryKey: queryKeys.records(options.client.url.href, args),
     queryFn: async () => {
-      const client = new EnsApiClient(config.client);
+      const client = new EnsApiClient(options.client);
       return client.resolveRecords(args.name, args.selection, args);
     },
   };
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/utils/query.ts` around lines 69 - 165, Rename the
parameter named config to options in all query builder functions
(createRecordsQueryOptions, createPrimaryNameQueryOptions,
createPrimaryNamesQueryOptions, createIndexingStatusQueryOptions,
createRegistrarActionsQueryOptions, createNameTokensQueryOptions), update its
type to EnsApiProviderOptions where declared, and replace all usages of config.*
with options.* (e.g., queryKeys.*(options.client.url.href, ...), new
EnsApiClient(options.client), etc.) so the parameter name aligns with callers
using providerOptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx`:
- Around line 24-27: The options object passed to EnsApiProvider is recreated on
every render because createEnsApiOptions(...) is called directly; wrap the call
in React's useMemo (in the SelectedEnsNodeProvider component) keyed on
selectedConnection.validatedSelectedConnection.url so the options object is
stable and the EnsApiInternalProvider's useMemo can work as intended; ensure you
import useMemo and use the memoized value (options) when rendering
<EnsApiProvider options={options}>{children}</EnsApiProvider>.

In `@packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts`:
- Around line 8-13: Remove the redundant/misleading JSDoc `@returns` tag from the
useEnsApiProviderOptions hook comment block; update the JSDoc above function
useEnsApiProviderOptions to keep the summary and `@param/`@throws if needed but
delete the `@returns` line (which redundantly repeats the summary and references
ENSNode) so the documentation is concise and accurate.

In `@packages/ensnode-react/src/hooks/useRecords.ts`:
- Around line 56-57: The hook useRecords uses the variable name _config for the
result of useEnsApiProviderOptions, which is inconsistent with sibling hooks
usePrimaryNames and useRegistrarActions that name this providerOptions; rename
_config to providerOptions in useRecords and update all its usages (the variable
returned from useEnsApiProviderOptions and any subsequent references) so the
hook consistently uses providerOptions like the others.

In `@packages/ensnode-react/src/provider.tsx`:
- Around line 36-37: The useMemo call in provider.tsx (const memoizedOptions =
useMemo(() => options, [options])) is a no-op because it only tracks the object
reference; fix by making the memo depend on stable primitive values or move the
memoization upstream in SelectedEnsApiProvider: either compute memoizedOptions
from the specific option fields (e.g., name, url, networkId) so useMemo
stabilizes on primitives, or in SelectedEnsApiProvider wrap
createEnsApiOptions(...) in useMemo with a dependency array of the underlying
primitive inputs passed to createEnsApiOptions; update any references to
memoizedOptions accordingly.

In `@packages/ensnode-react/src/types.ts`:
- Around line 17-23: Update the outdated JSDoc comments in this file to
reference the renamed symbols (EnsApi/options) instead of ENSNode/config: change
the top comment for the EnsApiProviderOptions interface to mention
EnsApi/options and update the inline comment for the client property to
reference EnsApiClientOptions/EnsApi options; also make the same updates for the
similar comments around lines 33-38 that reference the old ENSNode/config naming
so all documentation matches the renamed types.

In `@packages/ensnode-sdk/src/ensapi/api/indexing-status/zod-schemas.ts`:
- Around line 64-68: The serialized Ok response schema currently uses z.object
which allows unknown keys; make it consistent with
makeEnsApiIndexingStatusResponseOkSchema and the error schema by changing
z.object({...}) to z.strictObject({...}) around the response (or, if the
relaxation is intentional, add a clarifying comment explaining why extra keys
must be allowed), and ensure the same pattern is applied where
makeSerializedRealtimeIndexingStatusProjectionSchema and
makeSerializedEnsApiPublicConfigSchema are composed so unknown keys are rejected
unless explicitly intended.

---

Outside diff comments:
In `@apps/ensadmin/src/hooks/active/use-active-connection.tsx`:
- Around line 5-17: The JSDoc `@returns` is stale: update the comment for the hook
(use-active-connection / the hook that returns useEnsApiConfig().data) so it
accurately describes that the hook returns an EnsApiPublicConfig (including
version and theGraphFallback as well as ensIndexerPublicConfig) instead of
saying "(currently only the ENSIndexer config)"; either remove the parenthetical
or replace it with a concise phrase like "includes version, theGraphFallback,
and ensIndexerPublicConfig" and ensure the `@returns` line matches the actual
returned type from useEnsApiConfig().data.

In `@packages/ensnode-react/README.md`:
- Around line 127-143: Update the EnsApiProvider API docs to match the new
surface: replace references to the old EnsApiProviderProps/config/ENSNodeConfig
with the current props using options and EnsApi types; specifically, document
the props as something like options: EnsApiOptions (or options) and api?: EnsApi
(or api) / queryClient? / queryClientOptions? as applicable to the actual
component signature, and update the Props list bullets to reference options and
EnsApi types instead of config/ENSNodeConfig so the README aligns with the
EnsApiProvider implementation.
- Around line 233-251: The README examples use the old prop name `config` for
EnsApiProvider; update them to use the new `options` prop instead. Find the
EnsApiProvider usage examples (including the snippet that mirrors advanced usage
and the later similar snippet) and replace `config={config}` with
`options={options}` (and update any variable names or surrounding text to match
`options` if necessary) so the docs reflect the new provider API.

In `@packages/ensnode-react/src/hooks/usePrimaryName.ts`:
- Around line 15-16: The JSDoc for the usePrimaryName hook contains a redundant
`@returns` tag that restates the summary; edit the JSDoc above the usePrimaryName
function in packages/ensnode-react/src/hooks/usePrimaryName.ts and remove the
`@returns` line so only the descriptive summary remains, leaving parameter tags
(e.g., `@param` parameters) intact.

In `@packages/ensnode-react/src/hooks/useResolvedIdentity.ts`:
- Around line 26-27: Update the JSDoc for useResolvedIdentity to use the correct
parameter name "namespace" (not "namespaceId"); locate the docblocks mentioning
"parameters.namespaceId" (around the comment for
getResolvePrimaryNameChainIdParam usage) and replace them with
"parameters.namespace" so the param name aligns with the actual function
signature and do the same for the second occurrence referenced at line ~41.

In `@packages/ensnode-react/src/provider.tsx`:
- Around line 97-106: createEnsApiOptions calls EnsApiClient.defaultOptions()
twice; assign the result to a local variable (e.g., defaults =
EnsApiClient.defaultOptions()), use defaults.url as the fallback when building
url (options?.url ? new URL(options.url) : defaults.url), and then spread
defaults into the returned client ({ ...defaults, url }) so defaultOptions is
invoked only once; update the function createEnsApiOptions accordingly.

In `@packages/ensnode-react/src/utils/query.ts`:
- Around line 69-165: Rename the parameter named config to options in all query
builder functions (createRecordsQueryOptions, createPrimaryNameQueryOptions,
createPrimaryNamesQueryOptions, createIndexingStatusQueryOptions,
createRegistrarActionsQueryOptions, createNameTokensQueryOptions), update its
type to EnsApiProviderOptions where declared, and replace all usages of config.*
with options.* (e.g., queryKeys.*(options.client.url.href, ...), new
EnsApiClient(options.client), etc.) so the parameter name aligns with callers
using providerOptions.

In `@packages/ensnode-sdk/src/ensapi/api/indexing-status/deserialize.ts`:
- Around line 27-33: The deserializer assumes serializedResponse.config always
exists and will throw for existing test fixtures missing config (type
SerializedEnsApiIndexingStatusResponseOk). Fix by making config optional at
deserialization: in deserialize.ts check for serializedResponse.config and only
call buildUnvalidatedEnsApiPublicConfig when present (e.g., config:
serializedResponse.config ?
buildUnvalidatedEnsApiPublicConfig(serializedResponse.config) : undefined), and
update the serialized type (SerializedEnsApiIndexingStatusResponseOk) or schema
to mark config as optional for backward compatibility; alternatively, add the
missing config objects to the test fixtures in client.test.ts to match the
required schema.

In `@packages/ensnode-sdk/src/ensapi/config/deserialize.ts`:
- Around line 12-19: Remove the redundant JSDoc `@return/`@returns tag from the
comment block above buildUnvalidatedEnsApiPublicConfig; keep the existing
summary and `@param` description but delete the line that restates the return
value so the documentation is not duplicative.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e772ab and cbfea62.

📒 Files selected for processing (34)
  • apps/ensadmin/src/components/config/useEnsApiConfig.ts
  • apps/ensadmin/src/components/connection/cards/ensnode-info.tsx
  • apps/ensadmin/src/components/connections/require-active-connection.tsx
  • apps/ensadmin/src/components/indexing-status/use-indexing-status-with-swr.ts
  • apps/ensadmin/src/components/layout-wrapper.tsx
  • apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx
  • apps/ensadmin/src/components/registrar-actions/use-stateful-fetch-registrar-actions.ts
  • apps/ensadmin/src/hooks/active/use-active-connection.tsx
  • apps/ensadmin/src/hooks/async/use-namespace.ts
  • apps/ensapi/src/cache/indexing-status.cache.ts
  • apps/ensapi/src/handlers/ensnode-api.ts
  • packages/ensnode-react/README.md
  • packages/ensnode-react/src/context.ts
  • packages/ensnode-react/src/hooks/index.ts
  • packages/ensnode-react/src/hooks/useENSNodeConfig.ts
  • packages/ensnode-react/src/hooks/useENSNodeSDKConfig.ts
  • packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts
  • packages/ensnode-react/src/hooks/useIndexingStatus.ts
  • packages/ensnode-react/src/hooks/useNameTokens.ts
  • packages/ensnode-react/src/hooks/usePrimaryName.ts
  • packages/ensnode-react/src/hooks/usePrimaryNames.ts
  • packages/ensnode-react/src/hooks/useRecords.ts
  • packages/ensnode-react/src/hooks/useRegistrarActions.ts
  • packages/ensnode-react/src/hooks/useResolvedIdentity.ts
  • packages/ensnode-react/src/provider.tsx
  • packages/ensnode-react/src/types.ts
  • packages/ensnode-react/src/utils/query.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/deserialize.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/response.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/serialize.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/serialized-response.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/zod-schemas.ts
  • packages/ensnode-sdk/src/ensapi/config/deserialize.ts
  • packages/namehash-ui/src/components/identity/ResolveAndDisplayIdentity.tsx
💤 Files with no reviewable changes (2)
  • packages/ensnode-react/src/hooks/useENSNodeSDKConfig.ts
  • packages/ensnode-react/src/hooks/useENSNodeConfig.ts

@changeset-bot
Copy link

changeset-bot bot commented Mar 2, 2026

⚠️ No Changeset found

Latest commit: 073f642

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file replaces packages/ensnode-react/src/hooks/useENSNodeSDKConfig.ts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replaced with packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts.

Comment on lines -119 to -131
/**
* Creates query options for ENSNode Config API
*/
export function createConfigQueryOptions(config: ENSNodeSDKConfig) {
return {
enabled: true,
queryKey: queryKeys.config(config.client.url.href),
queryFn: async () => {
const client = new ENSNodeClient(config.client);
return client.config();
},
};
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Config endpoint has been merged into the Indexing Status endpoint, so we don't need a separate query for it.

Copilot AI review requested due to automatic review settings March 2, 2026 16:00
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 2, 2026 16:00 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 2, 2026 16:00 Inactive
@tk-o
Copy link
Contributor Author

tk-o commented Mar 2, 2026

@greptile review

Copy link
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 39 out of 39 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (2)

apps/ensadmin/src/app/mock/indexing-stats/page.tsx:14

  • CrossChainIndexingStatusSnapshot is imported but no longer used after changing fetchMockedIndexingStatus to return the full response object. This unused import will fail Biome lint; remove it.
import {
  CrossChainIndexingStatusSnapshot,
  createRealtimeIndexingStatusProjection,
  EnsApiIndexingStatusResponseOk,
  IndexingStatusResponseCodes,
  IndexingStatusResponseOk,
  OmnichainIndexingStatusIds,
} from "@ensnode/ensnode-sdk";

packages/ensnode-react/README.md:141

  • The README's API reference still documents EnsApiProviderProps as taking a config prop and uses ENSNodeConfig types, but the implementation now expects options: EnsApiProviderOptions. This will mislead consumers—update the interface snippet and props list to reflect the new options prop and correct type names.
### EnsApiProvider

The provider component that supplies ENSNode configuration to all child components.

```tsx
interface EnsApiProviderProps {
  config: ENSNodeConfig;
  queryClient?: QueryClient;
  queryClientOptions?: QueryClientOptions;
}

Props

  • config: ENSNode configuration object
</details>



---

💡 <a href="/namehash/ensnode/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.

Comment on lines 7 to 14
import {
createIndexingStatusQueryOptions,
QueryParameter,
useENSNodeSDKConfig,
useEnsApiProviderOptions,
type useIndexingStatus,
useSwrQuery,
WithSDKConfigParameter,
WithEnsApiProviderOptions,
} from "@ensnode/ensnode-react";
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

type useIndexingStatus is imported but never referenced in a type position (it only appears in a JSDoc {@link ...}), which will trip Biome's unused-imports rule. Remove this import (or reference a real type) to keep lint passing.

Copilot uses AI. Check for mistakes.
Comment on lines 42 to 46
export type EnsApiIndexingStatusResponseOk = {
responseCode: typeof EnsApiIndexingStatusResponseCodes.Ok;
realtimeProjection: RealtimeIndexingStatusProjection;
config: EnsApiPublicConfig;
};
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

The PR/issue description mentions adding an ensApiPublicConfig field to the indexing-status OK response, but the SDK type introduces the field as config. If the intended public API field name is ensApiPublicConfig, this should be renamed for consistency (or the PR/issue description and downstream clients should be updated to match config).

Copilot uses AI. Check for mistakes.
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR consolidates ENSApi endpoints by merging /api/config into /api/indexing-status. The indexing status response now includes the config data, eliminating the need for separate API calls.

Key Changes:

  • Removed /api/config endpoint from ENSApi server
  • Updated EnsApiIndexingStatusResponseOk data model to include config field
  • Renamed types across the stack: ENSNodeProviderEnsApiProvider, ENSNodeSDKConfigEnsApiProviderOptions, ENSNodeClientEnsApiClient
  • Created new useEnsApiConfig hook in ENSAdmin that extracts config from indexing status response
  • Updated all React hooks and components to use the new data model and naming conventions

Critical Issues Found:

  • The config() method in packages/ensnode-sdk/src/ensapi/client.ts still references the removed /api/config endpoint and will fail at runtime with 404 errors
  • Typo in variable name selectedConenctionUrl in ENSAdmin provider component

Architecture:
The refactoring successfully consolidates two API calls into one, simplifying client logic. ENSAdmin now fetches indexing status (which includes config) and caches both pieces of data together. This reduces network overhead and ensures config data stays synchronized with indexing status.

Confidence Score: 2/5

  • This PR has a critical runtime bug that will break existing code calling the config API
  • Score reflects one critical logic error (broken config() method) and one syntax error (typo). The core refactoring is sound, but the SDK client wasn't updated to handle the removed endpoint, causing runtime failures. The PR cannot be safely merged until the config() method is fixed.
  • Critical attention needed on packages/ensnode-sdk/src/ensapi/client.ts to fix or remove broken config() method. Also fix typo in apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx

Important Files Changed

Filename Overview
packages/ensnode-sdk/src/ensapi/client.ts CRITICAL: config() method still references removed /api/config endpoint, will fail at runtime with 404
apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx Renamed provider from ENSNodeProvider to EnsApiProvider, but contains typo in variable name selectedConenctionUrl
apps/ensapi/src/handlers/ensnode-api.ts Removed /api/config endpoint handler, now builds and includes config in indexing status response
packages/ensnode-sdk/src/ensapi/api/indexing-status/response.ts Added config field to EnsApiIndexingStatusResponseOk type to include ENSApi config in response
apps/ensadmin/src/components/config/useEnsApiConfig.ts New hook that extracts config from indexing status response, replacing direct config API calls
packages/ensnode-react/src/provider.tsx Renamed ENSNodeProvider to EnsApiProvider, updated parameter names from config to options, and renamed helper function to createEnsApiOptions
packages/ensnode-react/src/utils/query.ts Removed createConfigQueryOptions, renamed ENSNodeClient to EnsApiClient, updated all query functions to use new types

Sequence Diagram

sequenceDiagram
    participant Client as React Component
    participant Hook as useEnsApiConfig
    participant IndexingHook as useIndexingStatusWithSwr
    participant API as ENSApi Server
    
    Note over Client,API: Before: Two separate API calls
    Client->>API: GET /api/config
    API-->>Client: Config data
    Client->>API: GET /api/indexing-status
    API-->>Client: Indexing status
    
    Note over Client,API: After: Single consolidated call
    Client->>IndexingHook: Fetch indexing status
    IndexingHook->>API: GET /api/indexing-status
    API->>API: buildEnsApiPublicConfig()
    API-->>IndexingHook: {realtimeProjection, config}
    IndexingHook-->>IndexingHook: Cache both snapshot + config
    
    Client->>Hook: Get config
    Hook->>IndexingHook: Read indexingStatus.data?.config
    IndexingHook-->>Hook: config from cached data
    Hook-->>Client: Config data
Loading

Last reviewed commit: 073f642

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

40 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Change memoization level for ENSApi options object
Copilot AI review requested due to automatic review settings March 2, 2026 17:38
@tk-o tk-o force-pushed the ensapi-merge-config-with-indexing-status branch from ad3f6d5 to 073f642 Compare March 2, 2026 17:38
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 2, 2026 17:38 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 2, 2026 17:38 Inactive
@tk-o
Copy link
Contributor Author

tk-o commented Mar 2, 2026

@greptile review

Copy link
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 40 out of 40 changed files in this pull request and generated 3 comments.


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

Comment on lines 23 to 31
if (selectedConnection.validatedSelectedConnection.isValid) {
return (
<ENSNodeProvider
config={{ client: { url: selectedConnection.validatedSelectedConnection.url } }}
>
{children}
</ENSNodeProvider>
const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConenctionUrl,
}),
[selectedConenctionUrl],
);
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

useMemo is called inside a conditional branch (if (…isValid)), which violates the Rules of Hooks and can break at runtime when the condition changes between renders. Move the useMemo call to the top level of the component (compute options from a url variable) and only conditionally render EnsApiProvider based on validity.

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +30
const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConenctionUrl,
}),
[selectedConenctionUrl],
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

Typo in variable name selectedConenctionUrl (extra 'en'). Rename to selectedConnectionUrl for clarity and to avoid propagating misspellings.

Suggested change
const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConenctionUrl,
}),
[selectedConenctionUrl],
const selectedConnectionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConnectionUrl,
}),
[selectedConnectionUrl],

Copilot uses AI. Check for mistakes.
Copy link
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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/ensadmin/src/app/mock/indexing-stats/page.tsx (1)

53-57: 🧹 Nitpick | 🔵 Trivial

Remove the assertion to preserve compile-time shape checks.

as IndexingStatusResponseOk can hide fixture drift (especially missing config). Prefer explicit typed assignment to EnsApiIndexingStatusResponseOk.

Proposed refactor
-      const response = indexingStatusResponseOkOmnichain[
-        selectedVariant
-      ] as IndexingStatusResponseOk;
+      const response: EnsApiIndexingStatusResponseOk =
+        indexingStatusResponseOkOmnichain[selectedVariant];
 
       return response;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensadmin/src/app/mock/indexing-stats/page.tsx` around lines 53 - 57,
Remove the type assertion on the fixture and instead explicitly type the
variable so TypeScript enforces the full shape: replace the usage of "as
IndexingStatusResponseOk" when assigning to response from
indexingStatusResponseOkOmnichain[selectedVariant] with an explicit declaration
of response as EnsApiIndexingStatusResponseOk; this preserves compile-time
checks (so missing fields like config are caught) and keeps selectedVariant and
indexingStatusResponseOkOmnichain usage the same.
♻️ Duplicate comments (4)
packages/ensnode-react/src/hooks/useRecords.ts (1)

57-63: 🧹 Nitpick | 🔵 Trivial

Consider renaming _config to providerOptions for consistency.

The hook now works with options terminology; this local name still reflects the old config naming.

♻️ Suggested rename
-  const _config = useEnsApiProviderOptions(options);
+  const providerOptions = useEnsApiProviderOptions(options);
@@
-    ? createRecordsQueryOptions(_config, { ...args, name })
+    ? createRecordsQueryOptions(providerOptions, { ...args, name })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/hooks/useRecords.ts` around lines 57 - 63, Rename
the local variable _config to providerOptions for consistency with the options
terminology: update the declaration that assigns
useEnsApiProviderOptions(options) from const _config =
useEnsApiProviderOptions(options); to const providerOptions =
useEnsApiProviderOptions(options); and then replace all uses of _config (e.g.,
in the call to createRecordsQueryOptions(providerOptions, { ...args, name })) so
that createRecordsQueryOptions and any other references use providerOptions
instead of _config.
packages/ensnode-react/src/types.ts (1)

33-38: ⚠️ Potential issue | 🟡 Minor

Update stale doc wording from “config” to “options.”

The interface has been renamed to WithEnsApiProviderOptions, but the header comment still references config.

✏️ Suggested doc fix
- * Configuration parameter for hooks that need access to config
+ * Configuration parameter for hooks that need access to provider options
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/types.ts` around lines 33 - 38, The top-of-block
doc comment above the WithEnsApiProviderOptions interface is stale (mentions
"config"); update the comment to reference "options" instead so it matches the
renamed interface and describes that it provides options for hooks needing
access to provider options (i.e., change the wording in the comment above
WithEnsApiProviderOptions to say "Configuration parameter for hooks that need
access to options" or similar).
packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts (1)

11-13: ⚠️ Potential issue | 🟡 Minor

Use “options” terminology consistently in JSDoc.

@throws still says “no config is available,” which is outdated for this hook.

✏️ Suggested doc fix
- * `@throws` Error if no config is available in context or parameters
+ * `@throws` Error if no options are available in context or parameters
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts` around lines 11
- 13, Update the JSDoc for the useEnsApiProviderOptions hook to use “options”
terminology consistently: change any remaining references to “config” (e.g., in
the `@throws` description) to mention “options” or “configuration” for this hook,
and adjust the `@throws` text to something like “@throws Error if no options are
available in context or parameters” so it accurately reflects the hook’s
behavior; ensure the `@param` still documents the options parameter and remove any
duplicate/outdated wording.
apps/ensadmin/src/components/config/useEnsApiConfig.ts (1)

11-15: ⚠️ Potential issue | 🟠 Major

Derived config query can go stale versus indexing-status source data.

This creates an independent cache entry from indexingStatus.data?.config but doesn’t reliably track source query updates for the same URL key. Prefer deriving directly from useIndexingStatusWithSwr() instead of nesting a second query.

Suggested fix
-import { useQuery } from "@tanstack/react-query";
-
-import { useEnsApiProviderOptions } from "@ensnode/ensnode-react";
-
 import { useIndexingStatusWithSwr } from "@/components/indexing-status";

 export function useEnsApiConfig() {
-  const ensApiProviderOptions = useEnsApiProviderOptions();
   const indexingStatus = useIndexingStatusWithSwr();

-  return useQuery({
-    enabled: indexingStatus.isSuccess,
-    queryKey: ["swr", ensApiProviderOptions.client.url.href, "config"],
-    queryFn: async () => indexingStatus.data?.config, // enabled flag ensures this is only called when indexingStatus.data is available
-  });
+  return {
+    ...indexingStatus,
+    data: indexingStatus.data?.config,
+  };
 }
In TanStack Query v5, if a useQuery keeps the same queryKey but queryFn closes over changing external state, does the cached query automatically recompute/refetch, or can it remain stale until explicit invalidation/refetch?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensadmin/src/components/config/useEnsApiConfig.ts` around lines 11 - 15,
The current useQuery in useEnsApiConfig creates a separate cached entry
(queryKey ["swr", ensApiProviderOptions.client.url.href, "config"]) that can
become stale versus the source indexingStatus; instead, remove the secondary
useQuery and return a value derived directly from useIndexingStatusWithSwr()
(the indexingStatus object) — e.g., read indexingStatus.data?.config and
indexingStatus.isSuccess and expose that directly from useEnsApiConfig so
updates to useIndexingStatusWithSwr() immediately propagate; locate the useQuery
call in useEnsApiConfig.ts (referenced symbols: useQuery, indexingStatus,
ensApiProviderOptions.client.url.href) and replace it with a derived return (or
a memoized computed value) based on indexingStatus rather than a new
queryKey-based cache.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensadmin/src/components/connections/require-active-connection.tsx`:
- Line 13: RequireActiveConnection currently reads ensApiConfig.status from
useEnsApiConfig, but that hook is disabled when indexingStatus.isSuccess is
false so its status stays "pending" and the error UI is never shown; update
RequireActiveConnection to derive error/loading states from indexingStatus
directly (use indexingStatus.isError / indexingStatus.error to render the error
UI) or ensure useEnsApiConfig runs regardless of indexingStatus (remove the
query's enabled: false gating) so ensApiConfig.status can transition to "error";
locate the logic in RequireActiveConnection that uses ensApiConfig.status and
replace it with checks against indexingStatus (or re-enable the hook) and
propagate the indexing error into the same error rendering path.

In `@apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx`:
- Around line 23-31: The hook useMemo is being called conditionally inside the
if that checks selectedConnection.validatedSelectedConnection.isValid; move the
useMemo call to the top-level of the component so hooks remain stable, e.g.
extract the validatedSelectedConnection and its url
(selectedConnection.validatedSelectedConnection.url) into a local variable, then
call useMemo once and inside its callback return createEnsApiOptions({ url })
when isValid is true or null/undefined when false; assign that result to options
and keep the conditional logic only inside the memo callback (referencing
selectedConnection, validatedSelectedConnection, isValid, url, useMemo,
createEnsApiOptions, and options).

In `@packages/ensnode-react/src/hooks/useNameTokens.ts`:
- Around line 17-20: The hook is passing the entire parameters object (which
includes hook-only fields like options and query) into
createNameTokensQueryOptions, causing unintended fields to flow into the
outgoing client.nameTokens call; update the call to pass only the
NameTokensRequest fields by creating a request object that omits options and
query (e.g., const request = { ...parameters } without options/query or
explicitly pick NameTokensRequest properties) and then call
createNameTokensQueryOptions(providerOptions, request) (ensure the request is
typed as NameTokensRequest) so only valid request fields reach
client.nameTokens.

In `@packages/ensnode-react/src/hooks/useRegistrarActions.ts`:
- Around line 21-24: The hook is passing the entire parameters object (which
contains hook-only fields options and query) into
createRegistrarActionsQueryOptions, risking sending internal fields as part of
RegistrarActionsRequest; update the call to build and pass only the request
payload (omit options and query) — e.g., destructure parameters to extract and
exclude options/query and pass the remaining request object into
createRegistrarActionsQueryOptions (so client.registrarActions receives only
valid RegistrarActionsRequest fields).

---

Outside diff comments:
In `@apps/ensadmin/src/app/mock/indexing-stats/page.tsx`:
- Around line 53-57: Remove the type assertion on the fixture and instead
explicitly type the variable so TypeScript enforces the full shape: replace the
usage of "as IndexingStatusResponseOk" when assigning to response from
indexingStatusResponseOkOmnichain[selectedVariant] with an explicit declaration
of response as EnsApiIndexingStatusResponseOk; this preserves compile-time
checks (so missing fields like config are caught) and keeps selectedVariant and
indexingStatusResponseOkOmnichain usage the same.

---

Duplicate comments:
In `@apps/ensadmin/src/components/config/useEnsApiConfig.ts`:
- Around line 11-15: The current useQuery in useEnsApiConfig creates a separate
cached entry (queryKey ["swr", ensApiProviderOptions.client.url.href, "config"])
that can become stale versus the source indexingStatus; instead, remove the
secondary useQuery and return a value derived directly from
useIndexingStatusWithSwr() (the indexingStatus object) — e.g., read
indexingStatus.data?.config and indexingStatus.isSuccess and expose that
directly from useEnsApiConfig so updates to useIndexingStatusWithSwr()
immediately propagate; locate the useQuery call in useEnsApiConfig.ts
(referenced symbols: useQuery, indexingStatus,
ensApiProviderOptions.client.url.href) and replace it with a derived return (or
a memoized computed value) based on indexingStatus rather than a new
queryKey-based cache.

In `@packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts`:
- Around line 11-13: Update the JSDoc for the useEnsApiProviderOptions hook to
use “options” terminology consistently: change any remaining references to
“config” (e.g., in the `@throws` description) to mention “options” or
“configuration” for this hook, and adjust the `@throws` text to something like
“@throws Error if no options are available in context or parameters” so it
accurately reflects the hook’s behavior; ensure the `@param` still documents the
options parameter and remove any duplicate/outdated wording.

In `@packages/ensnode-react/src/hooks/useRecords.ts`:
- Around line 57-63: Rename the local variable _config to providerOptions for
consistency with the options terminology: update the declaration that assigns
useEnsApiProviderOptions(options) from const _config =
useEnsApiProviderOptions(options); to const providerOptions =
useEnsApiProviderOptions(options); and then replace all uses of _config (e.g.,
in the call to createRecordsQueryOptions(providerOptions, { ...args, name })) so
that createRecordsQueryOptions and any other references use providerOptions
instead of _config.

In `@packages/ensnode-react/src/types.ts`:
- Around line 33-38: The top-of-block doc comment above the
WithEnsApiProviderOptions interface is stale (mentions "config"); update the
comment to reference "options" instead so it matches the renamed interface and
describes that it provides options for hooks needing access to provider options
(i.e., change the wording in the comment above WithEnsApiProviderOptions to say
"Configuration parameter for hooks that need access to options" or similar).

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c53e716 and 073f642.

📒 Files selected for processing (40)
  • apps/ensadmin/src/app/mock/config-api.mock.ts
  • apps/ensadmin/src/app/mock/indexing-stats/page.tsx
  • apps/ensadmin/src/app/mock/indexing-status-api.mock.ts
  • apps/ensadmin/src/components/config/useEnsApiConfig.ts
  • apps/ensadmin/src/components/connection/cards/ensnode-info.tsx
  • apps/ensadmin/src/components/connections/require-active-connection.tsx
  • apps/ensadmin/src/components/indexing-status/use-indexing-status-with-swr.ts
  • apps/ensadmin/src/components/layout-wrapper.tsx
  • apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx
  • apps/ensadmin/src/components/registrar-actions/use-stateful-fetch-registrar-actions.ts
  • apps/ensadmin/src/hooks/active/use-active-connection.tsx
  • apps/ensadmin/src/hooks/async/use-namespace.ts
  • apps/ensapi/src/cache/indexing-status.cache.ts
  • apps/ensapi/src/handlers/ensnode-api.routes.ts
  • apps/ensapi/src/handlers/ensnode-api.ts
  • apps/ensindexer/ponder/src/api/handlers/ensnode-api.ts
  • packages/ensnode-react/README.md
  • packages/ensnode-react/src/context.ts
  • packages/ensnode-react/src/hooks/index.ts
  • packages/ensnode-react/src/hooks/useENSNodeConfig.ts
  • packages/ensnode-react/src/hooks/useENSNodeSDKConfig.ts
  • packages/ensnode-react/src/hooks/useEnsApiProviderOptions.ts
  • packages/ensnode-react/src/hooks/useIndexingStatus.ts
  • packages/ensnode-react/src/hooks/useNameTokens.ts
  • packages/ensnode-react/src/hooks/usePrimaryName.ts
  • packages/ensnode-react/src/hooks/usePrimaryNames.ts
  • packages/ensnode-react/src/hooks/useRecords.ts
  • packages/ensnode-react/src/hooks/useRegistrarActions.ts
  • packages/ensnode-react/src/hooks/useResolvedIdentity.ts
  • packages/ensnode-react/src/provider.tsx
  • packages/ensnode-react/src/types.ts
  • packages/ensnode-react/src/utils/query.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/deserialize.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/response.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/serialize.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/serialized-response.ts
  • packages/ensnode-sdk/src/ensapi/api/indexing-status/zod-schemas.ts
  • packages/ensnode-sdk/src/ensapi/client.test.ts
  • packages/ensnode-sdk/src/ensapi/config/deserialize.ts
  • packages/namehash-ui/src/components/identity/ResolveAndDisplayIdentity.tsx
💤 Files with no reviewable changes (2)
  • packages/ensnode-react/src/hooks/useENSNodeConfig.ts
  • packages/ensnode-react/src/hooks/useENSNodeSDKConfig.ts

*/
export function RequireActiveConnection({ children }: PropsWithChildren) {
const { status, error } = useENSNodeConfig();
const ensApiConfig = useEnsApiConfig();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# First, let's check the useEnsApiConfig hook to see how it's gated
echo "=== Checking useEnsApiConfig implementation ==="
if [ -f "apps/ensadmin/src/components/config/useEnsApiConfig.ts" ]; then
  cat -n "apps/ensadmin/src/components/config/useEnsApiConfig.ts"
else
  echo "File not found, searching for it..."
  find . -name "useEnsApiConfig.ts" -type f
fi

Repository: namehash/ensnode

Length of output: 837


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check RequireActiveConnection component
echo "=== Checking RequireActiveConnection implementation ==="
if [ -f "apps/ensadmin/src/components/connections/require-active-connection.tsx" ]; then
  cat -n "apps/ensadmin/src/components/connections/require-active-connection.tsx"
else
  echo "File not found, searching for it..."
  find . -name "require-active-connection.tsx" -type f
fi

Repository: namehash/ensnode

Length of output: 1284


Error UI is unreachable when indexing status fails during initial load.

RequireActiveConnection checks ensApiConfig.status to show error messages, but useEnsApiConfig has its query disabled when indexingStatus.isSuccess is false. When indexing fails before the first query execution, the status remains stuck at "pending" instead of transitioning to "error", leaving users with a permanent loading spinner. Either disable the component before calling the hook or derive error states directly from indexing status.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensadmin/src/components/connections/require-active-connection.tsx` at
line 13, RequireActiveConnection currently reads ensApiConfig.status from
useEnsApiConfig, but that hook is disabled when indexingStatus.isSuccess is
false so its status stays "pending" and the error UI is never shown; update
RequireActiveConnection to derive error/loading states from indexingStatus
directly (use indexingStatus.isError / indexingStatus.error to render the error
UI) or ensure useEnsApiConfig runs regardless of indexingStatus (remove the
query's enabled: false gating) so ensApiConfig.status can transition to "error";
locate the logic in RequireActiveConnection that uses ensApiConfig.status and
replace it with checks against indexingStatus (or re-enable the hook) and
propagate the indexing error into the same error rendering path.

Comment on lines 23 to 31
if (selectedConnection.validatedSelectedConnection.isValid) {
return (
<ENSNodeProvider
config={{ client: { url: selectedConnection.validatedSelectedConnection.url } }}
>
{children}
</ENSNodeProvider>
const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConenctionUrl,
}),
[selectedConenctionUrl],
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# First, let's read the file to see the actual code structure
if [ -f "apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx" ]; then
  echo "=== Full file content ==="
  cat -n "apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx"
else
  echo "File not found at expected location"
  # Try to find the file
  find . -name "selected-ensnode-provider.tsx" -type f 2>/dev/null || echo "Could not find file"
fi

Repository: namehash/ensnode

Length of output: 2081


Move useMemo out of the conditional block.

useMemo is a hook and must not be called conditionally. The current code calls useMemo only when selectedConnection.validatedSelectedConnection.isValid is true, which violates React's Rules of Hooks. If this condition changes between renders, the hook call order will be inconsistent, breaking React's internal hook management and causing runtime errors.

Extract the URL at the top level and make the options creation conditional inside the useMemo callback instead:

Suggested fix
 export function SelectedEnsApiProvider({ children }: PropsWithChildren) {
   const selectedConnection = useSelectedConnection();
+  const selectedConnectionUrl = selectedConnection.validatedSelectedConnection.isValid
+    ? selectedConnection.validatedSelectedConnection.url
+    : undefined;
+  const options = useMemo(
+    () =>
+      selectedConnectionUrl
+        ? createEnsApiOptions({
+            url: selectedConnectionUrl,
+          })
+        : undefined,
+    [selectedConnectionUrl],
+  );

-  if (selectedConnection.validatedSelectedConnection.isValid) {
-    const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
-    const options = useMemo(
-      () =>
-        createEnsApiOptions({
-          url: selectedConenctionUrl,
-        }),
-      [selectedConenctionUrl],
-    );
-
+  if (selectedConnection.validatedSelectedConnection.isValid && options) {
     return <EnsApiProvider options={options}>{children}</EnsApiProvider>;
   } else {
📝 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
if (selectedConnection.validatedSelectedConnection.isValid) {
return (
<ENSNodeProvider
config={{ client: { url: selectedConnection.validatedSelectedConnection.url } }}
>
{children}
</ENSNodeProvider>
const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConenctionUrl,
}),
[selectedConenctionUrl],
);
export function SelectedEnsApiProvider({ children }: PropsWithChildren) {
const selectedConnection = useSelectedConnection();
const selectedConnectionUrl = selectedConnection.validatedSelectedConnection.isValid
? selectedConnection.validatedSelectedConnection.url
: undefined;
const options = useMemo(
() =>
selectedConnectionUrl
? createEnsApiOptions({
url: selectedConnectionUrl,
})
: undefined,
[selectedConnectionUrl],
);
if (selectedConnection.validatedSelectedConnection.isValid && options) {
return <EnsApiProvider options={options}>{children}</EnsApiProvider>;
} else {
return <>{children}</>;
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx` around
lines 23 - 31, The hook useMemo is being called conditionally inside the if that
checks selectedConnection.validatedSelectedConnection.isValid; move the useMemo
call to the top-level of the component so hooks remain stable, e.g. extract the
validatedSelectedConnection and its url
(selectedConnection.validatedSelectedConnection.url) into a local variable, then
call useMemo once and inside its callback return createEnsApiOptions({ url })
when isValid is true or null/undefined when false; assign that result to options
and keep the conditional logic only inside the memo callback (referencing
selectedConnection, validatedSelectedConnection, isValid, url, useMemo,
createEnsApiOptions, and options).

Comment on lines +17 to +20
const { options, query = {} } = parameters;
const providerOptions = useEnsApiProviderOptions(options);

const queryOptions = createNameTokensQueryOptions(_config, parameters);
const queryOptions = createNameTokensQueryOptions(providerOptions, parameters);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Only pass NameTokensRequest fields to the query builder.

At Line 20, passing full parameters includes hook-only fields (options, query) and can unintentionally alter the outgoing client.nameTokens(args) request payload.

💡 Proposed fix
 export function useNameTokens(parameters: WithEnsApiProviderOptions & UseNameTokensParameters) {
-  const { options, query = {} } = parameters;
+  const { options, query = {}, ...request } = parameters;
   const providerOptions = useEnsApiProviderOptions(options);

-  const queryOptions = createNameTokensQueryOptions(providerOptions, parameters);
+  const queryOptions = createNameTokensQueryOptions(providerOptions, request);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/hooks/useNameTokens.ts` around lines 17 - 20, The
hook is passing the entire parameters object (which includes hook-only fields
like options and query) into createNameTokensQueryOptions, causing unintended
fields to flow into the outgoing client.nameTokens call; update the call to pass
only the NameTokensRequest fields by creating a request object that omits
options and query (e.g., const request = { ...parameters } without options/query
or explicitly pick NameTokensRequest properties) and then call
createNameTokensQueryOptions(providerOptions, request) (ensure the request is
typed as NameTokensRequest) so only valid request fields reach
client.nameTokens.

Comment on lines +21 to +24
const { options, query = {} } = parameters;
const providerOptions = useEnsApiProviderOptions(options);

const queryOptions = createRegistrarActionsQueryOptions(_config, parameters);
const queryOptions = createRegistrarActionsQueryOptions(providerOptions, parameters);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Pass only request fields into createRegistrarActionsQueryOptions.

At Line 24, parameters includes hook-only fields (options, query) and is passed as RegistrarActionsRequest. This can send unintended fields to client.registrarActions(args).

💡 Proposed fix
 export function useRegistrarActions(
   parameters: WithEnsApiProviderOptions & UseRegistrarActionsParameters = {},
 ) {
-  const { options, query = {} } = parameters;
+  const { options, query = {}, ...request } = parameters;
   const providerOptions = useEnsApiProviderOptions(options);

-  const queryOptions = createRegistrarActionsQueryOptions(providerOptions, parameters);
+  const queryOptions = createRegistrarActionsQueryOptions(providerOptions, request);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-react/src/hooks/useRegistrarActions.ts` around lines 21 -
24, The hook is passing the entire parameters object (which contains hook-only
fields options and query) into createRegistrarActionsQueryOptions, risking
sending internal fields as part of RegistrarActionsRequest; update the call to
build and pass only the request payload (omit options and query) — e.g.,
destructure parameters to extract and exclude options/query and pass the
remaining request object into createRegistrarActionsQueryOptions (so
client.registrarActions receives only valid RegistrarActionsRequest fields).

Comment on lines +24 to +30
const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConenctionUrl,
}),
[selectedConenctionUrl],
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: selectedConenctionUrl should be selectedConnectionUrl

Suggested change
const selectedConenctionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConenctionUrl,
}),
[selectedConenctionUrl],
const selectedConnectionUrl = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(
() =>
createEnsApiOptions({
url: selectedConnectionUrl,
}),
[selectedConnectionUrl],

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Additional Comments (1)

packages/ensnode-sdk/src/ensapi/client.ts
The /api/config endpoint was removed but this method still references it. This will fail with 404 at runtime.

Options:

  1. Remove this method entirely (breaking change)
  2. Update to call /api/indexing-status and extract config from response
  3. Mark as deprecated and update implementation

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.

2 participants