DEV Community

Nikhil Ranka
Nikhil Ranka

Posted on

How I Built an Autonomous AI Agent That Earns USDC While I Sleep

How I Built an Autonomous AI Agent That Earns USDC While I Sleep

Target audience: developers who want to put a lightweight, self‑serving agent into production and get paid per invocation in USDC on Base.


1. Why an “earning‑while‑sleeping” agent?

Most hobby agents run on a schedule, poll for work, or sit idle until a human triggers them. If you want the agent to generate revenue without a constant operator, you need two things:

  1. Stateless execution – the agent can be started, do its job, and shut down with no lingering state.
  2. Built‑in monetization – each invocation must be able to request payment before doing any work, and the payment must be settled on‑chain with minimal friction.

The x402 standard (a draft for HTTP‑based micropayments) fits the second point nicely: a client sends a small USDC amount in the x402-Payment header, the server verifies it on‑chain, and only then proceeds with the request. Combined with a serverless platform like Cloudflare Workers, you get cheap, scalable execution that only runs when paid for.


2. High‑level architecture

+-------------------+        HTTP (x402)        +---------------------+
|   Client / UI     | <----------------------> |  Cloudflare Worker  |
+-------------------+                          (Agent Service)       
        ^                                            |
        |                                            v
        |                                   +------------------+
        |                                   |  x402 Verifier   |
        |                                   | (Base RPC +      |
        |                                   |  ERC‑20 USDC)    |
        |                                   +------------------+
        |                                            |
        |                                            v
        |                                   +------------------+
        |                                   |  Agent Logic     |
        |                                   | (LLM call,      |
        |                                   |  data fetch,    |
        |                                   |  etc.)          |
        |                                   +------------------+
        |                                            |
        +-------------------------------------------+
Enter fullscreen mode Exit fullscreen mode
  • Client – any HTTP caller (curl, Postman, a front‑end, or another agent) that wants the agent’s output.
  • Cloudflare Worker – provides the HTTP edge, runs the x402 verifier, and forwards the request to the agent logic only after payment succeeds.
  • x402 Verifier – a tiny library that checks the x402-Payment header, validates the signature against the Base network, and confirms the amount matches the price posted in the service’s x402-Price header.
  • Agent Logic – the actual AI workload (in my example, a simple summarization via an LLM API). It receives the payload only after the verifier says “paid”.

Because the Worker is stateless, you can scale to thousands of concurrent invocations without managing containers or VMs. The only state you keep is the USDC price you expose, which lives in the Worker’s environment variables.


3. Setting up the payment verifier

I used the open‑source @x402/verifier package (npm) which handles the Base RPC call and ERC‑20 approval check. Below is a minimal Worker that integrates it.

// worker.js
import { verifyX402Payment } from '@x402/verifier';
import { summarize } from './agentLogic.js'; // our LLM wrapper

// Configuration – set via wrangler.toml or dashboard secrets
const USDC_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; // Base USDC
const PRICE_USDC   = 0.02; // $0.02 per call
const RPC_URL      = 'https://base-mainnet.g.alchemy.com/v2/<YOUR_KEY>';

export default {
  async fetch(request, env) {
    // 1️⃣ Extract headers required by x402
    const paymentHeader = request.headers.get('x402-payment');
    const priceHeader   = request.headers.get('x402-price');

    if (!paymentHeader || !priceHeader) {
      return new Response('Missing x402 headers', { status: 402 });
    }

    // 2️⃣ Verify that the client paid enough USDC
    const isValid = await verifyX402Payment({
      paymentHeader,
      priceHeader,
      usdcAddress: USDC_ADDRESS,
      price: PRICE_USDC,
      rpcUrl: RPC_URL,
    });

    if (!isValid) {
      return new Response('Payment verification failed', { status: 402 });
    }

    // 3️⃣ If payment good, run the agent logic
    const payload = await request.json(); // expect { text: "..."}
    const result  = await summarize(payload.text);

    return new Response(JSON.stringify({ summary: result }), {
      headers: { 'Content-Type': 'application/json' },
    });
  },
};
Enter fullscreen mode Exit fullscreen mode

What the verifier does under the hood

  • Parses the x402-Payment header (contains token, amount, signature, nonce, chainId).
  • Calls eth_call on the Base RPC to read the USDC balanceOf the verifier address before and after the purported transfer.
  • Checks that the signature matches the sender’s address (recovering it via ecrecover).
  • Ensures the transferred amount ≥ the price advertised in x402-Price.

If any step fails, the Worker returns HTTP 402 Payment Required – the client knows to retry with a correct payment.


4. Agent logic – a realistic, low‑cost example

For the demo I chose a text summarization task that calls an external LLM API (e.g., OpenAI’s GPT‑4o-mini). The point is not to showcase a revolutionary model but to show how you can gate any compute‑heavy work behind a payment check.

// agentLogic.js
import { Configuration, OpenAIApi } from 'openai';

const config = new Configuration({
  apiKey: env.OPENAI_API_KEY, // injected via wrangler secret
});
const openai = new OpenAIApi(config);

export async function summarize(text) {
  if (!text || typeof text !== 'string') {
    throw new Error('Invalid input: expected a non‑empty string');
  }

  const response = await openai.createChatCompletion({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'system', content: 'You are a concise summarizer.' },
      { role: 'user',   content: `Summarize the following in 2‑3 bullet points:\n\n${text}` },
    ],
    temperature: 0.3,
    max_tokens: 150,
  });

  return response.data.choices[0].message.content.trim();
}
Enter fullscreen mode Exit fullscreen mode

Trade‑offs

Aspect Choice Reason Drawback
LLM provider OpenAI API (pay‑per‑token) Simple, low latency, no model hosting Ongoing cost; you must mark‑up the price to cover it
Model size gpt-4o-mini Good quality/price ratio for short summaries Not the cheapest possible; a smaller open‑model could reduce cost but increase complexity
Execution platform Cloudflare Workers Sub‑second cold start, zero‑ops scaling Limited execution time (50 s on paid plan) – fine for summarization, not for long‑running tasks
Payment granularity Per‑call USDC Aligns cost directly with value delivered Clients must manage micropayments; UX friction if they’re not familiar with x402

If your workload is heavier (e.g., image generation, model fine‑tuning), you may need to raise the price, use a longer‑lived compute environment (Durable Objects or a VPS), or batch multiple requests into a single payment.


5. Deployment & observability

  1. Secrets – Store OPENAI_API_KEY, ALCHEMY_BASE_KEY (or any Base RPC provider), and optionally a VERIFIER_ADDRESS (the address that will receive USDC) in Cloudflare Secrets via wrangler secret put.
  2. Wrangler config – A minimal wrangler.toml:
name = "x402-summarizer"
main = "src/worker.js"
compatibility_date = "2024-09-01"

[vars]
USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
PRICE_USDC   = "0.02"
RPC_URL      = "https://base-mainnet.g.alchemy.com/v2/${ALCHEMY_BASE_KEY}"

[env.production]
Enter fullscreen mode Exit fullscreen mode
  1. Deploywrangler publish. The Worker is now globally available at https://x402-summarizer.<your-subdomain>.workers.dev.

  2. Monitoring – Cloudflare provides built‑in analytics (request count, latency, error rate). For payment‑specific metrics, I log the x402-Payment header hash (not the full signature) to a custom logpush endpoint and alert if the verification failure rate spikes > 5 % (could indicate a mis‑priced service or an attacker trying to game the system).

  3. Security considerations

    • Replay attacks – The verifier includes a nonce; the client must increment it for each call. The Worker stores the last seen nonce in a short‑lived KV namespace (TT

Top comments (0)