Smart contracts for managing ENS-compatible names on the Celo network. This system enables subdomain registration, resolution, and management through a combination of L1 and L2 contracts.
The Celo Names system consists of four main contracts that work together to provide a complete naming service:
- L1Resolver: Resolves names on Ethereum mainnet and proxies subname resolution to L2 via CCIP-Read
- L2Registry: ERC721-based registry that manages subdomains as NFTs on Celo L2. It also acts on ENS compatible resolver that stores records for a name
- L2Registrar: Handles paid registration and renewal of subdomains
- L2SelfRegistrar: Allows Self-verified users to claim free subdomains
The L1Resolver serves two primary purposes:
- On-chain Resolution: Acts as a resolver for storing records for the parent name (e.g.,
celo.eth) on Ethereum mainnet - Off-chain Proxy: Uses wildcard resolution with CCIP-Read (ENSIP-10) to proxy subname resolution requests to the gateway server, which then queries the L2 registry
L2Registry is an ERC721-based registry that manages subdomains as NFTs on the Celo network. Each subdomain is minted as an NFT, providing ownership and transfer capabilities. Additionally, L2Registry implements resolver functionality, allowing it to store and read ENS records (addresses, text records, content hashes, etc.) directly on-chain.
L2Registrar handles paid registration and renewal of subdomains. It integrates with the L2Registry to create subdomains and manages pricing based on label length and duration.
L2SelfRegistrar allows users who have completed identity verification through the Self protocol to claim free subdomains. This provides a way for verified users to obtain their first subdomain without payment.
contracts/
├── contracts/
│ ├── L1Resolver.sol # L1 resolver with CCIP-Read support
│ ├── L2Registry.sol # ERC721 registry for subdomains
│ ├── L2Registrar.sol # Paid registration registrar
│ ├── L2SelfRegistrar.sol # Free claims for verified users
│ ├── L2Resolver.sol # Resolver implementation for L2
│ ├── common/ # Shared utilities
│ ├── interfaces/ # Contract interfaces
│ ├── registrar/ # Registrar components (pricing, treasury, rules)
│ ├── resolver/ # Resolver profiles (ABI, Addr, Text, etc.)
│ └── deployment/ # Deployment helpers
├── test/ # Comprehensive test suite
├── scripts/ # Deployment and utility scripts
│ ├── deploy_all_l2.ts # Main deployment script
│ ├── blacklist.ts # Blacklist management
│ └── premint.ts # Premint script
├── hardhat.config.ts # Hardhat configuration
└── package.json # Dependencies and scripts
- Node.js (v20 or later)
- npm or yarn
- Git
- Clone the repository and navigate to the contracts directory:
cd contracts- Install dependencies:
npm install- Set up environment variables:
Create a .env file in the contracts directory (see env.example for reference):
DEPLOYER_KEY=your_private_key_here
CELO_RPC_URL=https://forno.celo.org
CELO_SEPOLIA_RPC=https://sepolia-forno.celo.org
MAINNET_RPC_URL=https://eth.llamarpc.comCompile the contracts:
npm run compileRun the test suite:
npm testRun tests with gas reporting:
npm run test:gasGenerate coverage report:
npm run coverageFormat code using Prettier:
npm run formatCheck formatting without making changes:
npm run format:checkStart a local Hardhat node:
npm run nodeIn a separate terminal, deploy to localhost:
npm run deploy:localDeploy to Celo Sepolia testnet:
npm run deploy --network celotestDeploy to Celo mainnet:
npm run deploy --network celoDeploy to Ethereum mainnet (for L1Resolver):
npm run deploy --network mainnetThe deployment script (scripts/deploy_all_l2.ts) follows this order:
- Deploy
L2RegistryDeployerwhich deploys theL2Registrywith root name configuration - Deploy
L2RegistrarDeployerwhich deploys:RegistrarStoragefor whitelist/blacklist managementL2Registrarwith pricing and treasury configurationL2SelfRegistrarwith Self protocol integration
- Configure registrars in the registry (set both L2Registrar and L2SelfRegistrar as authorized registrars)
- Transfer ownership to multisig
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Run code formatting
- Submit a pull request
For questions or issues, please open an issue on the GitHub repository or join the Celonames support Telegram group.