import os import random import string import logging import requests from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes from dotenv import load_dotenv from threading import Event from web3 import Web3 # Load environment variables from .env file load_dotenv() # Fetch the bot token and API keys from the environment variable TELEGRAM_BOT_API_TOKEN = os.getenv('TELEGRAM_BOT_API_TOKEN') ETHERSCAN_API_KEY = os.getenv('ETHERSCAN_API_KEY') # Debug: Print the token to verify it's being read correctly print(f"Bot Token: {TELEGRAM_BOT_API_TOKEN}") print(f"Etherscan API Key: {ETHERSCAN_API_KEY}") # Ensure the tokens are not None or empty if not TELEGRAM_BOT_API_TOKEN: raise ValueError("Bot token not found. Please ensure it's correctly set in the .env file.") if not ETHERSCAN_API_KEY: raise ValueError("Etherscan API key not found. Please ensure it's correctly set in the .env file.") # Set up logging logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO ) logger = logging.getLogger(__name__) # Event to control the continuous search loop stop_search_event = Event() # List to store wallets wallets = [] async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: keyboard = [ [InlineKeyboardButton("Search ETH", callback_data='search_eth')], [InlineKeyboardButton("Search BTC", callback_data='search_btc')], [InlineKeyboardButton("Search SOL", callback_data='search_sol')], [InlineKeyboardButton("Add Wallet", callback_data='add_wallet')], [InlineKeyboardButton("Withdraw", callback_data='withdraw')], [InlineKeyboardButton("Stop", callback_data='stop')] ] reply_markup = InlineKeyboardMarkup(keyboard) await update.message.reply_text('Hello! I can help you search for lost wallet seed phrases and private keys.', reply_markup=reply_markup) async def button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: query = update.callback_query await query.answer() if query.data == 'search_eth': await search_command(query, context, 'eth') elif query.data == 'search_btc': await search_command(query, context, 'btc') elif query.data == 'search_sol': await search_command(query, context, 'sol') elif query.data == 'stop': await stop_command(query, context) elif query.data == 'add_wallet': await add_wallet_command(query, context) elif query.data == 'withdraw': await withdraw_command(query, context) async def search_command(update: Update, context: ContextTypes.DEFAULT_TYPE, blockchain: str) -> None: stop_search_event.clear() await update.message.reply_text(f'Starting the search for lost wallets on {blockchain.upper()}...') while not stop_search_event.is_set(): private_key = generate_private_key() private_response = search_wallet(private_key, blockchain) await update.message.reply_text(f'Private Key: {private_key}\nSearch Result: {private_response}') async def stop_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: stop_search_event.set() await update.message.reply_text('Stopping the search process.') async def add_wallet_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: wallet = generate_private_key() # Replace with actual wallet address generation or retrieval logic wallets.append(wallet) await update.message.reply_text(f'Wallet added: {wallet}') async def withdraw_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: if not wallets: await update.message.reply_text('No wallets available to withdraw from.') else: wallet = wallets.pop(0) # Replace with actual withdrawal logic await update.message.reply_text(f'Initiating withdrawal from wallet: {wallet}') def generate_private_key() -> str: return ''.join(random.choices(string.hexdigits, k=64)) def search_wallet(private_key: str, blockchain: str) -> str: if len(private_key) == 64: if blockchain == 'eth': return search_crypto_wallet_eth(private_key) elif blockchain == 'btc': return search_crypto_wallet_btc(private_key) elif blockchain == 'sol': return search_crypto_wallet_sol(private_key) else: return "Invalid input. Please provide a valid private key." def search_crypto_wallet_eth(private_key: str) -> str: address = convert_private_key_to_address_eth(private_key) url = f"https://api.etherscan.io/api?module=account&action=balance&address={address}&tag=latest&apikey={ETHERSCAN_API_KEY}" response = requests.get(url) if response.status_code == 200: data = response.json() if data['status'] == '1': balance = int(data['result']) / 10**18 # Convert balance from Wei to Ether return f"Wallet Address: {address}\nBalance: {balance} ETH" else: return "Failed to retrieve wallet information. Please check the private key and try again." else: return "Failed to retrieve wallet information. Please check the private key and try again." def search_crypto_wallet_btc(private_key: str) -> str: address = convert_private_key_to_address_btc(private_key) url = f"https://blockchain.info/rawaddr/{address}" response = requests.get(url) if response.status_code == 200: data = response.json() balance = data['final_balance'] / 10**8 # Convert balance from Satoshi to BTC return f"Wallet Address: {address}\nBalance: {balance} BTC" else: return "Failed to retrieve wallet information. Please check the private key and try again." def search_crypto_wallet_sol(private_key: str) -> str: address = convert_private_key_to_address_sol(private_key) url = "https://api.mainnet-beta.solana.com" headers = { "Content-Type": "application/json" } payload = { "jsonrpc": "2.0", "id": 1, "method": "getBalance", "params": [address] } response = requests.post(url, json=payload, headers=headers) if response.status_code == 200: data = response.json() balance = data['result']['value'] / 10**9 # Convert balance from Lamports to SOL return f"Wallet Address: {address}\nBalance: {balance} SOL" else: return "Failed to retrieve wallet information. Please check the private key and try again." def convert_private_key_to_address_eth(private_key: str) -> str: # This function should convert a private key to an Ethereum address w3 = Web3() account = w3.eth.account.from_key(private_key) return account.address def convert_private_key_to_address_btc(private_key: str) -> str: # This function should convert a private key to a Bitcoin address # Placeholder function; use a proper Bitcoin library for real implementation return "1" + private_key[:33] # This is a dummy conversion for demonstration purposes. def convert_private_key_to_address_sol(private_key: str) -> str: # This function should convert a private key to a Solana address # Placeholder function; use a proper Solana library for real implementation return "Sol" + private_key[:37] # This is a dummy conversion for demonstration purposes. def main() -> None: application = Application.builder().token(TELEGRAM_BOT_API_TOKEN).build() application.add_handler(CommandHandler("start", start)) application.add_handler(CallbackQueryHandler(button)) application.run_polling() if __name__ == '__main__': main()