├── README.md └── main.py /README.md: -------------------------------------------------------------------------------- 1 | # 🔐 Multi-Chain Wallet Rescue Bot 2 | 3 | Rescue both native (ETH, BNB, etc.) and ERC-20 tokens from compromised wallets securely and automatically. This bot supports multiple EVM-compatible blockchains and periodically scans wallet balances every 30 seconds. 4 | 5 | --- 6 | 7 | ## 🌍 Supported Networks 8 | 9 | - Ethereum 10 | - BNB Smart Chain (BSC) 11 | - Polygon 12 | - Arbitrum 13 | - Optimism 14 | - Fantom 15 | - Base 16 | - Gravity 17 | - Sonic 18 | - Soneium 19 | - Zora 20 | 21 | --- 22 | 23 | ## ✨ Features 24 | 25 | - ✅ Supports multiple wallets and multiple chains 26 | - ✅ Automatically transfers native and ERC-20 tokens 27 | - ✅ Smart gas fee buffer to avoid transaction failures 28 | - ✅ Periodic scanning every 30 seconds 29 | - ✅ Logs all transactions and errors 30 | 31 | --- 32 | 33 | ## ⚙️ Installation & Configuration 34 | 35 | ### 1. Clone the Repository 36 | ```bash 37 | git clone https://github.com/xPOURY4/wallet-rescue-bot.git 38 | cd wallet-rescue-bot 39 | ``` 40 | 41 | ### 2. Install Dependencies 42 | ```bash 43 | pip install web3 44 | ``` 45 | 46 | ### 3. Configure Wallets 47 | Edit the `wallets` list inside `main.py`: 48 | ```python 49 | wallets = [ 50 | { 51 | 'private_key': 'YOUR_PRIVATE_KEY', 52 | 'from_address': Web3.to_checksum_address('0xYourWallet'), 53 | 'safe_address': Web3.to_checksum_address('0xYourSafeWallet') 54 | }, 55 | # Add more wallets if needed 56 | ] 57 | ``` 58 | 59 | ### 4. Configure Tokens 60 | Update the `tokens` list to include your desired ERC-20 tokens: 61 | ```python 62 | tokens = [ 63 | {'symbol': 'USDC', 'address': '0x...'}, 64 | {'symbol': 'DAI', 'address': '0x...'}, 65 | # Add more tokens 66 | ] 67 | ``` 68 | 69 | ### 5. Run the Bot 70 | ```bash 71 | python main.py 72 | ``` 73 | 74 | --- 75 | 76 | ## 🧠 How It Works 77 | 78 | - ⛽ Scans ERC-20 token balances and transfers them to the safe address. 79 | - 💸 Transfers the remaining native token (e.g. ETH) minus gas fees. 80 | 81 | --- 82 | 83 | ## 📝 Logging 84 | 85 | All activity is saved to `log.txt`, including successful and failed transactions. 86 | 87 | --- 88 | 89 | ## 🤝 Contributing 90 | 91 | Pull requests are welcome to improve this tool. 92 | 93 | --- 94 | 95 | ## ⚠️ Disclaimer 96 | 97 | > This tool is intended for emergency fund recovery only. Do not expose or share your private keys under any circumstances. 98 | 99 | --- 100 | 101 | > Built by [@xPOURY4](https://github.com/xPOURY4) 102 | 103 | --- 104 | 105 | # 🔐 بات نجات کیف‌پول چندشبکه‌ای 106 | 107 | این بات پایتونی برای نجات خودکار توکن‌های بومی (مثل ETH، BNB) و توکن‌های ERC-20 از کیف‌پول‌های هک‌شده در شبکه‌های مختلف EVM طراحی شده و هر ۳۰ ثانیه کیف‌پول‌ها را بررسی کرده و در صورت وجود موجودی، به آدرس امن انتقال می‌دهد. 108 | 109 | --- 110 | 111 | ## 🌍 شبکه‌های پشتیبانی‌شده 112 | 113 | - اتریوم 114 | - زنجیره هوشمند BNB 115 | - پالیگان 116 | - آربیتروم 117 | - آپتیمیسم 118 | - فانتوم 119 | - بیس (Base) 120 | - گراویتی 121 | - سونیک 122 | - سونیوم 123 | - زورا 124 | 125 | --- 126 | 127 | ## ✨ امکانات 128 | 129 | - ✅ پشتیبانی از چندین کیف‌پول و شبکه 130 | - ✅ انتقال خودکار توکن‌های بومی و ERC-20 131 | - ✅ محاسبه هوشمند کارمزد برای جلوگیری از خطا 132 | - ✅ اسکن خودکار هر ۳۰ ثانیه 133 | - ✅ ثبت همه لاگ‌ها و خطاها در فایل 134 | 135 | --- 136 | 137 | ## ⚙️ مراحل نصب و راه‌اندازی 138 | 139 | ### 1. دریافت پروژه 140 | ```bash 141 | git clone https://github.com/xPOURY4/wallet-rescue-bot.git 142 | cd wallet-rescue-bot 143 | ``` 144 | 145 | ### 2. نصب پیش‌نیازها 146 | ```bash 147 | pip install web3 148 | ``` 149 | 150 | ### 3. تنظیم کیف‌پول‌ها 151 | فایل `main.py` را باز کرده و مقادیر زیر را ویرایش کنید: 152 | ```python 153 | wallets = [ 154 | { 155 | 'private_key': 'کلید خصوصی شما', 156 | 'from_address': Web3.to_checksum_address('آدرس کیف‌پول شما'), 157 | 'safe_address': Web3.to_checksum_address('آدرس کیف‌پول امن شما') 158 | }, 159 | # می‌توانید کیف‌پول‌های بیشتری اضافه کنید 160 | ] 161 | ``` 162 | 163 | ### 4. تنظیم توکن‌ها 164 | در همان فایل، لیست `tokens` را با توکن‌های مورد نظر به‌روزرسانی کنید: 165 | ```python 166 | tokens = [ 167 | {'symbol': 'USDC', 'address': '0x...'}, 168 | {'symbol': 'DAI', 'address': '0x...'}, 169 | # توکن‌های بیشتر اضافه کنید 170 | ] 171 | ``` 172 | 173 | ### 5. اجرای بات 174 | ```bash 175 | python main.py 176 | ``` 177 | 178 | --- 179 | 180 | ## 🧠 نحوه عملکرد 181 | 182 | - ابتدا همه توکن‌های ERC-20 موجود را به آدرس امن منتقل می‌کند. 183 | - سپس باقیمانده توکن گس (مثلاً ETH یا BNB) را منهای کارمزد انتقال می‌دهد. 184 | 185 | --- 186 | 187 | ## 📝 ثبت لاگ 188 | 189 | همه فعالیت‌ها، از جمله موفق یا ناموفق، در فایل `log.txt` ذخیره می‌شوند. 190 | 191 | --- 192 | 193 | ## 🤝 مشارکت 194 | 195 | برای ارتقاء این پروژه، Pull Request ارسال کنید 🙌 196 | 197 | --- 198 | 199 | ## ⚠️ هشدار امنیتی 200 | 201 | > این ابزار فقط برای مواقع اضطراری طراحی شده است. لطفاً کلید خصوصی خود را به‌هیچ‌وجه منتشر نکنید یا در اختیار دیگران قرار ندهید. 202 | 203 | --- 204 | 205 | > توسعه داده‌شده توسط [@xPOURY4](https://github.com/xPOURY4) ❤️ 206 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import time 2 | from datetime import datetime 3 | from web3 import Web3 4 | from web3.middleware import geth_poa_middleware 5 | import json 6 | 7 | # Supported EVM-compatible chains 8 | chains = { 9 | 'ethereum': {'rpc': 'https://ethereum-rpc.publicnode.com', 'chain_id': 1}, 10 | 'arbitrum': {'rpc': 'https://arb1.arbitrum.io/rpc', 'chain_id': 42161}, 11 | 'optimism': {'rpc': 'https://mainnet.optimism.io', 'chain_id': 10}, 12 | 'base': {'rpc': 'https://mainnet.base.org', 'chain_id': 8453}, 13 | 'bsc': {'rpc': 'https://bsc-dataseed1.binance.org/', 'chain_id': 56}, 14 | 'polygon': {'rpc': 'https://polygon-rpc.com/', 'chain_id': 137}, 15 | 'fantom': {'rpc': 'https://rpcapi.fantom.network', 'chain_id': 250}, 16 | 'gravity': {'rpc': 'https://rpc.gravity.xyz', 'chain_id': 1625}, 17 | 'sonic': {'rpc': 'https://sonic.api.onfinality.io/public', 'chain_id': 146}, 18 | 'soneium': {'rpc': 'https://soneium.drpc.org', 'chain_id': 1868}, 19 | 'zora': {'rpc': 'https://rpc.zora.energy', 'chain_id': 7777777} 20 | } 21 | 22 | # List of tokens to rescue 23 | ERC20_ABI = json.loads('[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"type":"function"}]') 24 | 25 | tokens = [ 26 | # Ethereum 27 | {'symbol': 'USDC', 'address': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48'}, 28 | {'symbol': 'DAI', 'address': '0x6B175474E89094C44Da98b954EedeAC495271d0F'}, 29 | {'symbol': 'UNI', 'address': '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'}, 30 | # BSC 31 | {'symbol': 'BUSD', 'address': '0xe9e7cea3dedca5984780bafc599bd69add087d56'}, 32 | {'symbol': 'CAKE', 'address': '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82'}, 33 | # Polygon 34 | {'symbol': 'WMATIC', 'address': '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270'}, 35 | {'symbol': 'QUICK', 'address': '0x831753dd7087cac61ab5644b308642cc1c33dc13'}, 36 | # Arbitrum 37 | {'symbol': 'ARB', 'address': '0x912CE59144191C1204E64559FE8253a0e49E6548'}, 38 | # Optimism 39 | {'symbol': 'OP', 'address': '0x4200000000000000000000000000000000000042'}, 40 | # Fantom 41 | {'symbol': 'FTM', 'address': '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83'} 42 | ] 43 | 44 | # Wallets 45 | wallets = [ 46 | { 47 | 'private_key': 'YOUR_PRIVATE_KEY_1', 48 | 'from_address': Web3.to_checksum_address('0xYourWalletAddress1'), 49 | 'safe_address': Web3.to_checksum_address('0xYourSafeWalletAddress1') 50 | }, 51 | { 52 | 'private_key': 'YOUR_PRIVATE_KEY_2', 53 | 'from_address': Web3.to_checksum_address('0xYourWalletAddress2'), 54 | 'safe_address': Web3.to_checksum_address('0xYourSafeWalletAddress2') 55 | } 56 | # Add more wallets as needed 57 | ] 58 | 59 | def log(msg): 60 | with open("log.txt", "a") as f: 61 | f.write(f"{datetime.now().isoformat()} | {msg}\n") 62 | print(msg) 63 | 64 | def rescue_tokens(w3, wallet, safe_address, nonce): 65 | for token in tokens: 66 | try: 67 | token_address = Web3.to_checksum_address(token['address']) 68 | contract = w3.eth.contract(address=token_address, abi=ERC20_ABI) 69 | balance = contract.functions.balanceOf(wallet['from_address']).call() 70 | if balance > 0: 71 | gas_price = w3.eth.gas_price 72 | tx = contract.functions.transfer(safe_address, balance).build_transaction({ 73 | 'from': wallet['from_address'], 74 | 'nonce': nonce, 75 | 'gas': 100000, 76 | 'gasPrice': gas_price, 77 | 'chainId': w3.eth.chain_id 78 | }) 79 | signed_tx = w3.eth.account.sign_transaction(tx, wallet['private_key']) 80 | tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction) 81 | log(f"[TOKEN:{token['symbol']}] Sent from {wallet['from_address']} to {safe_address} -> {tx_hash.hex()}") 82 | nonce += 1 83 | except Exception as e: 84 | log(f"[TOKEN:{token['symbol']}] Error for {wallet['from_address']}: {str(e)}") 85 | return nonce 86 | 87 | def scan_all_wallets(): 88 | for wallet in wallets: 89 | for name, chain in chains.items(): 90 | try: 91 | w3 = Web3(Web3.HTTPProvider(chain['rpc'])) 92 | w3.middleware_onion.inject(geth_poa_middleware, layer=0) 93 | if not w3.is_connected(): 94 | log(f"[{name.upper()}] RPC FAILED.") 95 | continue 96 | 97 | balance = w3.eth.get_balance(wallet['from_address']) 98 | log(f"[{name.upper()}] [{wallet['from_address']}] Balance: {w3.from_wei(balance, 'ether'):.18f}") 99 | 100 | nonce = w3.eth.get_transaction_count(wallet['from_address']) 101 | nonce = rescue_tokens(w3, wallet, wallet['safe_address'], nonce) 102 | 103 | network_gas_price = w3.eth.gas_price 104 | max_gas_price = w3.to_wei('50', 'gwei') 105 | gas_price = min(network_gas_price, max_gas_price) 106 | gas_limit = 21000 107 | fee = gas_price * gas_limit 108 | 109 | if balance <= fee: 110 | log(f"[{name.upper()}] Not enough to cover gas fee.") 111 | continue 112 | 113 | buffer = int(fee * 0.01) 114 | transferable_value = balance - fee - buffer 115 | 116 | if transferable_value <= 0: 117 | log(f"[{name.upper()}] Transferable value too small after buffer.") 118 | continue 119 | 120 | tx = { 121 | 'nonce': nonce, 122 | 'to': wallet['safe_address'], 123 | 'value': transferable_value, 124 | 'gas': gas_limit, 125 | 'gasPrice': gas_price, 126 | 'chainId': chain['chain_id'] 127 | } 128 | 129 | signed_tx = w3.eth.account.sign_transaction(tx, wallet['private_key']) 130 | tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction) 131 | log(f"[{name.upper()}] Native TX SENT -> {tx_hash.hex()}") 132 | 133 | except Exception as e: 134 | log(f"[{name.upper()}] [{wallet['from_address']}] Error: {str(e)}") 135 | 136 | while True: 137 | scan_all_wallets() 138 | time.sleep(30) 139 | --------------------------------------------------------------------------------