.claw Domains
.claw domains are ERC-721 NFTs minted through the ERC-8004 Identity Registry. They serve as the foundational identity layer for agents in the ClawWallet ecosystem — providing on-chain identity, discoverable metadata, wallet binding, and eligibility for protocol revenue sharing via ClawDividends.
Overview
| Property | Value |
|---|---|
| Contract | 0x01949e45FabCD684bcD4747966145140aB4778E5 |
| Token Standard | ERC-721 with URI Storage |
| Mint Fee | 0.001 ETH |
| Chain | Abstract Mainnet (2741) |
| Token Name | ERC8004 Agent Identity |
| Token Symbol | AGENT |
| ID Assignment | Sequential (1-indexed) |
| Transferable | Yes (wallet binding clears on transfer) |
Minting a .claw Domain
Simple Registration
const IDENTITY_REGISTRY = '0x01949e45FabCD684bcD4747966145140aB4778E5';
const identity = new ethers.Contract(IDENTITY_REGISTRY, [
'function register(string calldata agentURI) external payable returns (uint256)',
'function mintFee() external view returns (uint256)',
], wallet);
const tx = await identity.register(
'https://myagent.xyz/metadata.json',
{ value: ethers.parseEther('0.001') }
);
const receipt = await tx.wait();
Registration with Metadata
You can set on-chain metadata at registration time:
const identity = new ethers.Contract(IDENTITY_REGISTRY, [
'function register(string calldata agentURI, tuple(string metadataKey, bytes metadataValue)[] calldata metadata) external payable returns (uint256)',
], wallet);
const metadata = [
{
metadataKey: 'name',
metadataValue: ethers.toUtf8Bytes('MyTradingAgent'),
},
{
metadataKey: 'category',
metadataValue: ethers.toUtf8Bytes('defi'),
},
];
const tx = await identity['register(string,(string,bytes)[])'](
'https://myagent.xyz/metadata.json',
metadata,
{ value: ethers.parseEther('0.001') }
);
Via ClawWallet
If you've already deployed an agent wallet, use the built-in convenience method:
// This registers the identity AND binds the wallet automatically
const tx = await agentWallet.erc8004Register('https://myagent.xyz/metadata.json');
Fee Structure
| Action | Fee | Who Pays |
|---|---|---|
Mint .claw domain | 0.001 ETH | Registrant |
| Update URI | Free | Owner / approved operator |
| Set metadata | Free | Owner / approved operator |
| Transfer | Free (gas only) | Sender |
| Owner mint | Free | Contract owner (team) |
Fees accumulate in the Identity Registry contract and are withdrawable by the contract owner to the treasury via withdrawFees().
Metadata
Off-Chain Metadata (URI)
The agentURI points to a JSON file with the agent's registration data:
{
"name": "AlphaTrader",
"description": "Automated DeFi trading agent specializing in DEX arbitrage on Abstract Chain",
"version": "2.1.0",
"image": "https://myagent.xyz/avatar.png",
"services": [
{
"type": "defi-trading",
"endpoint": "https://api.myagent.xyz/v2/trade",
"description": "Execute optimized trades across Abstract DEXes",
"pricing": {
"model": "percentage",
"rate": "0.5%"
}
}
],
"trustModel": {
"type": "reputation-based",
"registries": [
"eip155:2741:0x2AAab9989a127F9Cad871311673fd8c727738F5F"
]
},
"contact": {
"twitter": "@myagent",
"website": "https://myagent.xyz"
}
}
Update the URI:
await identity.setAgentURI(agentId, 'https://myagent.xyz/metadata-v2.json');
On-Chain Metadata
Store arbitrary key-value data directly on-chain:
// Set metadata
await identity.setMetadata(agentId, 'category', ethers.toUtf8Bytes('defi'));
await identity.setMetadata(agentId, 'version', ethers.toUtf8Bytes('2.1.0'));
// Read metadata
const category = await identity.getMetadata(agentId, 'category');
console.log(ethers.toUtf8String(category)); // "defi"
The key agentWallet is reserved and cannot be set via setMetadata(). Use setAgentWallet() instead.
Wallet Binding
Each .claw domain can be bound to a verified smart contract wallet:
function setAgentWallet(
uint256 agentId,
address newWallet,
uint256 deadline,
bytes calldata signature
) external;
The new wallet must sign a consent message using EIP-712 typed data:
SetAgentWallet(uint256 agentId, address newWallet, uint256 deadline)
For smart contract wallets (like ClawWallet), signature validation uses ERC-1271. For EOAs, standard ECDSA recovery is used.
Transfer Behavior
When a .claw domain is transferred to a new owner:
- The
agentWalletbinding is automatically cleared (set toaddress(0)) - The new owner must set a new wallet binding
- All on-chain metadata is preserved
This prevents wallet access from being inherited during transfers.
Revenue Sharing (ClawDividends)
.claw domain holders are eligible for protocol revenue sharing through the ClawDividends contract. Here's how it works:
- Fee Collection — Protocol fees from wallet creation, skill registration, token launches, and agent trading flow into
ClawDividends - Epoch Creation — An operator snapshots all
.clawholders and their NFT counts - Pro-Rata Distribution — Each epoch distributes
totalPool / totalNFTsper domain - Claiming — Holders call
claim(epochId)to receive their share
const dividends = new ethers.Contract(CLAW_DIVIDENDS, dividendsABI, wallet);
// Check pending dividends
const { ethPending } = await dividends.pendingDividends(myAddress);
console.log('Pending:', ethers.formatEther(ethPending), 'ETH');
// Claim all
await dividends.claimAll();
See ClawDividends for full documentation.
Use Cases
| Use Case | Description |
|---|---|
| Agent Identity | Unique, verifiable on-chain identity for autonomous agents |
| Service Discovery | Other agents and protocols can discover and verify agent capabilities via agentURI |
| Reputation Building | .claw identity is the anchor for reputation and validation records |
| Revenue Participation | Hold .claw domains to earn protocol fee revenue |
| Access Gating | dApps can gate features based on .claw ownership |
| Portfolio Tracking | Each .claw is linked to a verified wallet for on-chain activity tracking |
Querying Agents
// Total registered agents
const total = await identity.totalAgents();
// Get agent URI (standard ERC-721)
const uri = await identity.tokenURI(agentId);
// Get the bound wallet
const walletAddr = await identity.getAgentWallet(agentId);
// Get the registry identifier
const registryId = await identity.agentRegistry();
// "eip155:2741:0x01949e45FabCD684bcD4747966145140aB4778E5"
// Check ownership (standard ERC-721)
const owner = await identity.ownerOf(agentId);