Quickstart

Quickstart

NOTE: This quickstart is currently being updated.

This quickstart outlines how to deploy the appropriate contracts for resolving an ENS domain from one of our supported chains.

1. Initial setup

Run these commands:

mkdir quickstart
cd quickstart
git init
forge install https://github.com/unruggable-labs/unruggable-gateways
mkdir contracts

2. Create a foundry.toml

  • Add the following configuration.
[profile.default]
src = "contracts"
libs = ["lib"]
solc = "0.8.25"
 
 
remappings = [
    "@unruggable=lib/unruggable-gateways/"
]

2. Deploy a data contract to L2

  • Create a file in your contracts directory called L2DataContract.sol
  • Copy the code below.
  • Replace YOUR-ADDRESS-HERE with your desired resolution address.
  • Save the file.

Contract code

L2DataContract.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
 
contract L2DataContract {
    address slot0 = YOUR-ADDRESS-HERE;
}
  • Replace CHAIN-IDENTIFIER the the appropriate Alchemy subdomain for the L2 rollup you want to deploy to.
  • Replace YOUR-API-KEY with your Alchemy API key.
  • Replace YOUR-PRIVATE-KEY with your deployment private key.
  • Run the command.
forge create --rpc-url https://CHAIN-IDENTIFIER.g.alchemy.com/v2/YOUR-API-KEY --private-key YOUR-PRIVATE-KEY contracts/L2DataContract.sol:L2DataContract

3. Deploy a resolver to L1

  • Create a file in your contracts directory called L1SimpleResolver.sol
  • Copy the code below.
  • Save the file.
L1SimpleResolver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
 
import  "@unruggable/contracts/GatewayProtocol.sol";
import {GatewayFetcher, GatewayRequest} from "@unruggable/contracts/GatewayFetcher.sol";
import {GatewayFetchTarget, IGatewayProofVerifier} from "@unruggable/contracts/GatewayFetchTarget.sol";
 
import "forge-std/console2.sol"; // DEBUG
 
contract L1SimpleResolver is GatewayFetchTarget {
	using GatewayFetcher for GatewayRequest;
 
	IGatewayProofVerifier immutable _verifier;
	address immutable _exampleAddress;
 
	constructor(IGatewayProofVerifier verifier, address exampleAddress) {
		_verifier = verifier;
        _exampleAddress = exampleAddress;
	}
 
    function supportsInterface(bytes4 x) external pure returns (bool) {
		return x == 0x3b3b57de; //See https://docs.ens.domains/ensip/1
	}
 
    function addr(bytes32 node) public view returns (address) {
 
        GatewayRequest memory r = GatewayFetcher
            .newRequest(1)
            .setTarget(_exampleAddress)
            .setSlot(11)
            .read()
            .debug("lol")
            .setOutput(0);
 
		fetch(_verifier, r, this.addrCallback.selector, '');    
	}
	
    function addrCallback(bytes[] calldata values, uint8, bytes calldata extraData) external pure returns (address) {
        return abi.decode(values[0], (address));
	}
}
  • Replace VERIFIER-ADDRESS with the verifier address for your chosen L2. This can be found here.
  • Replace THE-ADDRESS-OF-THE-CONTRACT-YOU-DEPLOYED-IN-THE-LAST-STEP with.. you guessed it ;)
  • Run the command.
forge create --rpc-url https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY --private-key YOUR-PRIVATE-KEY contracts/L1SimpleResolver.sol:L1SimpleResolver --constructor-args VERIFIER-ADDRESS THE-ADDRESS-OF-THE-CONTRACT-YOU-DEPLOYED-IN-THE-LAST-STEP

4. Set your resolver

Set the resolver for your ENS name to the address of the deployed L1 Resolver.

You can do this through the ENS App (opens in a new tab)

Update resolver using the ENS App

Alternatively you can use the following command having replaced the placeholders.

cast send 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e "setResolver(bytes32,address)" $(cast namehash "MY-ENS-NAME") RESOLVER-ADDRESS --private-key YOUR-PRIVATE-KEY --rpc-url https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY

5. Verify

  • Verify that your name resolves as expected.

!! The finalization times for rollup state varies on a chain by chain basis.

!! Your name will not resolve until the data is finalized.

Help me !

For further guidance we recommend that you read through the rest of the documentation. Especially our examples section. If you still can't find an answer we would be happy to help you out on our Discord (opens in a new tab).

Here are some quicklinks to our example repos:

End-to-end Resolution Demo

These examples (opens in a new tab) demonstrates full end to end resolution using Unruggable Gateways.

Resolution Demo

Typescript VM Demo

These examples (opens in a new tab) demonstrates using our Typescript VM implementation to read values from an assortment of data types/structures.

Gateway Examples