import os
import threading
import time
from mnemonic import Mnemonic
from eth_account import Account
import requests
import json
import sys

Account.enable_unaudited_hdwallet_features()
api_keys = ["9V98U5PIUSBU8GGE96KMTCBJGW9CGM1Z1K",
            "XYY8VPXWTWZIWGZ86T47JTCM53PASZPFM8",
            "8SCUMBDXDCBFEVQX8EHH3MWQZK8JT5TEWC"]
lock = threading.Lock()


def api_request(api_keys, endpoint, params):
    for key in api_keys:
        params['apikey'] = key
        try:
            response = requests.get(endpoint, params=params)
            response.raise_for_status()
            data = response.json()
            if data.get("status") == "1":
                return data
        except requests.exceptions.RequestException:
            continue
    raise Exception("All API keys failed or were rate-limited")


def create_directories():
    os.makedirs("wallets", exist_ok=True)
    os.makedirs("wallets_with_balance", exist_ok=True)


def generate_wallet(api_keys):
    mnemo = Mnemonic("english")
    while True:
        words = mnemo.generate(strength=128)
        filename = os.path.join("wallets", f"{words.replace(' ', '_')}.json")

        if not os.path.exists(filename):
            account = Account.from_mnemonic(words)
            data = {
                "mnemonic": words,
                "address": account.address,
                "checked": False
            }
            with open(filename, 'w') as f:
                json.dump(data, f)
            with lock:
                with open("statistics.json", 'r+') as stat_file:
                    stats = json.load(stat_file)
                    stats['wallet_count'] += 1
                    stat_file.seek(0)
                    json.dump(stats, stat_file)


def check_balance(api_keys):
    while True:
        files = [f for f in os.listdir("wallets") if f.endswith('.json')]
        for filename in files:
            filepath = os.path.join("wallets", filename)
            with open(filepath, 'r') as f:
                data = json.load(f)

            if not data["checked"]:
                try:
                    endpoint = "https://api.etherscan.io/api"
                    params = {
                        "module": "account",
                        "action": "balance",
                        "address": data["address"]
                    }
                    result = api_request(api_keys, endpoint, params)
                    balance = int(result["result"]) / 10 ** 18 if result["status"] == "1" else 0

                    if balance > 0:
                        with open(os.path.join("wallets_with_balance", filename), 'w') as balance_file:
                            data['balance'] = balance
                            json.dump(data, balance_file)

                    data["checked"] = True
                    with open(filepath, 'w') as f:
                        json.dump(data, f)

                    with lock:
                        with open("statistics.json", 'r+') as stat_file:
                            stats = json.load(stat_file)
                            stats['checked_wallets'] += 1
                            stat_file.seek(0)
                            json.dump(stats, stat_file)
                except Exception as e:
                    print(f"Error checking balance for {data['address']}: {e}")

        time.sleep(1)


def print_stats():
    with open("statistics.json", 'r') as stat_file:
        stats = json.load(stat_file)
        print(f"\rTotal wallets created: {stats['wallet_count']} | Total wallets checked: {stats['checked_wallets']}",
              end='')


def main(api_keys, num_threads):
    create_directories()

    if not os.path.exists("statistics.json"):
        with open("statistics.json", 'w') as stat_file:
            json.dump({"wallet_count": 0, "checked_wallets": 0}, stat_file)

    threads = []
    for _ in range(num_threads):
        t_generate = threading.Thread(target=generate_wallet, args=(api_keys,))
        t_generate.start()
        threads.append(t_generate)

    for _ in range(4):
        t_check = threading.Thread(target=check_balance, args=(api_keys,))
        t_check.start()
        threads.append(t_check)

    try:
        while True:
            time.sleep(1)
            print_stats()
    except KeyboardInterrupt:
        print("\nInterrupted!")
        for t in threads:
            t.join()
        print("Threads closed.")


if __name__ == "__main__":

    Account.enable_unaudited_hdwallet_features()

    # سوال از کاربر برای تعداد تردها
    num_threads = int(input("Enter the number of threads: "))

    main(api_keys, num_threads)


در این کد ، هر آدرس ولت به صورت جداگانه در 3 کلید api مختلف تست میشود ، من میخواهم به صورت همزمان هر ولت فقط در یک کلید بررسی شود ، چک کردن ولت تکراری سرعت را پایین می آورد