Skip to content

Commit

Permalink
Adding UR page (ensdomains#283)
Browse files Browse the repository at this point in the history
  • Loading branch information
serenae-fansubs authored Sep 25, 2024
1 parent b7960cb commit d6e515f
Show file tree
Hide file tree
Showing 6 changed files with 328 additions and 7 deletions.
6 changes: 6 additions & 0 deletions app/local/config/navigation/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ export const navigation: SectionData[] = [
wip: 70,
icon: '✍️',
},
{
title: 'Universal Resolver',
href: '/resolvers/universalresolver',
wip: 70,
icon: '✍️',
},
],
},
{
Expand Down
8 changes: 4 additions & 4 deletions app/local/data/resolver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ export const resolver_methods: ContractMethod[] = [
},
{
name: 'setAddr(bytes32 node, address a)',
interface: '0x3b3b57de',
usage: 'Write Ethereum Adress',
interface: '0xd5fa2b00',
usage: 'Write Ethereum Address',
seeMore: 'Implemented by Public Resolver',
input: [
{
Expand All @@ -217,7 +217,7 @@ export const resolver_methods: ContractMethod[] = [
events: ['event AddrChanged(bytes32 indexed node, address a);'],
},
{
name: 'setAddr(bytes32 node, uint coinType, bytes calldata a)',
name: 'setAddr(bytes32 node, uint256 coinType, bytes calldata a)',
interface: '0x8b95dd71',
usage: 'Set Multicoin Address',
seeMore: 'Implemented by Public Resolver',
Expand All @@ -229,7 +229,7 @@ export const resolver_methods: ContractMethod[] = [
},
{
name: 'coinType',
type: 'uint',
type: 'uint256',
description: 'The ENSIP-9 coin type to update.',
},
{
Expand Down
252 changes: 252 additions & 0 deletions app/local/data/universalresolver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/* eslint-disable sonarjs/no-duplicate-string */
import { ContractMethod } from './interfaces';

export const universalresolver_methods: ContractMethod[] = [
{
name: 'supportsInterface(bytes4 interfaceID) external pure returns (bool)',
interface: '0x01ffc9a7',
usage: 'Check Interface Support',
seeMore: 'EIP-165',
input: [
{
name: 'interfaceID',
type: 'bytes4',
description:
'The interface identifier, as specified in ERC-165',
},
],
output: [
{
type: 'bool',
description:
'True if the contract supports the specified interface.',
},
],
},
{
name: 'resolve(bytes calldata name, bytes memory data) external view returns (bytes memory, address)',
interface: '0x9061b923',
usage: 'Resolve Name',
seeMore: 'ENSIP-10',
input: [
{
name: 'name',
type: 'bytes',
description:
'The name to resolve, in normalised and DNS-encoded form.',
},
{
name: 'data',
type: 'bytes',
description: 'The resolution data, as specified in ENSIP-10.',
},
],
output: [
{
type: 'bytes',
description: 'The return data of the resolver call.',
},
{
type: 'address',
description: 'The address of the resolver contract.',
},
],
},
{
name: 'resolve(bytes calldata name, bytes memory data, string[] memory gateways) external view returns (bytes memory, address)',
interface: '0x0667cfea',
usage: 'Resolve Name (with custom gateways)',
seeMore: 'ENSIP-10',
input: [
{
name: 'name',
type: 'bytes',
description:
'The name to resolve, in normalised and DNS-encoded form.',
},
{
name: 'data',
type: 'bytes',
description: 'The resolution data, as specified in ENSIP-10.',
},
{
name: 'gateways',
type: 'string[]',
description: 'An array of custom CCIP Read gateway URLs.',
},
],
output: [
{
type: 'bytes',
description: 'The return data of the resolver call.',
},
{
type: 'address',
description: 'The address of the resolver contract.',
},
],
},
{
name: 'resolve(bytes calldata name, bytes[] memory data) external view returns (Result[] memory, address)',
interface: '0x206c74c9',
usage: 'Resolve Name (multiple records)',
seeMore: 'ENSIP-10',
input: [
{
name: 'name',
type: 'bytes',
description:
'The name to resolve, in normalised and DNS-encoded form.',
},
{
name: 'data',
type: 'bytes[]',
description: 'The resolution data, as specified in ENSIP-10.',
},
],
output: [
{
type: 'Result[]',
description:
'The return data of the resolver call. This is a struct with: [bool success, bytes returnData]',
},
{
type: 'address',
description: 'The address of the resolver contract.',
},
],
},
{
name: 'resolve(bytes calldata name, bytes[] memory data, string[] memory gateways) public view returns (Result[] memory, address)',
interface: '0x76286c00',
usage: 'Resolve Name (multiple records with custom gateways)',
seeMore: 'ENSIP-10',
input: [
{
name: 'name',
type: 'bytes',
description:
'The name to resolve, in normalised and DNS-encoded form.',
},
{
name: 'data',
type: 'bytes[]',
description: 'The resolution data, as specified in ENSIP-10.',
},
{
name: 'gateways',
type: 'string[]',
description: 'An array of custom CCIP Read gateway URLs.',
},
],
output: [
{
type: 'Result[]',
description:
'The return data of the resolver call. This is a struct with: [bool success, bytes returnData]',
},
{
type: 'address',
description: 'The address of the resolver contract.',
},
],
},
{
name: 'reverse(bytes calldata reverseName) external view returns (string memory, address, address, address)',
interface: '0xec11c823',
usage: 'Resolve Reverse Name',
seeMore: '',
input: [
{
name: 'reverseName',
type: 'bytes',
description:
'The reverse name to resolve, in normalised and DNS-encoded form.',
},
],
output: [
{
type: 'string',
description: 'The resolved name.',
},
{
type: 'address',
description: 'The resolved address.',
},
{
type: 'address',
description: 'The reverse resolver address.',
},
{
type: 'address',
description: 'The resolver address.',
},
],
},
{
name: 'reverse(bytes calldata reverseName, string[] memory gateways) public view returns (string memory, address, address, address)',
interface: '0xb241d0d3',
usage: 'Resolve Reverse Name (with custom gateways)',
seeMore: '',
input: [
{
name: 'reverseName',
type: 'bytes',
description:
'The reverse name to resolve, in normalised and DNS-encoded form.',
},
{
name: 'gateways',
type: 'string[]',
description: 'An array of custom CCIP Read gateway URLs.',
},
],
output: [
{
type: 'string',
description: 'The resolved name.',
},
{
type: 'address',
description: 'The resolved address.',
},
{
type: 'address',
description: 'The reverse resolver address.',
},
{
type: 'address',
description: 'The resolver address.',
},
],
},
{
name: 'findResolver(bytes calldata name) public view returns (Resolver, bytes32, uint256)',
interface: '0xa1cbcbaf',
usage: 'Find Resolver',
seeMore:
'Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.',
input: [
{
name: 'name',
type: 'bytes',
description:
'The name to resolve, in DNS-encoded and normalised form.',
},
],
output: [
{
type: 'address',
description: 'The Resolver responsible for this name.',
},
{
type: 'bytes32',
description: 'The namehash of the full name.',
},
{
type: 'uint256',
description: 'The offset of the first label with a resolver.',
},
],
},
];
5 changes: 4 additions & 1 deletion docs/resolvers/interfaces.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { h2, h3, h4 } from '@/components/mdx/heading/h2';
export const meta = {
description: '',
emoji: '👉',
contributors: []
contributors: [
'luc.eth',
'serenae.eth'
]
};

# Resolver Interface Standards
Expand Down
60 changes: 60 additions & 0 deletions docs/resolvers/universalresolver.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { WIP } from "@/components/wip/WIP";
import { interfaceDetails } from "#/data/interfaces";
import { universalresolver_methods } from "#/data/universalresolver";
import { h2, h3, h4 } from '@/components/mdx/heading/h2';

{/* * @type {import('@/lib/mdxPageProps').MdxMetaProps} */}
export const meta = {
description: '',
emoji: '👉',
contributors: [
'luc.eth',
'serenae.eth'
]
};

# Universal Resolver

## Overview

The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.

Note that this contract is already built into libraries like Viem and ENSjs, so most developers don't typically need to use it directly.

### Forward Resolution

To resolve one or more records for a name, use one of the `resolve` methods, such as `resolve(bytes name, bytes data)`.

The `name` argument for these methods will be the [DNS-encoded](/resolution/names#dns) version of the name. Make sure to [normalize](/resolution/names#normalize) the name first, as well! For example, given the name `My.Name.eth`:

1. Normalize:
- `My.Name.eth` -> `my.name.eth`
2. DNS Encode:
- `my.name.eth` -> `0x026d79046e616d650365746800`

The `data` argument for these methods will be an ABI-encoded call to the resolver for that name.

For example, if you want to resolve the ETH address for `my.name.eth`, using the `addr(bytes32 node)` method, then the corresponding ABI-encoded call would be:

```
0x3b3b57def61adbd8ee36cf930560efc644af752731733dc6421afe47608f8e2cfeaabe2b
```

See here for standard resolver methods: [Resolver Interface Standards](/resolvers/interfaces)

### Reverse Resolution

To reverse-resolve an address to an ENS name, call one of the `reverse` methods, such as `reverse(bytes reverseName)`.

The `reverseName` argument for these methods will be the [DNS-encoded](/resolution/names#dns) version of the reverse name. The "reverse name" is `[addr].addr.reverse`, where `[addr]` is the Ethereum public address (without the "0x"). Make sure to [normalize](/resolution/names#normalize) the name as well! For example, given the address `0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63`:

1. Construct Reverse Name:
- `0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63` -> `231b0Ee14048e9dCcD1d247744d114a4EB5E8E63.addr.reverse`
2. Normalize:
- `231b0Ee14048e9dCcD1d247744d114a4EB5E8E63.addr.reverse` -> `231b0ee14048e9dccd1d247744d114a4eb5e8e63.addr.reverse`
3. DNS Encode:
- `231b0ee14048e9dccd1d247744d114a4eb5e8e63.addr.reverse` -> `0x28323331623065653134303438653964636364316432343737343464313134613465623565386536330461646472077265766572736500`

## Interface Standards

{interfaceDetails(universalresolver_methods)}
4 changes: 2 additions & 2 deletions docs/wrapper/expiry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ The owner will *not* yet lose ownership of the name, but they will also not be a

When a name is merely **Wrapped** but not **Emancipated** or **Locked**, parent-controlled fuses can still be burned. This means that the parent can burn a custom fuse for a limited amount of time.

When the expiry is reached, all fuses will be reset, but the name will otherwise be unaffected.
When the expiry (end of grace period for .eth 2LDs) is reached, all fuses will be reset, but the name will otherwise be unaffected.

When a name is **Emancipated** or **Locked**, the expiry has an important additional effect. In this scenario, when the expiry has been reached, **the name itself will expire**, and the owner **loses ownership** of the name.
When a name is **Emancipated** or **Locked**, the expiry has an important additional effect. In this scenario, when the expiry (end of grace period for .eth 2LDs) has been reached, **the name itself will expire**, and the owner **loses ownership** of the name.

0 comments on commit d6e515f

Please sign in to comment.