Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions scripts/resolver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,139 @@ Then `docker compose down -v && docker compose up -d` (the `-v` wipes state so N
- Ports 30303/9000 are p2p — open on your firewall for sync.
- `jwt.hex` is generated on first run by the `jwt-init` service and shared between Reth and Nimbus via the `jwt` volume.
- To wipe state and re-sync: `docker compose down -v`.

## SNRC resolver REST API (`snrc-resolve.py`)

The companion script `snrc-resolve.py` exposes the SimpleX Namespace
Registry (SNRC) over a small JSON HTTP API. It talks to the same local
Reth + Nimbus stack described above (set `NETWORK=mainnet` in `.env`),
reading the SNRC contracts directly on Ethereum mainnet.

Install the only runtime dependency (same as `ens-lookup.py`):

```sh
pip install --break-system-packages 'eth-hash[pycryptodome]'
```

### Deployed registries

| TLD | Network | ENSRegistry address |
|------------|------------------|----------------------------------------------|
| `.testing` | Ethereum mainnet | `0x03f438da0bd44da3c6c1d0392f8ba183b8b3a7a6` |
| `.simplex` | — (not deployed) | — |

Each TLD is an independent ENS-shaped deployment with its own
`ENSRegistry`. The resolver dispatches by the queried name's rightmost
label, so a single instance can serve both TLDs concurrently once
`.simplex` launches.

### Running

With Reth bound to `127.0.0.1:8545` (the default Quickstart layout
above), no env vars are required — the script defaults to that RPC and
to the mainnet `.testing` registry:

```sh
./scripts/resolver/snrc-resolve.py
```

Output on startup:

```
snrc-resolve listening on 0.0.0.0:8000
RPC = http://127.0.0.1:8545
Registries:
.testing = 0x03f438da0bd44da3c6c1d0392f8ba183b8b3a7a6
.simplex = (not configured)
GET /resolve/<name> GET /health
```

Override the listen port or bind address with `SNRC_PORT` / `SNRC_BIND`.

### Resolving a name

`foobar.testing` is registered on mainnet with every text and
multicoin record populated (useful as a smoke-test target):

```sh
curl -s http://127.0.0.1:8000/resolve/foobar.testing | jq .
```

```json
{
"name": "foobar.testing",
"nickname": "Foo",
"website": "https://foo.bar",
"location": "",
"simplexContact": "https://smp16.simplex.im/a#Q_F00BA7",
"simplexChannel": "",
"eth": null,
"btc": "bc1qpzht4wp64yg7z6sgl07vvrnepyux740juynfcn",
"xmr": "4ANzdVJFxLtCKcBgNGkFSEA41zJFgrTX93LWt9UR6xpg7YNCsdrSV817cw2xKT8NXeS5euBBqTApS2u8kRTxMhyiDGN3Qgt",
"dot": "139GgyEsXDyGLhmhBTPmDmGCyTvTVuLad3YjHax2PWLK6p3s",
"owner": "0xd83bb610fbad567fb5d8755ec162881e46d1fbc9",
"resolver": "0x80fa1903e70af03e79c73fb7feae2fb33aebae01"
}
```

All field names are lowercase-initial and contain no dots, so they map
directly onto Haskell record fields and can be consumed via aeson's
`Generic`-derived `FromJSON` without a key-rewriting layer. Equivalent
Haskell record:

```haskell
data SnrcRecord = SnrcRecord
{ name :: Text
, nickname :: Text
, website :: Text
, location :: Text
, simplexContact :: Text
, simplexChannel :: Text
, eth :: Maybe Text
, btc :: Maybe Text
, xmr :: Maybe Text
, dot :: Maybe Text
, owner :: Text
, resolver :: Text
} deriving (Generic, FromJSON)
```

(The on-chain text-record keys still use the ENSIP-5 dot convention —
`simplex.contact` and `simplex.channel`. Only the resolver's JSON
surface camelCases them.)

Address encoding matches each chain's canonical user-facing form:
EIP-55 mixed-case for `eth`, bech32/bech32m for `btc` segwit/taproot
(base58check for legacy P2PKH/P2SH), SS58 with Polkadot prefix 0 for
`dot`, Monero-base58 for `xmr`. Unrecognised payloads fall back to
`0x`-prefixed hex.

#### Subnames

Subnames work exactly the same. try `bar.foobar.testing`.

```sh
curl -s http://127.0.0.1:8000/health
# → {"ok": true, "rpc": "http://127.0.0.1:8545", "registries": {"testing": "0x…", "simplex": ""}}
```

### Pointing at multiple deployments

Once `.simplex` deploys, point a single resolver instance at both
registries — requests are dispatched by the rightmost label:

```sh
SNRC_REGISTRY_SIMPLEX=0x...mainnet-simplex-ENSRegistry... \
./scripts/resolver/snrc-resolve.py
```

Queries for a TLD with no registry configured return HTTP 400 with the
list of supported TLDs.

### Error responses

| Status | When |
|--------|-----------------------------------------------------------------------|
| 400 | TLD not configured (`/resolve/foo.simplex` while `.simplex` is empty) or path not a fully-qualified name |
| 404 | Name has no resolver set on the registry (`ENSRegistry.resolver(node)` is zero) |
| 502 | Upstream RPC error / unreachable (Reth not running or not synced) |
Loading
Loading