<?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: Mr Hamlin</title>
    <description>The latest articles on DEV Community by Mr Hamlin (@mr_hamlin).</description>
    <link>https://dev.to/mr_hamlin</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%2F3815462%2F608d44c9-7dbf-4f19-bf5c-211f31b318fb.jpg</url>
      <title>DEV Community: Mr Hamlin</title>
      <link>https://dev.to/mr_hamlin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mr_hamlin"/>
    <language>en</language>
    <item>
      <title>Bringing Crypto Batch Payouts to E-Commerce</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Sat, 31 Oct 2026 20:26:04 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/bringing-crypto-batch-payouts-to-e-commerce-3c92</link>
      <guid>https://dev.to/mr_hamlin/bringing-crypto-batch-payouts-to-e-commerce-3c92</guid>
      <description>&lt;h2&gt;
  
  
  From Vendure to WooCommerce..
&lt;/h2&gt;

&lt;p&gt;Crypto checkout is a solved problem. Dozens of payment gateways let customers pay with crypto at checkout. But what happens after the sale? How does the marketplace operator pay their vendors? How does a store owner pay suppliers?&lt;/p&gt;

&lt;p&gt;That's the side of e-commerce payments nobody's building for. So we did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Payouts, Not Checkout
&lt;/h2&gt;

&lt;p&gt;Most crypto-in-commerce projects focus on the buy side: let a customer pay with ETH or USDC at checkout. That's fine, but it's competing with credit cards — and credit cards are really, really good at checkout.&lt;/p&gt;

&lt;p&gt;The payout side is different. When a marketplace has 50 vendors and needs to distribute last week's earnings, they're dealing with bank transfers, payment processors taking percentage cuts, international wire fees, and settlement times measured in days. For vendors in countries where traditional banking is unreliable or expensive, it's even worse.&lt;/p&gt;

&lt;p&gt;USDC batch payouts solve this cleanly: one on-chain transaction, all recipients paid simultaneously, settled in seconds, verifiable on-chain. The Spraay batch contract on Base handles up to 200 recipients per call. Gas costs are a fraction of what wire transfers charge.&lt;/p&gt;

&lt;p&gt;We built payout plugins for two major open-source e-commerce platforms to prove this works in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vendure: The First Plugin
&lt;/h2&gt;

&lt;p&gt;Vendure is a headless e-commerce framework built on Node.js and TypeScript. It's popular with developers building custom marketplace experiences.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;@plagtech/vendure-spraay-plugin&lt;/code&gt; adds a payout workflow to the Vendure admin panel. When a marketplace operator is ready to distribute earnings, they select the vendors, review the amounts, and approve the batch. The plugin calls the Spraay gateway, which returns an unsigned transaction. The operator signs it with their own wallet — we never touch their keys — and the batch settles on Base.&lt;/p&gt;

&lt;p&gt;The plugin is published on npm and we've submitted it to the Vendure Hub for listing.&lt;/p&gt;

&lt;p&gt;Key design decision: the plugin is &lt;strong&gt;non-custodial&lt;/strong&gt;. Plagtech never holds funds. The operator's wallet signs the transaction directly. We facilitate the batching, not the custody.&lt;/p&gt;

&lt;h2&gt;
  
  
  WooCommerce: Going Where the Merchants Are
&lt;/h2&gt;

&lt;p&gt;Vendure is developer-friendly but niche. WooCommerce powers over 35% of all online stores. If we wanted batch payouts to reach real merchants, WooCommerce was the obvious next target.&lt;/p&gt;

&lt;p&gt;But WooCommerce runs on PHP and WordPress. Our gateway is a Node.js service. We weren't about to ask WordPress hosts to run Node.&lt;/p&gt;

&lt;p&gt;The architecture we landed on: a thin PHP plugin that calls the Spraay REST gateway over HTTP. The plugin handles the WordPress admin UI — settings pages, payout history, batch management — and the gateway handles the crypto. No Node.js dependency on the merchant's hosting.&lt;/p&gt;

&lt;p&gt;The plugin works for two audiences: single-store owners paying suppliers, and multi-vendor marketplace operators distributing to vendors. We deliberately avoided requiring any specific multi-vendor plugin (Dokan, WCFM, etc.) as a dependency. The plugin reads WooCommerce's native order data and lets the operator define recipients.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Auth Problem
&lt;/h2&gt;

&lt;p&gt;Our gateway uses x402 — HTTP-native payment authentication. That's great for machine-to-machine scenarios, but a WordPress plugin can't pay an x402 challenge on every API call. Merchants need a simpler auth flow.&lt;/p&gt;

&lt;p&gt;So we shipped API key authentication on the gateway side. B2B clients get an API key (prefixed &lt;code&gt;sk_spraay_&lt;/code&gt; so it's easy to identify in config files), pass it in an &lt;code&gt;X-API-Key&lt;/code&gt; header, and skip the x402 challenge entirely. The gateway extends its existing key infrastructure with B2B-specific columns. Revenue comes from the same 0.3% on-chain protocol fee — no separate subscription or API pricing.&lt;/p&gt;

&lt;p&gt;This was a gateway-level change that benefits any future integration, not just WooCommerce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Tested
&lt;/h2&gt;

&lt;p&gt;We didn't ship this with only unit tests. We ran a full production test: a local WordPress install (via LocalWP), the plugin installed and configured, connected to the live Spraay gateway on Base mainnet.&lt;/p&gt;

&lt;p&gt;We triggered a real batch payout from the WordPress admin panel. Real USDC moved on-chain — 1 USDC to a recipient, 0.003 fee, settled on Base. The transaction confirmed and the plugin correctly reconciled the result by checking the on-chain receipt.&lt;/p&gt;

&lt;p&gt;Two bugs surfaced during the live test and we fixed them on the spot: a null array crash in the order ID handling, and a unit mismatch between human-readable decimals and base-unit amounts. The kind of stuff you only catch by actually running money through the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Submitted and Waiting
&lt;/h2&gt;

&lt;p&gt;The WooCommerce plugin is submitted to the WordPress.org plugin directory. We're waiting on reviewer approval. Once it's listed, any WooCommerce store can install it and start batching USDC payouts to their vendors or suppliers.&lt;/p&gt;

&lt;p&gt;We also published a ClawHub skill for it — AI agents can now help merchants configure and run batch payouts through the plugin.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;WooCommerce and Vendure aren't the end. Medusa.js is on our list as the next e-commerce integration target. The pattern is the same every time: thin plugin on the platform side, heavy lifting on the gateway, non-custodial signing, batch settlement on Base.&lt;/p&gt;

&lt;p&gt;The long-term play is straightforward: if you run an online marketplace and you need to pay people, you should be able to do it in one transaction, settled in seconds, for a fraction of what traditional payment processors charge.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Spraay Protocol is multi-chain batch payment infrastructure built by Plagtech. The WooCommerce plugin is pending at WordPress.org. The Vendure plugin is live on &lt;a href="https://www.npmjs.com/package/@plagtech/vendure-spraay-plugin" rel="noopener noreferrer"&gt;npm&lt;/a&gt;. Learn more at &lt;a href="https://spraay.app" rel="noopener noreferrer"&gt;spraay.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Uniswap v4 Hooks Explained — And What We Built for OnChain Revenue Sharing</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Sat, 31 Oct 2026 05:39:14 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/uniswap-v4-hooks-explained-and-what-we-built-for-onchain-revenue-sharing-29b4</link>
      <guid>https://dev.to/mr_hamlin/uniswap-v4-hooks-explained-and-what-we-built-for-onchain-revenue-sharing-29b4</guid>
      <description>&lt;p&gt;Uniswap v4 introduced one of the most significant architectural changes in DeFi: hooks. If you've heard the term but aren't sure what it means in practice, this post breaks it down — and shows a real hook we built and got merged into the official Uniswap hook registry.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Uniswap v4 Hooks?
&lt;/h2&gt;

&lt;p&gt;In previous versions of Uniswap, the protocol was essentially closed. You could create pools, add liquidity, and swap tokens, but you couldn't customize what happened during those operations. The logic was fixed.&lt;/p&gt;

&lt;p&gt;V4 changes that with hooks — external smart contracts that "hook into" the lifecycle of pool operations. Think of them like middleware for a DEX.&lt;/p&gt;

&lt;p&gt;Every major pool action in v4 has a before and after stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;beforeSwap / afterSwap&lt;/strong&gt; — runs before or after a token swap&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;beforeAddLiquidity / afterAddLiquidity&lt;/strong&gt; — runs when liquidity is added&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;beforeRemoveLiquidity / afterRemoveLiquidity&lt;/strong&gt; — runs when liquidity is removed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;beforeInitialize / afterInitialize&lt;/strong&gt; — runs when a pool is first created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a pool is created, the pool creator specifies a hook contract address. From that point on, every operation on that pool calls the relevant hook functions. The hook can run custom logic, modify behavior, collect fees, enforce rules — whatever the contract is designed to do.&lt;/p&gt;

&lt;p&gt;The key insight: hooks don't modify the Uniswap core protocol. They're external contracts that the protocol calls at defined points. This means anyone can write a hook, and pool creators choose which hook (if any) to attach to their pool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Hooks Matter
&lt;/h2&gt;

&lt;p&gt;Before v4, if you wanted custom behavior on a DEX — say, distributing a portion of swap fees to a list of stakeholders — you had two options: fork the entire protocol, or build a wrapper contract that interacted with the pool externally. Both were messy.&lt;/p&gt;

&lt;p&gt;Hooks make this native. Some real use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic fees&lt;/strong&gt; — adjust swap fees based on volatility, time of day, or pool utilization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-chain limit orders&lt;/strong&gt; — execute trades when price hits a target&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TWAP (time-weighted average price) orders&lt;/strong&gt; — spread large trades over time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom access control&lt;/strong&gt; — restrict who can trade in a pool (KYC pools, DAO-gated pools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revenue distribution&lt;/strong&gt; — automatically route a share of pool activity to stakeholders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one is what we built.&lt;/p&gt;

&lt;h2&gt;
  
  
  BatchDistributeHook: What It Does
&lt;/h2&gt;

&lt;p&gt;Our hook lets pool operators push-distribute ERC-20 tokens or native currency (ETH) to up to 200 recipients in a single transaction through the Spraay batch contract on Base.&lt;/p&gt;

&lt;p&gt;The use case: a pool generates fees or revenue, and the operator wants to distribute those funds to a list of stakeholders — liquidity providers, DAO members, team wallets, community funds, whatever the arrangement is.&lt;/p&gt;

&lt;p&gt;Without a hook, the operator would need to manually collect fees, calculate shares, and send individual transactions to each recipient. With BatchDistributeHook, they call the distribution function and the Spraay batch contract handles the rest: one on-chain transaction, all recipients paid, all amounts verifiable.&lt;/p&gt;

&lt;p&gt;The hook interacts with Spraay's batch contract on Base at &lt;code&gt;0xb9c1ab7bd023c784c19b8e9f10ce9cded9ff9010&lt;/code&gt;. This is the same contract that powers all of Spraay's batch payment infrastructure — the same one our e-commerce plugins, robot fleet payments, and gateway all settle through.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;The flow is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A pool is created with BatchDistributeHook as its hook contract&lt;/li&gt;
&lt;li&gt;The pool operates normally — swaps, liquidity, everything works as expected&lt;/li&gt;
&lt;li&gt;When the operator wants to distribute accumulated tokens, they call the hook's distribute function&lt;/li&gt;
&lt;li&gt;The hook approves the Spraay batch contract to spend the specified token amount&lt;/li&gt;
&lt;li&gt;The batch contract executes a single transaction that transfers tokens to all recipients&lt;/li&gt;
&lt;li&gt;Each recipient's share is settled on-chain, verifiable by anyone&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The operator defines the recipient list and amounts. The hook handles the approval and contract interaction. The batch contract handles the multi-send efficiently.&lt;/p&gt;

&lt;p&gt;Up to 200 recipients per batch means this scales to meaningful distribution sizes without needing multiple transactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merged Into the Uniswap Hook Registry
&lt;/h2&gt;

&lt;p&gt;Uniswap maintains an official hook registry — a curated list of hooks that developers have built for the v4 ecosystem. Getting listed means the hook has been reviewed and meets the registry's standards.&lt;/p&gt;

&lt;p&gt;Our BatchDistributeHook was merged into the Uniswap hooklist as PR #10617 in October 2026, listed as "Add BatchDistributeHook hook on base." It's now part of the official v4 hook ecosystem.&lt;/p&gt;

&lt;p&gt;This matters because it puts Spraay's batch payment infrastructure directly into the Uniswap developer surface. Anyone browsing the hook registry looking for distribution solutions finds our hook, and through it, the batch contract that powers the rest of our protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Hooks are still early. Most v4 pools are running without hooks, and the ecosystem of available hooks is still growing. But the architecture is powerful: it turns Uniswap from a fixed protocol into a programmable platform.&lt;/p&gt;

&lt;p&gt;For us, BatchDistributeHook is a proof point. The same batch contract that settles robot fleet payments and e-commerce vendor payouts can also settle DeFi revenue distribution — all through one on-chain primitive. That's the advantage of building infrastructure instead of applications: the same settlement layer works across use cases.&lt;/p&gt;

&lt;p&gt;If you're building on Uniswap v4 and need batch distribution, the hook is on the registry. If you're building anything that needs to pay multiple recipients on Base in one transaction, the Spraay batch contract is open and documented.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Spraay Protocol is multi-chain batch payment infrastructure built by Plagtech. BatchDistributeHook is listed on the &lt;a href="https://github.com/Uniswap/hooklist" rel="noopener noreferrer"&gt;Uniswap v4 hook registry&lt;/a&gt;. Learn more at &lt;a href="https://spraay.app" rel="noopener noreferrer"&gt;spraay.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>dex</category>
      <category>ethereum</category>
      <category>ai</category>
    </item>
    <item>
      <title>What Is x402 and Why It Matters for Machine-to-Machine Payments</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Fri, 30 Oct 2026 07:23:19 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/what-is-x402-and-why-it-matters-for-machine-to-machine-payments-213j</link>
      <guid>https://dev.to/mr_hamlin/what-is-x402-and-why-it-matters-for-machine-to-machine-payments-213j</guid>
      <description>&lt;p&gt;HTTP has a status code that almost nobody uses: &lt;strong&gt;402 Payment Required&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's been in the spec since HTTP/1.1 — reserved "for future use." That future is here. The x402 protocol turns that dusty status code into a real payment flow, and we've built our entire payment gateway around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Paying for APIs
&lt;/h2&gt;

&lt;p&gt;Right now, if you want to charge for an API, you have a few options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API keys with a billing account&lt;/strong&gt; — the client signs up, enters a credit card, gets a key, and you bill them monthly. Works great for humans. Terrible for machines. An autonomous agent can't fill out a signup form, and hardcoding API keys into agent workflows creates security and management headaches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OAuth + subscription tiers&lt;/strong&gt; — even more overhead. Token refresh flows, scope management, plan limitations. Fine for SaaS products with human users. Overkill for a machine that just needs to make one call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prepaid credits&lt;/strong&gt; — buy credits upfront, spend them per request. Better, but still requires account creation, and the credits are locked into one service.&lt;/p&gt;

&lt;p&gt;All of these assume a human is involved at setup time. That assumption breaks down when the client is an AI agent, a robot, an IoT device, or another service in a microservice mesh.&lt;/p&gt;

&lt;h2&gt;
  
  
  How x402 Works
&lt;/h2&gt;

&lt;p&gt;x402 takes a completely different approach: payment happens inline with the HTTP request. No accounts. No API keys. No signup. Just pay and go.&lt;/p&gt;

&lt;p&gt;Here's the flow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt; — the client makes a normal HTTP request to the API endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt; — the server responds with &lt;code&gt;402 Payment Required&lt;/code&gt; and includes payment details in the response headers: how much, which token, which chain, where to send it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt; — the client makes the payment on-chain (or provides proof of a payment already made).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt; — the client retries the original request, this time including the payment proof in a header.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt; — the server verifies the payment and serves the response.&lt;/p&gt;

&lt;p&gt;That's it. The client never created an account. The server never stored a credit card. The payment is settled on-chain, verifiable by both parties, and the whole flow happened over standard HTTP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why HTTP-Native Matters
&lt;/h2&gt;

&lt;p&gt;The genius of x402 is that it works with existing HTTP infrastructure. Proxies, load balancers, CDNs, monitoring tools — they all understand HTTP status codes. A 402 response flows through the same infrastructure as a 401 or a 403. No special protocol, no WebSocket upgrade, no custom transport.&lt;/p&gt;

&lt;p&gt;This means any HTTP client can be taught to handle x402 payments. A Python &lt;code&gt;requests&lt;/code&gt; call, a &lt;code&gt;curl&lt;/code&gt; command, a browser fetch — if it speaks HTTP, it can speak x402.&lt;/p&gt;

&lt;p&gt;For machine-to-machine scenarios, this is transformative. An AI agent making an API call doesn't need pre-provisioned credentials for every service it might use. It just needs a wallet with funds and the ability to handle a 402 response. First time calling a new API? Pay the 402 and you're in.&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Built On It: The Spraay Gateway
&lt;/h2&gt;

&lt;p&gt;Spraay's payment gateway at gateway.spraay.app is an x402-native service. Every paid endpoint responds with a 402 challenge that tells the caller exactly what to pay.&lt;/p&gt;

&lt;p&gt;The gateway handles batch payments — send USDC to up to 200 recipients in a single on-chain transaction on Base. The x402 flow means any HTTP client can use it without signing up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call the batch endpoint&lt;/li&gt;
&lt;li&gt;Receive a 402 with the fee amount and payment address&lt;/li&gt;
&lt;li&gt;Pay the fee on-chain&lt;/li&gt;
&lt;li&gt;Retry with the transaction hash in the header&lt;/li&gt;
&lt;li&gt;Receive the unsigned batch transaction to sign and submit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We support multiple chains for the payment itself (Base, Ethereum, Solana), and the gateway verifies payment on whichever chain the client used.&lt;/p&gt;

&lt;p&gt;The fee structure is simple: 0.3% of the batch amount, with a minimum. The client knows the exact cost before paying because the 402 response spells it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  x402 for Agents and Robots
&lt;/h2&gt;

&lt;p&gt;This is where x402 really shines. We've integrated Spraay's gateway with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI agent frameworks&lt;/strong&gt; — our payment tools are merged into NVIDIA's NeMo Agent Toolkit, Google's ADK community, and the Strands Agents documentation. Agents in these frameworks can handle x402 challenges natively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Robot fleet management&lt;/strong&gt; — our rmf-spraay bridge dispatches tasks through the gateway using x402. A robot fleet operator's software pays the 402 challenge, dispatches a task, and settles the payout — all over HTTP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;E-commerce plugins&lt;/strong&gt; — for platforms where x402 per-request payment doesn't make sense (a WordPress plugin can't pay a 402 on every batch call), we added API key authentication alongside x402. B2B clients get a key that bypasses the challenge. Same gateway, flexible auth.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The flexibility is the point. x402 is the default for machine clients that can handle it. API keys are there for platforms that can't. Both hit the same endpoints, same settlement, same on-chain verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Broader x402 Ecosystem
&lt;/h2&gt;

&lt;p&gt;We're not the only ones building on x402. Coinbase has championed the protocol, and an ecosystem of x402-compatible services is growing. The pattern is consistent: HTTP endpoint, 402 challenge, on-chain payment, proof-of-payment header, service delivery.&lt;/p&gt;

&lt;p&gt;What we've added to the ecosystem is batch payment infrastructure. Most x402 implementations handle simple one-to-one payments (pay $0.05, get an API response). Our gateway handles one-to-many: pay once, distribute to hundreds of recipients. That opens up use cases like payroll, vendor payments, revenue sharing, and fleet settlement that a simple per-request payment model can't cover.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why We Think This Is the Future
&lt;/h2&gt;

&lt;p&gt;Every trend points toward more machines talking to more machines, with less human involvement in each transaction. AI agents are calling APIs on your behalf. IoT devices are negotiating with services. Microservices are settling with each other.&lt;/p&gt;

&lt;p&gt;All of these need a payment flow that doesn't require a human to set up an account first. x402 provides that: an open, HTTP-native, on-chain-verified payment protocol that any machine can use.&lt;/p&gt;

&lt;p&gt;We've bet Spraay's entire architecture on it, and after months of building integrations across robotics, e-commerce, DeFi, and AI agents, the bet is holding up. The protocol works. The infrastructure works. The use cases are real.&lt;/p&gt;

&lt;p&gt;If you're building something that needs to charge for API access or settle payments between machines, take a look at x402. The 402 status code has been waiting since 1997. It's ready now.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Spraay Protocol is multi-chain batch payment infrastructure built by Plagtech. Our x402 gateway is live at gateway.spraay.app. Learn more at &lt;a href="https://spraay.app" rel="noopener noreferrer"&gt;spraay.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>crypto</category>
      <category>web3</category>
    </item>
    <item>
      <title>How to Pay Your Shopify Affiliates in USDC (Open Source)</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Fri, 31 Jul 2026 07:23:43 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/how-to-pay-your-shopify-affiliates-in-usdc-open-source-32p1</link>
      <guid>https://dev.to/mr_hamlin/how-to-pay-your-shopify-affiliates-in-usdc-open-source-32p1</guid>
      <description>&lt;p&gt;If you run affiliate or creator payouts for a Shopify store, you know the drill: export a spreadsheet, log into PayPal or a payout platform, pay per-transaction fees on every single recipient, wait days for settlement, and deal with the countries your payment provider doesn't support.&lt;/p&gt;

&lt;p&gt;There's a simpler way: &lt;strong&gt;batch USDC payouts on Base&lt;/strong&gt;. One transaction, N recipients, settlement in seconds, and it works for anyone with a wallet address — anywhere in the world.&lt;/p&gt;

&lt;p&gt;In this tutorial, you'll self-host an open-source Shopify app that adds a &lt;strong&gt;Payouts&lt;/strong&gt; section to your Shopify admin. You'll upload a CSV of affiliate wallet addresses and amounts, approve USDC once, and pay everyone in a single on-chain transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/plagtech/spraay-shopify" rel="noopener noreferrer"&gt;github.com/plagtech/spraay-shopify&lt;/a&gt; (MIT license)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;Using an OpenClaw agent?&lt;/strong&gt; Skip the manual setup entirely: &lt;code&gt;openclaw skills install @plagtech/spraay-shopify-selfhost&lt;/code&gt; walks you through deployment, and &lt;a href="https://clawhub.ai/plagtech/shopify-batch-payouts" rel="noopener noreferrer"&gt;&lt;code&gt;@plagtech/shopify-batch-payouts&lt;/code&gt;&lt;/a&gt; runs payouts via the Spraay gateway.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What you're building
&lt;/h2&gt;

&lt;p&gt;The Spraay Shopify app is an embedded admin app (built with Remix + Polaris, so it looks and feels native to Shopify) that lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upload or paste a CSV&lt;/strong&gt; of recipients — wallet address + USDC amount per row&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review the batch&lt;/strong&gt; — recipients, totals, and the 0.3% protocol fee, all shown before anything moves&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect a wallet&lt;/strong&gt; — MetaMask or Coinbase Smart Wallet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approve USDC once&lt;/strong&gt;, then execute the entire batch in one transaction on Base&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track payout history&lt;/strong&gt; right in your admin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under the hood, payouts go through the Spraay batch contract on Base (&lt;code&gt;0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC&lt;/code&gt;), using native USDC (&lt;code&gt;0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&lt;/code&gt;). Base transaction fees are typically a fraction of a cent, so the cost of paying 50 affiliates is basically the same as paying one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why self-hosted?
&lt;/h2&gt;

&lt;p&gt;Two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You control everything.&lt;/strong&gt; Your Shopify credentials, your database, your infrastructure. The app requests &lt;strong&gt;zero Shopify scopes&lt;/strong&gt; — it structurally cannot read your orders, customers, or products — and it never custodies funds: payouts are signed by &lt;em&gt;your&lt;/em&gt; wallet, in your browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom app distribution is Shopify's intended path&lt;/strong&gt; for merchant-specific tooling. You create your own app in the Shopify Dev Dashboard, install it on your store, and you're done. No app store, no waiting.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Shopify store (any plan; a development store works for testing)&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://partners.shopify.com" rel="noopener noreferrer"&gt;Shopify Partners&lt;/a&gt; account (free) to create the custom app&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://railway.app" rel="noopener noreferrer"&gt;Railway&lt;/a&gt; account for hosting (or any host that runs Docker/Node 20)&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://supabase.com" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; project for the Postgres database (free tier is fine)&lt;/li&gt;
&lt;li&gt;A wallet with USDC on Base (MetaMask or Coinbase Smart Wallet)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total setup time: about 15 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Fork and deploy
&lt;/h2&gt;

&lt;p&gt;Fork &lt;a href="https://github.com/plagtech/spraay-shopify" rel="noopener noreferrer"&gt;plagtech/spraay-shopify&lt;/a&gt;, then deploy it to Railway. The repo ships with a &lt;code&gt;railway.json&lt;/code&gt; and Dockerfile (node:20-alpine), so the &lt;strong&gt;Deploy to Railway&lt;/strong&gt; button in the README gets you a running instance quickly.&lt;/p&gt;

&lt;p&gt;One important detail: make sure &lt;code&gt;PORT=3000&lt;/code&gt; is set in your Railway service variables — the container expects it.&lt;/p&gt;

&lt;p&gt;Once deployed, Railway gives you a public URL (e.g. &lt;code&gt;your-app.up.railway.app&lt;/code&gt;). You can point a custom domain at it later via CNAME if you want something cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create your custom app in Shopify
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://dev.shopify.com" rel="noopener noreferrer"&gt;dev.shopify.com&lt;/a&gt; → Apps → &lt;strong&gt;Create app&lt;/strong&gt; → choose &lt;strong&gt;Custom distribution&lt;/strong&gt;. This is Shopify's intended path for merchant-specific tooling — no App Store review involved.&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;App URL&lt;/strong&gt; to your Railway deployment URL (HTTPS, no trailing slash).&lt;/li&gt;
&lt;li&gt;Add all three OAuth redirect URLs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   https://your-domain/auth/callback
   https://your-domain/auth/shopify/callback
   https://your-domain/api/auth/callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Copy the &lt;strong&gt;Client ID&lt;/strong&gt; and &lt;strong&gt;Client Secret&lt;/strong&gt; — they become &lt;code&gt;SHOPIFY_API_KEY&lt;/code&gt; and &lt;code&gt;SHOPIFY_API_SECRET&lt;/code&gt; in the next step. Then install the app on your store from the Dev Dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 3: Configure environment variables
&lt;/h2&gt;

&lt;p&gt;The repo includes a fully documented &lt;code&gt;.env.example&lt;/code&gt;. Set these in your Railway service variables (the Deploy button pre-prompts for all of them):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SHOPIFY_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Client ID from Step 2 (public — it ships in the browser bundle)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SHOPIFY_API_SECRET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Client Secret from Step 2 (keep secret — it signs webhooks and OAuth)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SHOPIFY_APP_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your Railway URL, no trailing slash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SCOPES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Leave &lt;strong&gt;empty&lt;/strong&gt; — the app uses no Shopify data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DATABASE_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Supabase &lt;strong&gt;pooled&lt;/strong&gt; connection string (port 6543), with &lt;code&gt;?schema=shopify&amp;amp;pgbouncer=true&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DIRECT_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Supabase &lt;strong&gt;direct&lt;/strong&gt; connection string (port 5432), with &lt;code&gt;?schema=shopify&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NODE_ENV&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;production&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PORT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two things worth knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PORT=3000&lt;/code&gt; is load-bearing.&lt;/strong&gt; The Dockerfile exposes 3000; if Railway injects its default 8080 instead, every route returns a 502 even though the deploy shows "Online." If you ever see that symptom, this is why.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;?schema=shopify&lt;/code&gt; suffix keeps the app's tables in their own Postgres schema, so it won't collide with anything else in your Supabase project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Migrations run automatically on boot. When the deploy logs show a successful migrate and the server's listen URL, and the app opens from your Shopify admin, you're wired up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Run your first payout
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open the app from your Shopify admin sidebar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upload a CSV&lt;/strong&gt; (or paste rows directly) in the format: &lt;code&gt;wallet_address,amount&lt;/code&gt;. Each row is one affiliate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review the batch.&lt;/strong&gt; You'll see every recipient, the total USDC, and the 0.3% protocol fee itemized before you sign anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect your wallet&lt;/strong&gt; — MetaMask or Coinbase Smart Wallet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approve USDC&lt;/strong&gt; for the batch total (one approval).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute.&lt;/strong&gt; One transaction on Base pays every recipient. Settlement is near-instant, and the transaction hash links straight to BaseScan.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your payout history is saved in the app, so month-over-month affiliate payments become a two-minute task: export your affiliate report as CSV, upload, execute.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this costs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base gas:&lt;/strong&gt; typically under a cent for the whole batch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol fee:&lt;/strong&gt; 0.3% of the batch total, collected on-chain by the batch contract&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting:&lt;/strong&gt; Railway's hobby tier + Supabase free tier cover a single-store deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare that to per-recipient fees on traditional payout rails, and the math gets very favorable very quickly once you're paying more than a handful of people.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use cases beyond affiliates
&lt;/h2&gt;

&lt;p&gt;The CSV-in, batch-out model fits anywhere you pay multiple people regularly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Creator/UGC payouts&lt;/strong&gt; for content programs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supplier payments&lt;/strong&gt; to international vendors who accept stablecoins&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Referral and ambassador programs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revenue splits&lt;/strong&gt; between co-founders or collaborators&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;You now have a self-hosted, open-source crypto payout system living inside your Shopify admin. No custodial platform, no per-recipient fees, no geography restrictions — just a CSV and one transaction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/plagtech/spraay-shopify" rel="noopener noreferrer"&gt;github.com/plagtech/spraay-shopify&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💧 &lt;strong&gt;Spraay Protocol:&lt;/strong&gt; &lt;a href="https://spraay.app" rel="noopener noreferrer"&gt;spraay.app&lt;/a&gt; — batch payment infrastructure on Base, Ethereum, Solana, and more&lt;/li&gt;
&lt;li&gt;🐦 Questions? Reach out &lt;a href="https://twitter.com/Spraay_app" rel="noopener noreferrer"&gt;@Spraay_app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you deploy it, open an issue or PR — contributions welcome.&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>web3</category>
      <category>cryptocurrency</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I wrote the book I wish existed when I started shipping solo with AI</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Mon, 06 Jul 2026 20:50:03 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/i-wrote-the-book-i-wish-existed-when-i-started-shipping-solo-with-ai-1iej</link>
      <guid>https://dev.to/mr_hamlin/i-wrote-the-book-i-wish-existed-when-i-started-shipping-solo-with-ai-1iej</guid>
      <description>&lt;p&gt;For the past year-plus I've been running multiple live products completely solo — a crypto payment gateway processing transactions across 16 chains, an LLM API proxy with Stripe billing, a DEX on Base mainnet, packages on npm and PyPI, and integration PRs merged into Google's, AWS's, and Coinbase's agent framework ecosystems.&lt;/p&gt;

&lt;p&gt;No team. No funding. One laptop and a set of AI tools that didn't exist a few years ago.&lt;/p&gt;

&lt;p&gt;People kept asking how the workflow actually works — not "what's your favorite AI tool" but the whole system: how you go from idea to deployed product to paying users when you're the entire engineering, marketing, and support department. So I wrote it down. All of it. The result is &lt;strong&gt;Build in Public with AI: The Solo Developer's Guide to Shipping Fast&lt;/strong&gt; — 268 pages, 13 chapters, and it just went live on Amazon.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually in it
&lt;/h2&gt;

&lt;p&gt;This is not a prompt engineering guide and not a listicle of tools. It's the operating system:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part I — The Solo AI Stack.&lt;/strong&gt; How to pick the two AI tools that actually matter and ignore the rest, structure your day around a Think → Prompt → Scaffold → Refine → Ship loop, and manage context across multiple projects without losing your mind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part II — Shipping Product.&lt;/strong&gt; The Minimum Deployable Product framework (zero to deployed in a day), building fast without building fragile, running 3–5 products at once with a tiering system that prevents burnout, and a full chapter on AI-assisted smart contract development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part III — Distribution.&lt;/strong&gt; The part most technical books skip. The PR Blitz strategy for getting your tool integrated into every major AI framework ecosystem, README-driven distribution, the awesome-list strategy, and building in public without it becoming a second job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part IV — The Operating System.&lt;/strong&gt; Revenue models that work for one person, wiring up Stripe in a weekend, the emotional reality of solo building, what AI still can't do, and a 30-day playbook you can start tomorrow.&lt;/p&gt;

&lt;p&gt;Plus appendices: the complete tool stack reference, 15 copy-paste prompt templates, and a printable Ship It checklist.&lt;/p&gt;

&lt;h2&gt;
  
  
  One idea from the book, free
&lt;/h2&gt;

&lt;p&gt;Here's the concept that changed how I ship more than any tool did: &lt;strong&gt;the Minimum Deployable Product&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An MVP is defined by features. An MDP is defined by a state: &lt;em&gt;deployed, reachable, and doing its one job in production&lt;/em&gt;. The difference sounds subtle but it inverts your priorities. You don't build features and then figure out deployment — you deploy a skeleton on day one (a single endpoint, a single page, whatever) and then every feature lands in a production context from the start.&lt;/p&gt;

&lt;p&gt;Why it matters for solo devs specifically: deployment problems are the ones AI helps you with &lt;em&gt;least&lt;/em&gt; — they're environmental, specific to your accounts and configs, and full of gotchas AI can't see. Feature code is what AI helps with &lt;em&gt;most&lt;/em&gt;. So you front-load the part AI can't do while your motivation is highest, and spend the rest of the build in AI's strongest territory. Every hour after day one compounds.&lt;/p&gt;

&lt;p&gt;Also, honestly: nothing sustains momentum like a live URL. Even an ugly one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who it's for
&lt;/h2&gt;

&lt;p&gt;Developers. You can read a stack trace and make architecture decisions — you don't need to be senior, but this isn't a learn-to-code book. If you've been watching the AI-assisted-shipping wave and wondering how people actually run the full loop solo, this is the manual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.amazon.com/dp/B0H7KWRDC9" rel="noopener noreferrer"&gt;Build in Public with AI: The Solo Developer's Guide to Shipping Fast — $4.99 on Amazon&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'll be posting build logs and revenue numbers as this launches — that's kind of the whole point of the title. If you read it and something's unclear, wrong, or missing, tell me. Solo also means the errata department is me.&lt;/p&gt;

&lt;p&gt;What's the biggest bottleneck in your own shipping loop — building, deploying, or distributing? Genuinely curious where people get stuck.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>I Built a Batch Payment Plugin for AI Agents in 48 Hours (and It Made Its First Cent On-Chain)</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Fri, 03 Jul 2026 19:34:44 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/i-built-a-batch-payment-plugin-for-ai-agents-in-48-hours-and-it-made-its-first-cent-on-chain-29p8</link>
      <guid>https://dev.to/mr_hamlin/i-built-a-batch-payment-plugin-for-ai-agents-in-48-hours-and-it-made-its-first-cent-on-chain-29p8</guid>
      <description>&lt;p&gt;Yesterday I had an idea about where value accrues in the AI agent ecosystem. Today the plugin is live on ClawHub, published on npm, and has already processed a real USDC payout on Base mainnet — with the protocol's first fee, all $0.009 of it, sitting on-chain.&lt;/p&gt;

&lt;p&gt;Here's the whole thing: the insight, the build, the receipts, and the pricing math.&lt;/p&gt;

&lt;h2&gt;
  
  
  The insight: plugins own execution paths, skills get invoked
&lt;/h2&gt;

&lt;p&gt;I've been building in the x402 / agent-payments ecosystem for months — my main project is an x402 payment gateway with ~190 endpoints. Watching which projects in this space actually generate revenue, one pattern kept jumping out:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The projects making money don't sell capabilities. They own a step in a loop.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;skill&lt;/em&gt; is something an agent invokes occasionally, when a task happens to call for it. A &lt;em&gt;plugin&lt;/em&gt; that sits on a recurring execution path gets exercised every single time the loop runs. Same amount of code. Wildly different revenue curves.&lt;/p&gt;

&lt;p&gt;Most of the plugin activity in the agent economy clusters around the &lt;strong&gt;money-in&lt;/strong&gt; layer — routing model calls, metering inference, charging for API access. That path is getting crowded.&lt;/p&gt;

&lt;p&gt;But agents don't just consume — increasingly, they &lt;em&gt;pay out&lt;/em&gt;. Revenue splits to contributors. Settlements with other agents. Payroll-shaped flows. Refunds. And the money-out layer was, as far as I could tell, unclaimed.&lt;/p&gt;

&lt;p&gt;So I claimed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SpraayBatch does
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/plagtech/SpraayBatch" rel="noopener noreferrer"&gt;SpraayBatch&lt;/a&gt; is an OpenClaw plugin (plus a standalone CLI) that gives an AI agent a treasury:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batch USDC payouts&lt;/strong&gt; — up to 200 recipients in one atomic transaction on Base. One tx, one gas fee, everyone paid or nobody is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-custodial auto-wallet&lt;/strong&gt; — generated locally on first run, key saved to &lt;code&gt;~/.spraay/.session&lt;/code&gt;, never transmitted anywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-agent budget caps&lt;/strong&gt; — a hard block, not a warning. An agent cannot spend past its cap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Append-only ledger&lt;/strong&gt; — every payout gets a receipt with a Basescan link.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional gasless mode&lt;/strong&gt; — via ERC-4337 and a CDP Paymaster &lt;em&gt;you&lt;/em&gt; configure. Agents holding only USDC, with zero ETH, can pay. No more topping up gas dust across a fleet of agent wallets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe by default&lt;/strong&gt; — installs pointed at Base Sepolia. Mainnet is opt-in, behind an explicit confirmation gate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Six tools, one manifest. An agent gets &lt;code&gt;spraay_wallet_info&lt;/code&gt;, &lt;code&gt;spraay_balance&lt;/code&gt;, &lt;code&gt;spraay_budget_set&lt;/code&gt;, &lt;code&gt;spraay_budget_status&lt;/code&gt;, &lt;code&gt;spraay_batch_pay&lt;/code&gt;, and &lt;code&gt;spraay_receipts&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 48 hours
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Day 1:&lt;/strong&gt; built the entire plugin in one Claude Code session — contract interaction, wallet management, the budget system, the ledger, the OpenClaw manifest. Deployed a test contract to Base Sepolia, proved the gasless path with a real sponsored payout (sender held zero ETH), pushed to GitHub, published to npm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Day 2 (today):&lt;/strong&gt; renamed the project (naming is hard; batch payments &lt;em&gt;is&lt;/em&gt; the product, so the name now says so), added full fee disclosure to every user-facing surface, ran the first real mainnet payout, passed ClawHub's security review, and launched.&lt;/p&gt;

&lt;p&gt;The rename alone touched 130 references across 18 files — package name, manifest, six tool IDs, CLI binary, docs, the GitHub repo itself. Claude Code planned it, grepped every occurrence first, and executed with hard stops before anything irreversible. The whole build-rename-launch cycle is the most concrete case I've had yet for AI-assisted solo development: not because the AI did it alone, but because one person plus an agent covered ground that used to need a team.&lt;/p&gt;

&lt;h2&gt;
  
  
  The receipt
&lt;/h2&gt;

&lt;p&gt;Talk is cheap. Here's the first real mainnet payout:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://basescan.org/tx/0xb96e8e42829c482998015353fba44dbed1b3611031bd7dbf41acbb78e1268964" rel="noopener noreferrer"&gt;basescan.org/tx/0xb96e8e42829c482998015353fba44dbed1b3611031bd7dbf41acbb78e1268964&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One &lt;code&gt;sprayEqual&lt;/code&gt; call. Three recipients, 1 USDC each. Total gas: &lt;strong&gt;$0.0014&lt;/strong&gt;. The 0.30% protocol fee — 0.009 USDC — visible right there in the transfer list, flowing to the fee collector. Five USDC transfers, one atomic transaction, complete transparency.&lt;/p&gt;

&lt;p&gt;That fee is the protocol's first revenue. It's less than a cent. I screenshotted it anyway, because every fee curve starts at its first data point.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pricing math
&lt;/h2&gt;

&lt;p&gt;SpraayBatch charges &lt;strong&gt;0.30% on mainnet batches&lt;/strong&gt;. Testnet is free. No subscription, no seats, no API key tiers.&lt;/p&gt;

&lt;p&gt;Here's why that's a good deal from the payer's side: a 1,000 USDC payout to 200 recipients costs 3 USDC in protocol fees — and lands in &lt;em&gt;one&lt;/em&gt; transaction. The alternative is 200 separate transfers: 200 signatures, 200 gas fees, 200 chances for one to fail and leave your payout half-done. Even on a cheap chain like Base, the operational cost of 200 individual sends dwarfs 3 USDC.&lt;/p&gt;

&lt;p&gt;And the fee isn't hiding anywhere. It's in the README, in the tool descriptions agents read before calling, in the dry-run output, and broken out explicitly in the mainnet confirmation gate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mainnet payout: 1.5 USDC to 3 recipient(s) + 0.0045 USDC protocol fee = 1.5045 USDC total.
Mainnet requires explicit confirmation. Add --confirm to send on mainnet.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The gate reads its numbers live from the contract, not from a hardcoded string — so it stays honest even if the fee ever changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design decisions worth stealing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Testnet-default, mainnet-gated.&lt;/strong&gt; A treasury plugin that can accidentally spend real money is a liability. SpraayBatch installs pointing at Sepolia; switching to mainnet is a deliberate config change, and even then, every real payout demands explicit confirmation. During my own demo recording, I ran the mainnet pay command without the confirm flag — and the gate refused, on camera. That refusal is the best frame in the demo GIF.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bring-your-own paymaster.&lt;/strong&gt; Gasless is genuinely useful — agents that never need ETH are operationally simpler — but subsidizing gas for strangers is a great way to get drained by dust spam. So sponsorship runs through &lt;em&gt;your&lt;/em&gt; CDP account and &lt;em&gt;your&lt;/em&gt; policy caps. The plugin never subsidizes anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fees as pricing, not fine print.&lt;/strong&gt; The 0.30% appears everywhere a user or agent could encounter it before money moves. A fee someone discovers in a transaction trace reads as sneaky. A fee stated in the tool description reads as a business model. Same number, opposite trust outcomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;As an OpenClaw plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw plugins &lt;span class="nb"&gt;install &lt;/span&gt;clawhub:spraay-batch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; spraay-batch
spraay-batch info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get a wallet on first run, pointed at testnet. Fund it with Sepolia USDC and batch away for free. When you're ready for mainnet, the config flip and the confirmation gate are waiting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/plagtech/SpraayBatch" rel="noopener noreferrer"&gt;github.com/plagtech/SpraayBatch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/spraay-batch" rel="noopener noreferrer"&gt;npmjs.com/package/spraay-batch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part of the &lt;a href="https://spraay.app" rel="noopener noreferrer"&gt;Spraay&lt;/a&gt; ecosystem — batch payments infrastructure for the agent economy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll be running a real batch payout through it every week and posting the receipts — dogfooding in public. Week one is already on-chain.&lt;/p&gt;

&lt;p&gt;If you're building agents that need to pay out — or you think the money-out layer needs something this doesn't cover — I want to hear it. Comments open, DMs open (@Spraay_app on X).&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>opensource</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>You're Running a GPU Rig and Waiting 2 Weeks to Get Paid. Why?</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Fri, 26 Jun 2026 18:56:43 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/youre-running-a-gpu-rig-and-waiting-2-weeks-to-get-paid-why-2gla</link>
      <guid>https://dev.to/mr_hamlin/youre-running-a-gpu-rig-and-waiting-2-weeks-to-get-paid-why-2gla</guid>
      <description>&lt;p&gt;Let me paint a picture most GPU operators know too well.&lt;/p&gt;

&lt;p&gt;You spent $2,000 on a used RTX 4090. You set it up, got verified on Vast.ai, dialed in your thermals, and started earning. The dashboard says you've made $180 this pay period. Nice.&lt;/p&gt;

&lt;p&gt;Now you wait.&lt;/p&gt;

&lt;p&gt;Vast.ai pays hosts every two weeks through PayPal or Wise. Your money sits in their system for 14 days before it moves. And when it does land, PayPal takes their cut. If you're international, Wise takes a currency conversion fee on top of that. By the time that $180 reaches your bank account, you're looking at maybe $155 and three weeks since the jobs actually ran.&lt;/p&gt;

&lt;p&gt;RunPod? They pay in platform credits. You earn compute hours, not dollars. Want to cash out? You're spending those credits back on RunPod's own infrastructure. It's store credit, not income.&lt;/p&gt;

&lt;p&gt;Salad pays in "Salad Balance" that you redeem for gift cards. Gift cards. You're running a $2,000 GPU and getting paid in Amazon gift cards.&lt;/p&gt;

&lt;p&gt;This is the state of GPU operator payouts in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question nobody is asking
&lt;/h2&gt;

&lt;p&gt;Here's what's strange about this whole situation. The AI compute rental market is worth over $8 billion this year. It's growing at 44% annually. There are over 120,000 developers on Vast.ai alone looking for GPU time. Demand is through the roof.&lt;/p&gt;

&lt;p&gt;And yet the people actually providing the compute — the operators running the rigs, paying the electricity, managing the hardware — are getting paid like it's 2015. Biweekly PayPal transfers. Platform credits. Gift cards.&lt;/p&gt;

&lt;p&gt;Meanwhile, USDC settles on Base in two seconds. Two seconds. Around the clock. No minimums. No platform holding your funds. No conversion fees. The infrastructure for instant payouts already exists. Nobody was using it for GPU operators.&lt;/p&gt;

&lt;p&gt;Until now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Spraay Direct actually does
&lt;/h2&gt;

&lt;p&gt;Spraay Direct is the first instant USDC payout system built specifically for GPU operators.&lt;/p&gt;

&lt;p&gt;You connect your GPU — whether you're running vLLM, Ollama, or ComfyUI — to the Spraay network. When an AI agent sends a job to your GPU, you get paid in USDC on Base the moment that job completes. Not in two weeks. Not in platform credits. Not in gift cards. In USDC, in your wallet, in about two seconds.&lt;/p&gt;

&lt;p&gt;There's no platform fee in the traditional sense. Vast.ai takes 15-25% of what renters pay. Spraay charges a flat $0.03 per job. That's it. The rest goes directly to your wallet.&lt;/p&gt;

&lt;p&gt;And if you're running a multi-GPU operation with a partner, or you want to automatically set aside a percentage for taxes or savings, Spraay's batch payment system lets you split every payout across multiple wallets in a single transaction. 70% to your operating wallet, 20% to savings, 10% to your partner — all settled atomically on-chain. Try doing that with a PayPal payout.&lt;/p&gt;

&lt;h2&gt;
  
  
  How this compares to what you're using now
&lt;/h2&gt;

&lt;p&gt;Let's be specific because vague claims don't help anyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vast.ai&lt;/strong&gt; pays hosts via PayPal or Wise every two weeks. There's a minimum threshold before you can withdraw. The platform takes 15-25% as commission. Payout currency is USD through traditional banking rails. No split payments. Your earnings sit in Vast's system until their next payout cycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RunPod&lt;/strong&gt; operates on platform credits. Their revenue sharing program for Hub publishers pays 3-7% of compute hours — in RunPod credits, not cash. If you're a Community Cloud host, payouts depend on the specific arrangement, but you're generally locked into the RunPod ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Salad&lt;/strong&gt; pays in Salad Balance. You can redeem it for gift cards, games, or crypto. The conversion rates vary. It's designed for gamers monetizing idle hardware, not serious operators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spraay Direct&lt;/strong&gt; pays in USDC on Base within seconds of job completion. No minimum payout. No platform commission beyond the per-job fee. No waiting period. No PayPal. No gift cards. Every payment is on-chain, meaning you have a permanent, auditable record of every dollar earned on Basescan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;If you're running one or more GPUs with at least 16GB of VRAM and you're already doing AI inference work — or thinking about starting — this is for you.&lt;/p&gt;

&lt;p&gt;If you're a Vast.ai host who's tired of the two-week payout cycle and the PayPal fees eating your margins, this is for you.&lt;/p&gt;

&lt;p&gt;If you're a crypto-native builder who wants earnings in USDC rather than fiat, this is for you.&lt;/p&gt;

&lt;p&gt;If you're running a small GPU farm with a partner and you're manually splitting PayPal payments or Venmo-ing each other after every payout cycle, the automatic batch splits alone might be worth the switch.&lt;/p&gt;

&lt;p&gt;And if you're someone who's been mining crypto and looking at the AI compute market as the next opportunity — this is how you get started without handing 20% of your earnings to a middleman.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part where I'm honest about what this isn't
&lt;/h2&gt;

&lt;p&gt;Spraay Direct isn't a marketplace. We're not replacing Vast.ai's marketplace or RunPod's infrastructure. We're a payment and settlement layer.&lt;/p&gt;

&lt;p&gt;Right now, when you connect to Spraay Direct, your GPU serves inference jobs from AI agents that discover Spraay through the x402 protocol and MCP ecosystem. This is a growing but still early network. You won't see the same volume of jobs you'd get on Vast.ai's marketplace with 120,000 developers on day one.&lt;/p&gt;

&lt;p&gt;What you will get is instant payouts, lower fees, USDC settlement, and batch splits from day one. And as the x402 agent economy grows — which it is, rapidly — the job volume follows.&lt;/p&gt;

&lt;p&gt;Some operators are running Spraay Direct alongside their Vast.ai listing. GPU idle on Spraay? Vast.ai picks it up. Job comes through Spraay? Instant USDC. Best of both worlds while the network scales.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens next
&lt;/h2&gt;

&lt;p&gt;You can check out the Spraay Direct proxy on GitHub. The setup takes about 30 minutes. You run a lightweight proxy on your machine that connects your inference engine to the Spraay gateway. When jobs come in, your GPU does the work. USDC lands in your wallet. That's the whole pitch.&lt;/p&gt;

&lt;p&gt;The GPU compute market is massive and growing. The operators powering it deserve to get paid like it's 2026, not 2015. That's what we're building.&lt;/p&gt;

&lt;p&gt;If you're running a rig and you're tired of waiting for your money, come try it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Spraay Direct is open source and built on Base. USDC settlement via the x402 protocol.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GitHub: &lt;a href="https://github.com/plagtech/spraay-direct-proxy" rel="noopener noreferrer"&gt;github.com/plagtech/spraay-direct-proxy&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Gateway: &lt;a href="https://gateway.spraay.app" rel="noopener noreferrer"&gt;gateway.spraay.app&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Twitter: &lt;a href="https://twitter.com/Spraay_app" rel="noopener noreferrer"&gt;@Spraay_app&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gpu</category>
      <category>ai</category>
      <category>usdc</category>
      <category>web3</category>
    </item>
    <item>
      <title>We Made Our x402 Payment Gateway Loop-Native — Here's How (and Why Your Agent Needs It)</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Wed, 24 Jun 2026 01:24:02 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/we-made-our-x402-payment-gateway-loop-native-heres-how-and-why-your-agent-needs-it-4iog</link>
      <guid>https://dev.to/mr_hamlin/we-made-our-x402-payment-gateway-loop-native-heres-how-and-why-your-agent-needs-it-4iog</guid>
      <description>&lt;p&gt;Two weeks ago, Boris Cherny — head of Claude Code at Anthropic — said something on stage that changed how I think about building infrastructure:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I don't prompt Claude anymore. I have loops running. They're the ones prompting Claude."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then Peter Steinberger dropped a post that put a name on it: &lt;strong&gt;loop engineering&lt;/strong&gt;. The idea is simple but the implications are massive. You stop writing prompts. You start designing the systems that prompt agents for you. The agent enters a cycle — reason, act, observe, repeat — and it doesn't stop until the goal is met or the budget is hit.&lt;/p&gt;

&lt;p&gt;That immediately raised a question for me: if agents are going to run autonomously in loops, what happens when the "act" step involves money?&lt;/p&gt;

&lt;p&gt;I run Spraay — an x402 payment gateway with 170+ endpoints across 16 chains. Agents already call our batch payment, escrow, and payroll endpoints through an MCP server. But every one of those calls was fire-and-forget. The agent sends a request, gets a response, and has no way to know when the payment actually settles unless it polls. Polling burns tokens. Burned tokens cost money. And in a loop, that cost compounds on every cycle.&lt;/p&gt;

&lt;p&gt;So we made the gateway loop-native. Here's what that means and how we built it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem: Loops Need Callbacks, Not Polling
&lt;/h2&gt;

&lt;p&gt;A loop-engineered agent doing batch payroll looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Observe: "10 employees need to be paid"
2. Reason: "I should batch these through Spraay"
3. Act: POST /api/v1/payroll/execute
4. Observe: ??? (How does the agent know it settled?)
5. Reason: ??? (Should I retry? Move on? Something failed?)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without callbacks, step 4 becomes a polling loop inside the main loop. The agent hammers &lt;code&gt;GET /status&lt;/code&gt; every few seconds, burning inference tokens while it waits. That's wasteful for one payment. For an agent running continuous operations — processing invoices, releasing escrow milestones, executing weekly payroll — it's unsustainable.&lt;/p&gt;

&lt;p&gt;The fix: let agents pass a &lt;code&gt;callback_url&lt;/code&gt; on any request. When the operation resolves, the gateway POSTs a signed payload to that URL. The agent's loop receives the event, processes it, and decides its next action. No polling. No wasted tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Implementation: Three Layers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Layer 1: Webhook Infrastructure
&lt;/h3&gt;

&lt;p&gt;The core system is a Supabase-backed event queue with a background dispatch worker. When an agent includes &lt;code&gt;callback_url&lt;/code&gt; in a request body, the gateway:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generates a per-event HMAC signing secret&lt;/li&gt;
&lt;li&gt;Queues the webhook event in a &lt;code&gt;webhook_events&lt;/code&gt; table&lt;/li&gt;
&lt;li&gt;Returns the normal response plus a &lt;code&gt;webhook&lt;/code&gt; object containing the &lt;code&gt;webhook_id&lt;/code&gt; and &lt;code&gt;webhook_secret&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A background worker polls for pending events and delivers them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what an agent sees when it includes &lt;code&gt;callback_url&lt;/code&gt;:&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="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/api/v&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;/batch/execute&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;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USDC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recipients"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xAlice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1000.00"&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;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xBob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2500.00"&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;span class="nl"&gt;"sender"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xEmployer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"callback_url"&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://agent.example.com/hooks/spraay"&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;Response:&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;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"contract"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"batch"&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;"recipientCount"&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;"totalAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3500.00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fee"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.50"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"totalWithFee"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3510.50"&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;"transaction"&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="err"&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;"webhook"&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;"webhook_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"afe9c56e-8074-4f5e-ae22-2eabd8cdcec0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webhook_secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"whsec_b8559497b5cf43..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"subscribed_events"&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="s2"&gt;"batch.created"&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="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;When the batch settles, the gateway POSTs to the agent's URL with HMAC-SHA256 signed headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST https://agent.example.com/hooks/spraay
X-Spraay-Signature: sha256=abc123...
X-Spraay-Event: batch.settled
X-Spraay-Delivery-Id: afe9c56e-...
X-Spraay-Timestamp: 2026-06-23T12:00:00.000Z
User-Agent: Spraay-Webhooks/1.0

{
  "id": "afe9c56e-...",
  "event_type": "batch.settled",
  "timestamp": "2026-06-23T12:00:00.000Z",
  "attempt": 1,
  "data": {
    "recipient_count": 2,
    "token": "USDC",
    "total_amount": "3500.00",
    "total_with_fee": "3510.50"
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent verifies the signature with the &lt;code&gt;webhook_secret&lt;/code&gt; from the original response, processes the event, and moves to the next step in its loop. If delivery fails, the worker retries with exponential backoff — 30s, 60s, 120s — up to 3 attempts before marking the event as exhausted.&lt;/p&gt;

&lt;p&gt;The key design decision: &lt;strong&gt;the callback system is entirely optional&lt;/strong&gt;. Agents that don't pass &lt;code&gt;callback_url&lt;/code&gt; see zero changes in the response. Every existing integration keeps working exactly as before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Safety Guards
&lt;/h3&gt;

&lt;p&gt;This is the part that kept me up the night before shipping. If agents are running autonomous payment loops, what happens when a loop has a bug?&lt;/p&gt;

&lt;p&gt;Picture this: an agent receives a &lt;code&gt;batch.settled&lt;/code&gt; callback, and its loop logic says "great, now pay the next batch." It fires another payment. Gets another callback. Fires again. The loop has no exit condition, and the wallet drains in minutes.&lt;/p&gt;

&lt;p&gt;That's not a Spraay bug — it's an agent design bug. But users will blame the gateway. So we built three safety layers that protect wallets regardless of how the agent is designed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-key rate limiting on payment endpoints.&lt;/strong&gt; Every API key gets a budget of 10 payment-moving calls per minute. A legitimate batch operation (even 200 recipients) is a single API call. You'd need to fire 10 completely separate operations within 60 seconds to hit the limit. A runaway loop hits it in seconds. Responses include &lt;code&gt;X-RateLimit-Remaining&lt;/code&gt; headers so well-built agents can self-regulate.&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;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rate_limit_exceeded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Too many requests to /api/v1/batch/execute. Limit: 10 per 60s."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"If this is a loop-engineered agent, ensure your loop has proper termination conditions."&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;&lt;strong&gt;Duplicate payment detection.&lt;/strong&gt; If the same API key sends an identical payload (same recipients, amounts, token) within 60 seconds, the gateway returns a 409 instead of processing a duplicate payment. The response tells the agent how to override this if the duplicate is intentional (add a unique &lt;code&gt;idempotency_key&lt;/code&gt; field).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Webhook delivery cooldown.&lt;/strong&gt; No callback URL receives deliveries faster than every 5 seconds. This caps the maximum possible loop cycle speed. A legitimate agent processing results never needs sub-5-second callbacks. A runaway loop would.&lt;/p&gt;

&lt;p&gt;All three guards are per-API-key, so a large company with heavy legitimate usage gets their own rate budget. And all three are additive — they sit in the middleware chain without touching any existing endpoint logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: Wiring Endpoints
&lt;/h3&gt;

&lt;p&gt;Making an endpoint callback-aware takes about 8 lines of code. The webhook middleware attaches a &lt;code&gt;webhookCallback&lt;/code&gt; helper to every request that includes &lt;code&gt;callback_url&lt;/code&gt;. Endpoint handlers just check if it's there:&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="c1"&gt;// Existing handler code builds the response...&lt;/span&gt;

&lt;span class="c1"&gt;// Add webhook callback (only fires if agent passed callback_url)&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhookCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhook&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;webhookCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;batch.created&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;recipient_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;recipients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;total_amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;totalAmount&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We wired up 6 handlers across 3 endpoint families:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batch payments&lt;/strong&gt; — &lt;code&gt;batch.created&lt;/code&gt; on execute&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escrow&lt;/strong&gt; — &lt;code&gt;escrow.created&lt;/code&gt;, &lt;code&gt;escrow.funded&lt;/code&gt;, &lt;code&gt;escrow.released&lt;/code&gt;, &lt;code&gt;escrow.disputed&lt;/code&gt; across all state transitions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payroll&lt;/strong&gt; — &lt;code&gt;batch.created&lt;/code&gt; with &lt;code&gt;type: 'payroll'&lt;/code&gt; in the payload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Escrow is the most interesting case because it's inherently a state machine. An agent loop managing a freelance contract can now receive callbacks at every stage: escrow created → funded → work completed → released. Each callback gives the agent the information it needs to decide its next action without polling.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Enables
&lt;/h2&gt;

&lt;p&gt;With loop-native callbacks, an agent can now do things like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated payroll processing&lt;/strong&gt;: Observe invoice queue → batch employees → receive settlement callback → update books → repeat next pay period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Escrow milestone management&lt;/strong&gt;: Create escrow → fund on approval → receive work → release on delivery → handle disputes. All event-driven, no polling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-chain treasury operations&lt;/strong&gt;: Monitor balances across chains → batch rebalancing payments → confirm settlements → repeat.&lt;/p&gt;

&lt;p&gt;The x402 per-call pricing model actually works in our favor here. Loop-engineered agents make more calls per task (that's the nature of the cycle), which means more microtransactions flowing through the gateway. Making the integration smoother via callbacks means agents are more likely to use Spraay as their payment layer — which means more volume, not less.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Didn't Build (and Why)
&lt;/h2&gt;

&lt;p&gt;We deliberately chose not to build a loop orchestration framework. The agent ecosystem already has plenty of those — Claude Code, OpenClaw, LangGraph, CrewAI. What it doesn't have is payment infrastructure designed for autonomous agent loops.&lt;/p&gt;

&lt;p&gt;Spraay's position is the settlement layer. We don't tell agents what to do or how to loop. We make sure that when the "act" step in any loop involves moving money, the infrastructure is fast, secure, signed, and event-driven.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Spraay's loop-native webhooks are live today across batch, escrow, and payroll endpoints. Add &lt;code&gt;callback_url&lt;/code&gt; to any request body and you'll get signed callbacks when the operation resolves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gateway&lt;/strong&gt;: gateway.spraay.app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs&lt;/strong&gt;: docs.spraay.app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Server&lt;/strong&gt;: smithery.ai/servers/Plagtech/Spraay-x402-mcp&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BPA Spec&lt;/strong&gt;: docs.spraay.app/bpa/1.0/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building loop-engineered agents that handle money, I'd love to hear how you're thinking about the payment layer. What safety guarantees matter most to you? What event types would you want callbacks for?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Spraay is an x402 payment gateway — 170+ endpoints, 16 chains, batch payments as the primary differentiator. Built by a solo founder in public.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow the build: &lt;a href="https://twitter.com/lostpoet" rel="noopener noreferrer"&gt;@lostpoet&lt;/a&gt; on X, &lt;a href="https://warpcast.com/plag" rel="noopener noreferrer"&gt;@plag&lt;/a&gt; on Farcaster.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>web3</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Ship Paid APIs in a Weekend. Here's the Exact Stack I Use Every Time.</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Sat, 20 Jun 2026 00:10:11 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/i-ship-paid-apis-in-a-weekend-heres-the-exact-stack-i-use-every-time-5166</link>
      <guid>https://dev.to/mr_hamlin/i-ship-paid-apis-in-a-weekend-heres-the-exact-stack-i-use-every-time-5166</guid>
      <description>&lt;p&gt;I've shipped three paid API products in the past six months. Each one took a weekend to reach a working, billable state — users signing up, generating API keys, making authenticated requests, and paying me through Stripe.&lt;/p&gt;

&lt;p&gt;Not because I'm fast. Because the infrastructure is the same every time.&lt;/p&gt;

&lt;p&gt;Auth is the same. API key management is the same. Stripe billing is the same. Rate limiting, usage tracking, the dashboard — all the same. The only thing that changes is the business logic behind the endpoints.&lt;/p&gt;

&lt;p&gt;After the third time wiring Stripe webhooks to Supabase to API key validation, I wrote down the pattern. Here it is.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Node.js + Express&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth &amp;amp; Database&lt;/td&gt;
&lt;td&gt;Supabase&lt;/td&gt;
&lt;td&gt;Free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Billing&lt;/td&gt;
&lt;td&gt;Stripe&lt;/td&gt;
&lt;td&gt;2.9% + 30¢ per txn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate Limiting&lt;/td&gt;
&lt;td&gt;Redis (Upstash)&lt;/td&gt;
&lt;td&gt;Free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;React + Vite&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;$5/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total cost at launch: &lt;strong&gt;$5/month&lt;/strong&gt;. Everything else is free until you have paying customers.&lt;/p&gt;

&lt;p&gt;Why these specific tools? I've tried the alternatives. Supabase beats Firebase for API businesses because relational data (users → keys → usage logs) is natural in Postgres and painful in document stores. Express beats Next.js for API servers because you don't need SSR, file-based routing, or React Server Components — you need a fast request-response pipeline. Upstash Redis beats Postgres for rate limiting because checking a counter needs to be sub-millisecond, not 5-20ms.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Middleware Chain
&lt;/h2&gt;

&lt;p&gt;This is the architecture pattern that makes everything work. Every API request passes through a chain of middleware before it hits your business logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request arrives
  → validateApiKey    (reject if invalid)
  → rateLimit         (reject if over per-minute limit)
  → trackUsage        (reject if monthly quota exceeded)
  → YOUR LOGIC        (do the actual work)
Response sent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the time your route handler runs, you &lt;strong&gt;know&lt;/strong&gt; three things: the key is valid, the request is within rate limits, and the monthly quota hasn't been exceeded. Your business logic never checks any of this. The middleware guarantees it.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Keys: The Pattern Everyone Skips
&lt;/h2&gt;

&lt;p&gt;Most tutorials use Bearer tokens for API auth and move on. That doesn't work for a business. Your customers need to generate keys from a dashboard, name them, revoke them, and see when they were last used.&lt;/p&gt;

&lt;p&gt;The security model matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never store raw keys.&lt;/strong&gt; Store a SHA-256 hash. When a request comes in, hash the provided key and look up the hash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show the key once.&lt;/strong&gt; After generation, you only show a masked preview like &lt;code&gt;sk_live_abc...xyz&lt;/code&gt;. Lost key? Generate a new one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a recognizable prefix.&lt;/strong&gt; &lt;code&gt;sk_live_&lt;/code&gt; tells GitHub's secret scanning that this is a credential. A leaked prefixed key gets caught before it causes damage.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&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;PREFIX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sk_live_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateApiKey&lt;/span&gt;&lt;span class="p"&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;random&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&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;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PREFIX&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;random&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;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256&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="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;256 bits of entropy. The same pattern Stripe and OpenAI use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate Limiting: The Sliding Window
&lt;/h2&gt;

&lt;p&gt;A fixed window rate limiter resets at the top of every minute, which means a customer can send their full quota at 0:59 and again at 1:01 — effectively doubling their rate. The sliding window counts the actual last 60 seconds from &lt;em&gt;right now&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Four Redis commands, one pipeline, one network round-trip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKeyId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxPerMinute&lt;/span&gt;&lt;span class="p"&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;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`ratelimit:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;apiKeyId&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;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;windowStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;60000&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;pipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zremrangebyscore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;windowStart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// remove old&lt;/span&gt;
  &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zadd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;now&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="nx"&gt;now&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="c1"&gt;// add current&lt;/span&gt;
  &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zcard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                            &lt;span class="c1"&gt;// count window&lt;/span&gt;
  &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                       &lt;span class="c1"&gt;// auto-cleanup&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&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;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;maxPerMinute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxPerMinute&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;count&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then set the standard headers on every response — not just 429s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;X-RateLimit-Limit&lt;/code&gt; — max per minute for this tier&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-RateLimit-Remaining&lt;/code&gt; — requests left in window&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-RateLimit-Reset&lt;/code&gt; — when the window resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your API consumers use these headers to implement client-side backoff. The good ones slow down before they hit the wall.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stripe Billing: The Four Webhooks That Matter
&lt;/h2&gt;

&lt;p&gt;Stripe sends dozens of event types. You need four:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;checkout.session.completed&lt;/code&gt;&lt;/strong&gt; — customer paid. Create the subscription record, upgrade their tier, update all their API keys to the new limits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;customer.subscription.updated&lt;/code&gt;&lt;/strong&gt; — plan change or renewal. Look up the new price, determine the tier, update the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;customer.subscription.deleted&lt;/code&gt;&lt;/strong&gt; — cancellation. Downgrade to free tier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;invoice.payment_failed&lt;/code&gt;&lt;/strong&gt; — card declined. Flag the account, notify the user.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The critical gotcha: Stripe signs webhooks against the &lt;strong&gt;raw request body&lt;/strong&gt;. If Express parses the body into JSON first, the signature verification fails. Mount your webhook route with &lt;code&gt;express.raw()&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; &lt;code&gt;express.json()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This line MUST come before express.json()&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/billing/webhook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I lost two hours to this bug on my first API. You don't have to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Weekend Timeline
&lt;/h2&gt;

&lt;p&gt;Here's how I actually spend the weekend:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Friday evening:&lt;/strong&gt; Set up the project, install deps, create Supabase project, get a health check endpoint running. 1 hour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Saturday morning:&lt;/strong&gt; Auth routes, API key system, validation middleware, first authenticated API call. 3 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Saturday afternoon:&lt;/strong&gt; Rate limiting in Redis, Stripe billing with all four webhook handlers. 3 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sunday morning:&lt;/strong&gt; Usage tracking, React dashboard with five pages (login, overview, keys, usage, billing). 2 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sunday afternoon:&lt;/strong&gt; Deploy to Railway, custom domain, write docs, post about it. 2 hours.&lt;/p&gt;

&lt;p&gt;Nine hours of building. A live, paid API on the internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Price higher than you think.&lt;/strong&gt; At $9/month you need 111 customers to make $1,000. At $29/month you need 35. At $79/month you need 13. Fewer customers = less support = more time building.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The free tier is a conversion mechanism.&lt;/strong&gt; A developer integrates your API, their project succeeds, they hit the limit, they upgrade. By then they've written code against your endpoints. Switching costs are real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good docs beat good marketing.&lt;/strong&gt; A developer who can integrate in five minutes becomes a customer. A developer who has to email you a question probably doesn't.&lt;/p&gt;




&lt;p&gt;I wrote the full process — all twelve chapters, every code file, the complete middleware chain, the dashboard, deployment, and launch strategy — into a book:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://brenthamlin.gumroad.com/l/ship-api-weekend" rel="noopener noreferrer"&gt;The Solo Developer's Guide to Shipping a Paid API in a Weekend&lt;/a&gt;&lt;/strong&gt; — 82 pages, $29, every line of code is production code.&lt;/p&gt;

&lt;p&gt;If you've been sitting on an API idea waiting for the right time to build the billing infrastructure, the right time is this weekend.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Brent Hamlin. I build paid APIs and write about the stack behind them. Find me at &lt;a href="https://dev.to/mr_hamlin"&gt;dev.to/mr_hamlin&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Added x402 Payments to Base's Agent Skills — Here's How</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Tue, 09 Jun 2026 21:09:24 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/i-added-x402-payments-to-bases-agent-skills-heres-how-17b8</link>
      <guid>https://dev.to/mr_hamlin/i-added-x402-payments-to-bases-agent-skills-heres-how-17b8</guid>
      <description>&lt;p&gt;If you build agents on Base, two things landed recently that are worth connecting.&lt;/p&gt;

&lt;p&gt;First: &lt;strong&gt;Base shipped its own Agent Skills.&lt;/strong&gt; There's now a &lt;code&gt;base/skills&lt;/code&gt; repo with consolidated skills that teach an AI agent to connect to Base, deploy contracts, authenticate wallets, and run nodes — installed with one command via Vercel's &lt;code&gt;npx skills&lt;/code&gt; CLI.&lt;/p&gt;

&lt;p&gt;Second: that CLI is part of a fast-growing, cross-agent ecosystem most crypto devs haven't clocked yet. So this post does two things — explains how &lt;code&gt;npx skills&lt;/code&gt; and &lt;code&gt;skills.sh&lt;/code&gt; actually work, and shows where the payment layer in Base's skills stops and how to extend it with &lt;strong&gt;x402 pay-per-call&lt;/strong&gt; and &lt;strong&gt;batch disbursement&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;npx skills&lt;/code&gt; actually is
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx skills&lt;/code&gt; is an open CLI from Vercel Labs for installing "skills" — modular &lt;code&gt;SKILL.md&lt;/code&gt; files that teach an agent a specific capability without stuffing everything into its context window. A few things make it different from what crypto devs usually expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub is the registry.&lt;/strong&gt; There's no central package server. Any public GitHub repo with a &lt;code&gt;SKILL.md&lt;/code&gt; at its root is a valid, installable skill. Install with &lt;code&gt;npx skills add owner/repo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's cross-agent.&lt;/strong&gt; The same skill installs into Claude Code, Cursor, Codex, GitHub Copilot, Goose, Windsurf, Gemini, and dozens more. You write once; it works across the agent you (or your users) actually run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;skills.sh&lt;/code&gt; is the directory + leaderboard.&lt;/strong&gt; It ranks skills by real install counts pulled from telemetry, with all-time, trending, and hot lists. There's no editorial submission step — you publish by putting a skill in a repo, and installs surface it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The format underneath — &lt;code&gt;SKILL.md&lt;/code&gt; — is an open spec, which is why Base, Vercel, Anthropic, and a long tail of independent devs all use the same files.&lt;/p&gt;

&lt;p&gt;Here's Base's install, for reference:&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;# Base's official agent skills&lt;/span&gt;
npx skills add base/skills &lt;span class="nt"&gt;--skill&lt;/span&gt; build-on-base
npx skills add base/skills &lt;span class="nt"&gt;--skill&lt;/span&gt; base-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;build-on-base&lt;/code&gt; is a consolidated Base dev playbook; &lt;code&gt;base-mcp&lt;/code&gt; wires up a Base MCP server that gives an agent a wallet — sending, swapping, signing, batched calls, balances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Base's skills stop
&lt;/h2&gt;

&lt;p&gt;This is the interesting gap. Base's skills give an agent a wallet and the ability to &lt;em&gt;transact&lt;/em&gt;: send a payment, swap a token, sign, batch several calls into one transaction. That's the on-chain action layer, and it's well covered.&lt;/p&gt;

&lt;p&gt;What that layer doesn't do is two distinct things the agent economy actually runs on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pay-per-call consumption.&lt;/strong&gt; When an agent needs to &lt;em&gt;buy&lt;/em&gt; data or compute — a price feed, a web search, an LLM completion — it needs to pay for that call, per call, without an API key or a billing account. That's &lt;a href="https://x402.org" rel="noopener noreferrer"&gt;x402&lt;/a&gt;: the HTTP 402 "Payment Required" status code turned into a machine-readable micropayment handshake. The agent hits an endpoint, gets a 402 with a price, signs a USDC authorization, retries, and gets the data. No signup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Batch disbursement.&lt;/strong&gt; "Batched calls" (bundling operations into one tx) is not the same as paying &lt;em&gt;many different recipients&lt;/em&gt; in one transaction — payroll, airdrops, contributor payouts, refunds. That's a disbursement primitive, and it's what the &lt;a href="https://docs.spraay.app/bpa/1.0/" rel="noopener noreferrer"&gt;Batch Payments for Agents (BPA 1.0)&lt;/a&gt; spec standardizes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both settle in USDC on Base. Neither is something a wallet-only skill handles. So they're a clean, complementary layer to drop on top of what Base ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the payment layer
&lt;/h2&gt;

&lt;p&gt;I published three skills that fill exactly that gap, each its own repo so you install only what you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/plagtech/defi-intelligence-x402" rel="noopener noreferrer"&gt;defi-intelligence-x402&lt;/a&gt;&lt;/strong&gt; — pay-per-call data + market intelligence on Base (prices, oracles, swap quotes, wallet analytics, ENS/Basename)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/plagtech/ai-compute-x402" rel="noopener noreferrer"&gt;ai-compute-x402&lt;/a&gt;&lt;/strong&gt; — pay-per-call AI inference (200+ LLMs, Bittensor, image gen, embeddings, GPU)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/plagtech/agent-payments-x402" rel="noopener noreferrer"&gt;agent-payments-x402&lt;/a&gt;&lt;/strong&gt; — batch payments, payroll, invoicing, escrow (BPA 1.0)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pay-per-call data + market intelligence on Base&lt;/span&gt;
npx skills add plagtech/defi-intelligence-x402

&lt;span class="c"&gt;# Pay-per-call AI inference (200+ LLMs, Bittensor, GPU)&lt;/span&gt;
npx skills add plagtech/ai-compute-x402

&lt;span class="c"&gt;# Batch payments, payroll, invoicing, escrow (BPA 1.0)&lt;/span&gt;
npx skills add plagtech/agent-payments-x402
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three call the &lt;a href="https://gateway.spraay.app" rel="noopener noreferrer"&gt;Spraay x402 Gateway&lt;/a&gt;, which is x402-native end to end — no API keys, no accounts. You fund a wallet with USDC on Base, set one env var, and the x402 client signs and retries payments automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;x402-client
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EVM_PRIVATE_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x...   &lt;span class="c"&gt;# wallet holding USDC on Base&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Worked example: an agent that prices before it acts
&lt;/h3&gt;

&lt;p&gt;A read call costs a fraction of a cent and needs no key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;createClient&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;x402-client&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="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&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://gateway.spraay.app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;privateKey&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;EVM_PRIVATE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Live oracle prices — pays ~$0.008 USDC, automatically&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prices&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/oracle/prices&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// { ETH: 2847.50, BTC: ... }&lt;/span&gt;

&lt;span class="c1"&gt;// Profile a wallet before interacting with it&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profile&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/analytics/wallet?address=0xabc...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Worked example: pay 50 people in one transaction
&lt;/h3&gt;

&lt;p&gt;This is the disbursement primitive a wallet-only skill can't express:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Batch-send USDC to many recipients in a single tx&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/batch/execute&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;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USDC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;recipients&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="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xabc...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10.00&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;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xdef...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;25.50&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// ...up to your full roster&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estimate first with &lt;code&gt;/api/v1/batch/estimate&lt;/code&gt; (≈$0.001) if you want a gas/fee preview before sending.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for agents on Base
&lt;/h2&gt;

&lt;p&gt;The mental model is two layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base's skills&lt;/strong&gt; = the agent has a wallet and can transact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;x402 skills&lt;/strong&gt; = the agent can pay for each call it makes, and pay many parties at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put them together and you have an agent that can read on-chain state, buy the data and compute it needs per call, and disburse funds — all in USDC on Base, all without a single API key or account. That's most of what an autonomous economic agent actually needs to do a job end to end.&lt;/p&gt;

&lt;p&gt;If you're building on Base, the install lines above are the fastest way to try the payment layer. Skills are just &lt;code&gt;SKILL.md&lt;/code&gt; files — open them before you install (it takes 30 seconds) and you'll see exactly which endpoints get called and what they cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills:&lt;/strong&gt; &lt;a href="https://github.com/plagtech/agent-payments-x402" rel="noopener noreferrer"&gt;agent-payments-x402&lt;/a&gt; · &lt;a href="https://github.com/plagtech/defi-intelligence-x402" rel="noopener noreferrer"&gt;defi-intelligence-x402&lt;/a&gt; · &lt;a href="https://github.com/plagtech/ai-compute-x402" rel="noopener noreferrer"&gt;ai-compute-x402&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://gateway.spraay.app" rel="noopener noreferrer"&gt;Spraay Gateway&lt;/a&gt; · &lt;a href="https://docs.spraay.app" rel="noopener noreferrer"&gt;Docs / full endpoint catalog&lt;/a&gt; · &lt;a href="https://live.spraay.app" rel="noopener noreferrer"&gt;Live gateway traffic&lt;/a&gt; · &lt;a href="https://docs.spraay.app/bpa/1.0/" rel="noopener noreferrer"&gt;BPA 1.0 spec&lt;/a&gt;&lt;/p&gt;

</description>
      <category>base</category>
      <category>ai</category>
      <category>web3</category>
      <category>x402</category>
    </item>
    <item>
      <title>📚 Why Every AI Agent Needs a Research Library</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Fri, 05 Jun 2026 02:39:03 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/why-every-ai-agent-needs-a-research-library-434p</link>
      <guid>https://dev.to/mr_hamlin/why-every-ai-agent-needs-a-research-library-434p</guid>
      <description>&lt;p&gt;Your AI agent just hit a wall.&lt;/p&gt;

&lt;p&gt;It needs to look up a chemical compound for a drug interaction check. Or find the latest papers on transformer architectures. Or pull US Census demographics for a market analysis. What does it do?&lt;/p&gt;

&lt;p&gt;It hallucinates.&lt;/p&gt;

&lt;p&gt;Training data is months or years old. Web searches return noisy HTML, not structured data. And the agent has no way to verify what it "knows" against the actual source of record. For any task that requires factual accuracy — scientific, medical, legal, demographic — the agent is guessing.&lt;/p&gt;

&lt;p&gt;This is a solvable problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Gap in Agent Infrastructure
&lt;/h2&gt;

&lt;p&gt;Look at what the agent ecosystem has built so far: payment rails, wallet provisioning, DeFi integrations, compute access, communication protocols. These are all critical. But there's a missing layer that nobody's talking about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge access.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a human researcher needs to verify a claim, they check PubMed. When they need a chemical structure, they check PubChem. When they need citation data, they check Crossref. When they need demographic trends, they check the Census Bureau.&lt;/p&gt;

&lt;p&gt;AI agents have no equivalent. They're making consequential decisions — medical summaries, investment research, compliance checks, scientific literature reviews — without access to the same authoritative sources that human experts rely on.&lt;/p&gt;

&lt;p&gt;That's the gap we just filled.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Built
&lt;/h2&gt;

&lt;p&gt;We added a full Research &amp;amp; Reference category to the &lt;a href="https://gateway.spraay.app" rel="noopener noreferrer"&gt;Spraay x402 gateway&lt;/a&gt; — 23 endpoints spanning 7 research domains, all accessible via micropayment (USDC on Base or Solana).&lt;/p&gt;

&lt;p&gt;Here's what an agent can now look up on demand:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language &amp;amp; Definitions&lt;/strong&gt; — word definitions, synonyms, antonyms, phonetics, and pronunciation audio across 9 languages. The foundation for any agent that processes or generates natural language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Academic Papers&lt;/strong&gt; — search across 250 million scholarly works spanning every discipline: physics, biology, computer science, economics, social sciences, humanities, engineering, medicine, law, education. Filter by field, year, author, or ORCID. Pull citation graphs. Track what's trending.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preprints&lt;/strong&gt; — the bleeding edge of science. 2.4 million preprints across physics, mathematics, computer science, quantitative biology, quantitative finance, statistics, and economics. These are the papers that haven't been published yet — the ones that move markets and shift research directions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scholarly Metadata&lt;/strong&gt; — 150 million published works with full metadata: journal articles, books, conference papers, and datasets. Citation counts, reference lists, journal info by ISSN. When an agent needs to verify a source exists and check its impact, this is the endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chemistry&lt;/strong&gt; — 110 million chemical compounds with molecular structures, physical properties, safety and toxicity data, and biological assay results. Structural similarity search for finding related compounds. This is the same database that pharmaceutical researchers and chemists use daily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Biomedical Literature&lt;/strong&gt; — 36 million papers covering medicine, pharmacology, genomics, neuroscience, public health, and more. Related article discovery for any given paper. When your agent is summarizing medical research or checking drug interactions, this is the authoritative source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demographics &amp;amp; Government Data&lt;/strong&gt; — US Census data by state, county, and zip code: population, income, housing, education, employment. Plus the entire federal open data catalog — transportation, climate, health, agriculture, energy, and crime statistics.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Endpoint Map
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;# Dictionary &amp;amp; Language
GET /api/v1/research/dictionary/define        $0.001
GET /api/v1/research/dictionary/synonyms      $0.001
GET /api/v1/research/dictionary/phonetics     $0.001

# Academic Papers (250M+ works)
GET /api/v1/research/papers/search            $0.002
GET /api/v1/research/papers/by-doi            $0.001
GET /api/v1/research/papers/by-author         $0.002
GET /api/v1/research/papers/citations         $0.002
GET /api/v1/research/papers/trending          $0.002

# Preprints (2.4M+ papers)
GET /api/v1/research/preprints/search         $0.002
GET /api/v1/research/preprints/by-id          $0.001
GET /api/v1/research/preprints/recent         $0.002

# Scholarly Metadata (150M+ works)
GET /api/v1/research/scholarly/search         $0.002
GET /api/v1/research/scholarly/by-doi         $0.001
GET /api/v1/research/scholarly/citations-count $0.001
GET /api/v1/research/scholarly/journal-info   $0.001

# Chemistry (110M+ compounds)
GET /api/v1/research/chemistry/compound       $0.002
GET /api/v1/research/chemistry/similarity     $0.002
GET /api/v1/research/chemistry/bioactivity    $0.002

# Biomedical (36M+ papers)
GET /api/v1/research/biomedical/search        $0.002
GET /api/v1/research/biomedical/by-pmid       $0.001
GET /api/v1/research/biomedical/related       $0.002

# Demographics &amp;amp; Government Data
GET /api/v1/research/demographics/census      $0.001
GET /api/v1/research/demographics/datasets    $0.001
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every response returns a unified JSON envelope with the source, license info, attribution, and a consistent result structure — regardless of which domain the query hits. One integration, every domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Demand Is
&lt;/h2&gt;

&lt;p&gt;These aren't hypothetical use cases. This is what agents are already trying to do, badly, with web scraping and hallucination:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pharmaceutical &amp;amp; biotech agents&lt;/strong&gt; — compound lookup, drug interaction screening, literature review across 36M biomedical papers. An agent advising on drug safety needs PubChem and PubMed, not a Google search.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Academic writing assistants&lt;/strong&gt; — paper discovery, citation graph traversal, related work identification. Every grad student's AI assistant needs structured access to the scholarly record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Market research agents&lt;/strong&gt; — Census demographics for TAM sizing, government datasets for industry analysis, trend tracking across academic publications for emerging technology identification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact-checking and verification&lt;/strong&gt; — DOI lookup confirms a source actually exists. Citation counts indicate impact. Cross-referencing preprints against published papers catches retractions and updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scientific monitoring&lt;/strong&gt; — agents that watch arXiv daily for new preprints in specific categories, track citation velocity on key papers, and flag when a trending paper crosses a threshold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance and regulatory&lt;/strong&gt; — biomedical literature search for adverse event signals, chemical safety data for REACH/GHS compliance, demographic data for fair lending analysis.&lt;/p&gt;

&lt;p&gt;The pattern is the same in every case: the agent needs structured, authoritative, verifiable data — not a web search result. And it needs it on demand, per call, without managing API keys and parsing 7 different response formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Gateway, Every Domain
&lt;/h2&gt;

&lt;p&gt;The value proposition for agent builders is simple: integrate once with Spraay, and your agent gets access to the same research infrastructure that universities and pharmaceutical companies use. Pay per call. No subscriptions, no rate limit negotiations, no format wrangling.&lt;/p&gt;

&lt;p&gt;The research endpoints sit alongside 115 existing endpoints on the gateway covering payments, DeFi, oracle, compute, communication, and more — 138 total across 34 categories. If your agent needs to look something up &lt;em&gt;and&lt;/em&gt; take action on what it finds, the entire stack is already wired together.&lt;/p&gt;

&lt;p&gt;The gateway is live at &lt;code&gt;gateway.spraay.app&lt;/code&gt;. The MCP server on &lt;a href="https://smithery.ai/servers/Plagtech/Spraay-x402-mcp" rel="noopener noreferrer"&gt;Smithery&lt;/a&gt; has all the tools pre-wired for Claude, GPT, and any MCP-compatible agent framework.&lt;/p&gt;

&lt;p&gt;Docs: &lt;a href="https://docs.spraay.app" rel="noopener noreferrer"&gt;docs.spraay.app&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/plagtech/spraay-x402-gateway" rel="noopener noreferrer"&gt;plagtech/spraay-x402-gateway&lt;/a&gt;&lt;br&gt;
Twitter: &lt;a href="https://twitter.com/Spraay_app" rel="noopener noreferrer"&gt;@Spraay_app&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Agents that know things make better decisions than agents that guess. Give yours a library card.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Batch Payments for Agents (BPA) 1.0: an open standard for how AI agents pay many recipients at once</title>
      <dc:creator>Mr Hamlin</dc:creator>
      <pubDate>Tue, 02 Jun 2026 20:22:14 +0000</pubDate>
      <link>https://dev.to/mr_hamlin/batch-payments-for-agents-bpa-10-an-open-standard-for-how-ai-agents-pay-many-recipients-at-once-22e3</link>
      <guid>https://dev.to/mr_hamlin/batch-payments-for-agents-bpa-10-an-open-standard-for-how-ai-agents-pay-many-recipients-at-once-22e3</guid>
      <description>&lt;p&gt;Agents can now &lt;em&gt;act&lt;/em&gt;. They book, they buy, they call tools, they spend. But ask a simple question — &lt;em&gt;how does an autonomous agent pay 500 people in one go?&lt;/em&gt; — and there's no clean answer. There's a pile of one-off integrations and a lot of hand-waving.&lt;/p&gt;

&lt;p&gt;So we wrote the spec. &lt;strong&gt;Batch Payments for Agents (BPA) 1.0&lt;/strong&gt; is a framework-neutral, open standard for how an agent disburses funds to many recipients in a single, governed, verifiable batch. It's live and citable here:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://docs.spraay.app/bpa/1.0/" rel="noopener noreferrer"&gt;docs.spraay.app/bpa/1.0&lt;/a&gt;&lt;/strong&gt; · source: &lt;strong&gt;&lt;a href="https://github.com/plagtech/bpa-spec" rel="noopener noreferrer"&gt;github.com/plagtech/bpa-spec&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This post is the why and the what.&lt;/p&gt;

&lt;h2&gt;
  
  
  The payments agents actually need are the ones the old rails punish
&lt;/h2&gt;

&lt;p&gt;Card and bank networks are optimized for a human clicking checkout once. Agent payouts are the opposite shape, and they break the cost model in three specific ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Micro-amounts.&lt;/strong&gt; Paying a crowd of data labelers $0.50 a task dies on fixed fees.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine-initiated.&lt;/strong&gt; No human at checkout, no card-present flow, no chargeback dance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-to-many, global.&lt;/strong&gt; Pay 200 contributors at once, many cross-border or unbanked, and settle in seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stablecoins on fast chains solve the &lt;em&gt;rail&lt;/em&gt;. What's missing is the &lt;em&gt;contract&lt;/em&gt; — the agreed-upon shape of "an agent safely pays many recipients at once." Without it, every team rebuilds the same fragile logic: how do you make a batch idempotent? what happens when line 347 of 500 fails? how do you prove it settled? how do you stop a misbehaving agent from draining a treasury?&lt;/p&gt;

&lt;p&gt;BPA answers those questions once, so nobody has to answer them again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What BPA 1.0 actually defines
&lt;/h2&gt;

&lt;p&gt;The spec is deliberately boring in the way good infrastructure is boring. It nails down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A request format&lt;/strong&gt; — one &lt;code&gt;Disbursement Request&lt;/code&gt; object, with a JSON Schema you can validate against.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency&lt;/strong&gt; — replay-safe by construction, because batch disbursement is irreversible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partial-failure semantics&lt;/strong&gt; — atomic by default; if a rail can't be atomic, per-recipient results and a retry token scoped to &lt;em&gt;only&lt;/em&gt; the failed lines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Settlement confirmation&lt;/strong&gt; — verifiable on-chain, per-chain finality rules, no "trust me, it sent."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A governance model&lt;/strong&gt; — spend caps, recipient allowlists, approval gating, and tamper-evident audit, all evaluated &lt;em&gt;before&lt;/em&gt; settlement and failing closed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transparent fees, transport bindings (x402 / MPP), and an MCP tool shape.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the core object an agent constructs:&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;"bpa_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"idempotency_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payout-2026-06-02-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chain"&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;"USDC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recipients"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xAbc..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"worker-001"&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;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xDef..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"worker-002"&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;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;Amounts are integer base units (no float drift). Validate it against the published &lt;a href="https://docs.spraay.app/bpa/1.0/disbursement-request.schema.json" rel="noopener noreferrer"&gt;JSON Schema&lt;/a&gt; before you send.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three design choices worth calling out
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Non-custodial end to end.&lt;/strong&gt; The facilitator only &lt;em&gt;builds&lt;/em&gt; the transaction; the agent's own signature authorizes the spend. The gateway never holds funds. That single property collapses a whole class of security concerns — a forged request just produces an unsigned transaction nobody can submit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Governed before execution, not after.&lt;/strong&gt; BPA treats every disbursement as a high-risk action. The goal isn't to &lt;em&gt;ask&lt;/em&gt; an agent to behave — it's to make an out-of-policy payout structurally impossible. Caps, allowlists, and approvals are deterministic checks the request must pass before a single token moves. If policy can't be evaluated, the answer is "denied."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three chains, on purpose.&lt;/strong&gt; BPA 1.0 is normatively defined for &lt;strong&gt;Base, Ethereum, and Solana&lt;/strong&gt; — where agent payment activity actually concentrates, plus institutional reach. We run the reference contract on more chains, but a spec's credibility is its weakest claim. Everything in the normative body is mainnet and source-verified (the settlement contracts are verified, exact-match, on BaseScan and Etherscan). Breadth that isn't load-bearing is just surface area for doubt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Spraay is the reference implementation (full disclosure: it's ours, and writing the spec forced us to make it airtight). You can hit it two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP / x402:&lt;/strong&gt; &lt;code&gt;POST https://gateway.spraay.app/api/v1/batch/execute&lt;/code&gt; — returns an unsigned transaction for your agent to sign.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP:&lt;/strong&gt; the &lt;code&gt;spraay_batch_execute&lt;/code&gt; tool, published on Smithery as &lt;code&gt;@plagtech/spraay-x402-mcp&lt;/code&gt;, described by intent so your agent matches it at runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The on-chain protocol fee is 0.30%, with a 200-recipient cap per call (chunk larger batches under one idempotency key).&lt;/p&gt;

&lt;h2&gt;
  
  
  It's an open standard — build on it
&lt;/h2&gt;

&lt;p&gt;BPA is published under &lt;strong&gt;CC-BY-4.0&lt;/strong&gt;. Implementations are unrestricted and need no permission. There's a conformance checklist (§14) and a self-attestation format for any facilitator — not just ours — to claim conformance. If you're building agent infrastructure and you touch payouts, this is meant to be the reference you point your own tooling at.&lt;/p&gt;

&lt;p&gt;If the attestation model for task-gated payments (pay-on-approval) is something you have strong opinions about, that's the one piece explicitly scoped for 1.1 — open an issue.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spec:&lt;/strong&gt; &lt;a href="https://docs.spraay.app/bpa/1.0/" rel="noopener noreferrer"&gt;docs.spraay.app/bpa/1.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/plagtech/bpa-spec" rel="noopener noreferrer"&gt;github.com/plagtech/bpa-spec&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference gateway:&lt;/strong&gt; &lt;a href="https://gateway.spraay.app" rel="noopener noreferrer"&gt;gateway.spraay.app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents are going to move a lot of money in small pieces to a lot of people. Let's at least agree on how.&lt;/p&gt;

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