How I Built an Autonomous AI Agent That Earns USDC While I Sleep
Traditional payment gateways are broken for autonomous AI agents. If your agent performs micro-tasks—such as summarizing a transcript, resolving a Git issue, or generating a targeted lead list—charging $0.02 per execution is financially impossible through Stripe. The $0.30 flat fee alone eats your entire margin.
To build an agent that can truly operate independently, sell its services globally, and settle transactions instantly, we have to look past the legacy banking stack.
This guide outlines how to build an autonomous, self-monetizing AI agent using USDC on Base (Ethereum Layer 2). I will share the architectural pattern, the actual TypeScript code for payment verification, and the brutal trade-offs you must make when moving from SaaS to Machine-to-Machine (M2M) micropayments.
The Architecture: The x402 Pattern
We use the standard HTTP status code 402 Payment Required. The architecture relies on an off-chain API verifying on-chain transactions before triggering the agent's core processing loop.
[ Client ]
│ 1. Pay $0.05 USDC on Base to Agent Wallet
▼
[ Blockchain (Base) ] ── (Tx Hash generated)
│
│ 2. POST /api/agent with Tx Hash in Header
▼
[ Agent API Gateway ]
│ 3. Verify Tx on-chain (Viem / RPC)
│ 4. Deduplicate Tx Hash (Redis / KV Store)
▼
[ LLM & Tool Execution Loop ]
│ 5. Run Agent Task
▼
[ Client ] (Returns Result)
By decoupling the payment processor from a centralized entity, the client pays the agent directly wallet-to-wallet. Base network's sub-cent transaction fees make micro-billing viable.
Implementing On-Chain Payment Verification
To verify that a client actually sent the correct amount of USDC before firing up our LLM orchestrator, we use viem to interact with a Base RPC node.
Here is the production-grade verification middleware. It verifies that the transaction was successful, was sent to our wallet, contains the correct amount of USDC (6 decimals), and has not been double-spent.
typescript
import { createPublicClient, http, parseAbi, type Hash } from 'viem';
import { base } from 'viem/chains';
// Standard ERC20 Transfer Event ABI
const ERC20_ABI = parseAbi([
'event Transfer(address indexed from, address indexed to, uint256 value)'
]);
const USDC_BASE_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bda02913';
const AGENT_WALLET = '0xYourAgentReceivingWalletAddressHere'.toLowerCase();
const client = createPublicClient({
chain: base,
transport: http(process.env.BASE_RPC_URL || 'https://mainnet.base.org'),
});
interface VerifyPaymentParams {
txHash: Hash;
expectedUsdcAmount: number; // e.g., 0.05
kvStore: { // Mock interface for Cloudflare KV / Redis
Top comments (0)