Quickstart
Arc mainnet uses chain ID 5042. Its native currency is USDC with 18 decimals, so transaction value and gas are both denominated in USDC.
pnpm add viemimport { createPublicClient, defineChain, http } from 'viem'
export const arc = defineChain({
id: 5042,
name: 'Arc mainnet',
nativeCurrency: { name: 'USD Coin', symbol: 'USDC', decimals: 18 },
rpcUrls: { default: { http: ['https://arcname.io/rpc/arc'] } },
blockExplorers: {
default: { name: 'Arc Explorer', url: 'https://arc.exploreme.pro' }
}
})
export const client = createPublicClient({
chain: arc,
transport: http()
})- Chain ID
5042- Native currency
- USDC, 18 decimals
- RPC
https://arcname.io/rpc/arc
Resolve a name
Normalize user input to lowercase, remove a trailing .arc, validate the label, then namehash the complete name. Read the current resolver from the controller so your integration follows future resolver upgrades.
import { namehash, parseAbi, zeroAddress } from 'viem'
import { client } from './arc'
const controller = '0x7D76e07fAc9ACCFEf16563Affef43c950038bB87'
const controllerAbi = parseAbi([
'function resolver() view returns (address)'
])
const resolverAbi = parseAbi([
'function addr(bytes32 node) view returns (address)'
])
const resolver = await client.readContract({
address: controller,
abi: controllerAbi,
functionName: 'resolver'
})
const address = await client.readContract({
address: resolver,
abi: resolverAbi,
functionName: 'addr',
args: [namehash('alice.arc')]
})
if (address === zeroAddress) throw new Error('Name does not resolve')The resolver returns the zero address when a name is expired or has no usable record. Do not send funds until the result is nonzero. Resolution is specific to this registry; standard Ethereum ENS clients do not discover .arc names automatically.
Register a name
Registration uses commit and reveal to prevent someone from copying a pending name from the public mempool. A complete purchase requires two wallet transactions.
Create and submit the commitment
Generate a private 32-byte secret. Call
makeCommitment(name, owner, duration, secret), then submit the returned value tocommit(bytes32). Keep the secret in the browser until registration finishes.Wait at least 60 seconds
The commitment remains usable for 24 hours. If it expires, create a new secret and commitment.
Quote the NAMES buyback
Read
namesToken()andbuybackAdapter(). Simulate the adapter’sbuycall with the registration price, then set a minimum output and a short deadline.Register and pay
Call
registerWithBuybackwith the same name, owner, duration, and secret. Set the transaction value to the exact price returned byrentPrice. The NFT and initial address record are assigned to the owner when the transaction confirms.
import { parseAbi } from 'viem'
import { client } from './arc'
const controller = '0x7D76e07fAc9ACCFEf16563Affef43c950038bB87'
const abi = parseAbi([
'function available(string name) view returns (bool)',
'function rentPrice(string name, uint256 duration) view returns (uint256)'
])
const oneYear = 365n * 24n * 60n * 60n
const [available, price] = await Promise.all([
client.readContract({
address: controller, abi, functionName: 'available', args: ['alice']
}),
client.readContract({
address: controller, abi, functionName: 'rentPrice', args: ['alice', oneYear]
})
])| Label length | Annual price | Minimum duration |
|---|---|---|
| 3 characters | 100 USDC | 1 year |
| 4 characters | 25 USDC | 1 year |
| 5 to 63 characters | 5 USDC | 1 year |
Each completed registration and renewal uses its registration payment to buy NAMES through the configured Argus pool and sends the purchased tokens to the burn address. The transaction reverts if the quote expires, the token configuration changes, or output falls below the submitted minimum.
Manage address records
A registration is an ERC-721 token. The current token owner can update the name’s Arc address through the resolver. Transfer the registrar NFT, then call reclaim if the registry owner must follow the new NFT owner.
import { namehash, parseAbi } from 'viem'
const resolverAbi = parseAbi([
'function setArcAddress(bytes32 node, address target)'
])
await walletClient.writeContract({
address: '0x1A192d7a63a05b339213a34f181f103A4eaB1441',
abi: resolverAbi,
functionName: 'setArcAddress',
args: [namehash('alice.arc'), newAddress],
account
})Deployed contracts
Use the controller as the entry point. The protocol is deployed behind transparent upgradeable proxies, and the controller exposes the active registry, registrar, resolver, token, and buyback adapter.
| Contract | Address | Role |
|---|---|---|
| Controller | 0x7D76e07fAc9ACCFEf16563Affef43c950038bB87 | Pricing, commitments, registration, renewal, and buybacks |
| Registry | 0x1C1678b8aD26A68e2AF22cdE6a29994d460329C4 | Ownership and resolver records for the .arc namespace |
| Registrar | 0x8B6f5c349669283451eE44629737bA1137E2eb72 | ERC-721 ownership and expiration for registered labels |
| Resolver | 0x1A192d7a63a05b339213a34f181f103A4eaB1441 | Arc address and text records for active names |
| Buyback adapter | 0xd9F4BE8f1E3A612f4Ed796655A504481837f7448 | Swaps registration revenue for NAMES through Argus |
Protocol behavior
- Valid labels
- 3 to 63 lowercase ASCII letters, numbers, or hyphens. A label cannot start or end with a hyphen.
- Expiration
- Expired names resolve to the zero address. The registrar keeps a renewal grace period before a name becomes available again.
- Upgrades
- The controller, registry, registrar, and resolver are proxies controlled by the configured ProxyAdmin. Read active child addresses from the controller where possible.
- Security status
- The contracts have automated tests and no published independent audit. Integrators should review the contracts and set conservative buyback slippage limits.