TypeScript quickstart
Pay-per-request from Node — @x402/fetch + viem, no API key.
Prerequisites
- Node 20+
- A throwaway EVM private key holding ~$1 of USDC on Base (and a few cents of ETH on Base are not needed — EIP-3009 transfers are gasless for you; the facilitator submits the transaction)
npm i @x402/fetch viemWrap fetch with a payment handler
import { wrapFetchWithPayment } from '@x402/fetch';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount(process.env.AGENT_PK as `0x${string}`);
// Hard budget: refuse to sign anything over $0.05 per call.
const fetchWithPay = wrapFetchWithPayment(fetch, account, {
maxValue: BigInt(50_000), // atomic USDC units (6 decimals)
});
const res = await fetchWithPay(
'https://api.polyrank.app/v1/agent/signals/smart-money',
);
console.log(res.status); // 200
console.log(await res.json()); // { window_hours: 24, rows: [...] }
// The settlement receipt carries the on-chain tx hash:
const receipt = JSON.parse(
Buffer.from(res.headers.get('x-payment-response')!, 'base64').toString(),
);
console.log(`paid — https://basescan.org/tx/${receipt.transaction}`);That's the whole integration. The wrapper sees the 402, signs an EIP-3009
transferWithAuthorization for exactly maxAmountRequired, retries with
the X-PAYMENT header, and hands you the 200.
What just happened
- The first request returned
402with PaymentRequirements. - Your key signed a USDC authorization (off-chain, gasless for you) bound to a one-time nonce.
- Polyrank verified it with the facilitator, ran the query, settled the transfer on-chain, and returned the data plus the receipt header.
Verify the payment on BaseScan — the USDC transfer goes to the Polyrank
treasury (payTo in the 402 body).
Guardrails for autonomous agents
- Budget cap —
maxValueabove is your hard per-call ceiling; also track cumulative spend per run. - Never reuse nonces — the SDK generates one per payment; replays are
rejected (
authorization nonce already used). - Handle 451 — OFAC-blocked payer addresses are refused before any payment moves.
Picking endpoints
Swap the URL — same wrapper pays for everything in the
price table. For a strategy loop, the usual
combination is signals/smart-money (what skilled wallets just did) +
market/{id} (does the skilled cohort disagree with the price?).