#!/usr/bin/env python3
"""verify_trace.py — re-walk pursekeeper /trace rows on-chain.

Snapshot read: 2026-09-21 02:24 UTC (page says node read 'at the date above').
For each resolved counterparty address: received_from_HOT, sent_to_HOT,
balance before snapshot, compared against the published row.
"""
import json, os, urllib.request, re, sys, time

RPC = "https://rpc.nano.to"
HOT = "nano_1xug1q5t7nxoj3ywwzokiea9jz8fq8qfgzp8pbyfr3co3e5xgj755uofu8ue"
SNAP = 1779759840  # 2026-05-26? compute below properly
import datetime
SNAP = int(datetime.datetime(2026,9,21,2,24,tzinfo=datetime.timezone.utc).timestamp())

def rpc(payload):
    req = urllib.request.Request(RPC, data=json.dumps(payload).encode(),
        headers={"Content-Type":"application/json","User-Agent":"ARION-traceQA/1.0"})
    return json.loads(urllib.request.urlopen(req,timeout=40).read())

ADDRS = {
 "NanoGPT deposit (my purchase)": "nano_3gmd94aey5nxrntgjrznnbssh3s7htyubeq91x8qgjpbe8qk59xiarf1homu",
 "ClearTable 402 address (workesfm)": "nano_3rb7dgcbk56zxypskwsdtxxbjxbzjg66mhzu7kcrtqkoa6i5airqbaw3wrq5",
 "llmrt": "nano_16fgnoqwia9haruycrgq38ot71bj8zthpmkutomdm7zb94egb7ucg7uk68cm",
 "pyfile-toolkit": "nano_3uojbn47b5xqcbs4yibbasamn8aeyqxgyi1z8peogwtdn6z3kagjanjpz4ss",
 "StringSafeQA": "nano_318agkr46xasmp96x6bgw89c89hpwk9msrmnhkhsz8u9znm7mh7uzx38uf3o",
 "workesfm payout address": "nano_394ub3cn6trqxcbhumxcuo5t7o9tmsshexmekna5ie7mw65cgw1scy8isseq",
 "Dalton's research agent": "nano_1u5zktci5e4jtrcf9poq66pc5wk6g4mnmruh5h3dg1bdac63nj5kck5w453x",
 "Jack Independent Research": "nano_3yzsns4z5z58dkgtz6hempm1qn9x3xb3j65g71s9d56jjjdcnggzspn4ae53",
 "Cleartask (MadebyDevX's Codex agent)": "nano_33tspkdqtf6nodp9n5xnid4upqpssdxknyhiw4atuw3nni8zw88int7uyizb",
 "nano_15s4fd48jzt": "nano_15s4fd48jztkijifk1agr5gtnkos55gex8nbzom7qxrt3hf985pbkjik3s84",
 "nano_1ez5y77rw84": "nano_1ez5y77rw84m5epan39bhgyfoc97i9bbt94ansigbazxwueheds1zgcg3jde",
 "OreoMuncher45 (api.shehriyar.ink)": "nano_1zqdw3qf1z8k3jx8jintaiwpo3yz7zqh1me4ph5j439ts8hsppx8dzy4xcsz",
 "nano_1yadwtsawdf": "nano_1yadwtsawdfa764zrszmxdyjjzqu5wynpg9o3hr9y8j8daxjcsyf16i43hri",
 "nano_1bfapscrwk7": "nano_1bfapscrwk7t66faz9emcqo318698d4yc9n7p8rh8gjuttg8ehgajgzw4bk1",
 "nano_1ds8dt9pknd": "nano_1ds8dt9pkndnzwgceo746pqn3bu5ugjm44arogk1x55wmn6cfa8bj7e54i4n",
 "nano_1yo6c1t64ah": "nano_1yo6c1t64ahfjdw1dxizmbbnpdmbrckwhw9phbg5pdkeubrizga4qhnjmnx7",
 "nano_1gc3p8f3dww": "nano_1gc3p8f3dww1j6y79s11wqpa1hrf1uo9w7s7qyerdweaizfog49cbajdb5op",
}

TR = {r["name"]: r["cells"] for r in json.load(open(os.path.join(os.path.dirname(os.path.abspath(__file__)),"trace_rows.json")))}

def num(s):
    try: return float(s)
    except: return None

out=[]
for name, addr in ADDRS.items():
    try:
        h = rpc({"action":"account_history","account":addr,"count":200,"raw":"true"})
    except Exception as e:
        print(name,"RPC-ERR",e); continue
    hist = h.get("history",[])
    fm=tm=recv=send=0
    for b in hist:
        ts=int(b.get("local_timestamp",0) or 0)
        if ts>SNAP: continue
        a=int(b["amount"])
        if b["type"]=="receive":
            recv+=a
            if b.get("account")==HOT: fm+=a
        elif b["type"]=="send":
            send+=a
            if b.get("account")==HOT: tm+=a
    bal=(recv-send)/1e30
    rowkey = name if name in TR else next((k for k in TR if k.startswith(name.split()[0].rstrip('…')) or (name in k)), None)
    tr = TR.get(rowkey, [])
    exp = [num(tr[i]) if i<len(tr) else None for i in (0,7,2)]  # from me, back to me, held
    got = [fm/1e30, tm/1e30, bal]
    flags=[]
    for i,lbl in enumerate(("from_me","back_to_me","held")):
        e,g=exp[i],got[i]
        if e is None: continue
        if abs(e-g) > max(0.001, abs(e)*0.01):
            flags.append(f"{lbl} EXP {e} GOT {g:.6f}")
    st = "OK" if not flags else "DIFF: "+"; ".join(flags)
    out.append({"name":name,"addr":addr,"expected":{"from_me":exp[0],"back_to_me":exp[1],"held":exp[2]},"computed":{"from_me":round(fm/1e30,6),"back_to_me":round(tm/1e30,6),"held_at_snap":round(bal,6)},"blocks":len(hist),"status":st})
    print(f"{name[:42]:44s} fm={fm/1e30:<10.6f} tm={tm/1e30:<10.6f} bal={bal:<12.6f} {st}")
json.dump({"snapshot":SNAP,"rows":out},open(os.path.join(os.path.dirname(os.path.abspath(__file__)),"trace_verify.json"),"w"),indent=1)
