<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Revnuvo Technologies Ltd</title>
    <description>The latest articles on DEV Community by Revnuvo Technologies Ltd (@revnuvo).</description>
    <link>https://dev.to/revnuvo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4051250%2Fec58f15b-7152-48fc-a989-a19140426800.png</url>
      <title>DEV Community: Revnuvo Technologies Ltd</title>
      <link>https://dev.to/revnuvo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/revnuvo"/>
    <language>en</language>
    <item>
      <title>How We Built x402 v2 Paid APIs on Cloudflare Workers — 3 Settled Transactions, Real USDC, Zero Auth</title>
      <dc:creator>Revnuvo Technologies Ltd</dc:creator>
      <pubDate>Tue, 28 Jul 2026 11:45:49 +0000</pubDate>
      <link>https://dev.to/revnuvo/how-we-built-x402-v2-paid-apis-on-cloudflare-workers-3-settled-transactions-real-usdc-zero-auth-20c5</link>
      <guid>https://dev.to/revnuvo/how-we-built-x402-v2-paid-apis-on-cloudflare-workers-3-settled-transactions-real-usdc-zero-auth-20c5</guid>
      <description>&lt;h2&gt;
  
  
  Building pay-per-request domain-intelligence APIs with no API keys, no rate limits, and no billing portal — just HTTP 402 and a signed EIP-3009 authorization on Base.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The problem: API authentication is broken
Every developer who has shipped a paid API knows the drill. You build the endpoint, then spend the next week bolting on the commerce layer:
An API key table, with provisioning, rotation, and revocation endpoints.
A rate limiter — usually a sliding window in Redis — because keys alone don't stop abuse.
A metering pipeline: a Kafka topic, a counter service, a usage aggregator, a reconciliation job that runs nightly and occasionally disagree with Stripe.
A billing system: monthly invoices, proration, dunning emails, tax handling for 40 jurisdictions.
A customer portal where users can find their key, see their usage, and argue about overages.
Each of those pieces is a separate failure surface, a separate database, and a separate pager. And the user pays for all of it: they have to sign up, wait for a key, read a rate-limit header, guess at next month's bill, and trust the metering. For an AI agent calling 10,000 endpoints a day, this is friction on top of friction.
What we wanted was simpler: one HTTP call, one payment, done. No account, no key, no quota. The protocol already has a status code for that — &lt;code&gt;402 Payment Required&lt;/code&gt; — and it's been sitting unused in the spec since 1991. x402 finally turns it on.&lt;/li&gt;
&lt;li&gt;The x402 solution
x402 is an open protocol that turns HTTP 402 into a real payment mechanism. The flow is three round-trips:
Challenge. The client sends the request. The server replies with &lt;code&gt;HTTP 402&lt;/code&gt;, a &lt;code&gt;WWW-Authenticate: x402&lt;/code&gt; header, and a JSON body describing what it accepts: &lt;code&gt;{ x402Version, scheme, network, asset, maxAmountRequired, payTo, resource, description, quote }&lt;/code&gt;.
Sign. The client signs an EIP-3009 &lt;code&gt;TransferWithAuthorization&lt;/code&gt; typed-data payload with their EOA private key. No on-chain transaction yet — just a signature that authorizes the payee to pull the funds.
Settle. The client retries the original request with an &lt;code&gt;X-Payment&lt;/code&gt; header carrying the signed authorization. The server forwards it to a facilitator, which verifies the signature, reserves the nonce (so it can't be replayed), broadcasts &lt;code&gt;transferWithAuthorization&lt;/code&gt; on Base, waits for confirmation, and only then releases the response.
No keys. No accounts. No metering database — the chain is the meter. A request that isn't paid simply doesn't execute.&lt;/li&gt;
&lt;li&gt;Architecture
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────┐   POST (no payment)      ┌─────────────────────────────────────┐
│  Client  │ ───────────────────────▶ │  Cloudflare Worker (edge)           │
│ (curl /  │                          │  Hono router                        │
│  SDK /   │   ◀── 402 + signed quote │  + @x402/hono@2.17.0 middleware     │
│  agent)  │                          │  + ExactEvmScheme                   │
│          │   POST + X-Payment       │  + HTTPFacilitatorClient            │
│          │ ───────────────────────▶ │                                     │
│          │                          │  worker → facilitator.xpay.sh       │
│          │   ◀── 200 + body +       │    /quote  /verify  /settle         │
│          │       X-Payment-Response │                                     │
└──────────┘                          └─────────────────────────────────────┘
                                                          │
                                                          ▼
                                              ┌────────────────────────┐
                                              │ Base mainnet (8453)    │
                                              │ USDC TransferWithAuth  │
                                              │ (EIP-3009)             │
                                              └────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worker never touches a private key, never signs a transaction, and never speaks to an RPC node directly. All of that lives in the facilitator. The worker is a thin, stateless edge proxy whose only job is to (a) emit the 402 challenge and (b) forward the client's &lt;code&gt;X-Payment&lt;/code&gt; header to the facilitator's &lt;code&gt;/verify&lt;/code&gt; + &lt;code&gt;/settle&lt;/code&gt; endpoints.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The implementation
4.1 Middleware setup
The entire payment layer is five lines of TypeScript. The &lt;code&gt;paymentMiddleware&lt;/code&gt; from &lt;code&gt;@x402/hono@2.17.0&lt;/code&gt; takes a route map (path → price + scheme + network + payTo) and a &lt;code&gt;resourceServer&lt;/code&gt; registered against a chain-specific scheme:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;facilitator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HTTPFacilitatorClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://facilitator.xpay.sh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resourceServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;x402ResourceServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;facilitator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eip155:8453&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ExactEvmScheme&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;resourceServer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;paymentMiddleware&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST /assess/domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;accepts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exact&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$0.05&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eip155:8453&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payTo&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;resourceServer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ExactEvmScheme&lt;/code&gt; is the "exact-amount EVM transfer" scheme — deterministic, replay-safe, and the right primitive for a fixed-price-per-call API. &lt;code&gt;HTTPFacilitatorClient&lt;/code&gt; is what talks to the xpay facilitator. Everything else (challenge signing, nonce reservation, on-chain broadcast, confirmation) happens server-side at &lt;code&gt;facilitator.xpay.sh&lt;/code&gt;.&lt;br&gt;
4.2 The v2 payment payload&lt;br&gt;
The 402 challenge body follows the x402 v2 shape — every field a client needs to sign without a second round-trip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"x402Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scheme"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"exact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eip155:8453"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payTo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x2aaD494F3f2f3f30E464cB84442924d764f19CE7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxAmountRequired"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"50000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"asset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://assess.revnuvo.site/assess/domain"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Domain trust and risk assessment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxTimeoutSeconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"quote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"quoteId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"q_..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scheme"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"exact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eip155:8453"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"asset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x8335..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"payTo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x2aaD..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxAmountRequired"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"50000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"issuedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1784&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expiresAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1784&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x..."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;quote&lt;/code&gt; sub-object is HMAC-signed by the facilitator. The client never trusts the outer fields alone — it signs against &lt;code&gt;quote.maxAmountRequired&lt;/code&gt;, &lt;code&gt;quote.payTo&lt;/code&gt;, and &lt;code&gt;quote.asset&lt;/code&gt;, and the facilitator rejects any payment whose signature doesn't match the quote it signed. That's what binds the payment to a specific resource + price: not a server-minted nonce, but the signed quote itself.&lt;br&gt;
4.3 The CORS lesson&lt;br&gt;
Our first deployment to &lt;code&gt;assess.revnuvo.site&lt;/code&gt; worked perfectly for curl and Postman — payments settled, USDC moved — but x402scan reported "no x402 paywall detected." A false negative: the paywall demonstrably worked (Basescan showed the tx), but the crawler couldn't see it.&lt;br&gt;
Root cause: our CORS config was an allowlist of three specific origins (&lt;code&gt;developers.revnuvo.site&lt;/code&gt;, &lt;code&gt;localhost:3000&lt;/code&gt;, &lt;code&gt;127.0.0.1:3000&lt;/code&gt;). The crawler's origin wasn't on the list, so the worker omitted the &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; header, the browser blocked the response, and the crawler saw nothing.&lt;br&gt;
The fix was one line — &lt;code&gt;origin: "*"&lt;/code&gt; — which is what &lt;code&gt;dns.revnuvo.site&lt;/code&gt; had been using all along and had registered cleanly. The mental flip: CORS does not protect a paid endpoint. CORS is a browser-side mechanism that doesn't affect server-side callers (curl, Postman, backends). The x402 payment layer is what actually gates access. Opening CORS to all origins doesn't reduce security because the endpoint is already paywalled — it just makes the paywall legible to browser-based tooling.&lt;br&gt;
4.4 The wildcard-method lesson&lt;br&gt;
The second gotcha was route registration. We initially keyed our route map as &lt;code&gt;"POST /assess/domain"&lt;/code&gt; — precise and correct for production traffic. But x402scan's crawler (and most discovery tools) probe with a &lt;code&gt;GET&lt;/code&gt; or &lt;code&gt;HEAD&lt;/code&gt; first to confirm a paywall exists before recording the endpoint. A POST-only route map means the probe sails past the payment middleware, hits a 404, and the endpoint looks unpaywalled.&lt;br&gt;
The pattern that registers cleanly: declare routes with a wildcard method (&lt;code&gt;"* /assess/domain"&lt;/code&gt;) in the middleware route map, and let your own handler short-circuit non-POST methods with a 405 after the 402 challenge has been served. The crawler gets its 402, the discovery listing populates, and real clients still get correct method validation. Lesson: the payment middleware must see every method the route responds to, including the probe methods.&lt;br&gt;
4.5 End-to-end with curl&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Step 1: the 402 challenge&lt;/span&gt;
curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://assess.revnuvo.site/assess/domain &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"domain":"example.com"}'&lt;/span&gt;

&lt;span class="c"&gt;# HTTP/1.1 402 Payment Required&lt;/span&gt;
&lt;span class="c"&gt;# WWW-Authenticate: x402 requirements=...&lt;/span&gt;
&lt;span class="c"&gt;# Content-Type: application/json&lt;/span&gt;
&lt;span class="c"&gt;# { "x402Version": 2, "scheme": "exact", "payTo": "0x2aaD...", "maxAmountRequired": "50000",&lt;/span&gt;
&lt;span class="c"&gt;#   "asset": "0x8335...", "quote": { "quoteId": "...", "sig": "0x..." } }&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: sign the EIP-3009 authorization against the quote, then retry&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://assess.revnuvo.site/assess/domain &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Payment: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;sign-eip3009 quote.json | &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"domain":"example.com"}'&lt;/span&gt;

&lt;span class="c"&gt;# HTTP/1.1 200 OK&lt;/span&gt;
&lt;span class="c"&gt;# X-Payment-Response: &amp;lt;base64 settlement receipt&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;# { "domain":"example.com", "trust_score":92, "grade":"A", "recommendation":"TRUSTED", ... }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.6 Paying with the SDK&lt;br&gt;
The &lt;code&gt;@revnuvo/x402&lt;/code&gt; SDK collapses both steps into one call — it intercepts the 402, signs against the challenge, retries with &lt;code&gt;X-Payment&lt;/code&gt;, and surfaces the final 200:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;X402Client&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@revnuvo/x402&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;X402Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PRIVATE_KEY&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://assess.revnuvo.site/assess/domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// { domain: "example.com", trust_score: 92, grade: "A", recommendation: "TRUSTED",&lt;/span&gt;
&lt;span class="c1"&gt;//   signals: { domain_exists: true, has_mx: true, dnssec_enabled: true, ... } }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SDK uses &lt;code&gt;viem&lt;/code&gt;'s &lt;code&gt;signTypedData&lt;/code&gt; against the standard USDC &lt;code&gt;TransferWithAuthorization&lt;/code&gt; EIP-712 type, picks a random 32-byte nonce, sets a 120-second &lt;code&gt;validBefore&lt;/code&gt;, and base64-encodes the &lt;code&gt;{ quote, payment }&lt;/code&gt; payload into the &lt;code&gt;X-Payment&lt;/code&gt; header. No wallet connection, no RPC call from the client — just one signature.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The proof — 3 settled transactions
Every endpoint has a real, on-chain settlement on Base mainnet. These aren't test transactions; they're USDC transfers that hit &lt;code&gt;0x2aaD494F3f2f3f30E464cB84442924d764f19CE7&lt;/code&gt; via &lt;code&gt;transferWithAuthorization&lt;/code&gt; on the USDC contract at &lt;code&gt;0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&lt;/code&gt;:
&lt;code&gt;/domain/verify&lt;/code&gt; — &lt;code&gt;0x450cb5d2...0f3a87&lt;/code&gt;
&lt;code&gt;/assess/domain&lt;/code&gt; — &lt;code&gt;0x0c263f26...2b9a3&lt;/code&gt;
&lt;code&gt;/dns/lookup&lt;/code&gt; (dns.revnuvo.site) — &lt;code&gt;0x5901d53f...9add5&lt;/code&gt;
Open any of them on Basescan and you'll see the same shape: a &lt;code&gt;transferWithAuthorization&lt;/code&gt; call, the payer's address as &lt;code&gt;from&lt;/code&gt;, our &lt;code&gt;payTo&lt;/code&gt; as &lt;code&gt;to&lt;/code&gt;, the atomic amount (5,000–50,000 units = $0.005–$0.05 at 6-decimal USDC), and the relayer's address as &lt;code&gt;msg.sender&lt;/code&gt;. That's the entire revenue trail. No invoice, no usage record, no reconciliation job.&lt;/li&gt;
&lt;li&gt;The distribution play
Shipping the APIs was half the work. The other half was making them discoverable by the two populations that matter: developers and AI agents.
x402scan — the registry of x402-powered endpoints. Once the CORS and wildcard-method lessons landed, all three endpoints registered cleanly and now show up with their price, network, and last-settled tx hash.
Smithery MCP — we ship a Model Context Protocol server (&lt;code&gt;mcp.revnuvo.site/mcp&lt;/code&gt;) that exposes &lt;code&gt;assess_domain&lt;/code&gt;, &lt;code&gt;verify_domain&lt;/code&gt;, and &lt;code&gt;dns_lookup&lt;/code&gt; as tools. Agents discover them via &lt;code&gt;tools/list&lt;/code&gt;, get a 402 on unpaid &lt;code&gt;tools/call&lt;/code&gt;, and retry with &lt;code&gt;_meta["x402/payment"]&lt;/code&gt;. The full handshake is in our SDK's MCP e2e test.
npm SDK — &lt;code&gt;@revnuvo/x402&lt;/code&gt; gives TypeScript developers a one-liner &lt;code&gt;payAndFetch&lt;/code&gt;. A Python equivalent is on PyPI.
Postman collection — a public collection with the 402 + payment flow pre-wired, so teams can hit the ground running without writing signing code.
developers.revnuvo.site — the canonical docs hub, with OpenAPI 3.1 schemas served live from each worker's &lt;code&gt;/openapi.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;What's next
The paid-API primitive is now proven. The next three things on the roadmap all build on top of it:
Leadgen tool. A paid &lt;code&gt;/leadgen/domain&lt;/code&gt; endpoint that returns verified contact data (emails, phone, LinkedIn URLs) for a domain, priced at $0.10–$0.25 per call. Same x402 flow, no new infrastructure.
Smartlead integration. Pipe verified leads directly into Smartlead cold-outreach campaigns via webhook — so an agent can &lt;code&gt;pay → assess → enrich → push to campaign&lt;/code&gt; in a single autonomous loop.
Customer portal. A read-only dashboard that queries the Base ledger for transfers to &lt;code&gt;payTo&lt;/code&gt; from a connected wallet, showing total spent, per-endpoint breakdown, and tx hashes. No backend database — the chain is the source of truth, and the portal is just a Basescan viewer with better UX.
The bigger thesis: for AI-agent workloads, x402 isn't a niche payment rail — it's the default API business model. Agents can't fill out a signup form, can't wait for an API key email, and can't read a rate-limit header. They can sign an EIP-3009 authorization. Once the tool layer is paywalled this way, every agent with a funded Base wallet becomes a paying customer with zero integration friction.
---
Links: x402scan · x402 spec · developers.revnuvo.site · SDK repo · assess worker · resource worker · Basescan: verify · Basescan: assess · Basescan: dns&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>x402</category>
      <category>babel</category>
      <category>cryptocurrency</category>
      <category>api</category>
    </item>
  </channel>
</rss>
