"""Pay one AgentGate tool from Python with the official x402 SDK (USDC on Base).
pip install -r requirements.txt
python pay_one_tool.py --dry-run # parse every tool's 402 challenge, no key, no payment
BUYER_KEY=0x... python pay_one_tool.py webread # real payment ($0.002 for WebRead)
Keep BUYER_KEY in the environment (a small hot wallet with a few cents of USDC on Base), never in code.
"""
import json
import os
import sys
import requests
from x402.http import decode_payment_required_header
from tools import TOOLS
def dry_run(only=None):
failed = 0
for key, (name, _price, url) in TOOLS.items():
if only and key != only:
continue
r = requests.get(url, timeout=20)
header = r.headers.get("PAYMENT-REQUIRED")
if r.status_code != 402 or not header:
print(f"{name}: expected 402 + PAYMENT-REQUIRED, got {r.status_code}")
failed += 1
continue
pr = decode_payment_required_header(header)
a = pr.accepts[0]
print(f"{name}: 402 OK, x402 v{pr.x402_version}, {int(a.amount) / 1e6} USDC on {a.network} to {a.pay_to}, "
f"resource {pr.resource.url}, listed as {pr.resource.service_name!r}")
return failed
def pay(key):
from eth_account import Account
from x402 import x402ClientSync
from x402.http.clients import wrapRequestsWithPayment
from x402.mechanisms.evm.exact import register_exact_evm_client
name, price, url = TOOLS[key]
client = x402ClientSync()
register_exact_evm_client(client, Account.from_key(os.environ["BUYER_KEY"]), networks="eip155:8453")
session = wrapRequestsWithPayment(requests.Session(), client)
r = session.get(url, timeout=60)
if r.status_code == 402:
header = r.headers.get("PAYMENT-REQUIRED")
print("Payment was not accepted:", decode_payment_required_header(header).error if header else r.status_code)
return 1
print(r.status_code, r.headers.get("PAYMENT-RESPONSE", "(no receipt)")[:80], "...")
print(json.dumps(r.json(), indent=2)[:2000])
return 0
if __name__ == "__main__":
args = [a for a in sys.argv[1:] if not a.startswith("--")]
key = args[0] if args else None
if "--dry-run" in sys.argv or not os.environ.get("BUYER_KEY"):
if not os.environ.get("BUYER_KEY") and "--dry-run" not in sys.argv:
print("No BUYER_KEY set: dry run only (no payment).")
sys.exit(1 if dry_run(key) else 0)
sys.exit(pay(key or "webread"))
agentgate-source: code mirror on Cloudflare Pages. All repos