# Verified records
URL: https://docs.arcns.io/verified/

> What the verified flag on an ArcNS address record means, how an owner proves control of an address for a coin type, and the arcns:v1 challenge format.

Every address record ArcNS returns carries a verification flag. This page says exactly what it means, so a wallet or explorer can decide what to show and what to warn about.

<LlmActions />

## What `verified` means

| Value        | Meaning                                                                                                                | What to do                                                  |
| ------------ | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `verified`   | The owner **proved control of this address for this coin type on chain** (`verified(node, coinType)` on the resolver). | Show it plainly.                                            |
| `unverified` | A record exists but ownership was never proved for it. It may still be correct; nobody has shown that it is.           | Show a warning and make the user look twice before sending. |

The flag is **per coin type**. `alice.arc` can have a verified Arc record and an unverified Bitcoin record at the same time. In the SDK it is `Resolved.verification` and `AddressRecord.verification`; in the API it is the boolean `addr.verified`.

Two things the flag never does:

* It never turns a controller into a payment address. `controller` (the SDK) or `owner` (the API) is who holds the name; the resolvers never fall back to it, verified or not.
* It never survives an ownership change. Records are keyed by the name's `epoch`, which bumps on every transfer, so a proof made by a previous owner is unreachable by construction.

Answers read from the pinned peer registry are always `unverified`: `verified` is an ArcNS resolver extension, and the peer resolver only exposes the legacy `addr(bytes32)` record.

## How a record becomes verified

For the Arc address itself, the simplest proof is a transaction from that address: `buildVerifyAddrSelf` proves `msg.sender`.

```ts
await wallet.sendTransaction(buildVerifyAddrSelf({ deployment, name: "alice.arc" }));   // proves the Arc address (msg.sender)
```

For another chain's address the owner signs a challenge with the wallet that holds that address, then submits the signature on Arc:

```ts
import { buildChallenge, generateNonce, encodeProof, buildVerifyAddr } from "@arcns/resolve";
const challenge = buildChallenge({ purpose: "rec", namespace: "arc", label: "alice", coinType: COIN_TYPE.ETH, epoch, chainId: 5042002, registry, nonce: generateNonce() });
// arcns:v1:rec:arc:alice:60:3:5042002:0x…:9f3c…
// the ETH wallet signs `challenge` (EIP-191); then:
buildVerifyAddr({ deployment, name: "alice.arc", chain: "ETH", proof: { signature } });
```

## The challenge format

```text
arcns:v1:rec:arc:alice:60:3:5042002:0x…:nonce
```

| Field      | Example   | Meaning                                                                                    |
| ---------- | --------- | ------------------------------------------------------------------------------------------ |
| `arcns:v1` |           | scheme and version                                                                         |
| purpose    | `rec`     | a record proof                                                                             |
| namespace  | `arc`     | `handle`, `arc` or `circle`                                                                |
| label      | `alice`   | the name's label                                                                           |
| coin type  | `60`      | ENSIP-9 / ENSIP-11 coin type being proved (`BTC` 0, `ETH` 60, `SOL` 501, `ARC` 2152525650) |
| epoch      | `3`       | the name's current epoch; the proof dies with it                                           |
| chain id   | `5042002` | Arc testnet                                                                                |
| registry   | `0x…`     | the registry the name lives in                                                             |
| nonce      | `9f3c…`   | from `generateNonce()`; one use                                                            |

Binding the name, coin type, epoch, chain id and registry into the signed string is what stops a signature from being replayed for a different name, a different chain, or the same name after it changes hands.

Signature forms by chain:

* **ETH (and other EVM coin types):** EIP-191 signature over the challenge.
* **BTC:** a BIP-137 signature plus the 64-byte uncompressed public key.
* **SOL / X1 (ed25519):** signature followed by the public key.

Local pre-checks (`verifyEthProofLocal`, `verifyEthTypedProofLocal`, `verifyControlProofLocal`) let a wallet refuse a doomed transaction before it is sent. Both the EIP-191 and the EIP-712 forms exist while the contracts lane finalises which one the resolver verifies; one is removed before the first tagged release.

## Showing it

* Wallets: `verified` next to the address, nothing more; `unverified` as a warning that the user must pass through before "Send" is enabled. See [Wallets](/wallet/).
* Explorers: show the flag per record on the name page and never render an unverified record as if it were confirmed. See [Explorers](/explorer/).
* Agents and machine consumers: treat `verification !== "verified"` as "do not pay without a human".

## Questions

Questions: [support@arcns.io](mailto:support@arcns.io).
