# ENS Alpha & ENSNode I documented the full set of queries performed by the Portal and Manager apps (at `dc76993f`) and compared that with the current ENSNode `ensv2` plugin featureset. Of note, the ENSNode `ensv2` plugin provides fully backwards-compatible ENSv1 and ENSv2 indexing in a unified datamodel, not just ENSv2 names, so the alpha apps could support management of ENSv1 names immediately. ## Summary In general, the Portal/Manager apps currently rely on the following: - ✅ get domains by owner address - 🚧 optionally with name search - pending Canonical Name implementation in ENSv2 contracts, but a heuristic could be used in the meantime - ✅ get domains - 🚧 by name - pending Canonical Name implementation - 🚧 w/ various orderings - straightforward to include - ✅ get domain by id or name - registration timestamp, expiry, etc - ✅ get domain's active resolver's address record keys & text record keys - ✅ avatar record resolution - currently this is domain->resolver->avatar lookup which is not ENSIP-10 compliant - in ENSNode this is the **Resolution API** which supports both ENSv1 and ENSv2 names - in ENSNode a future **Identity API** will further improve this DX What follows is a more exhaustive version of the summary above, and includes notes for the ENSNode integration as well as more specific TODO items for ENSNode. ## Notes for a Portal/Manager ENSNode Integration - [ ] GraphQL Client Compatibility - [ ] ensure codegen works correctly by pointing at ENSNode - [ ] current alpha apps use index-based pagination for `Query.domains`, will need to switch to cursor-based pagination - cascades to UI decision-making: move from page-based to 'load more' or infinite-scroll - suggest using urql's `cacheExchange` + [relay pagination](https://nearform.com/open-source/urql/docs/graphcache/local-resolvers/#relay-pagination) for trivial integration - ENSNode implements Relay Pagination to avoid offset-based scaling disaster - [ ] suggest integrating `cacheExchange` w/ Schema Awareness and Partial Results support: - each view context includes a minimal, type-safe query necessary for it to render - entities are minimally loaded and fully specified per context - partial result support means ui can optimistically render already-fetched entities while fetching the rest of the data necessary for the component - [ ] **Get Sidebar Domains** query doesn't seem to scope by `owner` and searches across all domains - is this intended behavior? - if intended, this behavior would be better served by an optimized domain search top-level query - if should be scoped to `owner`, in ENSNode this is `Account.domains` - [ ] `Domain.resolver` in both toy-indexer and ENSNode is the Domain's **assigned** Resolver, _not_ its ENSIP-10 **effective** resolver - if using to drive UI, the difference needs to be taken into account - [ ] `Domain.resolvedAddress` is the **Resolution API** in ENSNode - in toy-indexer this is derived from the **assigned** Resolver which is not ENS-protocol compliant (i.e. doesn't handle ENSIP-10 wildcard resolution) - [ ] toy-indexer has some logic for the case that `Registry:SubregistryUpdate` occurs before `Registry:NameRegistered` but this isn't possible in `Registry` contracts currently — it would be extremely beneficial to indexers if this continues to be the case, and `NameRegistered` always occurs before `SubregistryUpdate`, as it minimizes the temporary state necessary to index the contract correctly - [ ] toy-indexer listens to `Registry:NameBurned` and `Registry:NewSubname` but i don't see these in latest namechain: vestigal? ## ENSNode TODO - [x] release ENSv2 Sepolia support in `1.5.*` patch - [x] surface publicly via `api.sepolia-v2.ensnode.io` and `indexer.sepolia-v2.ensnode.io` - [ ] make sure GraphQL Codegen works against the ENSNode GraphQL Endpoint - [x] (Canonical) Name support for ENSv2 Domains - implement heuristic in advance of true canonical name support - [ ] implement `Domain.subdomains` - abstract over v1 (`Domain.children`) and v2 (`Domain.subregistry.domains`) - [x] `Account.domains` needs filters: - (canonical) name search - [ ] `Account.domains` needs ordering: - by (canonical) name asc/desc - by latest registration expiry asc/desc - by latest registration timestamp asc/desc - [ ] Avatar Resolution - current `wagmi#useEnsAvatar` / `viem#parseAvatarRecord` is reasonable - future ENSNode **Identity API** would provide a structured response for clients to render a name's name/avatar correctly and avoid client-side RPC roundtrips - [ ] if necessary, **Name Search API** to power top-level searching of domains by name - [ ] ENSv2 Migration Indexing - currently pending migration contract stability - would surface via some `Domain.migrationStatus` entity - `Domain.ejected` / `Domain.migrated` / `Domain.registry_locked` status flags used in toy-indexer --- ## Manager App Queries ### Get Dashboard Domains **Ordering** - by name asc/desc - by expiry date asc/desc - by registration asc/desc **Filters** - always filtered by `owner` - `name_contains_nocase` name filter ### Get Sidebar Domains **Ordering** - always `name`, `asc` **Filters** - `name_contains_nocase` name filter ### Profile Owned Names — `profileOwnedNames.ts` **Ordering** - always `RegistrationDate` / `desc` **Filters** - always filtered by `owner` ### Get Indexer Records — `getIndexerRecords.ts` **Fields** - `Domain.resolver.texts` - `Domain.resolver.addresses` ### Get Domain Registration — `profileRegistration.ts` **Fields** - `Domain.createdAt` (`Domain.registration.event.timestamp` in ENSNode) ### Domain Search Suggestion — `DashboardSidebarSearch.tsx` **Fields** - `Domain.id` - `Domain.name` - `Domain.createdAt` (`Domain.registration.event.timestamp` in ENSNode) - `Domain.resolver.avatar` (becomes Identity API in ENSNode) ### Address Profile View Domain Display — `AddressProfileView.tsx` **Fields** - `Domain.id` - `Domain.name` - `Domain.expiryDate` (`Domain.registration.expiry` in ENSNode) ### My Names List Domain Display — `MyNamesList.tsx` **Fields** - `Domain.id` - `Domain.name` - `Domain.expiryDate` (`Domain.registration.expiry` in ENSNode) - `Domain.resolver.avatar` (becomes Identity API in ENSNode) ### Profile Records — `profileRecords.ts` **Fields** - `Domain.resolver.texts` - `Domain.resolver.addresses` ## Portal App Queries ### Names by Address — `useV2NamesForAddress.ts` **Ordering** - none specified **Filters** - always filtered by `owner` ### Domain Subnames Gets the set of subnames of a domain. **Ordering** - none specified **Filters** - `name` ### Profile Records Gets resolver texts/addresses. ### V2 Registration & Expiry Data — `useV2RegistrationData.ts` in ENSNode: `Domain.registrations`