"""Pay per call with USDC on Base (x402). No account, no API key.

pip install requests "x402[httpx,evm]" eth-account
export X402_PRIVATE_KEY=0x...     # a DEDICATED wallet holding a few dollars of USDC on Base. Never your main wallet.

python x402_pay.py          # dry run: asks the price, pays NOTHING
python x402_pay.py --go     # really pays (about $0.0002 per location for weather)

Structure proven against this API with the official Python x402 v2 client. Other clients are untested.
GetFixn sells data, not trading advice. Forecasts can be wrong.
"""
import asyncio
import base64
import json
import os
import sys

import requests

URL = "https://data.truefixr.com/v1/weather/batch"
BODY = {"locations": [{"lat": 32.78, "lon": -96.80, "label": "Dallas"}]}


def quote():
    """Unpaid request. The server answers 402 and says what it wants. Costs nothing."""
    r = requests.post(URL, json=BODY, timeout=30)
    if r.status_code != 402:
        sys.exit("expected 402, got %s" % r.status_code)
    need = json.loads(base64.b64decode(r.headers["payment-required"]))["accepts"][0]
    usd = int(need["amount"]) / 1_000_000  # USDC has 6 decimals
    print("price: $%.4f USDC on %s, pay to %s" % (usd, need["network"], need["payTo"]))
    return usd


async def pay():
    from eth_account import Account
    from x402 import x402Client
    from x402.http.clients import x402HttpxClient
    from x402.mechanisms.evm import EthAccountSigner
    from x402.mechanisms.evm.exact import register_exact_evm_client

    acct = Account.from_key(os.environ["X402_PRIVATE_KEY"])
    client = x402Client()
    register_exact_evm_client(client, EthAccountSigner(acct))
    async with x402HttpxClient(client) as http:
        r = await http.post(URL, json=BODY)  # 402 -> sign -> retry, all inside the client
        await r.aread()
        print(r.status_code, r.text[:400])


if __name__ == "__main__":
    price = quote()
    if "--go" in sys.argv:
        asyncio.run(pay())
    else:
        print("dry run only. Add --go to pay $%.4f." % price)
