ENS Layer2 and offchain data support


With the proliferation of layer 2 solutions for Ethereum that are starting to reach maturity, it's important that ENS is able to provide resolution services across the entire ecosystem, as well as making it possible for ENS users to take advantage of the efficiencies made possible by Layer 2 solutions. Subsequent to a post by Vitalik that suggested a possible means for this, the ENS team and the wider ENS and L2 community have been working on a general-purpose "Layer 2 bridge" that makes cross-platform interoperability possible for both ENS and other applications that need to be able to retrieve data from a variety of offchain sources (any data that resides outside of Ethereum Mainnet also known as layer 1/L1. This includes both propriety database and layer 2/L2 solutions such as Optimism, Arbitrum, Starkware, ZKSync, and so on) in a trustless fashion and came up with standards.
EIP 3668 allows for offchain (including Layer 2/L2) lookups of data in a way that is transparent to clients and provides contract authors to implement whatever validation is necessary; in many cases, this can be provided without any additional trust assumptions over and above those required if data is stored onchain.
ENSIP 10 is a general way to resolve wildcard (eg: *.foo.eth) on L1. Issuing subdomains and moving the resolution of the parent name offchain allows dapps to create subdomains offchain yet make it accessible through L1.

Steps required for Dapps and wallets to support offchain data lookup.

If your dapps or wallets use one of those libraries, the EIP 3668 and ENSIP 10 support will be built in, so simply update the library when ready.


5.6.1 supports both EIP3668 and ENSIP 10.
No code change is required as long as your app is interacting with ENS through etherjs ENS methods.
To try out these features, offchainexample.eth points to so-called "offchain resolver" that fetches data from JSON configuration file hosted on google app engine. It will reply data to any record for offchainexample.eth and its subdomain record such as 2.offchainexample.eth. The example resolver is not using L2 data but the same mechanism works when the L2 resolver becomes ready.
const { ethers } = require("ethers");
const url = `https://mainnet.infura.io/v3/${process.env.API_KEY}`
const provider = new ethers.providers.JsonRpcProvider(url);
async function main(){
let resolver = await provider.getResolver('1.offchainexample.eth')
let address = await provider.resolveName('1.offchainexample.eth')
let email = await resolver.getText('email')
console.log({resolver:resolver.address, address, email})
The expected output is as follows.
$node index.js
resolver: '0xC1735677a60884ABbCF72295E88d47764BeDa282',
address: '0x41563129cDbbD0c5D3e1c86cf9563926b243834d',
@chainlink/ethers-ccip-read-provider(source) also implements EIP 3668 as an independent npm module
The basic usage example is as follows.
import { CCIPReadProvider } from '@chainlink/ethers-ccip-read-provider';
import { abi as IExtendedResolver_abi } from '@ensdomains/offchain-resolver-contracts/artifacts/contracts/IExtendedResolver.sol/IExtendedResolver.json';
const IExtendedResolver = new ethers.utils.Interface(IExtendedResolver_abi);
const baseProvider = ethers.getDefaultProvider(options.provider);
const provider = new CCIPReadProvider(baseProvider);
Please refer to offchain resolver client example code for more detail.


Work in progress

Any other libraries

If you use other libraries or custom integration, please raise the GitHub issue to the project repo or at ENS project management repo if the equivalent repo does not exist so that ENS team can keep track of the progress.

Steps required for Dapps and wallets to issue subdomains offchain

If you wish to issue subdomains using offchain data storage, please follow offchain resolver as a reference point. The example uses a flat file as a data source but can easily be replaced with database calls.
L2 support is still a work in progress.


Is the change backwards compatible?

Yes. The existing names on L1 will continue working without clients nor applications supporting these standards. Only names that are outside of L1 will not be resolved.

Will L2/offchain data be supported by GraphQL?

Once each L2 is officially supported, we will need to spin up a subgraph for each L2 bridge, and we will use schema stitching to make using them transparent to callers.
For names that are not hosted on a supported L2, we won't be able to fetch data that are normally only available on the subgraph

How do you support other EVM compatible chains?

Non-L2 chains lack ways to verify data on L1 in the trustless manner. The alternative is for chain bridge operators to act as a trusted third-party and hosts the offchain gateway, or individual dapps hosts own gateway and sign each data with the private key of the ENS name.

Can I issue a new tld unique to an offchain environment?

Can I set a primary name to names on offchain?

Yes, you can. However, reverse registrar (it is a hidden top-level domain starting with .addr.reverse) currently resides on L1; hence you have to pay gas on L1. We may consider moving the reverse registrar to L2 in future.

Can I register .eth name on offchain?

Only when we migrate .eth name to a specific L2 as one of the last steps of our migration after finding out which L2 supports ENS integration the best.

How do I handle contract addresses?

Unlike EOA (Externally Owned Account), contract based accounts such as multisig may only be accessible in certain chains. ENSIP-11 allows a single name to hold different addresses across multiple EVM compatible chains and recommendation is to store contract addresses to EVM chain specific address record field.

Can I use libraries from other name services that support .eth?

@unstoppabledomains/resolution removed ENS support as of December 2021. Other services tend not to support all ENS TLDs especially DNS based TLDs (.com, .net, etc) so we advise not to rely on these libraries resolving ENS names.

References and previous discussions