Skip to content

Commit 2f7f194

Browse files
committed
feat: l2 gateway sepolia
1 parent c437ed7 commit 2f7f194

24 files changed

Lines changed: 2132 additions & 555 deletions

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "lib/unruggable-gateways"]
2+
path = lib/unruggable-gateways
3+
url = https://github.com/unruggable-labs/unruggable-gateways

DEPLOYMENT.md

Lines changed: 289 additions & 138 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 149 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
11
# ENS Config Resolver
22

3-
A set of ENS contracts that enable users to claim address-based subnames under your ENS name.
3+
A set of ENS contracts that enable users to claim address-based subnames under your ENS name, with optional L1 → L2 CCIP-Read resolution.
44

55
## Overview
66

7-
This project provides two main contracts:
7+
This project provides three main contracts:
88

99
| Contract | Description |
1010
| --------------------------- | ------------------------------------------------------------------------------------- |
1111
| **ConfigResolver** | A general-purpose ENS resolver for setting records (text, address, contenthash, etc.) |
1212
| **AddressSubnameRegistrar** | Enables users to claim `<their-address>.yourname.eth` subnames |
13+
| **L1ConfigResolver** | Reads L2 ConfigResolver records from L1 via CCIP-Read (Unruggable Gateways) |
14+
15+
## Deployments
16+
17+
### Testnets
18+
19+
| Contract | Network | Address |
20+
| ---------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------- |
21+
| ConfigResolver | Base Sepolia | [`0xA66c55a6b76967477af18A03F2f12d52251Dc2C0`](https://sepolia.basescan.org/address/0xA66c55a6b76967477af18A03F2f12d52251Dc2C0) |
22+
| L1ConfigResolver | Sepolia | [`0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B`](https://sepolia.etherscan.io/address/0x380e926f5D78F21b80a6EfeF2B3CEf9CcC89356B) |
23+
24+
### Mainnet
25+
26+
| Contract | Network | Address |
27+
| ---------------- | -------- | ------- |
28+
| ConfigResolver | Base | TBD |
29+
| L1ConfigResolver | Ethereum | TBD |
1330

1431
### Example
1532

@@ -37,12 +54,57 @@ forge test
3754

3855
### Deploy
3956

57+
Deploy ConfigResolver + AddressSubnameRegistrar:
58+
59+
```bash
60+
# Sepolia
61+
PARENT_NODE=$(cast namehash "yourname.eth") \
62+
forge script script/Deploy.s.sol \
63+
--rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \
64+
--account deployer \
65+
--broadcast \
66+
--verify
67+
68+
# Mainnet
69+
PARENT_NODE=$(cast namehash "yourname.eth") \
70+
forge script script/Deploy.s.sol \
71+
--rpc-url https://eth-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY \
72+
--account deployer \
73+
--broadcast \
74+
--verify
75+
```
76+
77+
Deploy ConfigResolver only:
78+
79+
```bash
80+
forge script script/Deploy.s.sol --sig "deployConfigResolver()" \
81+
--rpc-url $RPC_URL \
82+
--account deployer \
83+
--broadcast \
84+
--verify
85+
```
86+
87+
Deploy L1ConfigResolver (for reading L2 records from L1):
88+
4089
```bash
41-
# Deploy to Sepolia
42-
./script/deploy.sh
90+
L2_CONFIG_RESOLVER=0x... \
91+
forge script script/Deploy.s.sol --sig "deployL1Resolver()" \
92+
--rpc-url $RPC_URL \
93+
--account deployer \
94+
--broadcast \
95+
--verify
96+
```
97+
98+
Deploy L1 AddressSubnameRegistrar (for L1 claiming with L2 storage):
4399

44-
# Deploy to Mainnet
45-
./script/deploy.sh mainnet
100+
```bash
101+
PARENT_NODE=$(cast namehash "yourname.eth") \
102+
L1_CONFIG_RESOLVER=0x... \
103+
forge script script/Deploy.s.sol --sig "deployL1Registrar()" \
104+
--rpc-url $RPC_URL \
105+
--account deployer \
106+
--broadcast \
107+
--verify
46108
```
47109

48110
See [DEPLOYMENT.md](./DEPLOYMENT.md) for the full deployment and setup guide.
@@ -90,6 +152,26 @@ registrar.getLabel(addr); // "8d25687829d6b85d9e0020b8c89e3ca24de20a89"
90152
registrar.node(addr);
91153
```
92154

155+
### L1ConfigResolver
156+
157+
An L1 resolver that reads ENS records from a ConfigResolver deployed on L2 (Base) using CCIP-Read:
158+
159+
```solidity
160+
// Supports standard ENS resolution methods
161+
resolver.addr(node); // Get ETH address
162+
resolver.text(node, "url"); // Get text record
163+
resolver.contenthash(node); // Get contenthash
164+
165+
// Also supports ENSIP-10 extended resolution
166+
resolver.resolve(name, data);
167+
```
168+
169+
**Verifier Addresses:**
170+
| Network | Verifier |
171+
|---------|----------|
172+
| Sepolia | `0x7F68510F0fD952184ec0b976De429a29A2Ec0FE3` |
173+
| Mainnet | `0x0bC6c539e5fc1fb92F31dE34426f433557A9A5A2` |
174+
93175
## Development
94176

95177
### Prerequisites
@@ -123,25 +205,68 @@ forge snapshot
123205

124206
## Architecture
125207

208+
### L1 Claiming with L2 Storage (Recommended)
209+
210+
Users claim subnames on L1 (Ethereum) and can change their resolver. Records are stored on L2 (Base) for lower gas costs.
211+
212+
```
213+
┌─────────────────────────────────────────────────────────────────────────┐
214+
│ L1 (Ethereum) │
215+
├─────────────────────────────────────────────────────────────────────────┤
216+
│ │
217+
│ ┌─────────────────────────────┐ ┌───────────────────────────────┐ │
218+
│ │ AddressSubnameRegistrar │ │ L1ConfigResolver │ │
219+
│ │ ───────────────────────── │ │ ─────────────────────────── │ │
220+
│ │ • Users call claim() │────▶│ • Default resolver for │ │
221+
│ │ • Creates ENS node on L1 │ │ claimed subnames │ │
222+
│ │ │ │ • Reads via CCIP-Read │ │
223+
│ └─────────────────────────────┘ └───────────────┬───────────────┘ │
224+
│ │ │
225+
│ User owns ENS node → can change resolver if desired │ │
226+
└───────────────────────────────────────────────────────┼──────────────────┘
227+
│ CCIP-Read
228+
229+
┌─────────────────────────────────────────────────────────────────────────┐
230+
│ L2 (Base) │
231+
├─────────────────────────────────────────────────────────────────────────┤
232+
│ ┌─────────────────────────────────────────────────────────────────┐ │
233+
│ │ ConfigResolver - stores records (text, address, contenthash) │ │
234+
│ └─────────────────────────────────────────────────────────────────┘ │
235+
└─────────────────────────────────────────────────────────────────────────┘
236+
```
237+
238+
**User Flow:**
239+
240+
1. Claim subname on L1 → `registrar.claim()`
241+
2. Set records on L2 → `resolver.setText(node, "url", "https://...")`
242+
3. L1 resolution reads from L2 via CCIP-Read
243+
4. Optionally change resolver on L1 (user owns the ENS node)
244+
245+
### CCIP-Read Flow
246+
126247
```
127-
┌─────────────────────────────────────────────────────────────┐
128-
│ User's Wallet │
129-
└─────────────────────────────────────────────────────────────┘
130-
131-
132-
┌─────────────────────────────────────────────────────────────┐
133-
│ AddressSubnameRegistrar │
134-
│ ┌─────────────────────────────────────────────────────┐ │
135-
│ │ claim() → creates <address>.parent.eth │ │
136-
│ └─────────────────────────────────────────────────────┘ │
137-
└─────────────────────────────────────────────────────────────┘
138-
139-
┌───────────────┴───────────────┐
140-
▼ ▼
141-
┌─────────────────────────┐ ┌─────────────────────────────┐
142-
│ ENS Registry │ │ ConfigResolver │
143-
│ (stores ownership) │ │ (stores records) │
144-
└─────────────────────────┘ └─────────────────────────────┘
248+
┌──────────────────┐ 1. Call ┌─────────────────────┐
249+
│ Your dApp │ ───────────────► │ L1ConfigResolver │
250+
│ (Frontend) │ │ (Ethereum L1) │
251+
└──────────────────┘ └────────┬────────────┘
252+
▲ │
253+
│ 2. Reverts with
254+
│ OffchainLookup
255+
│ │
256+
│ 5. Return ▼
257+
│ verified ┌─────────────────────────────┐
258+
│ data │ Gateway (off-chain) │
259+
│ └─────────────┬───────────────┘
260+
│ │
261+
│ 3. Fetch proofs from L2
262+
│ │
263+
│ ▼
264+
│ ┌─────────────────────────────┐
265+
│ │ ConfigResolver (Base L2) │
266+
│ └─────────────────────────────┘
267+
│ │
268+
│ 4. Return proofs
269+
└─────────────────────────────────┘
145270
```
146271

147272
## License

0 commit comments

Comments
 (0)