<?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: Amfibi</title>
    <description>The latest articles on DEV Community by Amfibi (@orenbot_4c47bce2264310840).</description>
    <link>https://dev.to/orenbot_4c47bce2264310840</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%2F4131139%2F14a51d10-f945-47df-b094-765fa90f8a9c.png</url>
      <title>DEV Community: Amfibi</title>
      <link>https://dev.to/orenbot_4c47bce2264310840</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/orenbot_4c47bce2264310840"/>
    <language>en</language>
    <item>
      <title>What happened when an agent paid for storage with no account (x402 in practice)</title>
      <dc:creator>Amfibi</dc:creator>
      <pubDate>Fri, 18 Sep 2026 08:29:33 +0000</pubDate>
      <link>https://dev.to/orenbot_4c47bce2264310840/what-happened-when-an-agent-paid-for-storage-with-no-account-x402-in-practice-422i</link>
      <guid>https://dev.to/orenbot_4c47bce2264310840/what-happened-when-an-agent-paid-for-storage-with-no-account-x402-in-practice-422i</guid>
      <description>&lt;p&gt;I built a small service for AI agents: store a JSON blob or a file, get it back later, or hand it to a human with a link. Nothing new there. The part I wanted to test was the payment model: no account, no API key, no credit card. The agent pays $0.01 in USDC per call, by itself, using the x402 protocol. This post is what that took, and what broke.&lt;/p&gt;

&lt;h2&gt;
  
  
  The flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The agent calls &lt;code&gt;POST /v1/items&lt;/code&gt; with the content.&lt;/li&gt;
&lt;li&gt;The API answers &lt;strong&gt;402 Payment Required&lt;/strong&gt; with a small JSON body: amount (10000 units = $0.01 USDC), asset (USDC on Base), recipient, and a timeout.&lt;/li&gt;
&lt;li&gt;The agent's x402 client signs an EIP-3009 &lt;code&gt;transferWithAuthorization&lt;/code&gt; for exactly that amount and retries the request with the signature in a header.&lt;/li&gt;
&lt;li&gt;The API asks a facilitator (Coinbase's) to verify and settle. The facilitator broadcasts the transfer and pays the gas.&lt;/li&gt;
&lt;li&gt;The API stores the item and returns 201 with an id, a one-time secret, and links.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent needs a wallet with USDC and nothing else. No ETH for gas. No sign-up anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  What broke
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The public testnet facilitator is flaky.&lt;/strong&gt; "Payment settlement failed: Missing or invalid parameters" and "replacement transaction underpriced" show up intermittently; its hot wallet collides on nonces. The fix on our side: treat a failed settlement as "nothing happened" (delete the half-written item, return 402, let the client sign a fresh payment). On-chain reconciliation confirmed a failed settlement never moved money. Production uses the CDP facilitator, which has been clean so far.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloudflare Workers caps PBKDF2 at 100,000 iterations.&lt;/strong&gt; Our password hashing used 600,000; local dev (workerd) does not enforce the cap, production does. The symptom was a 500 only in production on &lt;code&gt;PUT /password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A cached promise that never settles.&lt;/strong&gt; We cached the facilitator initialization promise at module level. When the first request was canceled mid-initialization, the pending promise stayed cached forever and every later request hung. Cache only initialized objects, never pending promises.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrent read counting on object storage.&lt;/strong&gt; R2 has conditional writes but no atomic decrement. 100 back-to-back reads lost 26–44 decrements. Backoff with jitter brought it down to a handful; we documented the counter as soft and moved on. A Durable Object would make it exact; it was not worth it at $0.01 per 1,000 reads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The client consumed the request body on retry.&lt;/strong&gt; The x402 fetch wrapper replays the request after the 402; a body stream can only be read once. Clone before the first attempt.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell someone doing the same
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Put a one-shot &lt;strong&gt;smoke test with real money&lt;/strong&gt; in the repo. Ours makes one upload, verifies the receipt and the single USDC &lt;code&gt;Transfer&lt;/code&gt; on chain, then deletes the item. It found a config regression that unit tests could not.&lt;/li&gt;
&lt;li&gt;Write the audit trail yourself. Logpush needs a paid plan; a background put per settlement into a separate bucket, rolled up daily, was 100 lines and works on the free plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agents do not discover services on their own yet.&lt;/strong&gt; They find them through developers. An MCP server (&lt;code&gt;npx -y fileshareforagents-mcp&lt;/code&gt;), &lt;code&gt;llms.txt&lt;/code&gt;, and being in the x402 Bazaar matter more than any feature.&lt;/li&gt;
&lt;li&gt;Terms matter even at $0.01. A drop box that deletes content at expiry needs to say so in plain words before anyone pays.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Numbers so far
&lt;/h2&gt;

&lt;p&gt;Two full end-to-end runs on mainnet (36 steps each, 10 settlements per run), every settlement reconciled on chain, zero money moved by failed settlements. Price: $0.01 per store, extend, or 1,000 reads. Everything else free.&lt;/p&gt;

&lt;p&gt;Try it on testnet with free USDC: &lt;a href="https://fileshareforagents.online" rel="noopener noreferrer"&gt;https://fileshareforagents.online&lt;/a&gt;. Docs for agents: &lt;a href="https://fileshareforagents.online/llms.txt" rel="noopener noreferrer"&gt;https://fileshareforagents.online/llms.txt&lt;/a&gt;. I read every message sent to &lt;code&gt;POST /v1/feedback&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>webdev</category>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
