Skip to content

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

Draft
tk-o wants to merge 13 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 13 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

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 13 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.
This will address the usecase previously served by `useENSNodeConfig` (that got just removed).
…Swr` to just `useIndexingStatusWithSwr`

`useIndexingStatusWithSwr` returns `data.config` object with is the cached `EnsApiPublicConfig` value.
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 Error Error Feb 24, 2026 10:07am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
ensnode.io Skipped Skipped Feb 24, 2026 10:07am
ensrainbow.io Skipped Skipped Feb 24, 2026 10:07am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

This PR migrates the configuration and provider system from ENSNode-based to EnsApi-based architecture. It introduces a new useEnsApiConfig hook, renames provider components and contexts, updates type names systematically, refactors hooks to use provider options instead of SDK config, and extends indexing-status responses to include public API configuration data alongside status information.

Changes

Cohort / File(s) Summary
New useEnsApiConfig Hook
apps/ensadmin/src/components/config/useEnsApiConfig.ts
Introduces new React hook that composes useEnsApiProviderOptions and useIndexingStatusWithSwr, returning a useQuery call to fetch API config once indexing status loads successfully.
ENSAdmin Component Migration
apps/ensadmin/src/components/connection/cards/ensnode-info.tsx, apps/ensadmin/src/components/connections/require-active-connection.tsx, apps/ensadmin/src/hooks/active/use-active-connection.tsx, apps/ensadmin/src/hooks/async/use-namespace.ts
Migrate from useENSNodeConfig to useEnsApiConfig; update error messages and loading states; rename ENSApiPublicConfig type accordingly.
Registrar Actions Simplification
apps/ensadmin/src/components/registrar-actions/use-stateful-fetch-registrar-actions.ts
Remove dependency on ENSNode config; extract ensIndexerPublicConfig from indexing status response instead; simplify pending and error handling.
Layout and Provider Refactoring
apps/ensadmin/src/components/layout-wrapper.tsx, apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx
Replace SelectedENSNodeProvider with SelectedEnsApiProvider; switch from ENSNodeProvider to EnsApiProvider with createEnsApiOptions; expand error handling with inline messages.
Indexing Status Hook Overhaul
apps/ensadmin/src/components/indexing-status/use-indexing-status-with-swr.ts
Replace SDK config with ENS API provider options; update types to EnsApi* variants; extend cached data to composite object holding snapshot and config; adjust queryFn and select to handle new structure.
ENS API Cache and Handler Updates
apps/ensapi/src/cache/indexing-status.cache.ts, apps/ensapi/src/handlers/ensnode-api.ts
Replace ENSNodeClient with EnsIndexerClient and update response codes; remove /config endpoint; embed config in indexing-status Ok response using new serializer; update error handling structure.
ENS React Package Provider Rename
packages/ensnode-react/src/provider.tsx, packages/ensnode-react/src/context.ts, packages/ensnode-react/src/types.ts
Rename ENSNodeProvider to EnsApiProvider, ENSNodeProviderProps to EnsApiProviderProps, ENSNodeSDKConfig to EnsApiProviderOptions; update context from ENSNodeContext to EnsApiContext; change config property to options throughout.
ENS React Hook Migrations
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
Remove old hooks (useENSNodeConfig, useENSNodeSDKConfig); add new useEnsApiProviderOptions hook; update re-exports.
ENS React Query Builders
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
Update parameter types from WithSDKConfigParameter to WithEnsApiProviderOptions; replace config accessor with useEnsApiProviderOptions; simplify return paths; adjust internal variable naming from _config to providerOptions.
ENS React Identity Resolution
packages/ensnode-react/src/hooks/useResolvedIdentity.ts
Remove dependency on useENSNodeConfig; read namespace directly from parameters instead of fetching; update enabled condition to depend on namespace being defined.
ENS React Query Utils
packages/ensnode-react/src/utils/query.ts
Replace ENSNodeClient with EnsApiClient; update all createQueryOptions functions to accept EnsApiProviderOptions instead of ENSNodeSDKConfig; remove createConfigQueryOptions function entirely.
ENS SDK Indexing Status Enhancement
packages/ensnode-sdk/src/ensapi/api/indexing-status/response.ts, packages/ensnode-sdk/src/ensapi/api/indexing-status/deserialize.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
Add config field to EnsApiIndexingStatusResponseOk; update deserialization to build unvalidated config; update serialization to include config in response; update schemas to validate config in both standard and serialized forms; change serialized Ok schema from strictObject to object.
ENS SDK Config Export
packages/ensnode-sdk/src/ensapi/config/deserialize.ts
Export buildUnvalidatedEnsApiPublicConfig function to make it publicly accessible.
Documentation Updates
packages/ensnode-react/README.md
Update all provider usage examples from ENSNodeProvider to EnsApiProvider; replace createConfig with createEnsApiOptions; update API reference to reflect new naming conventions.
UI Integration
packages/namehash-ui/src/components/identity/ResolveAndDisplayIdentity.tsx
Add namespaceId to useResolvedIdentity options via namespace property to enable identity resolution within specified namespace.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related issues

  • Merge /api/config into /api/indexing-status #1405 — The PR implements the primary objective by adding EnsApiPublicConfig to the indexing-status Ok response, updating serializers, handlers, caches, and all consumer hooks accordingly to propagate and utilize this new config field throughout the system.

Possibly related PRs

Suggested labels

ensnode-sdk

Poem

🐰 Providers leap through refactored trees,
From ENSNode chains to EnsApi breeze,
Config options dance, contexts align,
The indexing snapshot now carries design—
A hop, a skip, the migrations complete!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: merging the ENSApi /api/config endpoint into /api/indexing-status endpoint, which is the primary architectural change across this PR.
Description check ✅ Passed The description follows the required template structure with Summary, Why, Testing, Notes for Reviewer, and Pre-Review Checklist sections. All critical sections are present and reasonably detailed.
Docstring Coverage ✅ Passed Docstring coverage is 80.65% which is sufficient. The required threshold is 80.00%.

✏️ 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.

Comment on lines 61 to 68
export const makeSerializedEnsApiIndexingStatusResponseOkSchema = (
valueLabel: string = "Serialized Indexing Status Response OK",
) =>
z.strictObject({
z.object({
responseCode: z.literal(EnsApiIndexingStatusResponseCodes.Ok),
realtimeProjection: makeSerializedRealtimeIndexingStatusProjectionSchema(valueLabel),
config: makeSerializedEnsApiPublicConfigSchema(valueLabel),
});
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.

makeSerializedEnsApiIndexingStatusResponseOkSchema currently uses z.object(...), which allows unknown keys by default. If the intent is strict validation (as with other response schemas in this file), switch this back to z.strictObject(...) (or explicitly document why extra keys should be permitted for the serialized shape).

Copilot uses AI. Check for mistakes.
Comment on lines 268 to 274
});

<QueryClientProvider client={queryClient}>
<ENSNodeProvider config={config} queryClient={queryClient}>
<EnsApiProvider config={config} queryClient={queryClient}>
<App />
</ENSNodeProvider>
</EnsApiProvider>
</QueryClientProvider>;
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.

In the "Bring Your Own QueryClient" example, <EnsApiProvider config={config} ...> uses the old prop name. Update to options={options} (and ensure the example passes the same options object created by createEnsApiOptions).

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +26
/**
* Hook to access the EnsApiProviderOptions from context or parameters.
*
* @param config - Optional config parameter that overrides context
* @returns The ENSNode configuration
* @throws Error if no config is available in context or parameters
*/
export function useEnsApiProviderOptions<
TConfig extends EnsApiProviderOptions = EnsApiProviderOptions,
>(config?: TConfig): TConfig {
const contextConfig = useContext(EnsApiContext);

// Use provided config or fall back to context
const resolvedConfig = config ?? contextConfig;

if (!resolvedConfig) {
throw new Error(
"useEnsApiProviderOptions must be used within an EnsApiProvider or you must pass a config parameter",
);
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.

This hook’s JSDoc and thrown error message still refer to "config" / "ENSNode configuration", but the rest of the package has moved to "options" / "EnsApiProviderOptions". Update the param docs (@param) and the error text to use consistent terminology (options) to avoid confusion.

Copilot uses AI. Check for mistakes.
Comment on lines 17 to 23
/**
* Configuration options for the ENSNode provider
*/
export interface ENSNodeSDKConfig {
/** The ENSNode API client configuration */
client: ClientOptions;
export interface EnsApiProviderOptions {
/** The ENSApi client configuration */
client: EnsApiClientOptions;
}
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.

The comment above EnsApiProviderOptions still says "Configuration options for the ENSNode provider". Since this type is now specific to EnsApiProvider, update the wording to avoid implying it configures ENSNode provider behavior.

Copilot uses AI. Check for mistakes.
Comment on lines 40 to 42
export function useResolvedIdentity(parameters: UseResolvedIdentityParameters) {
const { identity, accelerate, query: _query = {} } = parameters;

const { data } = useENSNodeConfig();
const namespace = data?.ensIndexerPublicConfig.namespace;
const { identity, namespace, accelerate, query: _query = {} } = parameters;

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.

useResolvedIdentity now takes namespace, but the JSDoc for this hook still documents parameters.namespaceId. Please update the JSDoc parameter name/description to match the actual namespace property so generated docs and IDE hints stay correct.

Copilot uses AI. Check for mistakes.
Comment on lines 127 to 144
@@ -142,12 +142,12 @@ interface ENSNodeProviderProps {
- `queryClient`: Optional TanStack Query client instance (requires manual QueryClientProvider setup)
- `queryClientOptions`: Optional Custom options for auto-created QueryClient (only used when queryClient is not provided)

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.

The API reference still documents an EnsApiProviderProps with a config prop of type ENSNodeConfig, but the provider now takes options: EnsApiProviderOptions. Update the interface snippet and the prop documentation to match the new API so consumers don't copy/paste broken code.

Copilot uses AI. Check for mistakes.
Comment on lines 235 to 250
@@ -247,7 +247,7 @@ The `ENSNodeProvider` automatically creates and manages a QueryClient for you. C
}}
>
<App />
</ENSNodeProvider>
</EnsApiProvider>
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.

In the "Custom Query Configuration" example, <EnsApiProvider config={config} ...> uses the old prop name. This should be <EnsApiProvider options={options} ...> (and the surrounding variable names should align), otherwise the example won’t compile.

Copilot uses AI. Check for mistakes.
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

Comment on lines +13 to +14
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
Contributor

Choose a reason for hiding this comment

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

Suggested change
queryKey: ["swr", ensApiProviderOptions.client.url.href, "config"],
queryFn: async () => indexingStatus.data?.config, // enabled flag ensures this is only called when indexingStatus.data is available
queryKey: ["swr", ensApiProviderOptions.client.url.href, "config", indexingStatus.data],
queryFn: async () => {
if (!indexingStatus.data) {
throw new Error("indexingStatus.data is not available");
}
return indexingStatus.data.config;
},

The useEnsApiConfig hook's queryFn closure stales and may return undefined due to missing dependency on indexingStatus.data in queryKey

Fix on Vercel

```tsx
// Simple setup - no TanStack Query knowledge needed
<ENSNodeProvider
<EnsApiProvider
Copy link
Contributor

Choose a reason for hiding this comment

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

README documentation shows outdated parameter name config={config} instead of the correct options={options} for EnsApiProvider component

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

Comment on lines +24 to +27
const options = createEnsApiOptions({
url: selectedConnection.validatedSelectedConnection.url,
});
return <EnsApiProvider options={options}>{children}</EnsApiProvider>;
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

Options object recreated on every render.

createEnsApiOptions(...) returns a new object each time, which defeats the useMemo inside EnsApiInternalProvider (see comment on provider.tsx Line 37). Wrap in useMemo keyed on the URL to stabilise the context value.

♻️ Suggested fix
+import { useMemo } from "react";
 ...
+  const url = selectedConnection.validatedSelectedConnection.url;
+  const options = useMemo(() => createEnsApiOptions({ url }), [url]);
-  const options = createEnsApiOptions({
-    url: selectedConnection.validatedSelectedConnection.url,
-  });
   return <EnsApiProvider options={options}>{children}</EnsApiProvider>;
📝 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
const options = createEnsApiOptions({
url: selectedConnection.validatedSelectedConnection.url,
});
return <EnsApiProvider options={options}>{children}</EnsApiProvider>;
const url = selectedConnection.validatedSelectedConnection.url;
const options = useMemo(() => createEnsApiOptions({ url }), [url]);
return <EnsApiProvider options={options}>{children}</EnsApiProvider>;
🤖 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 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>.

Comment on lines +8 to +13
/**
* Hook to access the EnsApiProviderOptions from context or parameters.
*
* @param config - Optional config parameter that overrides context
* @returns The ENSNode configuration
* @throws Error if no config is available in context or 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 | 🟡 Minor

Remove redundant/misleading JSDoc return tag.

The summary already states what the hook returns, and the wording still references ENSNode.

🧹 Suggested change
- * `@returns` The ENSNode configuration

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/useEnsApiProviderOptions.ts` around lines 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.

Comment on lines +56 to +57
const { options, query = {}, name, ...args } = parameters;
const _config = useEnsApiProviderOptions(options);
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Inconsistent variable naming across sibling hooks.

This hook names the resolved provider options _config, while usePrimaryNames and useRegistrarActions use providerOptions. Aligning the name improves grep-ability and reduces cognitive overhead.

♻️ Suggested rename
-  const { options, query = {}, name, ...args } = parameters;
-  const _config = useEnsApiProviderOptions(options);
+  const { options, query = {}, name, ...args } = parameters;
+  const providerOptions = useEnsApiProviderOptions(options);

And update the usage on Line 62:

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

Comment on lines +36 to +37
// Memoize the options to prevent unnecessary re-renders
const memoizedOptions = useMemo(() => options, [options]);
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

useMemo is a no-op here — memoizes by object reference identity.

useMemo(() => options, [options]) re-runs whenever the options reference changes. Since callers like SelectedEnsApiProvider create a fresh object on every render via createEnsApiOptions(...), the memo never stabilises, causing all context consumers to re-render unnecessarily.

Memoize on stable primitives instead, or memoize upstream in the caller:

♻️ Option A: memoize on stable primitives
-  // Memoize the options to prevent unnecessary re-renders
-  const memoizedOptions = useMemo(() => options, [options]);
+  // Memoize options based on the URL to stabilise the context value
+  const memoizedOptions = useMemo(() => options, [options.client.url.href]);
♻️ Option B: memoize in SelectedEnsApiProvider instead

In apps/ensadmin/src/components/providers/selected-ensnode-provider.tsx:

+  const options = useMemo(
+    () => createEnsApiOptions({ url: selectedConnection.validatedSelectedConnection.url }),
+    [selectedConnection.validatedSelectedConnection.url],
+  );
-  const options = createEnsApiOptions({
-    url: selectedConnection.validatedSelectedConnection.url,
-  });
📝 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
// Memoize the options to prevent unnecessary re-renders
const memoizedOptions = useMemo(() => options, [options]);
// Memoize options based on the URL to stabilise the context value
const memoizedOptions = useMemo(() => options, [options.client.url.href]);
🤖 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 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.

Comment on lines 17 to 23
/**
* Configuration options for the ENSNode provider
*/
export interface ENSNodeSDKConfig {
/** The ENSNode API client configuration */
client: ClientOptions;
export interface EnsApiProviderOptions {
/** The ENSApi client configuration */
client: EnsApiClientOptions;
}
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 | 🟡 Minor

Update comments to reference EnsApi/options.

The comments still mention ENSNode/config after the rename.

✏️ Suggested doc updates
- * Configuration options for the ENSNode provider
+ * Configuration options for the EnsApi provider

 ...

- * Configuration parameter for hooks that need access to config
+ * Configuration parameter for hooks that need access to options

Also applies to: 33-38

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

Comment on lines +64 to 68
z.object({
responseCode: z.literal(EnsApiIndexingStatusResponseCodes.Ok),
realtimeProjection: makeSerializedRealtimeIndexingStatusProjectionSchema(valueLabel),
config: makeSerializedEnsApiPublicConfigSchema(valueLabel),
});
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

Serialized Ok schema relaxed from z.strictObject to z.object — is this intentional?

The non-serialized makeEnsApiIndexingStatusResponseOkSchema (Line 25) and the error schema (Line 37) both use z.strictObject, which rejects unknown keys. The serialized Ok variant now uses z.object, silently stripping/ignoring unexpected properties. This asymmetry could mask issues where the serialized response contains fields the SDK doesn't expect.

If the relaxation is intentional (e.g., to tolerate extra fields from future server versions), please add a comment explaining why. Otherwise, restore z.strictObject for consistency.

♻️ Restore strictObject if unintended
-  z.object({
+  z.strictObject({
     responseCode: z.literal(EnsApiIndexingStatusResponseCodes.Ok),
     realtimeProjection: makeSerializedRealtimeIndexingStatusProjectionSchema(valueLabel),
     config: makeSerializedEnsApiPublicConfigSchema(valueLabel),
   });
📝 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
z.object({
responseCode: z.literal(EnsApiIndexingStatusResponseCodes.Ok),
realtimeProjection: makeSerializedRealtimeIndexingStatusProjectionSchema(valueLabel),
config: makeSerializedEnsApiPublicConfigSchema(valueLabel),
});
z.strictObject({
responseCode: z.literal(EnsApiIndexingStatusResponseCodes.Ok),
realtimeProjection: makeSerializedRealtimeIndexingStatusProjectionSchema(valueLabel),
config: makeSerializedEnsApiPublicConfigSchema(valueLabel),
});
🤖 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/zod-schemas.ts` around
lines 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.

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