Skip to content

An extendable smart contract for developer to develop creative domain name use cases on superchain

Notifications You must be signed in to change notification settings

Opti-domains/opti-registry

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Opti.domains Singular Registry

A modular and customizable ENS V2-like style recursive registry

Deployments

OP Mainnet

OP Sepolia

Building custom subdomains registrar on OP Mainnet

Developers can build their own subdomain communities on Optimism by migrating their .eth domains to Optimism and delegating permissions to their custom registrar smart contracts, all without needing to reimplement the gateway.

1. Migrate your .eth domains to Optimism

You can migrate your .eth domains to Optimism by using our UI.

2. Develop your custom registrar smart contract

Registrar contract has a register function that is called by the UI when a user registers a subdomain. It performs neccessary checks and then calls the registerSubdomain function on the domain contract.

function register(
    address domain,
    string calldata label,
    address owner,
    ...
) external returns (address) {
    // TODO: Check if user has permission to register a subdomain

    // Register the subdomain
    address subdomain = IDomain(domain).registerSubdomain(label, owner);
    if (subdomain == address(0)) revert RegistrationFailed();

    emit SubdomainRegistered(domain, label, owner, deadline, nonce);

    return subdomain;
}

3. (Optional) Implement resolver controller logic to the registrar contract

You can implement resolver controller logic to restrict users from setting restricted records to their subdomains. For example, you can restrict users from setting text record with only whitelisted keys to their subdomains.

function setRecord(
    address domain,
    string calldata key,
    string calldata value,
) external {
    if (isWhitelistedKey(key)) {
        // TODO: Check if user has permission to set this record

        // Set the record
        ISingularResolver(resolver).setText(domain.dnsEncoded(), key, value);
    }
}

4. Delegate domain permissions to your custom registrar smart contract

Find the address of your domain and call addAuthorizedDelegate(registrar, true) on the domain contract.

You can get the address of your domain by calling getNestedAddress(reverseDnsEncoded) on the domain root contract.

reverseDnsEncoded is the reverse DNS encoded name of your domain. For example, if your domain is subdomain.mydomain.eth, reverseDnsEncoded is dns encoded name of eth.mydomain.subdomain. You can use https://ethtools.com/ethereum-name-service/ens-namehash-labelhash-node-generator to get your domain's reverse DNS encoded name.

(Optional) If you want users to fully control their subdomains, you can call setSubdomainOwnerDelegation(bool enabled, bool permanent) on the domain contract. Where enabled is true and if you want to make it permanent, permanent is true.

When setSubdomainOwnerDelegation(true, true) is called on the parent domain, users are fully owned their subdomains without any control from the parent domain. However, if setSubdomainOwnerDelegation(true, false) is called on the parent domain, parent can take the domain back at any time. This is useful in domain renting use cases where users can only control their subdomains for a limited period of time.

5. Implement user interface to register subdomains and manage records

Implement a user interface to register subdomains by calling register function on your registrar contract and manage records by calling setRecord function on your registrar contract. You can fetch existing records by calling respective getter functions on the SingularResolver contract.

Deploy on other Superchain

First, create .env file and set the following environment variables:

PRIVATE_KEY=0x...
RPC_URL=https://...
CHAIN=...
ETHERSCAN_API_KEY=...

Next, run source .env to load the environment variables.

And finally, run this command to deploy the contracts:

source .env
forge script script/DeployDeterministic.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --chain $CHAIN --etherscan-api-key $ETHERSCAN_API_KEY

Remove the --verify and --etherscan-api-key flags if that chain does not support Etherscan. For Blockscout, read https://docs.blockscout.com/devs/verification/foundry-verification

Configure gateway on ENS mainnet

Unlike other solutions that require you to develop your own gateway on the ETH mainnet, our approach is designed for ease of use: simply set your ENS mainnet resolver to our Superchain Resolver and point it to your SingularResolver deployment with a single transaction.

1. Set your ENS mainnet resolver to our Superchain Resolver

Go to https://app.ens.domains and set your ENS mainnet resolver to our Superchain Resolver (0x7BA8071B8AaD8E91C0eEA70D7cB6816699b1Cc72).

2. Point your ENS mainnet resolver to your SingularResolver deployment

Go to https://etherscan.io/address/0x7BA8071B8AaD8E91C0eEA70D7cB6816699b1Cc72#writeProxyContract and call setVerifierConfig with the following parameters:

  • node: namehash of your domain. You can use https://swolfeyes.github.io/ethereum-namehash-calculator to get the namehash of your domain.
  • verifier: 0xACe5278f0bB6EeBEe4429C8bb9863066dA60d5Aa (Address of OPVerifier contract).
  • resolver: Address of your SingularResolver deployment on the Superchain you want to deploy. Default deployment on Optimism is 0x16Af4Cb44e812075e108a95A5A9C7440D15c9B5D.
  • verifierData: abi.encode(optimismPortalAddress, minAge)
    • You can find optimismPortalAddress for your chain in the Superchain Registry
    • minAge is the finalization period for the records set on the Superchain in seconds. For example, if minAge is 3600, you have to wait for 1 hour (3600 seconds) after the record is set on the Superchain before it is available on ENS mainnet. We don't recommend setting minAge below 3600. For a high safety use cases, you should set minAge to 604800 (7 days).

If the verifier config is not set, it will default to Optimism mainnet with 3600 seconds minAge.

Frontend and Backend services deployment

To deploy frontend and backend services, please refer to the README in these repositories:

Customization

In most cases, you don't need to customize the implementation. You can use our default implementation and just deploy a custom registrar contract and delegate permissions to it.

However, if you insist to customize the implementation, you can fork this repo and customize the implementation to fit their needs. Here is an overview of each contract:

  • DomainImplementation: The implementation of the domain contract.
  • DomainRoot: The root contract of the domain.
  • PermissionedRegistry: The registry contract that manages domain registration logic.
  • SingularResolver: The resolver contract that stores and manages domain records.

DomainImplementation

DomainImplementation is the core contract that defines the domain and authorization logic. It is designed to be a modular and customizable ENS V2-like style recursive registry.

You can add more functionalities to every domain name. For example, you can let domain deploy a deterministic contract address given salt. In this case, you can add a deployContract function to DomainImplementation.

DomainRoot

DomainRoot is the contract that manages root node in the domain name system. It's usually owned by a multisig wallet with Timelock.

Root node is the parent of top-level domains such as .eth, .crypto, .nft, etc. These are all subdomains of the root node.

PermissionedRegistry

PermissionedRegistry is the contract that manages domain registration logic. Please read "Develop and deploy your custom registrar smart contract" section above for more details.

SingularResolver

SingularResolver is designed with a concept of one resolver, all superchains. It can be deployed on any Superchain and is instantly compatible with our mainnet Superchain Resolver, eliminating the need to develop your own gateway or CCIP resolver. It supports the following ENS resolver features:

  • Text records
  • Address records
  • Content Hash records

You are free to customize the resolver to add support for more types of records.

Commands

Build

$ forge build

Test

$ forge test

Format

$ forge fmt

Gas Snapshots

$ forge snapshot

Anvil

$ anvil

Deploy

$ source .env
$ forge script script/DeployDeterministic.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --chain optimism-sepolia --etherscan-api-key $ETHERSCAN_API_KEY

Cast

$ cast <subcommand>

Help

$ forge --help
$ anvil --help
$ cast --help

About

An extendable smart contract for developer to develop creative domain name use cases on superchain

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published