#!/usr/bin/env python3
"""Blockchain address tracing reference for authorized investigations.

This starter follows public Ethereum transfers for a known address using Web3.py.
It is for compliance, fraud investigation, and incident response use cases where
handling blockchain data is permitted by policy and law.
"""

from __future__ import annotations

import argparse
import csv
import os
from pathlib import Path

from web3 import Web3  # type: ignore


def main() -> int:
    parser = argparse.ArgumentParser(description="Trace recent Ethereum transactions for an address.")
    parser.add_argument("address", help="Ethereum address to review")
    parser.add_argument("--blocks", type=int, default=5000, help="Recent block window to inspect")
    parser.add_argument("--output", type=Path, default=Path("address_trace.csv"))
    args = parser.parse_args()

    rpc_url = os.environ.get("WEB3_PROVIDER_URI")
    if not rpc_url:
        raise SystemExit("Set WEB3_PROVIDER_URI to an authorized Ethereum RPC endpoint")
    web3 = Web3(Web3.HTTPProvider(rpc_url))
    address = Web3.to_checksum_address(args.address)
    latest = web3.eth.block_number
    start = max(0, latest - args.blocks)

    rows: list[dict[str, object]] = []
    for block_number in range(start, latest + 1):
        block = web3.eth.get_block(block_number, full_transactions=True)
        for tx in block.transactions:
            if tx["from"] == address or (tx.get("to") and Web3.to_checksum_address(tx["to"]) == address):
                rows.append({
                    "block": block_number,
                    "hash": tx["hash"].hex(),
                    "from": tx["from"],
                    "to": tx.get("to") or "contract_creation",
                    "eth": web3.from_wei(tx["value"], "ether"),
                })
    with args.output.open("w", newline="", encoding="utf-8") as handle:
        writer = csv.DictWriter(handle, fieldnames=["block", "hash", "from", "to", "eth"])
        writer.writeheader()
        writer.writerows(rows)
    print(f"Wrote {len(rows)} transactions to {args.output}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
