import time
from web3 import Web3
from web3.middleware import ExtraDataToPOAMiddleware
# Chainstack Zora mainnet endpoint
ZORA_RPC = "YOUR_CHAINSTACK_HTTP_ENDPOINT"
# Exclude these tokens (USDzC and WETH)
EXCLUDED_TOKENS = {
    "0xCccCCccc7021b32EBb4e8C08314bD62F7c653EC4".lower(), # USDzC
    "0x4200000000000000000000000000000000000006".lower(), # WETH
}
# Standard ERC-20 ABI fragments
ERC20_ABI = [
    {
        "anonymous": False,
        "inputs": [
            {"indexed": True, "name": "from", "type": "address"},
            {"indexed": True, "name": "to", "type": "address"},
            {"indexed": False, "name": "value", "type": "uint256"},
        ],
        "name": "Transfer",
        "type": "event",
    },
    {"constant": True, "inputs": [], "name": "name", "outputs": [{"name": "", "type": "string"}], "type": "function"},
    {"constant": True, "inputs": [], "name": "symbol", "outputs": [{"name": "", "type": "string"}], "type": "function"},
    {"constant": True, "inputs": [], "name": "decimals", "outputs": [{"name": "", "type": "uint8"}], "type": "function"},
]
# Connect to Zora mainnet
w3 = Web3(Web3.HTTPProvider(ZORA_RPC))
# Zora is OP Stack, so it needs POA middleware
w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
print(f"Connected to Zora: {w3.is_connected()}")
# Get the Transfer event signature hash
TRANSFER_EVENT_SIG = "0x" + w3.keccak(text="Transfer(address,address,uint256)").hex()
# Track seen token addresses
seen_tokens = set()
# Helper to get token info
def get_token_info(token_address):
    # Convert to checksum address for web3.py compatibility
    checksum_address = Web3.to_checksum_address(token_address)
    contract = w3.eth.contract(address=checksum_address, abi=ERC20_ABI)
    try:
        name = contract.functions.name().call()
    except Exception:
        name = "?"
    try:
        symbol = contract.functions.symbol().call()
    except Exception:
        symbol = "?"
    try:
        decimals = contract.functions.decimals().call()
    except Exception:
        decimals = "?"
    return name, symbol, decimals
# Start from latest block
start_block = w3.eth.block_number
print(f"Starting from block {start_block}")
while True:
    latest_block = w3.eth.block_number
    for block_num in range(start_block, latest_block + 1):
        block = w3.eth.get_block(block_num, full_transactions=False)
        logs = w3.eth.get_logs({
            "fromBlock": block_num,
            "toBlock": block_num,
            "topics": [TRANSFER_EVENT_SIG],
        })
        for log in logs:
            token_address = log["address"].lower()
            if token_address in EXCLUDED_TOKENS:
                continue
            # Only fetch token info once per token
            if token_address not in seen_tokens:
                name, symbol, decimals = get_token_info(token_address)
                seen_tokens.add(token_address)
                print(f"\nNew token detected: {token_address}")
                print(f"  Name: {name}")
                print(f"  Symbol: {symbol}")
                print(f"  Decimals: {decimals}")
            # Parse transfer event
            from_addr = "0x" + log["topics"][1].hex()[-40:]
            to_addr = "0x" + log["topics"][2].hex()[-40:]
            value = int.from_bytes(log["data"].rjust(32, b"\x00"), byteorder="big")
            print(f"Transfer | Token: {token_address} | From: {from_addr} | To: {to_addr} | Value: {value}")
    start_block = latest_block + 1
    time.sleep(2)