DEV3.eth: ENS-on-Github by NameSys


Dear ENS Developers, Enthusiasts & Community,

:rocket:  We are glad to announce the mainnet launch of our free subdomain project dev3.eth  :rocket:

:point_right: dev3.eth is a free subdomain project soulbound to the Github ecosystem. Github user arachnid can redeem their soulbound subdomain arachnid.dev3.eth and host their subdomain’s records on Github Pages with simple commands such as npm run init and npm run sign in their consoles! Read more about dev3.eth below :point_down:


dev3.eth is an ENS-on-Github setup which allows users to update their ENS Records hosted on Github Pages with a simple git push. Users of dev3.eth CLI can redeem a free subdomain soulbound to their Github ID <id>.dev3.eth. This soubdomain is enabled to read ENS Records from your self-hosted CCIP-Read gateway: your Github homepage https://<id> Your records are signed by you and validated by the Cloudflare micro-approver against Man In The Middle attacks (MITM) due to hypothetical compromise of CCIP providers’ centralised infrastructure.

CLI: namesys-eth/dev3-eth-cli

Resolver: namesys-eth/dev3-eth-resolver



  • dev3.eth feeds on your Github Pages for ENS Records. You must have your Github Homepage https://<id> configured to publish from <id> repository by default. Simple guide to doing this is here.

    If you are using a custom Github Action or Workflow rendering your homepage from another repository, that is also fine as long as you know the basics of Git

  • It is advisable to have your Github homepage auto-deploy upon push. This is default for <id> repository and you don’t need to do anything in this case.

    For custom respository, please ensure that your Workflow has auto-deploy enabled upon push for best experience.

  • Have access to your <id> or custom repository linked to Github Pages. Duh!


Claiming your dev3.eth Subdomain!

Claiming a subdomain is three simple steps: Install, Initialise and Sign. The install step installs the dev3-eth client. init step sets up the environment for publishing ENS records. sign step signs your records against any kind of tampering (e.g. by Github).

:point_down: Details are below in short form and then in long form after that!


cd into your <id> or custom repository in terminal window or your favourite IDE console (e.g. VS Code) with:

cd <id>


Install dev3-eth CLI locally in your <id> or custom repository, or globally for better accessibility. That’s it! You are now ready to redeem your free dev3.eth subdomain!

Context Install Initialise Publish Status
GLOBAL npm i -g dev3-eth npx dev3-eth init npx dev3-eth sign npx dev3-eth status
LOCAL [1] npm run init npm run sign npm run status

:bulb: HINT: If you encounter Permission Denied error for npx dev3 executable, allow it to run with: chmod +x <path>/.bin/dev3


VERSION=0.0.3-beta && curl -LO && source


Each subdomain has their profile auto-deployed by default in their contenthash :point_down:



GLOBAL Installation

dev3-eth client can be installed globally for quick access with npx :point_down:

Install Package

npm i -g dev3-eth

Initialise sub.dev3.eth

npx dev3-eth init

Sign Records for sub.dev3.eth

npx dev3-eth sign

View Records for sub.dev3.eth

npx dev3-eth view


LOCAL Installation

Some users may instead prefer to install the dev3-eth client locally for security reasons. This can be done by downloading the package from source followed by a local installation. Local installation is also better suited if someone wants to play around with the client :point_down:

Install Package

VERSION=0.0.3-beta && curl -LO && source

Initialise sub.dev3.eth

npm run init

Sign Records for sub.dev3.eth

npm run sign

View Records for sub.dev3.eth

npm run view

This is very clever! For anyone not following along at home - this works by putting your encoded ENS records in GitHub, and serving them up via Github Pages as static files. Because of the way CCIP-Read is designed, a static website can serve as a CCIP-Read gateway. The records are signed so that they can’t be manipulated by someone with access to your GitHub account.

Looking at your resolver code, I notice you’re decoding the request sent to resolve in order to construct a path. It’s worth pointing out that you could have simply named the files after the calldata required to fetch them - so you could just use the static URL{{data}}.json.


Approver is verifying & approving github page url and signer address from …/verify.json file, so records are all signed & controlled by github users… resolver can’t do anything if users have their Github IDs compromised.

We’re using reverse directory name for readability as it’s hard to decode hex for devs & users when they’ve to copy/debug records. We’ve secondary domain isdev.eth attached to same resolver so users are free to use ../.well-known/eth/dev3/<username>/.. for <username>.dev3.eth and then copy-paste OR sign new records in ../.well-known/eth/isdev/<username>/.. directory for <username>.isdev.eth. Resolver also support deep subdomains (capped at 42 levels) in same reverse directory format.


Finally for bonus feature users are free to import their ENS domain, setup their own web2 gateways in any github/repo or web2 servers using same directory format. We’re testing more tools for domain.tld DNS imported in ENS to run CCIP-gateways in https://domain.tld/.well-known/tld/domain/..sub directory format.


Like @0xc0de4c0ffee pointed out, this is sadly not true. The records are signed by a local newly generated key and not by a signer who can be externally referenced on chain. If someone has access to your Github account, they can replace the local signer and create false records . The reason for having a local signer is that we didn’t want to ask users to pay for an on-chain signer. This is different from typical setups where we usually have the owner or the manager of ENS domain as an on-chain external reference. Even if we did have an external on-chain reference, it would have been unwise to ask users to import signer’s private key into .env. It only takes one deletion of .gitignore to mess with everything :sweat_smile: I guess there is some room for a terminal → browser deep ref-link authorisation setup, similar to how npm authorises 2FA through CLI.

† this issue can be circumvented though if the Github user has strict signed commits enabled but even that has limitations against someone with core admin access to your Github account

More interesting aspects of this prototype have been left unspoken. In principle, devs can host records for others for generic .eth parent names, delegate signing to a Github Action Workflow for more automation etc etc. Even the reliance on Github is not bad in the end since a seasoned dev can easily deploy a GitLab instance with a gateway and continue on their merry way. I guess this could make for a good Hackathon concept. We made this in about 7-10 days so there are limitations to it still…

P.S. The current dev3.eth resolver is also fully modular, and currently works on both dev3.eth and isdev.eth. If someone wants to do the same with their domains, they can deploy the contract with couple of their own parameters in the constructor and Bob’s their uncle :rocket:

1 Like

Thanks for the correction.

Why not have the user sign a message containing the address of the local keypair, using the account that owns the name?

This is precisely what we do for the NameSys Resolver. In CLI environment however, it would still require the user to either sign the message ‘offline’ and paste the signature manually, or import their key to .env. Both are not ideal… unless someone wants to build a deeplink redirectooor to browser and back to CLI for signing. It may exist already but we haven’t checked.

Seems like I may have misunderstood the comment and @0xc0de4c0ffee corrected me offline.

Did you mean dev3.eth and its owner? This wouldn’t help against account compromise since hijacker of nick.dev3.eth can always generate a new local signer and get it approved by the owner of dev3.eth. Only way to escape this situation is if nick.dev3.eth has an on-chain owner to validate against. Without external on-chain reference to nick.dev3.eth, it’s a circularly referencing system. One possible way is to issue a time-lock on validating a new signer in our CF approver, i.e. a user must wait X amount of time before validating a new signer; this solution can be integrated in more serious implementations. dev3.eth is a simple prototype for developers to play with and possibly extend to better versions.

P.S. We do precisely what you suggest for NameSys Resolver. Owner of each domain.eth has their on-chain owner who can validate the signer. In dev3.eth that’s not the case since subnames are off-chain.

This is a really cool concept.

I like the design and security decisions that you’ve made regarding signing keys, and I’ve had a brief look through your code. It looks like a great demonstration of the ENSIP10 and CCIP Read (3668) specifications.

The command line stuff is cool. Perhaps an extension of this could be a basic UI such that a non-dev member of the public could download a/the repo source code and step by step their way through a setup authorising Github with oAuth, deploying their records, and signing through whatever wallet provider they may have setup in their browser. 2015 MyEtherWallet style XD

1 Like