etherscan.io multichain checker
etherscan.io multichain checker
import json
import requests
from web3 import Web3
from eth_account import Account
from pathlib import Path
def generate_public_address(mnemonic):
"""
Generate Ethereum public address from a mnemonic phrase.
"""
try:
wallet_account = Account.from_mnemonic(mnemonic)
return wallet_account.address
except Exception as e:
print(f"[ERROR] Failed to generate public address: {e}")
return None
params = {
"chainid": chain_id,
"module": "account",
"action": "balance",
"address": address,
"tag": "latest",
"apikey": API_KEY,
}
response_data = response.json()
if response_data.get("status") != "1":
print(f"[WARNING] {chain_name.capitalize()} API returned an error:
{response_data.get('message')}")
return {"error": response_data.get("message")} # Add error for
tracking
# Convert the balance from Wei to Ether (or chain native token units)
balance_wei = int(response_data.get("result", "0"))
balance_eth = Web3.from_wei(balance_wei, "ether")
return {"balance": float(balance_eth)} # Convert to float for JSON
serialization
except ValueError as e:
# JSONDecodeError sometimes manifests as ValueError
print(f"[ERROR] Failed to parse JSON response from
{chain_name.capitalize()} API: {e}")
return {"error": "Invalid or empty JSON response"}
except Exception as e:
print(f"[ERROR] Failed to query {chain_name.capitalize()} API: {e}")
return {"error": str(e)}
finally:
# Add a small delay every 2-3 checks to avoid hitting rate limits
if counter % 3 == 0: # Pause after every 3 requests
print("[INFO] Adding a 0.5 second delay to avoid throttling...")
time.sleep(0.5)
def query_multichain_portfolio_v2(address):
"""
Query balances across all chains provided in SUPPORTED_CHAINS.
Implements rate limiting to stay within 5 calls per second allowed by
Etherscan's API.
"""
portfolio = {}
counter = 0 # Counter to manage delays
def main():
"""
Main program for retrieving balances across multiple chains via Etherscan V2
with rate limiting.
"""
# Load decrypted wallets from the previously generated file
decrypted_wallets_file = Path("decrypted_mnemonics.json")
if not decrypted_wallets_file.exists():
print("[ERROR] Decrypted wallets file not found!")
return
output_file = Path("multichain_portfolio_v2.json")
all_portfolio_data = []
if not mnemonic:
print(f"[WARNING] Missing mnemonic for wallet in folder: {subfolder}")
continue