agentgate-examples / tree / typescript/src/pay-one-tool.ts ยท raw (this view has old GitHub links rewritten for the mirror; raw is byte-exact)
// Pay one AgentGate tool with @x402/fetch + a viem wallet (USDC on Base).
//   BUYER_KEY=0x... npm run pay -- webread      (real payment: $0.002 for WebRead)
// Without BUYER_KEY it stops at the 402 and prints the price instead of paying.
// Keep the key in an env var or a secrets manager, never in code. Use a small hot wallet holding a few cents of USDC on Base.
import { wrapFetchWithPaymentFromConfig, decodePaymentResponseHeader } from '@x402/fetch';
import { decodePaymentRequiredHeader } from '@x402/core/http';
import { ExactEvmScheme } from '@x402/evm';
import { privateKeyToAccount } from 'viem/accounts';
import { TOOLS, type ToolKey } from './tools.js';

const key = (process.argv[2] || 'webread') as ToolKey;
const tool = TOOLS[key];
if (!tool) throw new Error(`unknown tool ${key}; one of ${Object.keys(TOOLS).join(', ')}`);

const buyerKey = process.env.BUYER_KEY as `0x${string}` | undefined;
if (!buyerKey) {
  const res = await fetch(tool.url);
  console.log(`No BUYER_KEY set: not paying. ${tool.name} answered ${res.status}; price ${tool.price} USDC on Base. Set BUYER_KEY to pay.`);
  process.exit(0);
}

const account = privateKeyToAccount(buyerKey);
const fetchWithPay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: 'eip155:8453', client: new ExactEvmScheme(account) }],
});
const res = await fetchWithPay(tool.url);
if (res.status === 402) {
  const pr = res.headers.get('PAYMENT-REQUIRED');
  console.log('Payment was not accepted:', pr ? decodePaymentRequiredHeader(pr).error : res.status);
  process.exit(1);
}
const receipt = res.headers.get('PAYMENT-RESPONSE');
console.log(res.status, receipt ? decodePaymentResponseHeader(receipt) : '(no receipt)');
console.log(JSON.stringify(await res.json(), null, 2).slice(0, 2000));

agentgate-source: code mirror on Cloudflare Pages. All repos