Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evm reverse resolution #157

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open

Evm reverse resolution #157

wants to merge 26 commits into from

Conversation

jefflau
Copy link
Member

@jefflau jefflau commented Aug 24, 2023

Renamed the branch so it isn't ensip-16. Old comments/PR here: #132

### Resolving Primary ENS Names by a dapp

* If a dapp has a connected user it SHOULD first check the chainId of the user
* If the chainId is not 1, it SHOULD then construct the ENS name [address].[evmChainCoinType].reverse to obtain the primary ENS name of the user. If none is found, it SHOULD assume that the user has no primary ENS name set

Choose a reason for hiding this comment

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

this is cool and kinda what I had in mind but I like the proposal of having L2 registrars in the mix, still grokking but 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

Appreciate any and all feedback!

1) Sign a message to set a default record
2) call `setName()` on the default registrar on L1

Possibility: Allowing L1 Primary ENS names to also use `default.addr`. This could be incorporated into the public resolver's `name()` function.
Copy link
Member

Choose a reason for hiding this comment

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

Should this be default.reverse ?

Copy link
Member

@Arachnid Arachnid left a comment

Choose a reason for hiding this comment

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

You should probably explicitly include the directions from ENSIP 11 here on how to create a coin type from a chain ID.

Perhaps we should have some syntax for this? Most primary names are going to be for chains that have chain IDs as coin types, and it seems weird that they would all have hugely long decimal identifiers instead of the shorter ones a chain ID would offer. The extended DNS resolver uses the syntax e<chain id> as a shorthand; perhaps we can do something like that here too?

Copy link

cloudflare-pages bot commented Mar 20, 2024

Deploying ens-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8fa5b3c
Status:🚫  Build failed.

View logs


To determine the avatar URI for a specific EVM chain address, the client MUST reverse-resolve the address by querying the ENS registry on Ethereum for the resolver of `<address>.<coinType>.reverse`, where `<address>` is the lowercase hex-encoded Ethereum address, without leading '0x'. Then, the client calls `.text(namehash('<address>.<coinType>.reverse'), 'avatar')` to retrieve the avatar URI for the address.

If a resolver is returned for the reverse record, but calling `text` causes a revert or returns an empty string, the client MUST call `.name(namehash('<address>.<coinType>.reverse'))`. If this method returns a valid ENS name, the client MUST:
Copy link
Member

Choose a reason for hiding this comment

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

The way this is worded is overly specific, and implies a method that won't work for a default reverse resolver.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah actually this doesn't really make sense, because there are no custom resolvers on L2 reverse registrars anyway

Copy link
Member

Choose a reason for hiding this comment

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

Also, the examples should be written descriptively - describing what the client does in the example scenario. SHOULd and MUST etc are for the specification itself.

jefflau and others added 3 commits March 28, 2024 14:26
Co-authored-by: Nick Johnson <arachnid@notdot.net>
Co-authored-by: Nick Johnson <arachnid@notdot.net>
Co-authored-by: Nick Johnson <arachnid@notdot.net>
Copy link
Member

@Arachnid Arachnid left a comment

Choose a reason for hiding this comment

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

This also needs updating to reflect the decision to hex-encode chain IDs.


To determine the avatar URI for a specific EVM chain address, the client MUST reverse-resolve the address by querying the ENS registry on Ethereum for the resolver of `<address>.<coinType>.reverse`, where `<address>` is the lowercase hex-encoded Ethereum address, without leading '0x'. Then, the client calls `.text(namehash('<address>.<coinType>.reverse'), 'avatar')` to retrieve the avatar URI for the address.

If a resolver is returned for the reverse record, but calling `text` causes a revert or returns an empty string, the client MUST call `.name(namehash('<address>.<coinType>.reverse'))`. If this method returns a valid ENS name, the client MUST:
Copy link
Member

Choose a reason for hiding this comment

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

Also, the examples should be written descriptively - describing what the client does in the example scenario. SHOULd and MUST etc are for the specification itself.

@jefflau jefflau requested review from Arachnid and makoto May 10, 2024 09:35
### Resolving Primary ENS Names by a dapp

1) If a dapp has a connected user it SHOULD first check the chainId of the user.
2) It MUST then construct the cointype using ENSIP11: `coinType = 0x80000000 | chainId`, which must be converted to the hexadecimal representation.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
2) It MUST then construct the cointype using ENSIP11: `coinType = 0x80000000 | chainId`, which must be converted to the hexadecimal representation.
2) It MUST then construct the cointype using ENSIP11: `coinType = 0x80000000 | chainId`, which must be converted to lower-case hexadecimal representation.


### Resolving Primary ENS Names by a dapp

1) If a dapp has a connected user it SHOULD first check the chainId of the user.
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure the use of SHOULD and MUST is appropriate here. It's describing an algorithm, and the client doesn't really have any choice about which bits of the algorithm it does; if it doesn't do all of them as-written, it won't work.


1) If a dapp has a connected user it SHOULD first check the chainId of the user.
2) It MUST then construct the cointype using ENSIP11: `coinType = 0x80000000 | chainId`, which must be converted to the hexadecimal representation.
3) If the chainId is not 1, it SHOULD then construct the ENS node representing the reverse node on that network using the coinType and the user's connected `address`: `node = namehash([address].[coinTypeAsHex].reverse)`
Copy link
Member

Choose a reason for hiding this comment

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

What if the chainId is 1?

10) If a string is found, skip to step 12
11) If `name` is an empty string, the dapp MUST assume that a primary name does not exist and instead show the address instead. The name resolution process ends here.
12) If the dapp finds an ENS name, it MUST first check the forward resolution. This can be done by constructing the ENS node for the primary name found: `primaryName = namehash(name)`
13) It MUST then call the registry to retrieve the resolver `registry.resolver(primaryName)`
Copy link
Member

Choose a reason for hiding this comment

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

This implies not using ENSIP-11 wildcard resolution. Instead, this should just specify that it's to use the resolution process documented there.

11) If `name` is an empty string, the dapp MUST assume that a primary name does not exist and instead show the address instead. The name resolution process ends here.
12) If the dapp finds an ENS name, it MUST first check the forward resolution. This can be done by constructing the ENS node for the primary name found: `primaryName = namehash(name)`
13) It MUST then call the registry to retrieve the resolver `registry.resolver(primaryName)`
14) Once it has the resolver it MUST call the addr function with the appropriate coinType. If a name was found on step 6, it must use the `coinType` from the chainId of the user. If a name was found at step 9, which is the default Primary name for EoAs, it must check the coinType of chainId 0, which represents [an EoA across all EVM chains](https://namespaces.chainagnostic.org/eip155/caip10). `resolvedAddress = resolver.addr(coinType)`
Copy link
Member

Choose a reason for hiding this comment

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

Worth specifying if the legacy addr function could/should be used for chainid 1.


### Examples of valid L2 reverse resolution

* Arbitrum: 0F32b753aFc8ABad9Ca6fE589F707755f4df2353.2147525809.reverse
Copy link
Member

Choose a reason for hiding this comment

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

These examples still have decimal cointypes.


To make things explicit we will require the signing of a message to confirm that the address in question would like to use mainnet or another network as fallback. This would either resolve directly on mainnet. Defaults would only be applicable to EoAs that can sign a message. This is because smart contract accounts would not be able to reliably set a default on all chains.

### Setting default
Copy link
Member

Choose a reason for hiding this comment

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

This is quite vague. Is it worth including at all?

1) Sign a message to set a default record
2) call `setName()` on the default registrar on L1

Possibility: Allowing L1 Primary ENS names to also use `default.reverse`. This could be incorporated into the public resolver's `name()` function.
Copy link
Member

Choose a reason for hiding this comment

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

???

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants