"""Buy one verdict from Clearsigned and verify the receipt yourself.

Setup (once):
    pip install "x402[evm]" httpx eth-account
    export BUYER_PRIVATE_KEY=0x...   # any EVM key holding a few cents of
                                     # USDC on Base mainnet (eip155:8453)

Run:
    python buy_a_verdict.py "The Eiffel Tower is located in Paris, France."

What you get: a SUPPORTED / REFUTED / UNVERIFIABLE verdict whose confidence
is a MEASURED realized rate (see the calibration_version on the receipt), an
evidence trail with per-source stances, and an Ed25519 signature this script
verifies OFFLINE against the published key — pinned from /pubkey, never
trusted from the receipt itself.

Note the 120s timeout: evidence is gathered live; verdicts take 10-40s.
"""

import asyncio
import json
import os
import sys

import httpx
from eth_account import Account

from x402 import x402Client
from x402.http import x402HTTPClient
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client

API = "https://verify.clearsigned.com"


def verify_signature_offline(receipt: dict, pinned_public_key_hex: str) -> bool:
    """The receipt verification recipe from /pubkey, self-contained."""
    from cryptography.exceptions import InvalidSignature
    from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

    sig = receipt.get("signature", {})
    if sig.get("public_key", "").lower() != pinned_public_key_hex.lower():
        return False  # signed under some other key — reject, whoever it claims to be
    payload = {k: v for k, v in receipt.items() if k != "signature"}
    canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"),
                           ensure_ascii=False).encode("utf-8")
    try:
        Ed25519PublicKey.from_public_bytes(
            bytes.fromhex(pinned_public_key_hex)
        ).verify(bytes.fromhex(sig["signature"]), canonical)
        return True
    except (InvalidSignature, ValueError):
        return False


async def main() -> int:
    claim = sys.argv[1] if len(sys.argv) > 1 else "The Eiffel Tower is located in Paris, France."
    account = Account.from_key(os.environ["BUYER_PRIVATE_KEY"])
    print(f"buyer: {account.address}")

    client = x402Client()
    register_exact_evm_client(client, EthAccountSigner(account))
    helper = x402HTTPClient(client)

    async with x402HttpxClient(client, timeout=120.0) as http:
        resp = await http.post(f"{API}/verify/t1", json={"claim": claim, "evidence": []})
        await resp.aread()
        receipt = json.loads(resp.text)
        settle = helper.get_payment_settle_response(lambda h: resp.headers.get(h))

    print(f"verdict: {receipt.get('verdict')} @ {receipt.get('confidence')}")
    print(f"curve:   {receipt.get('calibration_version')}")
    print(f"paid:    settlement tx {settle.transaction}")
    for e in receipt.get("evidence_evaluated", []):
        print(f"  {e['stance']:8s} {e['source']}")

    pinned = httpx.get(f"{API}/pubkey", timeout=15).json()["public_key"]
    ok = verify_signature_offline(receipt, pinned)
    print(f"signature (verified offline vs pinned /pubkey key): {'VALID' if ok else 'INVALID'}")
    return 0 if ok else 1


if __name__ == "__main__":
    sys.exit(asyncio.run(main()))
