Building an AI Agent with Web3 Identity
Learn how to create an AI agent that uses ENS names, x402 micropayments, and on-chain identity.
Overviewโ
This guide walks through building an autonomous AI agent with:
- ENS identity โ Resolvable name (e.g.,
yourbot.aboutme.eth) - Wallet capability โ Sign transactions and payments
- x402 integration โ Pay for API access without API keys
- On-chain registration โ ERC-8004 agent identity
Time to build: ~2 hours
Prerequisites: Node.js, basic Ethereum knowledge, $5 in ETH/USDC
Architectureโ
โโโโโโโโโโโโโโโโโโโ
โ Your Agent โ
โ (Node.js app) โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โโโ> Wallet (viem)
โ โโ> Sign EIP-712 messages
โ
โโโ> ENS Name (yourbot.aboutme.eth)
โ โโ> Resolves to your agent's wallet
โ
โโโ> Web3 Identity API
โโ> x402 payments for unlimited access
Step 1: Set Up Your Agent Walletโ
Every agent needs a wallet for identity and payments.
Install Dependenciesโ
npm install viem @x402/client dotenv
Generate a Walletโ
// scripts/generate-wallet.js
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
import fs from 'fs';
const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);
console.log('Agent Wallet:', account.address);
console.log('Private Key:', privateKey);
// Save securely (NEVER commit to git!)
fs.writeFileSync('.agent-wallet.key', privateKey, { mode: 0o600 });
Run it:
node scripts/generate-wallet.js
# Agent Wallet: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEa7
# Private Key: 0x...
โ ๏ธ Security: Add .agent-wallet.key to .gitignore immediately.
Step 2: Fund Your Agentโ
Your agent needs:
- ETH โ For gas fees (~$2-5)
- USDC (Base) โ For x402 API payments (~$1-2)
Get Testnet Funds (Development)โ
Base Sepolia:
- ETH: https://www.coinbase.com/faucets/base-ethereum-sepolia-faucet
- USDC: Use Uniswap faucet or bridge from Sepolia mainnet
Production Fundingโ
Base Mainnet:
- Bridge ETH/USDC from Ethereum mainnet using bridge.base.org
- Or buy directly on Base via Coinbase
Step 3: Register Your ENS Nameโ
Give your agent a human-readable identity.
Option A: Use aboutme.eth Subnames (Recommended)โ
// scripts/register-subname.js
import { createPublicClient, createWalletClient, http } from 'viem';
import { mainnet } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import fs from 'fs';
const privateKey = fs.readFileSync('.agent-wallet.key', 'utf8').trim();
const account = privateKeyToAccount(privateKey);
const client = createWalletClient({
account,
chain: mainnet,
transport: http()
});
// Register via Web3 Identity API
async function registerSubname(name) {
const response = await fetch(
`https://api.web3identity.com/api/subnames/aboutme.eth`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name,
owner: account.address,
records: {
description: 'AI agent for Web3 automation',
url: 'https://yourbot.example.com',
'com.twitter': '@yourbot'
}
})
}
);
const data = await response.json();
if (!response.ok) {
throw new Error(`Registration failed: ${data.error}`);
}
return data;
}
// Register yourbot.aboutme.eth
const result = await registerSubname('yourbot');
console.log('Registered:', result.name);
console.log('Cost:', result.payment.amount, 'USDC');
Pricing:
- 5+ characters: $0.97/year
- 3-4 characters: $4.97/year
- First subname per address: FREE ๐
Option B: Buy a Custom ENS Nameโ
If you want a top-level .eth name (e.g., yourbot.eth):
- Go to app.ens.domains
- Search for your desired name
- Purchase (prices vary: 3-letter = $640/yr, 5+ letter = $5/yr)
Step 4: Register as an ERC-8004 Agentโ
On-chain agent registration provides:
- Verifiable agent identity
- Searchable registry
- Reputation tracking (future)
// scripts/register-erc8004.js
import { createPublicClient, createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import fs from 'fs';
const privateKey = fs.readFileSync('.agent-wallet.key', 'utf8').trim();
const account = privateKeyToAccount(privateKey);
const client = createWalletClient({
account,
chain: base,
transport: http()
});
const REGISTRY_ADDRESS = '0x...'; // ERC-8004 registry on Base
const agentName = 'yourbot.aboutme.eth';
const agentType = 1; // 1 = autonomous agent
const metadata = JSON.stringify({
name: 'YourBot',
description: 'AI agent for Web3 automation',
version: '1.0.0',
capabilities: ['ens-resolution', 'x402-payments', 'data-aggregation']
});
const tx = await client.writeContract({
address: REGISTRY_ADDRESS,
abi: [{
name: 'registerAgent',
type: 'function',
inputs: [
{ name: 'name', type: 'string' },
{ name: 'agentType', type: 'uint8' },
{ name: 'metadata', type: 'string' }
],
outputs: [{ name: 'agentId', type: 'uint256' }]
}],
functionName: 'registerAgent',
args: [agentName, agentType, metadata]
});
console.log('Registration TX:', tx);
Gas cost: ~$0.50 on Base
Step 5: Integrate x402 Paymentsโ
Now your agent can pay for its own API access.
Install x402 Clientโ
npm install @x402/client
Make Your First Paid Requestโ
// scripts/agent-query.js
import { X402Client } from '@x402/client';
import { createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import fs from 'fs';
const privateKey = fs.readFileSync('.agent-wallet.key', 'utf8').trim();
const account = privateKeyToAccount(privateKey);
const wallet = createWalletClient({
account,
chain: base,
transport: http()
});
const x402 = new X402Client({
wallet,
chainId: 8453, // Base
facilitatorUrl: 'https://api.cdp.coinbase.com/platform/v2/x402'
});
// Query ENS name with automatic payment
async function resolveENS(name) {
const response = await x402.request(
`https://api.web3identity.com/api/ens/${name}`
);
return response.data;
}
const profile = await resolveENS('vitalik.eth');
console.log('Address:', profile.address);
console.log('Avatar:', profile.avatar);
console.log('Payment:', x402.lastPayment); // ~$0.01
How it works:
- Agent requests a paid endpoint
- x402 client signs an EIP-712 payment message
- Payment settles in USDC on Base
- API returns data instantly
Step 6: Build Agent Logicโ
Now assemble your agent's core functionality.
Example: ENS Monitoring Agentโ
// index.js
import { X402Client } from '@x402/client';
import { createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import fs from 'fs';
const privateKey = fs.readFileSync('.agent-wallet.key', 'utf8').trim();
const account = privateKeyToAccount(privateKey);
const wallet = createWalletClient({
account,
chain: base,
transport: http()
});
const x402 = new X402Client({
wallet,
chainId: 8453,
facilitatorUrl: 'https://api.cdp.coinbase.com/platform/v2/x402'
});
// Monitor ENS name changes
async function monitorENS(name) {
console.log(`[${new Date().toISOString()}] Monitoring ${name}...`);
const response = await x402.request(
`https://api.web3identity.com/api/ens/${name}`
);
const data = response.data;
// Check for changes
const lastState = loadState(name);
if (lastState && lastState.address !== data.address) {
console.log(`๐จ ${name} address changed!`);
console.log(` Old: ${lastState.address}`);
console.log(` New: ${data.address}`);
await sendAlert(name, lastState.address, data.address);
}
saveState(name, data);
}
// Alert function (send to Discord, Telegram, etc.)
async function sendAlert(name, oldAddress, newAddress) {
await fetch('https://discord.com/api/webhooks/YOUR_WEBHOOK', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
content: `๐จ **${name}** address changed!\n\`\`\`diff\n- ${oldAddress}\n+ ${newAddress}\n\`\`\``
})
});
}
// Simple state persistence
function loadState(name) {
try {
const data = fs.readFileSync(`.state/${name}.json`, 'utf8');
return JSON.parse(data);
} catch {
return null;
}
}
function saveState(name, data) {
fs.mkdirSync('.state', { recursive: true });
fs.writeFileSync(`.state/${name}.json`, JSON.stringify(data, null, 2));
}
// Monitor vitalik.eth every 5 minutes
setInterval(() => monitorENS('vitalik.eth'), 5 * 60 * 1000);
monitorENS('vitalik.eth'); // Initial check
Step 7: Deploy Your Agentโ
Local Developmentโ
node index.js
Production Deploymentโ
Option A: PM2 (VPS/EC2)
npm install -g pm2
pm2 start index.js --name "yourbot-agent"
pm2 save
pm2 startup
Option B: Docker
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
CMD ["node", "index.js"]
docker build -t yourbot-agent .
docker run -d --restart=unless-stopped yourbot-agent
Option C: Systemd (Linux)
# /etc/systemd/system/yourbot-agent.service
[Unit]
Description=YourBot Agent
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser/yourbot-agent
ExecStart=/usr/bin/node index.js
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl enable yourbot-agent
sudo systemctl start yourbot-agent
Cost Breakdownโ
| Item | One-Time | Monthly |
|---|---|---|
| ENS subname (5+ chars) | $0.97 | $0.08 |
| ERC-8004 registration | $0.50 | - |
| x402 API calls (1000/day) | - | $10 |
| Server (AWS t3.micro) | - | $10 |
| Total | $1.47 | ~$20 |
Free tier alternative:
- 100 API calls/day: $0/month
- Use free hosting (Render, Railway)
- Total: $1.47 one-time
Advanced Featuresโ
Multi-Chain Identityโ
Your agent can resolve names across chains:
// Resolve Base name
const baseProfile = await x402.request(
'https://api.web3identity.com/api/basename/hyperwave.base.eth'
);
// Resolve ENS on L2
const l2Profile = await x402.request(
'https://api.web3identity.com/api/ens/l2/vitalik.eth'
);
Batch Operationsโ
Save on payments by batching requests:
const names = ['vitalik.eth', 'nick.eth', 'brantly.eth'];
const response = await x402.request(
'https://api.web3identity.com/api/ens/batch',
{
method: 'POST',
body: JSON.stringify({ names })
}
);
console.log('Resolved:', response.data); // All 3 names
console.log('Cost:', x402.lastPayment); // Single payment for all
Rate Limit Managementโ
x402 has no hard rate limits, but implement backoff for reliability:
async function requestWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await x402.request(url);
} catch (error) {
if (error.status === 429 && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
Security Best Practicesโ
1. Secure Your Private Keyโ
// โ
Good: Use environment variables or encrypted key files
const privateKey = process.env.AGENT_PRIVATE_KEY;
// โ Bad: Hardcode in source
const privateKey = '0x1234...'; // NEVER DO THIS
2. Monitor Spendingโ
// Track cumulative spend
let totalSpent = 0;
const DAILY_LIMIT = 100; // $100/day
x402.on('payment', (payment) => {
totalSpent += payment.amount;
if (totalSpent > DAILY_LIMIT) {
console.error('โ ๏ธ Daily spending limit reached!');
process.exit(1);
}
});
3. Implement Circuit Breakersโ
let consecutiveFailures = 0;
const MAX_FAILURES = 5;
async function safeRequest(url) {
try {
const response = await x402.request(url);
consecutiveFailures = 0; // Reset on success
return response;
} catch (error) {
consecutiveFailures++;
if (consecutiveFailures >= MAX_FAILURES) {
console.error('Circuit breaker triggered!');
await sendAdminAlert('Agent failing repeatedly');
// Pause for 5 minutes
await new Promise(resolve => setTimeout(resolve, 5 * 60 * 1000));
consecutiveFailures = 0;
}
throw error;
}
}
4. Log All Transactionsโ
import fs from 'fs';
x402.on('payment', (payment) => {
const log = {
timestamp: new Date().toISOString(),
amount: payment.amount,
currency: 'USDC',
endpoint: payment.endpoint,
txHash: payment.txHash
};
fs.appendFileSync(
'logs/payments.jsonl',
JSON.stringify(log) + '\n'
);
});
Troubleshootingโ
"Insufficient funds for gas"โ
Cause: Not enough ETH for transaction fees.
Fix: Bridge more ETH to Base:
# Check balance
cast balance YOUR_AGENT_ADDRESS --rpc-url https://mainnet.base.org
"402 Payment Required but no payment made"โ
Cause: x402 client not properly initialized or wallet not funded with USDC.
Fix:
- Verify USDC balance on Base
- Check wallet client configuration
- Ensure
chainId: 8453(Base mainnet)
"ENS name not resolving"โ
Cause: Subname registration pending or not propagated.
Fix: Wait 1-2 minutes after registration, then verify:
curl "https://api.web3identity.com/api/ens/yourbot.aboutme.eth"
Next Stepsโ
- Add intelligence: Integrate OpenAI or Anthropic for NLP
- Agent-to-agent messaging: Use XMTP for decentralized communication
- On-chain actions: Add token swaps, NFT minting, governance voting
- Reputation system: Track agent reliability on-chain
Example Agents to Studyโ
| Agent | ENS | Purpose |
|---|---|---|
| ATV | atv.eth | Identity verification & trust |
| clawd.atg | clawd.atg.eth | Web3 development assistant |
| Lauki | lauki.eth | DeFi automation |
Resourcesโ
- Web3 Identity API: https://docs.web3identity.com
- x402 Protocol: https://docs.web3identity.com/guides/handling-x402-payments
- ERC-8004 Spec: https://eips.ethereum.org/EIPS/eip-8004
- viem Docs: https://viem.sh
- ENS Docs: https://docs.ens.domains
Supportโ
Need help building your agent?
- Discord: discord.gg/web3identity
- Email: support@web3identity.com
- Twitter: @ATV_eth
Guide last updated: February 10, 2026