Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,23 @@ sidebar:
# Pull Request Templates

We use pull request templates to help guide contributors through the process of creating a pull request.

- [Lite PR](https://github.com/namehash/ensnode/blob/main/.github/pull_request_template.md)
- *The default PR template for non-significant or low-risk changes.*
- _The default PR template for non-significant or low-risk changes._
- [Substantial PR](https://github.com/namehash/ensnode/blob/main/.github/PULL_REQUEST_TEMPLATE/substantial.md)
- *Template for significant changes or PRs that are complex or higher-risk to review.*
- _Template for significant changes or PRs that are complex or higher-risk to review._

# Standard PR Process

1. Apply the appropriate [Pull Request Template](#pull-request-templates) based on the nature of the changes.
2. Create your PR as a "Draft" first until it is ready for review.
3. Complete all of your work, self-reviews, and PR description updates on the PR.
- If your PR aims to close an issue, [link the PR to the issue through the PR description](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword).
- If your PR aims to close an issue, [link the PR to the issue through the PR description](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword).
4. Complete all checkboxes on the PR description.
5. Convert the PR from "Draft" to "Ready for Review".
6. Wait for automated PR reviews from Greptile and GitHub Copilot. Resolve any of their suggestions as appropriate.
- After applying updates, if you want Greptile to make additional follow-up reviews, add a comment to the PR with the phrase "@greptile".
- GitHub Copilot will automatically re-review each push to the PR.
- After applying updates, if you want Greptile to make additional follow-up reviews, add a comment to the PR with the phrase "@greptile".
- GitHub Copilot will automatically re-review each push to the PR.
7. Send a message to notify the ENSNode team that the PR is ready for manual-review.

# Changesets
Expand All @@ -39,6 +40,7 @@ A "logical change" is a cohesive set of related modifications that share a commo
Changesets should not be created robotically for every "logical change" in a PR. We create changesets specifically for the purposes of managing version bumps and autogenerated release notes.

Only the following types of "logical changes" should be documented in a changeset:

- Changes that should bump versions.
- Changes that are relevant to communicate to the ENS ecosystem in release notes.

Expand All @@ -49,6 +51,7 @@ If a PR does not introduce any "logical changes" meeting the above criteria then
Ensure that each "logical change" described in a changeset is appropriately mapped to the relevant package/app.

Example: assume changes A, B, and C in a PR pass the criteria for changesets, with the following applicability: change A applies only to package/app X, change B applies to both package/app X and package/app Y, and change C applies only to package/app Y. This means multiple distinct changesets should be created as follows:

- Changeset 1: Documenting change A for package/app X
- Changeset 2: Documenting change B for package/app X and package/app Y
- Changeset 3: Documenting change C for package/app Y
Expand All @@ -62,15 +65,16 @@ When you open a PR you should include relevant changeset files that document you
1. Run `pnpm changeset` in the monorepo root.
2. Select the packages/apps that the "logical change" affects using the interactive prompt.
3. Choose the version bump type:
- *NOTE: At this time, we are NOT using [semantic versioning](https://semver.org/). Breaking changes are classified as "minor" rather than "major".*
- "major" - currently reserved only for specially approved cases
- "minor" - breaking changes (note: ENSNode doesn't follow standard semver where breaking = major)
- "patch" - non-breaking changes
- _NOTE: At this time, we are NOT using [semantic versioning](https://semver.org/). Breaking changes are classified as "minor" rather than "major"._
- "major" - currently reserved only for specially approved cases
- "minor" - breaking changes (note: ENSNode doesn't follow standard semver where breaking = major)
- "patch" - non-breaking changes
4. Write a clear description of the "logical change" - this will appear in the next autogenerated release notes.

The `changesets/bot` will automatically comment on your PR to either remind you to add a changeset or confirm the version changes that will happen when your PR is merged.

**Important notes:**

- Changesets should optimize for the narrative of the next [autogenerated release notes](https://github.com/namehash/ensnode/releases). Optimize for how the resulting release notes will read to a developer in the ENS Ecosystem. Communicate all ideas with a positive frame by emphasizing benefits to users, describing fixes in terms of what now works, and using active, solution‑oriented language rather than focusing on past problems.
- All apps and packages in the ENSNode monorepo use "fixed" versioning - they all share the same version number regardless of which app or package triggered the version bump.
- An exception to the above "fixed" versioning is the "fallback-ensapi" app. This is a Lambda containing logic specific to NameHash deployments of ENSNode and is therefore versioned independently.
Expand Down
46 changes: 29 additions & 17 deletions docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,32 @@ A **Subregistry** is any data structure outside of the [Registry](https://docs.e

Some specific implementations of subregistries include:

* The [BaseRegistrar](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/BaseRegistrarImplementation.sol) that holds supplemental state for direct subnames of .eth. This includes state for ERC721 NFTs and expiry times.
* The [NameWrapper](https://docs.ens.domains/terminology#name-wrapper), which serves as a subregistry for the entire ENS root (all ENS names). This includes state for ERC1155 NFTs, expiry times, and fuses.
* Note how direct subnames of .eth are an example of multiple subregistries potentially holding supplemental state for a name outside the Registry.
* The contracts on Base that manage supplemental state for direct subnames of [base.eth](https://www.base.org/names).
* The contracts on Linea that manage supplemental state for direct subnames of [linea.eth](https://names.linea.build/).
* The contracts on Base / Optimism that manage supplemental state for DNS names managed by [3DNS](https://3dns.box/).
* The offchain databases that manage supplemental state for direct subnames of [uni.eth](https://blog.uniswap.org/introducing-uni-eth-your-unique-web3-username).
* The offchain databases that manage supplemental state for direct subnames of [cb.id](https://help.coinbase.com/en/wallet/managing-account/coinbase-ens-support).
* DNS nameservers for (essentially) all DNS names. Since ENS is a superset of DNS, (essentially) any DNS name is an ENS name. Therefore, whenever supplemental state associated with a DNS name is updated in a DNS nameserver, a subregistry is being updated.
- The [BaseRegistrar](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/BaseRegistrarImplementation.sol) that holds supplemental state for direct subnames of .eth. This includes state for ERC721 NFTs and expiry times.
- The [NameWrapper](https://docs.ens.domains/terminology#name-wrapper), which serves as a subregistry for the entire ENS root (all ENS names). This includes state for ERC1155 NFTs, expiry times, and fuses.
- Note how direct subnames of .eth are an example of multiple subregistries potentially holding supplemental state for a name outside the Registry.
- The contracts on Base that manage supplemental state for direct subnames of [base.eth](https://www.base.org/names).
- The contracts on Linea that manage supplemental state for direct subnames of [linea.eth](https://names.linea.build/).
- The contracts on Base / Optimism that manage supplemental state for DNS names managed by [3DNS](https://3dns.box/).
- The offchain databases that manage supplemental state for direct subnames of [uni.eth](https://blog.uniswap.org/introducing-uni-eth-your-unique-web3-username).
- The offchain databases that manage supplemental state for direct subnames of [cb.id](https://help.coinbase.com/en/wallet/managing-account/coinbase-ens-support).
- DNS nameservers for (essentially) all DNS names. Since ENS is a superset of DNS, (essentially) any DNS name is an ENS name. Therefore, whenever supplemental state associated with a DNS name is updated in a DNS nameserver, a subregistry is being updated.

### Subregistrar

A **Subregistrar** is any system that is a [Registrar](https://docs.ens.domains/terminology#registrar) or that writes to a subregistry.

This definition expands the definition of Registrar to include cases such as:

* The [ETHRegistrarController](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/ETHRegistrarController.sol) that writes to BaseRegistrar (the owner of the "eth" TLD). Note how the definition of "Registrar" in the official ENS glossary only includes contracts that are pointed to by the owner field of the Registry. Therefore, the BaseRegistrar is a Registrar (and a Subregistry), while the ETHRegistrarController is a Subregistrar.
* The contracts on Base that write to the Subregistry for direct subnames of base.eth. These contracts live on Base, therefore they cannot meet the definition of Registrar because they can't be set as the owner in the Registry on Ethereum mainnet.
* The offchain systems that write to the offchain databases associated with direct subnames of uni.eth and cb.id.
* Any NFT marketplace that supports the exchange of an NFT representing ownership of an ENS name. Each time a NFT is exchanged, state about that NFT must be updated within a related subregistry. Therefore the marketplace enabling that trade is a Subregistrar.
* Any DNS registrar, as ENS is a superset of DNS.
- The [ETHRegistrarController](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/ETHRegistrarController.sol) that writes to BaseRegistrar (the owner of the "eth" TLD). Note how the definition of "Registrar" in the official ENS glossary only includes contracts that are pointed to by the owner field of the Registry. Therefore, the BaseRegistrar is a Registrar (and a Subregistry), while the ETHRegistrarController is a Subregistrar.
- The contracts on Base that write to the Subregistry for direct subnames of base.eth. These contracts live on Base, therefore they cannot meet the definition of Registrar because they can't be set as the owner in the Registry on Ethereum mainnet.
- The offchain systems that write to the offchain databases associated with direct subnames of uni.eth and cb.id.
- Any NFT marketplace that supports the exchange of an NFT representing ownership of an ENS name. Each time a NFT is exchanged, state about that NFT must be updated within a related subregistry. Therefore the marketplace enabling that trade is a Subregistrar.
- Any DNS registrar, as ENS is a superset of DNS.

### Shadow Registry

A **Shadow Registry** is a Subregistry meeting ALL of the following constraints:

1. Not the Registry;
2. Implemented as a smart contract exposing the same interface as the Registry;
3. Used as part of the source of truth for a CCIP-Read Gateway Server for ENSIP-10 (wildcard resolution) powered subnames.
Expand Down Expand Up @@ -94,7 +95,7 @@ In this terminology reference, we say that the **LabelHash** of a **Label** is t
That is, `0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc` is the **LabelHash** of `vitalik`, which is the result of calling the **`labelhash` function** like so:

```ts
import { labelhashInterpretedLabel, asInterpretedLabel } from 'enssdk';
import { labelhashInterpretedLabel, asInterpretedLabel } from "enssdk";
const labelHash = labelhashInterpretedLabel(asInterpretedLabel("vitalik"));
```

Expand Down Expand Up @@ -161,31 +162,39 @@ ENSNode's indexing pipeline transforms raw blockchain data into user-friendly fo
When processing ENS data, it's important to distinguish between the literal data read from blockchain sources and the interpreted form used in applications:

### Literal Label

A **Literal Label** is the raw label data as it exists in onchain storage or event data, before any processing or interpretation. This represents the exact bytes or string as emitted by contracts.

### Interpreted Label

An **Interpreted Label** is a **Label** that is either:

- (if normalized): a normalized **Literal Label**
- (if not normalized or **Unknown**): an **Encoded LabelHash**

Apps building on ENSNode should take special note to align their implementation of **ENS Normalize** with the **ENS Normalize** used by the ENSNode they use. The **ENS Normalize** version used by each ENSNode can be referenced in the ENSIndexer Config API.

### Literal Name

A **Literal Name** is a Name exclusively composed of 0 or more **Literal Labels**.

### Interpreted Name

An **Interpreted Name** is a Name exclusively composed of 0 or more **Interpreted Labels**.

## Subgraph Indexability & Label/Name Interpretation

### Subgraph-Indexable Labels / Subgraph-Unindexable Labels

The legacy ENS Subgraph specifies that **Unknown Labels** and labels containing certain UTF-8 characters are "invalid". We refer to this concept as `subgraph-indexable` and `subgraph-unindexable`.

A **Literal Label** is `subgraph-unindexable` if it:
- is an **Unknown Label**, or
- contains any of the following prohibited UTF-8 characters.

- is an **Unknown Label**, or
- contains any of the following prohibited UTF-8 characters.

The `subgraph-unindexable` UTF-8 characters are:

1. `\0` (null byte) - PostgreSQL does not allow storing this character in text fields
2. `.` (period) - Conflicts with ENS label separator logic
3. `[` (left square bracket) - Conflicts with "unknown label" representations
Expand All @@ -194,9 +203,12 @@ The `subgraph-unindexable` UTF-8 characters are:
A `subgraph-indexable` **Literal Label** is a **Known Literal Label** that does NOT contain any of the prohibited UTF-8 characters.

### Subgraph Interpreted Label

A **Subgraph Interpreted Label** is a **Label** that is either:

- (if `subgraph-indexable`): a **Literal Label** guaranteed to not contain any of the `subgraph-unindexable` UTF-8 characters, or
- (if `subgraph-unindexable`): an Encoded LabelHash.

### Subgraph Interpreted Name

A **Subgraph Interpreted Name** is a name exclusively composed of 0 or more **Subgraph Interpreted Labels**.
Loading
Loading