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