<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Testril Blog</title>
  <link>https://testril.ai/blog/</link>
  <atom:link href="https://testril.ai/feed.xml" rel="self" type="application/rss+xml"/>
  <description>Insights from Testril on onchain data, AI agents, and provenance.</description>
  <language>en</language>
  <lastBuildDate>Thu, 10 Sep 2026 00:00:00 GMT</lastBuildDate>
  <item>
    <title>x402 as agent UX</title>
    <link>https://testril.ai/blog/x402-as-agent-ux/</link>
    <guid isPermaLink="true">https://testril.ai/blog/x402-as-agent-ux/</guid>
    <pubDate>Thu, 10 Sep 2026 00:00:00 GMT</pubDate>
    <dc:creator>Paul Murphy</dc:creator>
    <description>Why x402 agent payments need quote-first UX. Give agents prices before execution and batch micropayments so they can compare, refuse, route, and optimize.</description>
    <content:encoded><![CDATA[<p>Agents don’t need a checkout. They need a quote they can refuse.</p>
<p>The right flow is simple. Three steps:</p>
<ol>
<li>Agent states what it wants</li>
<li>Platform provides a quote</li>
<li>Agent pays or moves on</li>
</ol>
<p>That framing came out of a thread with Kevin (@kleffew94) — co-author of the x402 whitepaper, now building agent payments at Coinbase — on agents buying data on demand. Andrew (@andrewhong5297), co-founder of Herd and formerly Headmaster at Dune, pushed on the opposite failure mode: unknown costs up front.</p>
<p>If price isn’t agreed before a transaction, someone is likely to lose. For any ordinary purchase we expect terms before the deal. Restaurants don’t prepare meals hoping someone will buy them, and nobody orders food without knowing what it will cost. Agents should get the same courtesy.</p>
<p>If a price isn’t adjusted for an agentic transaction, it can be economically irrational. Most x402 offerings today fall into that category.</p>
<p>Most “agent-native” x402 deployments still fail that test in one of two ways:</p>
<ul>
<li><strong>Work first, settle later</strong>: run the job, then figure out the bill.</li>
<li><strong>Wrong grain</strong>: the rail is right, but the cost is way off.</li>
</ul>
<h2>Work first, settle later</h2>
<p>In that thread, Andrew clearly states the problem: for a SQL query you may not know the cost until it finishes, so do you make the agent put up an escrow and refund the surplus?</p>
<p>At first glance this appears rational. In fact, it’s a vendor shortcut disguised as payment UX.</p>
<p>A vendor should be able to figure out what a job will cost to run with relative accuracy. Not revealing a job’s price until after the job is complete puts the agent in a terrible position because it can’t say “no” before committing. At the outset, the escrow has to be considered the cost of the job. A refund is a bonus.</p>
<p>Dune provides a concrete example. Dune doesn’t use x402 — but it is the canonical version of the pattern that x402 offerings often copy. Its credit system bills from actual compute after the query runs. Processing, data scanned, and engine time are all taken into account. Dune’s own FAQ is blunt: “Will I see the cost before running a query? You’ll see costs after execution.” They don’t publish a single per-query price because usage depends on real-time factors. You can set a per-query credit cap and a monthly extra-credit limit, but those are ceilings on a bill you still get after the work.</p>
<h2>Wrong grain</h2>
<p>The unit of settlement is coarser than the unit of work.</p>
<p>Even when the quote is clear, the unit is often still wrong.</p>
<p>The Graph’s Studio (designed for humans) meters GraphQL queries: 100,000 free per month, then $2 per 100,000 queries, about $0.00002 per query.</p>
<p>The agent x402 path on the same network is still per GraphQL query. Official Graph docs describe the flow, not a price. They leave that to the ecosystem clients. PayQL’s live gateway preflight returns USDC 0.01 per paid gateway query.</p>
<p>Same data network. Same query grain. $0.01 per agent query vs. $0.00002 per Studio query — a 500x difference. Agents inherited human GraphQL metering and a cent-scale floor. The reason is almost certainly technical:</p>
<ul>
<li>Settling a transaction lower than $0.01 isn’t economically viable, even on chains with very low fees.</li>
<li>Batching small transactions until settlement becomes economically viable is complicated. x402 supports it, but the needed escrow contracts aren’t available on most chains.</li>
</ul>
<h2>What Testril does instead</h2>
<p>The fix is not a nicer checkout. It is a quote primitive.</p>
<p>Two problems to fix: price before work, and prices in line with actual work.</p>
<h3>Quote first</h3>
<p>Same three-step loop for every paid request:</p>
<ol>
<li>Unpaid call returns soft <code>payment_required</code> on the success path: <code>quote_id</code>, line items, amount.</li>
<li>Agent calls <code>pay_quote({ quote_id[, payload] })</code> if it accepts.</li>
<li>Same verb again with <code>payment_id</code> only.</li>
</ol>
<p><code>quote_id</code> freezes the work for 120s (an eternity for agents). After that, re-quote. You buy what was quoted. No Dune-style “cost after execution.”</p>
<h3>Batch micropayments</h3>
<p>Settling every agent hop on-chain at a cent is expensive. Settling below a cent needs batching.</p>
<p>Testril uses two settlement schemes on accepts:</p>
<ul>
<li>Exact: one EIP-3009 USDC transfer per quote (payload required) for work at or above the floor (currently $0.01).</li>
<li>Batch-settlement: buyer deposits USDC into an x402 batch escrow, then signs vouchers for later quotes. Each later quote is a new voucher, not a new transfer. Testril accumulates vouchers until they reach an aggregate amount worth settling.</li>
</ul>
<p>In future, the settlement floor may change, but the settlement mechanism won’t. It’s difficult to imagine a time when settling USDC 0.000001 becomes viable.</p>
<h2>The real UX is the quote</h2>
<p>x402 is not interesting because it lets software pay a web server. That part is plumbing.</p>
<p>The interesting part is what the payment flow teaches the agent before it commits.</p>
<p>For agents, price is not a checkout detail. It is part of the interface. A usable agent service needs to answer three questions before work begins: what will you do, what will it cost, and what exactly am I buying?</p>
<p>If the answer comes after execution, the agent cannot be a rational buyer. If the unit is wrong, the price is only technically correct. A one-cent floor on a query that should cost a thousandth of a cent is not micropayment infrastructure. It is human-era pricing dragged onto an agent rail.</p>
<p>The right abstraction is quote-first, settle-later. Give the agent a firm price, freeze the work long enough to accept, and batch the tiny units until settlement makes economic sense. The chain should clear value. It should not force every useful action to become a standalone financial event.</p>
<p>That is the UX standard x402 has to meet. Not “can an agent pay?” but “can an agent decide?” Agents need to compare, refuse, route around, and optimize. They need prices in the same place they need schemas, latency, and quality signals: before the call.</p>
<p>Payment rails matter. But agent-native commerce starts at the quote.</p>
]]></content:encoded>
  </item>
  <item>
    <title>Why AI Agents Waste 97% of Their Tokens on Raw Data</title>
    <link>https://testril.ai/blog/why-ai-agents-waste-tokens-on-raw-data/</link>
    <guid isPermaLink="true">https://testril.ai/blog/why-ai-agents-waste-tokens-on-raw-data/</guid>
    <pubDate>Tue, 28 Jul 2026 00:00:00 GMT</pubDate>
    <dc:creator>Paul Murphy</dc:creator>
    <description>We measured what 18 stats cost an agent computing them from raw rows instead of asking for the finished answer. 12,476 tokens versus 395, a 97% cut.</description>
    <content:encoded><![CDATA[<p>If you provide raw data to agents, the best way to bankrupt your clients is to just keep doing what you&#39;re doing.</p>
<p>Here&#39;s the core problem: agents are being forced to download a mountain of data to derive answers the data source should have provided directly.</p>
<p>We did an experiment to show how serious this problem is.</p>
<h2>The experiment</h2>
<p>We used a <a href="https://myceliumdata.org/">Mycelium network</a> (an experimental data layer that returns derived stats instead of raw rows) to run these tests.</p>
<p>Imagine an AI agent that needs one career baseball stat. Hank Aaron&#39;s career home runs or Nolan Ryan&#39;s ERA, WHIP, or strikeouts per nine.</p>
<p>In the traditional raw-data model the agent doesn&#39;t get the answer. It gets every season row required to compute the answer itself, dumped as JSON.</p>
<p>In the derivative model the agent asks for the finished number and receives one value.</p>
<p>We ran this on the full historic Lahman baseball database using Hank Aaron and Nolan Ryan. Token counts came from OpenAI&#39;s <code>cl100k_base</code> tokenizer on the actual JSON payloads an agent would see. The DIY side only received the minimum columns needed for each calculation. That is the generous case for raw data.</p>
<p>The results were not ambiguous.</p>
<h2>The numbers</h2>
<div class="table-scroll"><table>
<thead>
<tr>
<th>What we asked for</th>
<th align="right">Season rows</th>
<th align="right">DIY tokens</th>
<th align="right">One-answer tokens</th>
<th align="right">Reduction</th>
</tr>
</thead>
<tbody><tr>
<td>Career home runs (Aaron)</td>
<td align="right">23</td>
<td align="right">502</td>
<td align="right">20</td>
<td align="right">96%</td>
</tr>
<tr>
<td>OPS (Aaron)</td>
<td align="right">23</td>
<td align="right">1,215</td>
<td align="right">21</td>
<td align="right">98%</td>
</tr>
<tr>
<td>Career ERA (Ryan)</td>
<td align="right">27</td>
<td align="right">707</td>
<td align="right">23</td>
<td align="right">97%</td>
</tr>
<tr>
<td>Fielding percentage (Aaron)</td>
<td align="right">36</td>
<td align="right">1,063</td>
<td align="right">23</td>
<td align="right">98%</td>
</tr>
<tr>
<td>Career strikeouts (Ryan)</td>
<td align="right">27</td>
<td align="right">572</td>
<td align="right">22</td>
<td align="right">96%</td>
</tr>
<tr>
<td>WHIP (Ryan)</td>
<td align="right">27</td>
<td align="right">815</td>
<td align="right">23</td>
<td align="right">97%</td>
</tr>
</tbody></table></div>
<p>Same pattern for simple sums, fixed rate formulas, and LLM-derived stats. Ten pre-defined stats cost 6,074 tokens when fetched separately versus 213 tokens when the source returned the finished answers (96% savings). Eight derived stats cost 6,402 versus 182 (97% savings).</p>
<h2>The bigger picture</h2>
<ul>
<li>Separate fetches for all 18 example stats: <strong>12,476 tokens</strong> and 439 season rows.</li>
<li>One derived answer per stat: <strong>395 tokens</strong>.</li>
<li>Savings: <strong>12,081 tokens (97%)</strong>.</li>
</ul>
<p>Even a smart client that reuses three shared pulls (Aaron batting + Ryan pitching + Aaron fielding) still burns 3,854 tokens. Mycelium stays at 395. That&#39;s still a 90% cut.</p>
<p>And remember, these numbers already give raw data the benefit of the doubt. Full database rows typically cost two to three times more.</p>
<h2>Why this matters</h2>
<p>Agents can compute batting average or OPS. But they shouldn&#39;t have to. When a thousand agents all want the same deterministic result, making every one of them re-download the same rows and redo the same math isn&#39;t flexibility. It&#39;s pure waste.</p>
<p>Think of it this way: if a robot asks for a screwdriver, handing it a mine, a smelter, and a steel mill is technically complete, but practically insane. Raw records are the ore. Derivative data is the screwdriver.</p>
<p>A serious data source shouldn&#39;t stop at exposing raw data. It should also return derivative data that agents request. These derivative results aren&#39;t approximations, they are exact, relative to the source records and the derivation logic. A well-designed system can optionally return the provenance so any client can audit the answer.</p>
<p>Traditional data interfaces were built for expensive human analysts. Agents are cheap and they arrive in volume. 97% fewer tokens is not a nice-to-have. It is the difference between a data source that scales and one that quietly bankrupts its clients.</p>
]]></content:encoded>
  </item>
  <item>
    <title>Why AI agents don't need raw blockchain data</title>
    <link>https://testril.ai/blog/agents-dont-need-raw-data/</link>
    <guid isPermaLink="true">https://testril.ai/blog/agents-dont-need-raw-data/</guid>
    <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
    <dc:creator>The Testril team</dc:creator>
    <description>Feeding an agent raw blocks, logs, and traces is slow and expensive. What an agent needs is the answer, and a way to check that it is right.</description>
    <content:encoded><![CDATA[<p>Most blockchain data tooling was built for people. You define a schema, deploy a subgraph, run a pipeline, and query the tables it produces. That works when a person is in the loop to design the pipeline and read the result.</p>
<p>Agents work differently. An agent asks a question, gets an answer, and acts on it. When you hand an agent raw blocks, logs, and traces, you push the pipeline&#39;s work into the agent itself. It has to load a large amount of data into context and reason across all of it to reach a single number.</p>
<h2>The cost shows up twice</h2>
<p>Raw data costs an agent twice. It pays once to read the data into context, and again to reason over that context to produce a result. A question like &quot;how did USDC transfer volume change over the past year&quot; can pull millions of events into the model to return one figure. The answer is slow and expensive, and you cannot reliably reproduce it. Ask the same question twice and you can get two different numbers.</p>
<h2>Ask for the answer instead</h2>
<p>Testril takes a different approach. You ask a question in plain language over CLI or MCP, and you get the answer back. If we have computed it before, we serve it from cache. If we have not, we compute it on demand. The agent never holds the raw data in context.</p>
<p>This keeps the token cost per answer low, and a single question can span many chains instead of stopping at one. Because every value traces back to the blocks it came from, the agent can also confirm the answer is right before it acts on it.</p>
<p>Raw data is the input to a pipeline. An agent wants the output of one.</p>
]]></content:encoded>
  </item>
  <item>
    <title>Provenance by default: making onchain answers verifiable</title>
    <link>https://testril.ai/blog/provenance-by-default/</link>
    <guid isPermaLink="true">https://testril.ai/blog/provenance-by-default/</guid>
    <pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate>
    <dc:creator>The Testril team</dc:creator>
    <description>Every value Testril returns traces back to the blocks it came from and the code that produced it. That is what lets an agent trust an answer.</description>
    <content:encoded><![CDATA[<p>An answer an agent cannot check is a risk. If a model reads &quot;18,442 unique wallets&quot; from an API, it has no way to tell whether that number is right, out of date, or invented. It has to trust the source.</p>
<p>That kind of trust does not scale to systems that run on their own. So we made provenance part of every answer instead of a feature you request separately.</p>
<h2>What provenance means here</h2>
<p>For any value Testril returns, you can ask where it came from. We report the source events, the block range, the transformation we applied, and the latest block the answer reflects. The number and the record of how we produced it stay together.</p>
<h2>Why computing on demand helps</h2>
<p>Testril computes answers from indexed source data rather than serving tables built in advance. Because we run the computation when you ask, the full path from source block to final value is always available, and we can replay it. Nothing sits between the chain and the result that we cannot account for.</p>
<p>This has a useful side effect. Two agents that ask the same question get the same answer, and both can trace it back to the same blocks.</p>
<h2>Verifiable by construction</h2>
<p>Self-describing JSON tells an agent the shape of a result. A provenance request tells it where the result came from. Together they let an agent confirm an answer before acting on it. That is the point of giving agents data they can reason about rather than data they have to take on faith.</p>
]]></content:encoded>
  </item>
  <item>
    <title>See the price before anything runs</title>
    <link>https://testril.ai/blog/see-the-price-first/</link>
    <guid isPermaLink="true">https://testril.ai/blog/see-the-price-first/</guid>
    <pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate>
    <dc:creator>The Testril team</dc:creator>
    <description>Testril quotes every request before it runs, so an agent sees the cost first and nothing happens until it agrees to pay.</description>
    <content:encoded><![CDATA[<p>When an agent pays for each query, an unexpected bill is a real problem. A question that looks simple can turn into a large amount of work, and the agent only learns the cost after the work is done.</p>
<p>So Testril quotes the request first.</p>
<h2>The quote comes before the work</h2>
<p>When you ask Testril for something, it prices the request up front. You see what the data will cost and what it takes to produce before any block is read. Nothing runs until you accept the quote.</p>
<p>For a system that spends its own money, this matters. The agent can weigh the cost against the value of the answer, decide, and only then commit. There are no runaway jobs and no charges for work it did not want.</p>
<h2>Paying over the right rail</h2>
<p>When the agent accepts, it pays over rails built for software, x402 and MPP, and the data comes back as self-describing JSON. Every step of the exchange is readable by a machine. The agent asks, sees a price, pays, receives the data, and can verify it.</p>
<p>Quoting before computing makes the cost predictable, and it makes per-query data safe to hand to an agent that pays for its own requests.</p>
]]></content:encoded>
  </item>
  <item>
    <title>What x402 and MPP mean for machine payments</title>
    <link>https://testril.ai/blog/x402-mpp-machine-payments/</link>
    <guid isPermaLink="true">https://testril.ai/blog/x402-mpp-machine-payments/</guid>
    <pubDate>Sat, 20 Jun 2026 00:00:00 GMT</pubDate>
    <dc:creator>The Testril team</dc:creator>
    <description>When an agent pays for each query, the payment rail matters. A short explanation of x402, MPP, and per-request pricing.</description>
    <content:encoded><![CDATA[<p>The old model for selling data was a subscription. You paid once a month and queried as much as you wanted. That assumes a person is deciding what to buy. Agents change the shape of the transaction, because they pay for each question on their own, at a price agreed for that call.</p>
<p>That only works if the payment rail is built for software.</p>
<h2>x402</h2>
<p>x402 takes an old idea and makes it usable. The HTTP status &quot;402 Payment Required&quot; becomes a real flow. A request arrives, the server responds with a price, the client pays, and the request completes. There are no accounts to set up and no invoices to reconcile. The payment happens inside the same request and response the client was already making.</p>
<p>For an agent, this fits well. It can learn the price, decide, and pay in one exchange.</p>
<h2>MPP</h2>
<p>MPP covers the wider path for machine-to-machine payment. It defines how a client settles an agreed amount for a specific piece of work. Combined with an up-front quote, it turns a data request into a clean transaction with an agreed price and a settled payment.</p>
<h2>Why per-request pricing fits agents</h2>
<p>A subscription cannot say that one specific answer is worth one specific amount. Per-request pricing can. The agent asks, receives a quote, and pays for exactly what it uses. Testril supports x402 and MPP so that exchange works without extra steps, which is why we price every request before it runs.</p>
]]></content:encoded>
  </item>
</channel>
</rss>
