| name | meganames |
| description | AI coding skill for MegaNames (.mega naming service on MegaETH). Covers name registration with USDM payments, forward/reverse resolution, text records, free subdomains, subdomain marketplace with token gating, Warren Protocol contenthash for on-chain websites, and frontend integration with wagmi/viem. Works with Claude Code, Cursor, Windsurf, and OpenClaw. |
MegaNames (.mega) Development Skill
What This Skill Is For
Use this skill when the user asks for:
- Registering or renewing
.mega names on MegaETH
- Resolving names to addresses (forward) or addresses to names (reverse)
- Setting text records (avatar, social links, bio)
- Creating or revoking subdomains
- Selling subdomains via the marketplace (SubdomainRouter)
- Token-gating subdomain purchases
- Linking Warren Protocol on-chain websites to
.mega names
- Building frontends that integrate MegaNames resolution
- Querying name ownership, expiry, or marketplace state
Chain Configuration
| Network | Chain ID | RPC | Explorer |
|---|
| Mainnet | 4326 | https://mainnet.megaeth.com/rpc | https://mega.etherscan.io |
| Testnet | 6343 | https://carrot.megaeth.com/rpc | https://testnet-mega.etherscan.io |
Contract Addresses (Mainnet)
| Contract | Address |
|---|
| MegaNames | 0x5B424C6CCba77b32b9625a6fd5A30D409d20d997 |
| USDM | 0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7 |
| Renderer | 0x8d206c277E709c8F4f8882fc0157bE76dA0C48C4 |
| SubdomainRouter | 0xdB5e5Ab907e62714D7d9Ffde209A4E770a0507Fe |
| SubdomainLogic | 0xf09fB5cB77b570A30D68b1Aa1d944256171C5172 |
| Fee Recipient | 0x25925C0191E8195aFb9dFA35Cd04071FF11D2e38 |
Testnet: MegaNames 0x8F0310eEDcfB71E5095ee5ce4f3676D9cEA65101 · MockUSDM 0xa8a7Ea151E366532ce8b0442255aE60E0ff2F833
Frontend: dotmega.domains
Default Stack Decisions (Opinionated)
1. Use eth_sendRawTransactionSync for all writes
MegaETH returns receipts in <10ms via EIP-7966. No polling needed.
2. Use registerWithPermit when possible
Single-tx registration via ERC-2612 permit — better UX than approve + register.
3. Use on-contract fee calculation
Call calculateFee(labelLength, numYears) instead of replicating discount logic locally.
4. Resolve via tokenId, not string lookups
Compute the tokenId client-side, then call addr(tokenId). Never send raw label strings to read functions.
5. Labels are always lowercase
Normalize labels with .toLowerCase() before hashing. The contract enforces [a-z0-9-] with no leading/trailing hyphens. Max 255 characters.
Token ID Computation
Names map to ERC-721 token IDs via ENS-style namehashing:
import { keccak256, encodePacked, toBytes } from 'viem'
const MEGA_NODE = keccak256(encodePacked(['bytes32', 'bytes32'], [
'0x0000000000000000000000000000000000000000000000000000000000000000',
keccak256(toBytes('mega'))
]))
function getTokenId(label: string): bigint {
return BigInt(keccak256(encodePacked(['bytes32', 'bytes32'], [
MEGA_NODE, keccak256(toBytes(label.toLowerCase()))
])))
}
function getSubTokenId(parentTokenId: bigint, subLabel: string): bigint {
const parentBytes = `0x${parentTokenId.toString(16).padStart(64, '0')}` as `0x${string}`
return BigInt(keccak256(encodePacked(['bytes32', 'bytes32'], [
parentBytes, keccak256(toBytes(subLabel.toLowerCase()))
])))
}
Fee Schedule
All fees in USDM (18 decimals).
| Label Length | Annual Fee | Multi-Year Discounts |
|---|
| 1 char | $1,000 | 2yr: 5%, 3yr: 10%, 5yr: 15%, 10yr: 25% |
| 2 chars | $500 | Same discount tiers |
| 3 chars | $100 | Same discount tiers |
| 4 chars | $10 | Same discount tiers |
| 5+ chars | $1 | Same discount tiers |
Core Operations
Register a Name
const fee = await publicClient.readContract({
address: MEGANAMES, abi, functionName: 'calculateFee',
args: [BigInt(label.length), BigInt(numYears)]
})
await walletClient.writeContract({
address: USDM, abi: erc20Abi, functionName: 'approve',
args: [MEGANAMES, fee]
})
await walletClient.writeContract({
address: MEGANAMES, abi, functionName: 'register',
args: [label, ownerAddress, BigInt(numYears)]
})
Register with Permit (Single Transaction)
megaNames.registerWithPermit(
"yourname",
msg.sender,
1, // numYears
deadline, // permit deadline
v, r, s // ERC-2612 permit signature
);
Resolve Name → Address
const tokenId = getTokenId("bread")
const address = await publicClient.readContract({
address: MEGANAMES, abi, functionName: 'addr', args: [tokenId]
})
Resolve Address → Name (Reverse)
const name = await publicClient.readContract({
address: MEGANAMES, abi, functionName: 'getName', args: [userAddress]
})
Set Text Records
await walletClient.writeContract({
address: MEGANAMES, abi, functionName: 'setText',
args: [tokenId, "com.twitter", "@yourhandle"]
})
Standard keys: avatar, url, com.twitter, com.github, com.discord, org.telegram, description
Create Subdomains (Free)
await walletClient.writeContract({
address: MEGANAMES, abi, functionName: 'registerSubdomain',
args: [parentTokenId, "blog"]
})
Subdomain Marketplace
Name owners sell subdomains through the SubdomainRouter. 97.5% to owner, 2.5% protocol fee.
Seller Setup
const ROUTER = '0xdB5e5Ab907e62714D7d9Ffde209A4E770a0507Fe'
const LOGIC = '0xf09fB5cB77b570A30D68b1Aa1d944256171C5172'
await walletClient.writeContract({
address: MEGANAMES, abi: erc721Abi, functionName: 'setApprovalForAll',
args: [ROUTER, true]
})
await walletClient.writeContract({
address: LOGIC, abi: logicAbi, functionName: 'setPrice',
args: [parentTokenId, parseUnits('1', 18)]
})
await walletClient.writeContract({
address: ROUTER, abi: routerAbi, functionName: 'configure',
args: [parentTokenId, payoutAddress, true, 0]
})
Buyer Flow
const [allowed, price, protocolFee, total] = await publicClient.readContract({
address: ROUTER, abi: routerAbi, functionName: 'quote',
args: [parentTokenId, "sublabel", buyerAddress]
})
await walletClient.writeContract({
address: USDM, abi: erc20Abi, functionName: 'approve',
args: [ROUTER, total]
})
await walletClient.writeContract({
address: ROUTER, abi: routerAbi, functionName: 'register',
args: [parentTokenId, "sublabel", '0x0000000000000000000000000000000000000000']
})
Token Gating
await walletClient.writeContract({
address: LOGIC, abi: logicAbi, functionName: 'setTokenGate',
args: [parentTokenId, tokenContractAddress, 1n]
})
Batch Registration
// Register up to 50 subdomains in one tx
string[] memory labels = new string[](3);
labels[0] = "alpha"; labels[1] = "beta"; labels[2] = "gamma";
uint256[] memory tokenIds = router.registerBatch(parentTokenId, labels, address(0));
Warren Contenthash (On-Chain Websites)
Link a .mega name to a Warren Protocol on-chain website:
await walletClient.writeContract({
address: MEGANAMES, abi, functionName: 'setWarrenContenthash',
args: [tokenId, warrenTokenId, true]
})
const warren = await publicClient.readContract({
address: MEGANAMES, abi, functionName: 'warren', args: [tokenId]
})
Expired Names & Premium Decay
Names expire after their registration period. After a 90-day grace period, names become available with a Dutch auction premium decaying linearly from $10,000 → $0 over 21 days.
const premium = await publicClient.readContract({
address: MEGANAMES, abi, functionName: 'currentPremium', args: [tokenId]
})
Enumeration & Stats
const tokenIds = await publicClient.readContract({
address: MEGANAMES, abi, functionName: 'tokensOfOwner', args: [userAddress]
})
const registered = await publicClient.readContract({ address: MEGANAMES, abi, functionName: 'totalRegistrations' })
const volume = await publicClient.readContract({ address: MEGANAMES, abi, functionName: 'totalVolume' })
MegaETH-Specific Notes
- Gas estimation: Always use
eth_estimateGas via RPC — local Foundry estimation may undercount on MegaETH
- Instant receipts: Use
eth_sendRawTransactionSync (EIP-7966) for immediate confirmation
- USDM: 18 decimals, ERC-2612 permit supported
- No commit-reveal: MegaETH block times (~10ms) make front-running impractical
Full ABI Reference
See AGENTS.md in the repo root for the complete function reference, events, and integration patterns.