A service returned 402 and named an asset you may not hold. This is how you get it and pay — about five minutes, no signup.
Everything below happens on Robinhood Chain (eip155:4663). You need two things there: a little ETH for gas, and USDG.
If you have neither, the usual route is bridging from a chain you already use — relay.link supports Robinhood Chain, and accrue.fund is built on exactly that path (card or bank → USDC on Base → relay → USDG). Use whichever bridge you already trust; this facilitator has no preference and takes no cut of it.
You do not need gas to pay for a service — payments are signed off-chain and this facilitator sponsors the gas. Gas is only needed for the one-time wrap in step 02.
You need USDC on Robinhood Chain — the canonical Paxos stablecoin at 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.
Check the address, don't search by name. Six impersonator tokens on this chain answer symbol() == "USDG", some with over 100,000 holders. The real one has 6 decimals and implements EIP-3009; the fakes have 18 and don't.
Depositing mints yUSDCx roughly 1:1, less a 1bps entry fee that stays in the vault — so it raises the redemption value of every unit, including the ones you just received.
# approve the wrapper to pull your USDC cast send 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \ "approve(address,uint256)" 0xd3bB2402D9877F4b29B9B4929DA47ff0bf84e38f 1000000 \ --rpc-url https://mainnet.base.org --private-key $PK # deposit 1 USDC (6 decimals), receive yUSDCx cast send 0xd3bB2402D9877F4b29B9B4929DA47ff0bf84e38f \ "deposit(uint256,address)" 1000000 $YOUR_ADDRESS \ --rpc-url https://mainnet.base.org --private-key $PK
You do not have to build the signature by hand. x402-fetch wraps fetch() and handles the 402 → sign → retry loop for you:
npm i x402-fetch viem
// point it at a wallet holding wUSDGx; it reads the 402 and pays
import { wrapFetchWithPayment } from "x402-fetch";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.PK);
const wallet = createWalletClient({ account, transport: http("https://mainnet.base.org") });
const pay = wrapFetchWithPayment(fetch, wallet);
const r = await pay("https://themes.oddballer.fun/themes");
console.log(await r.json());
Doing it manually instead? The mechanics:
You never send a transaction to pay. You sign an EIP-3009 authorization off-chain and hand it over in a header; this facilitator relays it and pays the gas.
The 402 response tells you exactly what to sign — asset, maxAmountRequired, payTo, and the validity window. Any x402 client library builds the signature from that block.
# see what a service is asking for curl -s https://themes.oddballer.fun/themes | jq .accepts # pay: your client signs, then retries with the header curl -s https://themes.oddballer.fun/themes \ -H "X-PAYMENT: <base64 payload>"
Each settlement takes 2bps: one burns, raising redemption value for every holder — including your own float — and one funds the gas that keeps the rail running. Your fee is not somebody's revenue; it is the next participant's yield, and theirs is yours.
That is why holding the float is rational rather than a cost of doing business. Break-even against idling in a stablecoin is measured live on /stats, with the block range so you can recompute it instead of trusting it.
Anything you list makes the others easier to find, and every payment through any of them raises the float they all settle in.
curl -X POST https://x402.accrue.fund/discovery/register \
-H 'content-type: application/json' \
-d '{"resource":"https://your.api/endpoint",
"description":"what it does",
"accepts":[{"scheme":"exact","network":"eip155:8453",
"asset":"0xd3bB2402D9877F4b29B9B4929DA47ff0bf84e38f",
"maxAmountRequired":"1000",
"payTo":"0xYOUR_ADDRESS"}]}'