Spaces:
Running
Running
| """W17-A diagnostic: dump on-chain reputation/registration state for all 6 seeder addresses. | |
| Reads: | |
| - REPUTATION_REGISTRY_ADDRESS / TRANSLATION_AUCTION_ADDRESS / ARC_TESTNET_USDC_ADDRESS / ARC_TESTNET_RPC from .env | |
| - ABI from contracts/out/ | |
| For each of the 6 addresses (3 old gemini/deepseek/qwen + 3 v2 wallets derived | |
| from HACKATHON_WALLET_PRIVATE_KEY), prints: | |
| - getReputation(addr) — raw uint256 + scaled float | |
| - getStats(addr) — totalBids/totalWins/qualityPasses/cumulativeFees/score | |
| - reps(addr).lastUpdated — to distinguish "never touched" from "score reset" | |
| - auction.registered(addr) — whether they finished registerAgent | |
| - auction.stakes(addr) / lockedStakes(addr) — staked USDC | |
| - reputation_registry.authorized(addr) — only relevant for owner check | |
| - USDC.balanceOf(addr) and ETH balance | |
| Plus derives v2 wallets from HACKATHON_WALLET_PRIVATE_KEY and confirms the | |
| addresses match outputs/agent_wallets.json (rules out hypothesis B). | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import sys | |
| from pathlib import Path | |
| # Load .env manually (avoid pulling in app deps) | |
| ROOT = Path(__file__).resolve().parents[1] | |
| ENV_PATH = ROOT / ".env" | |
| def load_env() -> None: | |
| if not ENV_PATH.exists(): | |
| return | |
| for raw in ENV_PATH.read_text().splitlines(): | |
| line = raw.strip() | |
| if not line or line.startswith("#"): | |
| continue | |
| if "=" not in line: | |
| continue | |
| k, v = line.split("=", 1) | |
| os.environ.setdefault(k.strip(), v.strip()) | |
| load_env() | |
| sys.path.insert(0, str(ROOT)) | |
| from web3 import Web3 # noqa: E402 | |
| from eth_account import Account # noqa: E402 | |
| from polyglot_alpha.agents.wallets import derive_agent_wallet, AGENT_NAMES # noqa: E402 | |
| def load_abi(path: Path) -> list: | |
| return json.loads(path.read_text())["abi"] | |
| # ERC-20 minimal ABI for balanceOf | |
| ERC20_ABI = [ | |
| { | |
| "constant": True, | |
| "inputs": [{"name": "owner", "type": "address"}], | |
| "name": "balanceOf", | |
| "outputs": [{"name": "", "type": "uint256"}], | |
| "stateMutability": "view", | |
| "type": "function", | |
| }, | |
| { | |
| "constant": True, | |
| "inputs": [], | |
| "name": "decimals", | |
| "outputs": [{"name": "", "type": "uint8"}], | |
| "stateMutability": "view", | |
| "type": "function", | |
| }, | |
| ] | |
| def main() -> int: | |
| rpc = os.environ["ARC_TESTNET_RPC"] | |
| rep_addr = os.environ["REPUTATION_REGISTRY_ADDRESS"] | |
| auc_addr = os.environ["TRANSLATION_AUCTION_ADDRESS"] | |
| usdc_addr = os.environ["ARC_TESTNET_USDC_ADDRESS"] | |
| op_pk = os.environ["HACKATHON_WALLET_PRIVATE_KEY"] | |
| print(f"RPC = {rpc}") | |
| print(f"ReputationRegistry = {rep_addr}") | |
| print(f"TranslationAuction = {auc_addr}") | |
| print(f"USDC = {usdc_addr}") | |
| w3 = Web3(Web3.HTTPProvider(rpc, request_kwargs={"timeout": 30})) | |
| print(f"chain connected = {w3.is_connected()} chainId={w3.eth.chain_id}") | |
| rep_abi = load_abi(ROOT / "contracts/out/ReputationRegistry.sol/ReputationRegistry.json") | |
| auc_abi = load_abi(ROOT / "contracts/out/TranslationAuction.sol/TranslationAuction.json") | |
| rep = w3.eth.contract(address=Web3.to_checksum_address(rep_addr), abi=rep_abi) | |
| auc = w3.eth.contract(address=Web3.to_checksum_address(auc_addr), abi=auc_abi) | |
| usdc = w3.eth.contract(address=Web3.to_checksum_address(usdc_addr), abi=ERC20_ABI) | |
| # Confirm wallet derivation | |
| print("\n=== Wallet derivation cross-check (rules out hypothesis B) ===") | |
| derived: dict[str, str] = {} | |
| for name in AGENT_NAMES: | |
| w = derive_agent_wallet(op_pk, name) | |
| derived[name] = w.address | |
| print(f" {name:<14} -> {w.address}") | |
| saved = json.loads((ROOT / "outputs/agent_wallets.json").read_text()) | |
| for name in AGENT_NAMES: | |
| match = derived[name].lower() == saved[name]["address"].lower() | |
| print( | |
| f" {name:<14} saved={saved[name]['address']} match={match}" | |
| ) | |
| # 6 addresses to investigate. Old gemini/deepseek/qwen addresses | |
| # come from the original W14-CONTRACT-PREP keys (sha256(op_pk + ':gemini') etc). | |
| # If that derivation has been retired we still want to inspect the | |
| # historic addresses cited in the bug report. | |
| old_addresses = { | |
| "gemini-old": "0x396B...", # placeholder; only the v2 row is required | |
| } | |
| # We don't actually know the literal old hex from the env; derive what the | |
| # PRE-v2 naming would have produced (sha256(pk + ':gemini')). | |
| import hashlib | |
| for legacy_name in ("gemini", "deepseek", "qwen"): | |
| seed = hashlib.sha256(f"{op_pk}:{legacy_name}".encode()).hexdigest() | |
| acct = Account.from_key("0x" + seed) | |
| old_addresses[f"{legacy_name}-old"] = acct.address | |
| targets: list[tuple[str, str]] = [] | |
| for legacy in ("gemini", "deepseek", "qwen"): | |
| targets.append((f"{legacy}-old", old_addresses[f"{legacy}-old"])) | |
| for name in AGENT_NAMES: | |
| targets.append((name, derived[name])) | |
| print("\n=== Per-address chain state ===") | |
| print( | |
| f"{'name':<15}{'address':<45}{'rep_raw':>22}{'rep_f':>10}" | |
| f"{'lastUpd':>12}{'tBids':>7}{'tWins':>7}{'qPass':>7}" | |
| f"{'cumFee':>10}{'reg':>5}{'stake':>10}{'lock':>10}" | |
| f"{'usdc':>10}{'eth':>10}" | |
| ) | |
| for label, addr in targets: | |
| addr_cs = Web3.to_checksum_address(addr) | |
| rep_raw = rep.functions.getReputation(addr_cs).call() | |
| stats = rep.functions.getStats(addr_cs).call() | |
| reps_struct = rep.functions.reps(addr_cs).call() | |
| # reps struct: totalBids, totalWins, totalQualityPasses, cumulativeFeesEarned, score, lastUpdated | |
| last_updated = reps_struct[5] | |
| registered = auc.functions.registered(addr_cs).call() | |
| stake = auc.functions.stakes(addr_cs).call() | |
| try: | |
| locked = auc.functions.lockedStakes(addr_cs).call() | |
| except Exception: | |
| locked = 0 | |
| usdc_bal = usdc.functions.balanceOf(addr_cs).call() | |
| eth_bal = w3.eth.get_balance(addr_cs) | |
| print( | |
| f"{label:<15}{addr_cs:<45}{rep_raw:>22}{rep_raw/1e18:>10.4f}" | |
| f"{last_updated:>12}{stats[0]:>7}{stats[1]:>7}{stats[2]:>7}" | |
| f"{stats[3]:>10}{int(registered):>5}{stake/1e6:>10.4f}{locked/1e6:>10.4f}" | |
| f"{usdc_bal/1e6:>10.4f}{eth_bal/1e18:>10.4f}" | |
| ) | |
| # Owner of ReputationRegistry + authorized set | |
| try: | |
| owner = rep.functions.owner().call() | |
| print(f"\nReputationRegistry.owner = {owner}") | |
| except Exception as exc: | |
| print(f"\nReputationRegistry.owner read failed: {exc}") | |
| # Also dump bytecode size to confirm both contracts are deployed | |
| rep_code = w3.eth.get_code(Web3.to_checksum_address(rep_addr)) | |
| auc_code = w3.eth.get_code(Web3.to_checksum_address(auc_addr)) | |
| print( | |
| f"\nReputationRegistry bytecode bytes = {len(rep_code)}" | |
| f" TranslationAuction bytecode bytes = {len(auc_code)}" | |
| ) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |