├── requirements.txt ├── proxy.txt ├── accounts.json ├── README.md ├── bot.py └── setup.py /requirements.txt: -------------------------------------------------------------------------------- 1 | curl-cffi==0.7.1 2 | colorama==0.4.6 3 | pytz==2024.1 -------------------------------------------------------------------------------- /proxy.txt: -------------------------------------------------------------------------------- 1 | ip:port # Default Protcol HTTP. 2 | protocol://ip:port 3 | protocol://user:pass@ip:port -------------------------------------------------------------------------------- /accounts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Email": "your_email_address_1", 4 | "Password": "your_password_1" 5 | }, 6 | { 7 | "Email": "your_email_address_2", 8 | "Password": "your_password_2" 9 | } 10 | ] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exeos BOT 2 | Exeos BOT 3 | 4 | - Register Here : [Exeos](https://app.exeos.network?referralCode=REFZ26PQGAF) 5 | - Use Code `REFZ26PQGAF` 6 | 7 | ## Features 8 | 9 | - Auto Get Account Information 10 | - Auto Run With [Free Proxyscrape](https://proxyscrape.com/free-proxy-list) Proxy - `Choose 1` 11 | - Auto Run With Private Proxy - `Choose 2` 12 | - Auto Run Without Proxy - `Choose 3` 13 | - Auto Rotate Invalid Proxies - `y` or `n` 14 | - Auto Register or Use Exiting Node Ids 15 | - Auto Connect Nodes & Maintain Liveness 16 | - Multi Accounts With Threads 17 | 18 | ## Requiremnets 19 | 20 | - Make sure you have Python3.9 or higher installed and pip. 21 | 22 | ## Instalation 23 | 24 | 1. **Clone The Repositories:** 25 | ```bash 26 | git clone https://github.com/vonssy/Exeos-BOT.git 27 | ``` 28 | ```bash 29 | cd Exeos-BOT 30 | ``` 31 | 32 | 2. **Install Requirements:** 33 | ```bash 34 | pip install -r requirements.txt #or pip3 install -r requirements.txt 35 | ``` 36 | 37 | ## Configuration 38 | 39 | - **accounts.json:** You will find the file `accounts.json` inside the project directory. Make sure `accounts.json` contains data that matches the format expected by the script. Here are examples of file formats: 40 | ```json 41 | [ 42 | { 43 | "Email": "your_email_address_1", 44 | "Password": "your_password_1" 45 | }, 46 | { 47 | "Email": "your_email_address_2", 48 | "Password": "your_password_2" 49 | } 50 | ] 51 | ``` 52 | 53 | - **proxy.txt:** You will find the file `proxy.txt` inside the project directory. Make sure `proxy.txt` contains data that matches the format expected by the script. Here are examples of file formats: 54 | ```bash 55 | ip:port # Default Protcol HTTP. 56 | protocol://ip:port 57 | protocol://user:pass@ip:port 58 | ``` 59 | 60 | ## Setup 61 | 62 | ```bash 63 | python setup.py #or python3 setup.py 64 | ``` 65 | 66 | ## Run 67 | 68 | ```bash 69 | python bot.py #or python3 bot.py 70 | ``` 71 | 72 | ## Buy Me a Coffee 73 | 74 | - **EVM:** 0xe3c9ef9a39e9eb0582e5b147026cae524338521a 75 | - **TON:** UQBEFv58DC4FUrGqinBB5PAQS7TzXSm5c1Fn6nkiet8kmehB 76 | - **SOL:** E1xkaJYmAFEj28NPHKhjbf7GcvfdjKdvXju8d8AeSunf 77 | - **SUI:** 0xa03726ecbbe00b31df6a61d7a59d02a7eedc39fe269532ceab97852a04cf3347 78 | 79 | Thank you for visiting this repository, don't forget to contribute in the form of follows and stars. 80 | If you have questions, find an issue, or have suggestions for improvement, feel free to contact me or open an *issue* in this GitHub repository. 81 | 82 | **vonssy** -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | from curl_cffi import requests 2 | from datetime import datetime 3 | from colorama import * 4 | import asyncio, random, json, os, pytz 5 | 6 | wib = pytz.timezone('Asia/Jakarta') 7 | 8 | USER_AGENT = [ 9 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36", 10 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36", 11 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.138 Safari/537.36", 12 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36", 13 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 Safari/537.36", 14 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.133 Safari/537.36", 15 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537.36", 16 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:115.0) Gecko/20100101 Firefox/115.0", 17 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:114.0) Gecko/20100101 Firefox/114.0", 18 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:113.0) Gecko/20100101 Firefox/113.0", 19 | "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0", 20 | "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:115.0) Gecko/20100101 Firefox/115.0", 21 | "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:113.0) Gecko/20100101 Firefox/113.0", 22 | "Mozilla/5.0 (X11; Arch Linux; Linux x86_64; rv:112.0) Gecko/20100101 Firefox/112.0", 23 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36 Edg/113.0.1774.35", 24 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.121 Safari/537.36 Edg/112.0.1722.64", 25 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.64 Safari/537.36 Edg/111.0.1661.54", 26 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.137 Safari/537.36 Edg/112.0.1722.68", 27 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.1 Safari/605.1.15", 28 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Safari/605.1.15", 29 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_7_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Safari/605.1.15", 30 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36 OPR/99.0.4788.77", 31 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36 OPR/98.0.4759.15", 32 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36 Brave/1.52.129", 33 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.126 Safari/537.36 Brave/1.51.110", 34 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36", 35 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36", 36 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36 Vivaldi/6.1.3035.100", 37 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.126 Safari/537.36 Vivaldi/6.0.2979.22", 38 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36", 39 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36", 40 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/114.0.5735.91 Safari/537.36" 41 | ] 42 | 43 | class Exeos: 44 | def __init__(self) -> None: 45 | self.BASE_API = "https://api.exeos.network/extension" 46 | self.HEADERS = {} 47 | self.proxies = [] 48 | self.proxy_index = 0 49 | self.account_proxies = {} 50 | self.access_tokens = {} 51 | self.ip_address = {} 52 | 53 | def clear_terminal(self): 54 | os.system('cls' if os.name == 'nt' else 'clear') 55 | 56 | def log(self, message): 57 | print( 58 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 59 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}{message}", 60 | flush=True 61 | ) 62 | 63 | def welcome(self): 64 | print( 65 | f""" 66 | {Fore.GREEN + Style.BRIGHT}Exeos {Fore.BLUE + Style.BRIGHT}Auto BOT 67 | """ 68 | f""" 69 | {Fore.GREEN + Style.BRIGHT}Rey? {Fore.YELLOW + Style.BRIGHT} 70 | """ 71 | ) 72 | 73 | def format_seconds(self, seconds): 74 | hours, remainder = divmod(seconds, 3600) 75 | minutes, seconds = divmod(remainder, 60) 76 | return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}" 77 | 78 | def load_accounts(self): 79 | filename = "nodes.json" 80 | try: 81 | if not os.path.exists(filename): 82 | self.log(f"{Fore.RED}File {filename} Not Found.{Style.RESET_ALL}") 83 | return 84 | 85 | with open(filename, 'r') as file: 86 | data = json.load(file) 87 | if isinstance(data, list): 88 | return data 89 | return [] 90 | except json.JSONDecodeError: 91 | return [] 92 | 93 | async def load_proxies(self, use_proxy_choice: int): 94 | filename = "proxy.txt" 95 | try: 96 | if use_proxy_choice == 1: 97 | response = await asyncio.to_thread(requests.get, "https://raw.githubusercontent.com/monosans/proxy-list/refs/heads/main/proxies/all.txt") 98 | response.raise_for_status() 99 | content = response.text 100 | with open(filename, 'w') as f: 101 | f.write(content) 102 | self.proxies = [line.strip() for line in content.splitlines() if line.strip()] 103 | else: 104 | if not os.path.exists(filename): 105 | self.log(f"{Fore.RED + Style.BRIGHT}File {filename} Not Found.{Style.RESET_ALL}") 106 | return 107 | with open(filename, 'r') as f: 108 | self.proxies = [line.strip() for line in f.read().splitlines() if line.strip()] 109 | 110 | if not self.proxies: 111 | self.log(f"{Fore.RED + Style.BRIGHT}No Proxies Found.{Style.RESET_ALL}") 112 | return 113 | 114 | self.log( 115 | f"{Fore.GREEN + Style.BRIGHT}Proxies Total : {Style.RESET_ALL}" 116 | f"{Fore.WHITE + Style.BRIGHT}{len(self.proxies)}{Style.RESET_ALL}" 117 | ) 118 | 119 | except Exception as e: 120 | self.log(f"{Fore.RED + Style.BRIGHT}Failed To Load Proxies: {e}{Style.RESET_ALL}") 121 | self.proxies = [] 122 | 123 | def check_proxy_schemes(self, proxies): 124 | schemes = ["http://", "https://", "socks4://", "socks5://"] 125 | if any(proxies.startswith(scheme) for scheme in schemes): 126 | return proxies 127 | return f"http://{proxies}" 128 | 129 | def get_next_proxy_for_account(self, account): 130 | if account not in self.account_proxies: 131 | if not self.proxies: 132 | return None 133 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index]) 134 | self.account_proxies[account] = proxy 135 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies) 136 | return self.account_proxies[account] 137 | 138 | def rotate_proxy_for_account(self, account): 139 | if not self.proxies: 140 | return None 141 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index]) 142 | self.account_proxies[account] = proxy 143 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies) 144 | return proxy 145 | 146 | def mask_account(self, account): 147 | if '@' in account: 148 | local, domain = account.split('@', 1) 149 | mask_account = local[:3] + '*' * 3 + local[-3:] 150 | return f"{mask_account}@{domain}" 151 | 152 | def print_message(self, account, node_id, proxy, color, message): 153 | self.log( 154 | f"{Fore.CYAN + Style.BRIGHT}[ Account: {Style.RESET_ALL}" 155 | f"{Fore.WHITE + Style.BRIGHT}{self.mask_account(account)}{Style.RESET_ALL}" 156 | f"{Fore.MAGENTA + Style.BRIGHT} - {Style.RESET_ALL}" 157 | f"{Fore.CYAN + Style.BRIGHT}Node Id:{Style.RESET_ALL}" 158 | f"{Fore.WHITE + Style.BRIGHT} {node_id} {Style.RESET_ALL}" 159 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}" 160 | f"{Fore.CYAN + Style.BRIGHT} Proxy: {Style.RESET_ALL}" 161 | f"{Fore.WHITE + Style.BRIGHT}{proxy}{Style.RESET_ALL}" 162 | f"{Fore.MAGENTA + Style.BRIGHT} - {Style.RESET_ALL}" 163 | f"{Fore.CYAN + Style.BRIGHT}Status:{Style.RESET_ALL}" 164 | f"{color + Style.BRIGHT} {message} {Style.RESET_ALL}" 165 | f"{Fore.CYAN + Style.BRIGHT}]{Style.RESET_ALL}" 166 | ) 167 | 168 | def print_question(self): 169 | while True: 170 | try: 171 | print(f"{Fore.WHITE + Style.BRIGHT}1. Run With Free Proxyscrape Proxy{Style.RESET_ALL}") 172 | print(f"{Fore.WHITE + Style.BRIGHT}2. Run With Private Proxy{Style.RESET_ALL}") 173 | print(f"{Fore.WHITE + Style.BRIGHT}3. Run Without Proxy{Style.RESET_ALL}") 174 | choose = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2/3] -> {Style.RESET_ALL}").strip()) 175 | 176 | if choose in [1, 2, 3]: 177 | proxy_type = ( 178 | "With Free Proxyscrape" if choose == 1 else 179 | "With Private" if choose == 2 else 180 | "Without" 181 | ) 182 | print(f"{Fore.GREEN + Style.BRIGHT}Run {proxy_type} Proxy Selected.{Style.RESET_ALL}") 183 | break 184 | else: 185 | print(f"{Fore.RED + Style.BRIGHT}Please enter either 1, 2 or 3.{Style.RESET_ALL}") 186 | except ValueError: 187 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number (1, 2 or 3).{Style.RESET_ALL}") 188 | 189 | rotate = False 190 | if choose in [1, 2]: 191 | while True: 192 | rotate = input(f"{Fore.BLUE + Style.BRIGHT}Rotate Invalid Proxy? [y/n] -> {Style.RESET_ALL}").strip() 193 | 194 | if rotate in ["y", "n"]: 195 | rotate = rotate == "y" 196 | break 197 | else: 198 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter 'y' or 'n'.{Style.RESET_ALL}") 199 | 200 | return choose, rotate 201 | 202 | async def check_connection(self, email: str, node_id: str, proxy=None): 203 | url = "https://api.ipify.org?format=json" 204 | proxies = {"http":proxy, "https":proxy} if proxy else None 205 | await asyncio.sleep(3) 206 | try: 207 | response = await asyncio.to_thread(requests.get, url=url, proxies=proxies, timeout=30, impersonate="chrome110", verify=False) 208 | response.raise_for_status() 209 | return response.json() 210 | except Exception as e: 211 | self.print_message(email, node_id, proxy, Fore.RED, f"Connection Not 200 OK: {Fore.YELLOW + Style.BRIGHT}{str(e)}{Style.RESET_ALL}") 212 | return None 213 | 214 | async def node_stats(self, email: str, node_id: str, proxy=None, retries=5): 215 | url = f"{self.BASE_API}/stats" 216 | data = json.dumps({"extensionId":node_id}) 217 | headers = self.HEADERS[f'{email}_{node_id}'].copy() 218 | headers["Authorization"] = f"Bearer {self.access_tokens[email]}" 219 | headers["Content-Length"] = str(len(data)) 220 | headers["Content-Type"] = "application/json" 221 | for attempt in range(retries): 222 | proxies = {"http":proxy, "https":proxy} if proxy else None 223 | await asyncio.sleep(5) 224 | try: 225 | response = await asyncio.to_thread(requests.post, url=url, headers=headers, data=data, proxies=proxies, timeout=60, impersonate="chrome110", verify=False) 226 | response.raise_for_status() 227 | return response.json() 228 | except Exception as e: 229 | if attempt < retries - 1: 230 | continue 231 | self.print_message(email, node_id, proxy, Fore.RED, f"Update Stats Failed: {Fore.YELLOW + Style.BRIGHT}{str(e)}{Style.RESET_ALL}") 232 | return None 233 | 234 | async def node_connect(self, email: str, node_id: str, proxy=None, retries=5): 235 | url = f"{self.BASE_API}/connect" 236 | data = json.dumps({"extensionId":node_id, "ip":self.ip_address[node_id]}) 237 | headers = self.HEADERS[f'{email}_{node_id}'].copy() 238 | headers["Authorization"] = f"Bearer {self.access_tokens[email]}" 239 | headers["Content-Length"] = str(len(data)) 240 | headers["Content-Type"] = "application/json" 241 | for attempt in range(retries): 242 | proxies = {"http":proxy, "https":proxy} if proxy else None 243 | await asyncio.sleep(5) 244 | try: 245 | response = await asyncio.to_thread(requests.post, url=url, headers=headers, data=data, proxies=proxies, timeout=60, impersonate="chrome110", verify=False) 246 | response.raise_for_status() 247 | return response.json() 248 | except Exception as e: 249 | if attempt < retries - 1: 250 | continue 251 | self.print_message(email, node_id, proxy, Fore.RED, f"Node Not Connected: {Fore.YELLOW + Style.BRIGHT}{str(e)}{Style.RESET_ALL}") 252 | return None 253 | 254 | async def node_liveness(self, email: str, node_id: str, proxy=None, retries=5): 255 | url = f"{self.BASE_API}/liveness" 256 | data = json.dumps({"extensionId":node_id}) 257 | headers = self.HEADERS[f'{email}_{node_id}'].copy() 258 | headers["Authorization"] = f"Bearer {self.access_tokens[email]}" 259 | headers["Content-Length"] = str(len(data)) 260 | headers["Content-Type"] = "application/json" 261 | for attempt in range(retries): 262 | proxies = {"http":proxy, "https":proxy} if proxy else None 263 | await asyncio.sleep(5) 264 | try: 265 | response = await asyncio.to_thread(requests.post, url=url, headers=headers, data=data, proxies=proxies, timeout=60, impersonate="chrome110", verify=False) 266 | response.raise_for_status() 267 | return response.json() 268 | except Exception as e: 269 | if attempt < retries - 1: 270 | continue 271 | self.print_message(email, node_id, proxy, Fore.RED, f"Maintain Liveness Failed: {Fore.YELLOW + Style.BRIGHT}{str(e)}{Style.RESET_ALL}") 272 | return None 273 | 274 | async def process_check_connection(self, email: str, node_id: str, use_proxy: bool, rotate_proxy: bool): 275 | while True: 276 | proxy = self.get_next_proxy_for_account(node_id) if use_proxy else None 277 | 278 | is_valid = await self.check_connection(email, node_id, proxy) 279 | if is_valid: 280 | self.ip_address[node_id] = is_valid["ip"] 281 | return True 282 | 283 | if rotate_proxy: 284 | proxy = self.rotate_proxy_for_account(node_id) 285 | 286 | async def process_node_stats(self, email: str, node_id: str, use_proxy: bool, rotate_proxy: bool): 287 | while True: 288 | is_valid = await self.process_check_connection(email, node_id, use_proxy, rotate_proxy) 289 | if is_valid: 290 | proxy = self.get_next_proxy_for_account(node_id) if use_proxy else None 291 | 292 | update = await self.node_stats(email, node_id, proxy) 293 | if update: 294 | self.print_message(email, node_id, proxy, Fore.GREEN, "Stats Updated Successfully") 295 | return True 296 | 297 | async def process_node_connect(self, email: str, node_id: str, use_proxy: bool, rotate_proxy: bool): 298 | while True: 299 | update = await self.process_node_stats(email, node_id, use_proxy, rotate_proxy) 300 | if update: 301 | proxy = self.get_next_proxy_for_account(node_id) if use_proxy else None 302 | 303 | connect = await self.node_connect(email, node_id, proxy) 304 | if connect and connect.get("status") == "success": 305 | uptime_total = connect.get("data", {}).get("uptimeTotal") 306 | 307 | self.print_message(email, node_id, proxy, Fore.GREEN, "Node Is Connected " 308 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}" 309 | f"{Fore.CYAN + Style.BRIGHT} Uptime Total: {Style.RESET_ALL}" 310 | f"{Fore.WHITE + Style.BRIGHT}{uptime_total}{Style.RESET_ALL}" 311 | ) 312 | return True 313 | 314 | async def process_node_liveness(self, email: str, node_id: str, use_proxy: bool, rotate_proxy: bool): 315 | while True: 316 | print( 317 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 318 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}" 319 | f"{Fore.BLUE + Style.BRIGHT}Wait For a Hours For Maintaining Liveness...{Style.RESET_ALL}", 320 | end="\r", 321 | flush=True 322 | ) 323 | await asyncio.sleep(1 * 60 * 60) 324 | 325 | proxy = self.get_next_proxy_for_account(node_id) if use_proxy else None 326 | 327 | liveness = await self.node_liveness(email, node_id, proxy) 328 | if liveness and liveness.get("status") == "success": 329 | earn_today = liveness.get("updatedData", {}).get("nodeExtension", {}).get("todayRewards", 0) 330 | earn_total = liveness.get("updatedData", {}).get("nodeExtension", {}).get("totalRewards", 0) 331 | uptime_total = liveness.get("updatedData", {}).get("nodeExtension", {}).get("uptimeTotal", 0) 332 | 333 | self.print_message(email, node_id, proxy, Fore.GREEN, "Maintain Liveness Success" 334 | f"{Fore.MAGENTA + Style.BRIGHT} - {Style.RESET_ALL}" 335 | f"{Fore.CYAN + Style.BRIGHT}Earning:{Style.RESET_ALL}" 336 | f"{Fore.WHITE + Style.BRIGHT} Today {earn_today} PTS{Style.RESET_ALL}" 337 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}" 338 | f"{Fore.WHITE + Style.BRIGHT} Total {earn_total} PTS {Style.RESET_ALL}" 339 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}" 340 | f"{Fore.CYAN + Style.BRIGHT} Uptime Total: {Style.RESET_ALL}" 341 | f"{Fore.WHITE + Style.BRIGHT}{uptime_total}{Style.RESET_ALL}" 342 | ) 343 | 344 | elif liveness and liveness.get("status") == "fail": 345 | await self.process_node_connect(email, node_id, use_proxy, rotate_proxy) 346 | continue 347 | 348 | async def process_accounts(self, email: str, nodes: list, use_proxy: bool, rotate_proxy: bool): 349 | tasks = [] 350 | 351 | async def process_node_session(node): 352 | node_id = node.get("nodeId") 353 | 354 | if node_id: 355 | self.HEADERS[f'{email}_{node_id}'] = { 356 | "Accept": "application/json, text/plain, */*", 357 | "Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7", 358 | "Origin": "chrome-extension://ijapofapbjjfegefdmhhgijgkillnogl", 359 | "Sec-Fetch-Dest": "empty", 360 | "Sec-Fetch-Mode": "cors", 361 | "Sec-Fetch-Site": "none", 362 | "Sec-Fetch-Storage-Access": "active", 363 | "User-Agent": random.choice(USER_AGENT) 364 | } 365 | 366 | connected = await self.process_node_connect(email, node_id, use_proxy, rotate_proxy) 367 | if connected: 368 | tasks.append(asyncio.create_task(self.process_node_liveness(email, node_id, use_proxy, rotate_proxy))) 369 | 370 | await asyncio.gather(*[process_node_session(node) for node in nodes if node]) 371 | 372 | await asyncio.gather(*tasks) 373 | 374 | async def main(self): 375 | try: 376 | accounts = self.load_accounts() 377 | if not accounts: 378 | self.log(f"{Fore.RED+Style.BRIGHT}No Accounts Loaded.{Style.RESET_ALL}") 379 | return 380 | 381 | proxy_choice, rotate_proxy = self.print_question() 382 | 383 | use_proxy = False 384 | if proxy_choice in [1, 2]: 385 | use_proxy = True 386 | 387 | 388 | self.clear_terminal() 389 | self.welcome() 390 | self.log( 391 | f"{Fore.GREEN + Style.BRIGHT}Account's Total: {Style.RESET_ALL}" 392 | f"{Fore.WHITE + Style.BRIGHT}{len(accounts)}{Style.RESET_ALL}" 393 | ) 394 | 395 | if use_proxy: 396 | await self.load_proxies(proxy_choice) 397 | 398 | self.log(f"{Fore.CYAN + Style.BRIGHT}={Style.RESET_ALL}"*75) 399 | 400 | tasks = [] 401 | for idx, account in enumerate(accounts, start=1): 402 | if account: 403 | email = account["Email"] 404 | token = account["Token"] 405 | nodes = account["Nodes"] 406 | 407 | if not "@" in email or not token: 408 | self.log( 409 | f"{Fore.CYAN + Style.BRIGHT}[ Account: {Style.RESET_ALL}" 410 | f"{Fore.WHITE + Style.BRIGHT}{self.mask_account(email)}{Style.RESET_ALL}" 411 | f"{Fore.MAGENTA + Style.BRIGHT} - {Style.RESET_ALL}" 412 | f"{Fore.CYAN + Style.BRIGHT}Status:{Style.RESET_ALL}" 413 | f"{Fore.RED + Style.BRIGHT} Invalid Nodes Data {Style.RESET_ALL}" 414 | f"{Fore.CYAN + Style.BRIGHT}]{Style.RESET_ALL}" 415 | ) 416 | continue 417 | 418 | if not nodes or isinstance(nodes, list) and len(nodes) == 0: 419 | self.log( 420 | f"{Fore.CYAN + Style.BRIGHT}[ Account: {Style.RESET_ALL}" 421 | f"{Fore.WHITE + Style.BRIGHT}{self.mask_account(email)}{Style.RESET_ALL}" 422 | f"{Fore.MAGENTA + Style.BRIGHT} - {Style.RESET_ALL}" 423 | f"{Fore.CYAN + Style.BRIGHT}Status:{Style.RESET_ALL}" 424 | f"{Fore.RED + Style.BRIGHT} No Nodes Loaded {Style.RESET_ALL}" 425 | f"{Fore.CYAN + Style.BRIGHT}]{Style.RESET_ALL}" 426 | ) 427 | continue 428 | 429 | self.access_tokens[email] = token 430 | 431 | tasks.append(asyncio.create_task(self.process_accounts(email, nodes, proxy_choice, rotate_proxy))) 432 | 433 | await asyncio.gather(*tasks) 434 | 435 | except Exception as e: 436 | self.log(f"{Fore.RED+Style.BRIGHT}Error: {e}{Style.RESET_ALL}") 437 | raise e 438 | 439 | if __name__ == "__main__": 440 | try: 441 | bot = Exeos() 442 | asyncio.run(bot.main()) 443 | except KeyboardInterrupt: 444 | print( 445 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 446 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}" 447 | f"{Fore.RED + Style.BRIGHT}[ EXIT ] Exeos - BOT{Style.RESET_ALL} " 448 | ) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from curl_cffi import requests 2 | from datetime import datetime 3 | from colorama import * 4 | import asyncio, random, json, uuid, os, pytz 5 | 6 | wib = pytz.timezone('Asia/Jakarta') 7 | 8 | USER_AGENT = [ 9 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36", 10 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36", 11 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.138 Safari/537.36", 12 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36", 13 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 Safari/537.36", 14 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.133 Safari/537.36", 15 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537.36", 16 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:115.0) Gecko/20100101 Firefox/115.0", 17 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:114.0) Gecko/20100101 Firefox/114.0", 18 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:113.0) Gecko/20100101 Firefox/113.0", 19 | "Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0", 20 | "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:115.0) Gecko/20100101 Firefox/115.0", 21 | "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:113.0) Gecko/20100101 Firefox/113.0", 22 | "Mozilla/5.0 (X11; Arch Linux; Linux x86_64; rv:112.0) Gecko/20100101 Firefox/112.0", 23 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36 Edg/113.0.1774.35", 24 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.121 Safari/537.36 Edg/112.0.1722.64", 25 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.64 Safari/537.36 Edg/111.0.1661.54", 26 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.137 Safari/537.36 Edg/112.0.1722.68", 27 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.1 Safari/605.1.15", 28 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Safari/605.1.15", 29 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_7_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Safari/605.1.15", 30 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36 OPR/99.0.4788.77", 31 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36 OPR/98.0.4759.15", 32 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36 Brave/1.52.129", 33 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.126 Safari/537.36 Brave/1.51.110", 34 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36", 35 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.127 Safari/537.36", 36 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36 Vivaldi/6.1.3035.100", 37 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.126 Safari/537.36 Vivaldi/6.0.2979.22", 38 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36", 39 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36", 40 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/114.0.5735.91 Safari/537.36" 41 | ] 42 | 43 | class Exeos: 44 | def __init__(self) -> None: 45 | self.BASE_API = "https://api.exeos.network" 46 | self.REF_CODE = "REFZ26PQGAF" # U can change it with yours 47 | self.HEADERS = {} 48 | self.proxies = [] 49 | self.proxy_index = 0 50 | self.account_proxies = {} 51 | self.access_tokens = {} 52 | self.user_nodes = [] 53 | self.node_datas = [] 54 | self.nodes_count = 0 55 | 56 | def clear_terminal(self): 57 | os.system('cls' if os.name == 'nt' else 'clear') 58 | 59 | def log(self, message): 60 | print( 61 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 62 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}{message}", 63 | flush=True 64 | ) 65 | 66 | def welcome(self): 67 | print( 68 | f""" 69 | {Fore.GREEN + Style.BRIGHT}Exeos {Fore.BLUE + Style.BRIGHT}Auto BOT 70 | """ 71 | f""" 72 | {Fore.GREEN + Style.BRIGHT}Rey? {Fore.YELLOW + Style.BRIGHT} 73 | """ 74 | ) 75 | 76 | def format_seconds(self, seconds): 77 | hours, remainder = divmod(seconds, 3600) 78 | minutes, seconds = divmod(remainder, 60) 79 | return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}" 80 | 81 | def load_accounts(self): 82 | filename = "accounts.json" 83 | try: 84 | if not os.path.exists(filename): 85 | self.log(f"{Fore.RED}File {filename} Not Found.{Style.RESET_ALL}") 86 | return 87 | 88 | with open(filename, 'r') as file: 89 | data = json.load(file) 90 | if isinstance(data, list): 91 | return data 92 | return [] 93 | except json.JSONDecodeError: 94 | return [] 95 | 96 | def save_nodes(self, new_nodes): 97 | filename = "nodes.json" 98 | try: 99 | if not os.path.exists(filename): 100 | with open(filename, 'w') as file: 101 | json.dump([], file, indent=4) 102 | 103 | if os.path.getsize(filename) == 0: 104 | existing_nodes = [] 105 | else: 106 | with open(filename, 'r') as file: 107 | existing_nodes = json.load(file) 108 | 109 | for new_node in new_nodes: 110 | email = new_node["Email"] 111 | token = new_node["Token"] 112 | new_node_list = new_node.get("Nodes", []) 113 | 114 | found = False 115 | for existing_node in existing_nodes: 116 | if existing_node["Email"] == email: 117 | found = True 118 | 119 | existing_node["Token"] = token 120 | 121 | if not existing_node.get("Nodes"): 122 | existing_node["Nodes"] = new_node_list 123 | else: 124 | existing_node_ids = {node["nodeId"] for node in existing_node["Nodes"]} 125 | for node in new_node_list: 126 | if node["nodeId"] not in existing_node_ids: 127 | existing_node["Nodes"].append(node) 128 | break 129 | 130 | if not found: 131 | existing_nodes.append(new_node) 132 | 133 | with open(filename, 'w') as file: 134 | json.dump(existing_nodes, file, indent=4) 135 | 136 | self.log(f"{Fore.GREEN + Style.BRIGHT}Nodes Data Have Been Saved Successfully{Style.RESET_ALL}") 137 | except Exception as e: 138 | self.log( 139 | f"{Fore.RED+Style.BRIGHT}Save Nodes Failed:{Style.RESET_ALL}" 140 | f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 141 | ) 142 | return [] 143 | 144 | async def load_proxies(self, use_proxy_choice: int): 145 | filename = "proxy.txt" 146 | try: 147 | if use_proxy_choice == 1: 148 | response = await asyncio.to_thread(requests.get, "https://raw.githubusercontent.com/monosans/proxy-list/refs/heads/main/proxies/all.txt") 149 | response.raise_for_status() 150 | content = response.text 151 | with open(filename, 'w') as f: 152 | f.write(content) 153 | self.proxies = [line.strip() for line in content.splitlines() if line.strip()] 154 | else: 155 | if not os.path.exists(filename): 156 | self.log(f"{Fore.RED + Style.BRIGHT}File {filename} Not Found.{Style.RESET_ALL}") 157 | return 158 | with open(filename, 'r') as f: 159 | self.proxies = [line.strip() for line in f.read().splitlines() if line.strip()] 160 | 161 | if not self.proxies: 162 | self.log(f"{Fore.RED + Style.BRIGHT}No Proxies Found.{Style.RESET_ALL}") 163 | return 164 | 165 | self.log( 166 | f"{Fore.GREEN + Style.BRIGHT}Proxies Total : {Style.RESET_ALL}" 167 | f"{Fore.WHITE + Style.BRIGHT}{len(self.proxies)}{Style.RESET_ALL}" 168 | ) 169 | 170 | except Exception as e: 171 | self.log(f"{Fore.RED + Style.BRIGHT}Failed To Load Proxies: {e}{Style.RESET_ALL}") 172 | self.proxies = [] 173 | 174 | def check_proxy_schemes(self, proxies): 175 | schemes = ["http://", "https://", "socks4://", "socks5://"] 176 | if any(proxies.startswith(scheme) for scheme in schemes): 177 | return proxies 178 | return f"http://{proxies}" 179 | 180 | def get_next_proxy_for_account(self, account): 181 | if account not in self.account_proxies: 182 | if not self.proxies: 183 | return None 184 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index]) 185 | self.account_proxies[account] = proxy 186 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies) 187 | return self.account_proxies[account] 188 | 189 | def rotate_proxy_for_account(self, account): 190 | if not self.proxies: 191 | return None 192 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index]) 193 | self.account_proxies[account] = proxy 194 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies) 195 | return proxy 196 | 197 | def generate_node_id(self): 198 | node_id = str(uuid.uuid4()) 199 | return f"node:ext:{node_id}" 200 | 201 | def mask_account(self, account): 202 | if '@' in account: 203 | local, domain = account.split('@', 1) 204 | mask_account = local[:3] + '*' * 3 + local[-3:] 205 | return f"{mask_account}@{domain}" 206 | 207 | def print_question(self): 208 | while True: 209 | try: 210 | print(f"{Fore.WHITE + Style.BRIGHT}1. Create New Nodes{Style.RESET_ALL}") 211 | print(f"{Fore.WHITE + Style.BRIGHT}2. Retrieve Exiting Nodes{Style.RESET_ALL}") 212 | option = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2] -> {Style.RESET_ALL}").strip()) 213 | 214 | if option in [1, 2]: 215 | option_type = "Create New" if option == 1 else "Retrieve Exiting" 216 | print(f"{Fore.GREEN + Style.BRIGHT}{option_type} Nodes Selected.{Style.RESET_ALL}") 217 | break 218 | else: 219 | print(f"{Fore.RED+Style.BRIGHT}Please enter either 1 or 2.{Style.RESET_ALL}") 220 | except ValueError: 221 | print(f"{Fore.RED+Style.BRIGHT}Invalid input. Enter a number (1 or 2).{Style.RESET_ALL}") 222 | 223 | if option == 1: 224 | while True: 225 | try: 226 | count = int(input(f"{Fore.YELLOW + Style.BRIGHT}How Many Nodes Do You Want to Create For Each Account? -> {Style.RESET_ALL}").strip()) 227 | if count > 0: 228 | self.nodes_count = count 229 | break 230 | else: 231 | print(f"{Fore.RED+Style.BRIGHT}Please enter a positive number.{Style.RESET_ALL}") 232 | except ValueError: 233 | print(f"{Fore.RED+Style.BRIGHT}Invalid input. Enter a number.{Style.RESET_ALL}") 234 | 235 | while True: 236 | try: 237 | print(f"{Fore.WHITE + Style.BRIGHT}1. Run With Free Proxyscrape Proxy{Style.RESET_ALL}") 238 | print(f"{Fore.WHITE + Style.BRIGHT}2. Run With Private Proxy{Style.RESET_ALL}") 239 | print(f"{Fore.WHITE + Style.BRIGHT}3. Run Without Proxy{Style.RESET_ALL}") 240 | choose = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2/3] -> {Style.RESET_ALL}").strip()) 241 | 242 | if choose in [1, 2, 3]: 243 | proxy_type = ( 244 | "With Free Proxyscrape" if choose == 1 else 245 | "With Private" if choose == 2 else 246 | "Without" 247 | ) 248 | print(f"{Fore.GREEN + Style.BRIGHT}Run {proxy_type} Proxy Selected.{Style.RESET_ALL}") 249 | break 250 | else: 251 | print(f"{Fore.RED + Style.BRIGHT}Please enter either 1, 2 or 3.{Style.RESET_ALL}") 252 | except ValueError: 253 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number (1, 2 or 3).{Style.RESET_ALL}") 254 | 255 | rotate = False 256 | if choose in [1, 2]: 257 | while True: 258 | rotate = input(f"{Fore.BLUE + Style.BRIGHT}Rotate Invalid Proxy? [y/n] -> {Style.RESET_ALL}").strip() 259 | 260 | if rotate in ["y", "n"]: 261 | rotate = rotate == "y" 262 | break 263 | else: 264 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter 'y' or 'n'.{Style.RESET_ALL}") 265 | 266 | return option, choose, rotate 267 | 268 | async def check_connection(self, proxy=None): 269 | url = "https://api.ipify.org?format=json" 270 | proxies = {"http":proxy, "https":proxy} if proxy else None 271 | try: 272 | response = await asyncio.to_thread(requests.get, url=url, proxies=proxies, timeout=30, impersonate="chrome110", verify=False) 273 | response.raise_for_status() 274 | return True 275 | except Exception as e: 276 | self.log( 277 | f"{Fore.CYAN + Style.BRIGHT}Status :{Style.RESET_ALL}" 278 | f"{Fore.RED + Style.BRIGHT} Connection Not 200 OK {Style.RESET_ALL}" 279 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}" 280 | f"{Fore.YELLOW + Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 281 | ) 282 | return None 283 | 284 | async def email_login(self, email: str, password: str, proxy=None, retries=5): 285 | url = f"{self.BASE_API}/auth/web/email/login" 286 | data = json.dumps({"email":email, "password":password, "referralCode":self.REF_CODE}) 287 | headers = self.HEADERS[email].copy() 288 | headers["Content-Length"] = str(len(data)) 289 | headers["Content-Type"] = "application/json" 290 | for attempt in range(retries): 291 | proxies = {"http":proxy, "https":proxy} if proxy else None 292 | try: 293 | response = await asyncio.to_thread(requests.post, url=url, headers=headers, data=data, proxies=proxies, timeout=60, impersonate="chrome110", verify=False) 294 | response.raise_for_status() 295 | return response.json() 296 | except Exception as e: 297 | if attempt < retries - 1: 298 | await asyncio.sleep(5) 299 | continue 300 | self.log( 301 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}" 302 | f"{Fore.RED+Style.BRIGHT} Login Failed {Style.RESET_ALL}" 303 | f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}" 304 | f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 305 | ) 306 | return None 307 | 308 | async def user_data(self, email: str, proxy=None, retries=5): 309 | url = f"{self.BASE_API}/account/web/me" 310 | headers = self.HEADERS[email].copy() 311 | headers["Authorization"] = f"Bearer {self.access_tokens[email]}" 312 | for attempt in range(retries): 313 | proxies = {"http":proxy, "https":proxy} if proxy else None 314 | try: 315 | response = await asyncio.to_thread(requests.get, url=url, headers=headers, proxies=proxies, timeout=60, impersonate="chrome110", verify=False) 316 | response.raise_for_status() 317 | return response.json() 318 | except Exception as e: 319 | if attempt < retries - 1: 320 | await asyncio.sleep(5) 321 | continue 322 | self.log( 323 | f"{Fore.CYAN+Style.BRIGHT}Error :{Style.RESET_ALL}" 324 | f"{Fore.RED+Style.BRIGHT} GET Exiting Node Ids Failed {Style.RESET_ALL}" 325 | f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}" 326 | f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 327 | ) 328 | return None 329 | 330 | async def process_check_connection(self, email: str, use_proxy: bool, rotate_proxy: bool): 331 | while True: 332 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None 333 | self.log( 334 | f"{Fore.CYAN+Style.BRIGHT}Proxy :{Style.RESET_ALL}" 335 | f"{Fore.WHITE+Style.BRIGHT} {proxy} {Style.RESET_ALL}" 336 | ) 337 | 338 | is_valid = await self.check_connection(proxy) 339 | if is_valid: 340 | return True 341 | 342 | if rotate_proxy: 343 | proxy = self.rotate_proxy_for_account(email) 344 | await asyncio.sleep(1) 345 | continue 346 | 347 | return False 348 | 349 | async def process_user_login(self, email: str, password: str, use_proxy: bool, rotate_proxy: bool): 350 | is_valid = await self.process_check_connection(email, use_proxy, rotate_proxy) 351 | if is_valid: 352 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None 353 | 354 | login = await self.email_login(email, password, proxy) 355 | if login and login.get("status") == "success": 356 | self.access_tokens[email] = login["data"]["token"] 357 | 358 | self.log( 359 | f"{Fore.CYAN + Style.BRIGHT}Status :{Style.RESET_ALL}" 360 | f"{Fore.GREEN + Style.BRIGHT} Login Success {Style.RESET_ALL}" 361 | ) 362 | return True 363 | 364 | elif login and login.get("status") == "fail": 365 | err_msg = login.get("error", "Unknown Error") 366 | self.log( 367 | f"{Fore.CYAN + Style.BRIGHT}Status :{Style.RESET_ALL}" 368 | f"{Fore.RED + Style.BRIGHT} Login Failed {Style.RESET_ALL}" 369 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}" 370 | f"{Fore.YELLOW + Style.BRIGHT} {err_msg} {Style.RESET_ALL}" 371 | ) 372 | 373 | return False 374 | 375 | async def process_get_exiting_nodes(self, email: str, use_proxy: bool): 376 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None 377 | 378 | user = await self.user_data(email, proxy) 379 | if user and user.get("status") == "success": 380 | exciting_nodes = user["data"]["networkNodes"] 381 | 382 | if isinstance(exciting_nodes, list) and len(exciting_nodes) == 0: 383 | self.log( 384 | f"{Fore.CYAN + Style.BRIGHT}Nodes :{Style.RESET_ALL}" 385 | f"{Fore.RED + Style.BRIGHT} No Node Ids Found {Style.RESET_ALL}" 386 | ) 387 | return self.node_datas 388 | 389 | for node in exciting_nodes: 390 | node_id = node["nodeId"] 391 | self.node_datas.append({"nodeId":node_id}) 392 | 393 | self.log( 394 | f"{Fore.CYAN + Style.BRIGHT}Nodes :{Style.RESET_ALL}" 395 | f"{Fore.GREEN + Style.BRIGHT} You Have {Style.RESET_ALL}" 396 | f"{Fore.WHITE + Style.BRIGHT}{len(exciting_nodes)} Node Ids{Style.RESET_ALL}" 397 | ) 398 | return self.node_datas 399 | 400 | return self.node_datas 401 | 402 | async def process_create_new_nodes(self): 403 | for i in range(self.nodes_count): 404 | node_id = self.generate_node_id() 405 | self.node_datas.append({"nodeId":node_id}) 406 | 407 | self.log( 408 | f"{Fore.CYAN + Style.BRIGHT}Nodes :{Style.RESET_ALL}" 409 | f"{Fore.WHITE + Style.BRIGHT} {self.nodes_count} Node Ids {Style.RESET_ALL}" 410 | f"{Fore.GREEN + Style.BRIGHT}Have Been Created Successfully{Style.RESET_ALL}" 411 | ) 412 | return self.node_datas 413 | 414 | async def process_accounts(self, email: str, password: str, option: int, use_proxy: bool, rotate_proxy: bool): 415 | logined = await self.process_user_login(email, password, use_proxy, rotate_proxy) 416 | if logined: 417 | 418 | if option == 1: 419 | node_datas = await self.process_create_new_nodes() 420 | self.user_nodes.append({"Email":email, "Token":self.access_tokens[email], "Nodes":node_datas}) 421 | self.save_nodes(self.user_nodes) 422 | 423 | elif option == 2: 424 | node_datas = await self.process_get_exiting_nodes(email, use_proxy) 425 | self.user_nodes.append({"Email":email, "Token":self.access_tokens[email], "Nodes":node_datas}) 426 | self.save_nodes(self.user_nodes) 427 | 428 | async def main(self): 429 | try: 430 | accounts = self.load_accounts() 431 | if not accounts: 432 | self.log(f"{Fore.RED+Style.BRIGHT}No Accounts Loaded.{Style.RESET_ALL}") 433 | return 434 | 435 | option, proxy_choice, rotate_proxy = self.print_question() 436 | 437 | use_proxy = False 438 | if proxy_choice in [1, 2]: 439 | use_proxy = True 440 | 441 | self.clear_terminal() 442 | self.welcome() 443 | self.log( 444 | f"{Fore.GREEN + Style.BRIGHT}Account's Total: {Style.RESET_ALL}" 445 | f"{Fore.WHITE + Style.BRIGHT}{len(accounts)}{Style.RESET_ALL}" 446 | ) 447 | 448 | if use_proxy: 449 | await self.load_proxies(proxy_choice) 450 | 451 | separator = "=" * 25 452 | for idx, account in enumerate(accounts, start=1): 453 | if account: 454 | email = account["Email"] 455 | password = account["Password"] 456 | self.log( 457 | f"{Fore.CYAN + Style.BRIGHT}{separator}[{Style.RESET_ALL}" 458 | f"{Fore.WHITE + Style.BRIGHT} {idx} {Style.RESET_ALL}" 459 | f"{Fore.CYAN + Style.BRIGHT}Of{Style.RESET_ALL}" 460 | f"{Fore.WHITE + Style.BRIGHT} {len(accounts)} {Style.RESET_ALL}" 461 | f"{Fore.CYAN + Style.BRIGHT}]{separator}{Style.RESET_ALL}" 462 | ) 463 | 464 | if not "@" in email or not password: 465 | self.log( 466 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}" 467 | f"{Fore.RED+Style.BRIGHT} Invalid Account Data {Style.RESET_ALL}" 468 | ) 469 | continue 470 | 471 | self.HEADERS[email] = { 472 | "Accept": "*/*", 473 | "Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7", 474 | "Origin": "https://app.exeos.network", 475 | "Referer": "https://app.exeos.network/", 476 | "Sec-Fetch-Dest": "empty", 477 | "Sec-Fetch-Mode": "cors", 478 | "Sec-Fetch-Site": "same-site", 479 | "User-Agent": random.choice(USER_AGENT) 480 | } 481 | 482 | self.log( 483 | f"{Fore.CYAN + Style.BRIGHT}Account:{Style.RESET_ALL}" 484 | f"{Fore.WHITE + Style.BRIGHT} {self.mask_account(email)} {Style.RESET_ALL}" 485 | ) 486 | 487 | await self.process_accounts(email, password, option, use_proxy, rotate_proxy) 488 | await asyncio.sleep(3) 489 | 490 | self.log(f"{Fore.CYAN + Style.BRIGHT}={Style.RESET_ALL}"*60) 491 | 492 | except Exception as e: 493 | self.log(f"{Fore.RED+Style.BRIGHT}Error: {e}{Style.RESET_ALL}") 494 | raise e 495 | 496 | if __name__ == "__main__": 497 | try: 498 | bot = Exeos() 499 | asyncio.run(bot.main()) 500 | except KeyboardInterrupt: 501 | print( 502 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 503 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}" 504 | f"{Fore.RED + Style.BRIGHT}[ EXIT ] Exeos - BOT{Style.RESET_ALL} " 505 | ) --------------------------------------------------------------------------------