├── README.md ├── main.py ├── proxy.txt └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | BOT GRASS SESSION 2 LIVE NOW !! 2 | NEW USER TO JOIN : https://app.getgrass.io/register?referralCode=14euVrmXslgPwPI 3 | 4 | need userid : check this video to get userid 5 | 6 | format proxy ( proxy.txt ) 7 | http://user:pass@ip:port 8 | 9 | u can change http or socks5 or socks4 dll 10 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import random 3 | import ssl 4 | import json 5 | import time 6 | import uuid 7 | from loguru import logger 8 | from websockets_proxy import Proxy, proxy_connect 9 | 10 | async def connect_to_wss(socks5_proxy, user_id): 11 | device_id = str(uuid.uuid3(uuid.NAMESPACE_DNS, socks5_proxy)) 12 | logger.info(device_id) 13 | while True: 14 | try: 15 | await asyncio.sleep(random.uniform(0.1, 1.0)) # Reduced frequency 16 | custom_headers = { 17 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" 18 | } 19 | ssl_context = ssl.create_default_context() 20 | ssl_context.check_hostname = False 21 | ssl_context.verify_mode = ssl.CERT_NONE 22 | 23 | # Define server hostname and both ports 24 | server_hostname = "proxy2.wynd.network" 25 | ports = [4444, 4650] 26 | 27 | for port in ports: 28 | uri = f"wss://{server_hostname}:{port}/" 29 | try: 30 | proxy = Proxy.from_url(socks5_proxy) 31 | # Connecting with the proxy 32 | async with proxy_connect(uri, proxy=proxy, ssl=ssl_context, extra_headers={ 33 | "Origin": "chrome-extension://lkbnfiajjmbhnfledhphioinpickokdi", 34 | "User-Agent": custom_headers["User-Agent"] 35 | }) as websocket: 36 | logger.info(f"Connected to {uri} via proxy {socks5_proxy}") 37 | 38 | # Function to send PING message periodically 39 | async def send_ping(): 40 | while True: 41 | send_message = json.dumps( 42 | {"id": str(uuid.uuid4()), "version": "1.0.0", "action": "PING", "data": {}}) 43 | logger.debug(send_message) 44 | await websocket.send(send_message) 45 | await asyncio.sleep(10) # Increased interval to reduce bandwidth usage 46 | 47 | # Start sending ping messages 48 | send_ping_task = asyncio.create_task(send_ping()) 49 | try: 50 | while True: 51 | response = await websocket.recv() 52 | message = json.loads(response) 53 | logger.info(message) 54 | if message.get("action") == "AUTH": 55 | auth_response = { 56 | "id": message["id"], 57 | "origin_action": "AUTH", 58 | "result": { 59 | "browser_id": device_id, 60 | "user_id": user_id, 61 | "user_agent": custom_headers['User-Agent'], 62 | "timestamp": int(time.time()), 63 | "device_type": "extension", 64 | "version": "4.26.2", 65 | "extension_id": "lkbnfiajjmbhnfledhphioinpickokdi" 66 | } 67 | } 68 | logger.debug(auth_response) 69 | await websocket.send(json.dumps(auth_response)) 70 | 71 | elif message.get("action") == "PONG": 72 | pong_response = {"id": message["id"], "origin_action": "PONG"} 73 | logger.debug(pong_response) 74 | await websocket.send(json.dumps(pong_response)) 75 | finally: 76 | send_ping_task.cancel() 77 | break # Exit the loop if connected successfully 78 | except Exception as e: 79 | logger.error(f"Error connecting to {uri} with proxy {socks5_proxy}: {str(e)}") 80 | # If the first URI fails, try the next one 81 | continue 82 | 83 | except Exception as e: 84 | logger.error(f"Error with proxy {socks5_proxy}: {str(e)}") 85 | if any(error_msg in str(e) for error_msg in [ 86 | "[SSL: WRONG_VERSION_NUMBER]", 87 | "invalid length of packed IP address string", 88 | "Empty connect reply", 89 | "Device creation limit exceeded", 90 | "sent 1011 (internal error) keepalive ping timeout; no close frame received"]): 91 | logger.info(f"Removing error proxy from the list: {socks5_proxy}") 92 | remove_proxy_from_list(socks5_proxy) 93 | return None # Signal to the main loop to replace this proxy 94 | else: 95 | continue # Continue to try to reconnect or handle other errors 96 | 97 | async def main(): 98 | # Prompt the user to input their user ID 99 | _user_id = input('Please enter your user ID: ').strip() 100 | if not _user_id: 101 | logger.error("User ID is required. Exiting.") 102 | return # Exit if no user ID is provided 103 | 104 | # Prompt the user to input the number of proxies they want to use 105 | try: 106 | num_proxies_to_use = int(input('Please enter the number of proxies you want to use: ').strip()) 107 | if num_proxies_to_use <= 0: 108 | raise ValueError("The number of proxies must be a positive integer.") 109 | except ValueError as e: 110 | logger.error(f"Invalid number of proxies: {e}. Exiting.") 111 | return # Exit if an invalid number is entered 112 | 113 | proxy_file = 'proxy.txt' # Path to your proxy.txt file 114 | # format => socks5://username:pass@ip:port 115 | try: 116 | with open(proxy_file, 'r') as file: 117 | all_proxies = file.read().splitlines() 118 | except FileNotFoundError: 119 | logger.error(f"Proxy file '{proxy_file}' not found. Exiting.") 120 | return # Exit if the proxy file is not found 121 | 122 | # Check if there are enough proxies available 123 | num_proxies_to_use = min(num_proxies_to_use, len(all_proxies)) # Ensure we don't exceed the available proxies 124 | logger.info(f"Using {num_proxies_to_use} proxies.") 125 | 126 | active_proxies = random.sample(all_proxies, num_proxies_to_use) # Select the proxies to use 127 | tasks = {asyncio.create_task(connect_to_wss(proxy, _user_id)): proxy for proxy in active_proxies} 128 | 129 | while True: 130 | done, pending = await asyncio.wait(tasks.keys(), return_when=asyncio.FIRST_COMPLETED) 131 | for task in done: 132 | if task.result() is None: 133 | failed_proxy = tasks[task] 134 | logger.info(f"Removing and replacing failed proxy: {failed_proxy}") 135 | active_proxies.remove(failed_proxy) 136 | new_proxy = random.choice(all_proxies) 137 | active_proxies.append(new_proxy) 138 | new_task = asyncio.create_task(connect_to_wss(new_proxy, _user_id)) 139 | tasks[new_task] = new_proxy # Replace the task in the dictionary 140 | tasks.pop(task) # Remove the completed task whether it succeeded or failed 141 | 142 | # Replenish the tasks if any have completed 143 | for proxy in set(active_proxies) - set(tasks.values()): 144 | new_task = asyncio.create_task(connect_to_wss(proxy, _user_id)) 145 | tasks[new_task] = proxy 146 | 147 | def remove_proxy_from_list(proxy): 148 | with open("proxy.txt", "r+") as file: 149 | lines = file.readlines() 150 | file.seek(0) 151 | for line in lines: 152 | if line.strip() != proxy: 153 | file.write(line) 154 | file.truncate() 155 | 156 | if __name__ == '__main__': 157 | asyncio.run(main()) 158 | -------------------------------------------------------------------------------- /proxy.txt: -------------------------------------------------------------------------------- 1 | add proxy here 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | asyncio 3 | loguru 4 | fake_useragent 5 | websockets_proxy 6 | websockets --------------------------------------------------------------------------------