├── tokens.json
├── emails.txt
├── images
└── banner.png
├── proxy.txt
├── requirements.txt
├── README.md
├── bot.py
└── setup.py
/tokens.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/emails.txt:
--------------------------------------------------------------------------------
1 | your_email_address_1
2 | your_email_address_2
--------------------------------------------------------------------------------
/images/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vonssy/Dawn-BOT/HEAD/images/banner.png
--------------------------------------------------------------------------------
/proxy.txt:
--------------------------------------------------------------------------------
1 | ip:port # Default Protcol HTTP.
2 | protocol://ip:port
3 | protocol://user:pass@ip:port
4 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | aiohttp==3.11.10
2 | aiohttp-socks==0.9.1
3 | fake-useragent==1.5.1
4 | colorama==0.4.6
5 | pytz==2024.1
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌅 Dawn Validator BOT
2 |
3 | > Automated Dawn Validator management with multi-threading and proxy support
4 |
5 | [](https://www.python.org/downloads/)
6 | [](LICENSE)
7 | [](https://github.com/vonssy/Dawn-BOT/stargazers)
8 |
9 | ## 📋 Table of Contents
10 |
11 | - [Overview](#overview)
12 | - [Features](#features)
13 | - [Requirements](#requirements)
14 | - [Installation](#installation)
15 | - [Configuration](#configuration)
16 | - [Setup & Usage](#setup--usage)
17 | - [Proxy Recommendation](#proxy-recommendation)
18 | - [Support](#support)
19 | - [Contributing](#contributing)
20 |
21 | ## 🎯 Overview
22 |
23 | Dawn Validator BOT is an automated tool designed to manage Dawn Validator nodes efficiently with multi-threading support. It provides seamless proxy integration and automated keep-alive functionality to ensure optimal validator performance.
24 |
25 | **🔗 Get Started:** [Register on Dawn Validator](https://dashboard.dawninternet.com/signup)
26 |
27 | > **Referral Code:** Use code `02lt4r` during registration for benefits!
28 |
29 | **📥 Extension:** [Download Chrome Extension](https://chromewebstore.google.com/detail/dawn-validator-chrome-ext/fpdkjdnhkakefebpekbdhillbhonfjjp?hl=en)
30 |
31 | ## ✨ Features
32 |
33 | - 🤖 **Automated Token Extraction** - Auto-fetch bearer tokens
34 | - 🔄 **Automated Account Management** - Retrieve account information automatically
35 | - 🌐 **Flexible Proxy Support** - Run with or without proxy configuration
36 | - 🔀 **Smart Proxy Rotation** - Automatic rotation of invalid proxies
37 | - 💓 **Ping System** - Automated ping signals every 10 minutes
38 | - ⚡ **Multi-Threading Support** - Handle multiple accounts simultaneously
39 |
40 | ## 📋 Requirements
41 |
42 | - **Python:** Version 3.9 or higher
43 | - **pip:** Latest version recommended
44 |
45 | ## 🛠 Installation
46 |
47 | ### 1. Clone the Repository
48 |
49 | ```bash
50 | git clone https://github.com/vonssy/Dawn-BOT.git
51 | cd Dawn-BOT
52 | ```
53 |
54 | ### 2. Install Dependencies
55 |
56 | ```bash
57 | pip install -r requirements.txt
58 | # or for Python 3 specifically
59 | pip3 install -r requirements.txt
60 | ```
61 |
62 | ## ⚙️ Configuration
63 |
64 | ### Account Configuration
65 |
66 | Create or edit `emails.txt` in the project directory:
67 |
68 | ```
69 | your_email_address_1
70 | your_email_address_2
71 | ```
72 |
73 | ### Proxy Configuration (Optional)
74 |
75 | Create or edit `proxy.txt` in the project directory:
76 |
77 | ```
78 | # Simple format (HTTP protocol by default)
79 | 192.168.1.1:8080
80 |
81 | # With protocol specification
82 | http://192.168.1.1:8080
83 | https://192.168.1.1:8080
84 |
85 | # With authentication
86 | http://username:password@192.168.1.1:8080
87 | ```
88 |
89 | ## 🚀 Setup & Usage
90 |
91 | ### Automatic Token Setup
92 |
93 | Run the setup script to automatically fetch tokens using your configured account credentials:
94 |
95 | ```bash
96 | python setup.py
97 | # or for Python 3 specifically
98 | python3 setup.py
99 | ```
100 |
101 | > **💡 What does setup.py do?**
102 | > - Automatically logs in to your Dawn Validator accounts
103 | > - Extracts bearer tokens automatically
104 | > - Saves tokens to `tokens.json` for the bot to use
105 |
106 | ### Start the Bot
107 |
108 | After running the setup, launch the Dawn Validator BOT:
109 |
110 | ```bash
111 | python bot.py
112 | # or for Python 3 specifically
113 | python3 bot.py
114 | ```
115 |
116 | ### Runtime Options
117 |
118 | When starting the bot, you'll be prompted to choose:
119 |
120 | 1. **Proxy Mode Selection:**
121 | - Option `1`: Run with proxy
122 | - Option `2`: Run without proxy
123 |
124 | 2. **Auto-Rotation:**
125 | - `y`: Enable automatic invalid proxy rotation
126 | - `n`: Disable auto-rotation
127 |
128 | ## 🌐 Proxy Recommendation
129 |
130 |
131 |

132 |
133 |
134 | For reliable multi-wallet automation and geo-restriction bypass, we recommend **Nstproxy**:
135 |
136 | ### Why Nstproxy?
137 | - 💰 **Affordable pricing** starting from $0.1/GB
138 | - 🌍 **Global coverage** with multiple locations
139 | - 🔄 **Advanced rotation control**
140 | - 🛡️ **Anti-ban technology**
141 |
142 | ### Get Started with Nstproxy
143 | - 🔗 **Website:** [Nstproxy.com](https://www.nstproxy.com/?utm_source=vonssy)
144 | - 💬 **Telegram:** [@nstproxy](https://t.me/nstproxy)
145 | - 🎮 **Discord:** [Join Server](https://discord.gg/5jjWCAmvng)
146 | - 📚 **GitHub:** [Nstproxy Repository](https://github.com/Nstproxy)
147 |
148 | > 🎁 **Special Offer:** Use code `VONSSY` for **10% OFF** your first purchase!
149 |
150 | ## 💖 Support the Project
151 |
152 | If this project has been helpful to you, consider supporting its development:
153 |
154 | ### Cryptocurrency Donations
155 |
156 | | Network | Address |
157 | |---------|---------|
158 | | **EVM** | `0xe3c9ef9a39e9eb0582e5b147026cae524338521a` |
159 | | **TON** | `UQBEFv58DC4FUrGqinBB5PAQS7TzXSm5c1Fn6nkiet8kmehB` |
160 | | **SOL** | `E1xkaJYmAFEj28NPHKhjbf7GcvfdjKdvXju8d8AeSunf` |
161 | | **SUI** | `0xa03726ecbbe00b31df6a61d7a59d02a7eedc39fe269532ceab97852a04cf3347` |
162 |
163 | ## 🤝 Contributing
164 |
165 | We welcome contributions from the community! Here's how you can help:
166 |
167 | 1. ⭐ **Star this repository** if you find it useful
168 | 2. 👥 **Follow** for updates on new features
169 | 3. 🐛 **Report issues** via GitHub Issues
170 | 4. 💡 **Suggest improvements** or new features
171 | 5. 🔧 **Submit pull requests** for bug fixes or enhancements
172 |
173 | ## 📞 Contact & Support
174 |
175 | - **Developer:** vonssy
176 | - **Issues:** [GitHub Issues](https://github.com/vonssy/Dawn-BOT/issues)
177 | - **Discussions:** [GitHub Discussions](https://github.com/vonssy/Dawn-BOT/discussions)
178 |
179 | ---
180 |
181 |
182 |
183 | **Made with ❤️ by [vonssy](https://github.com/vonssy)**
184 |
185 | *Thank you for using Dawn Validator BOT! Don't forget to ⭐ star this repository.*
186 |
187 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | from aiohttp import ClientResponseError, ClientSession, ClientTimeout, BasicAuth
2 | from aiohttp_socks import ProxyConnector
3 | from fake_useragent import FakeUserAgent
4 | from datetime import datetime, timezone
5 | from colorama import *
6 | import asyncio, random, json, pytz, re, os
7 |
8 | wib = pytz.timezone('Asia/Jakarta')
9 |
10 | class Dawn:
11 | def __init__(self) -> None:
12 | self.BASE_API = "https://api.dawninternet.com"
13 | self.HEADERS = {}
14 | self.proxies = []
15 | self.proxy_index = 0
16 | self.account_proxies = {}
17 | self.user_ids = {}
18 | self.session_tokens = {}
19 |
20 | def clear_terminal(self):
21 | os.system('cls' if os.name == 'nt' else 'clear')
22 |
23 | def log(self, message):
24 | print(
25 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
26 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}{message}",
27 | flush=True
28 | )
29 |
30 | def welcome(self):
31 | print(
32 | f"""
33 | {Fore.GREEN + Style.BRIGHT}Dawn {Fore.BLUE + Style.BRIGHT}Auto BOT
34 | """
35 | f"""
36 | {Fore.GREEN + Style.BRIGHT}Rey? {Fore.YELLOW + Style.BRIGHT}
37 | """
38 | )
39 |
40 | def format_seconds(self, seconds):
41 | hours, remainder = divmod(seconds, 3600)
42 | minutes, seconds = divmod(remainder, 60)
43 | return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}"
44 |
45 | def load_accounts(self):
46 | filename = "tokens.json"
47 | try:
48 | if not os.path.exists(filename):
49 | self.log(f"{Fore.RED}File {filename} Not Found.{Style.RESET_ALL}")
50 | return
51 |
52 | with open(filename, 'r') as file:
53 | data = json.load(file)
54 | if isinstance(data, list):
55 | return data
56 | return []
57 | except json.JSONDecodeError:
58 | return []
59 |
60 | async def load_proxies(self):
61 | filename = "proxy.txt"
62 | try:
63 | if not os.path.exists(filename):
64 | self.log(f"{Fore.RED + Style.BRIGHT}File {filename} Not Found.{Style.RESET_ALL}")
65 | return
66 | with open(filename, 'r') as f:
67 | self.proxies = [line.strip() for line in f.read().splitlines() if line.strip()]
68 |
69 | if not self.proxies:
70 | self.log(f"{Fore.RED + Style.BRIGHT}No Proxies Found.{Style.RESET_ALL}")
71 | return
72 |
73 | self.log(
74 | f"{Fore.GREEN + Style.BRIGHT}Proxies Total : {Style.RESET_ALL}"
75 | f"{Fore.WHITE + Style.BRIGHT}{len(self.proxies)}{Style.RESET_ALL}"
76 | )
77 |
78 | except Exception as e:
79 | self.log(f"{Fore.RED + Style.BRIGHT}Failed To Load Proxies: {e}{Style.RESET_ALL}")
80 | self.proxies = []
81 |
82 | def check_proxy_schemes(self, proxies):
83 | schemes = ["http://", "https://", "socks4://", "socks5://"]
84 | if any(proxies.startswith(scheme) for scheme in schemes):
85 | return proxies
86 | return f"http://{proxies}"
87 |
88 | def get_next_proxy_for_account(self, account):
89 | if account not in self.account_proxies:
90 | if not self.proxies:
91 | return None
92 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index])
93 | self.account_proxies[account] = proxy
94 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies)
95 | return self.account_proxies[account]
96 |
97 | def rotate_proxy_for_account(self, account):
98 | if not self.proxies:
99 | return None
100 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index])
101 | self.account_proxies[account] = proxy
102 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies)
103 | return proxy
104 |
105 | def build_proxy_config(self, proxy=None):
106 | if not proxy:
107 | return None, None, None
108 |
109 | if proxy.startswith("socks"):
110 | connector = ProxyConnector.from_url(proxy)
111 | return connector, None, None
112 |
113 | elif proxy.startswith("http"):
114 | match = re.match(r"http://(.*?):(.*?)@(.*)", proxy)
115 | if match:
116 | username, password, host_port = match.groups()
117 | clean_url = f"http://{host_port}"
118 | auth = BasicAuth(username, password)
119 | return None, clean_url, auth
120 | else:
121 | return None, proxy, None
122 |
123 | raise Exception("Unsupported Proxy Type.")
124 |
125 | def mask_account(self, account):
126 | if "@" in account:
127 | local, domain = account.split('@', 1)
128 | mask_account = local[:3] + '*' * 3 + local[-3:]
129 | return f"{mask_account}@{domain}"
130 |
131 | def print_message(self, email, proxy, color, message):
132 | self.log(
133 | f"{Fore.CYAN + Style.BRIGHT}[ Account:{Style.RESET_ALL}"
134 | f"{Fore.WHITE + Style.BRIGHT} {self.mask_account(email)} {Style.RESET_ALL}"
135 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}"
136 | f"{Fore.CYAN + Style.BRIGHT} Proxy: {Style.RESET_ALL}"
137 | f"{Fore.WHITE + Style.BRIGHT}{proxy}{Style.RESET_ALL}"
138 | f"{Fore.MAGENTA + Style.BRIGHT} - {Style.RESET_ALL}"
139 | f"{Fore.CYAN + Style.BRIGHT}Status:{Style.RESET_ALL}"
140 | f"{color + Style.BRIGHT} {message} {Style.RESET_ALL}"
141 | f"{Fore.CYAN + Style.BRIGHT}]{Style.RESET_ALL}"
142 | )
143 |
144 | def print_question(self):
145 | while True:
146 | try:
147 | print(f"{Fore.WHITE + Style.BRIGHT}1. Run With Proxy{Style.RESET_ALL}")
148 | print(f"{Fore.WHITE + Style.BRIGHT}2. Run Without Proxy{Style.RESET_ALL}")
149 | proxy_choice = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2] -> {Style.RESET_ALL}").strip())
150 |
151 | if proxy_choice in [1, 2]:
152 | proxy_type = (
153 | "With" if proxy_choice == 1 else
154 | "Without"
155 | )
156 | print(f"{Fore.GREEN + Style.BRIGHT}Run {proxy_type} Proxy Selected.{Style.RESET_ALL}")
157 | break
158 | else:
159 | print(f"{Fore.RED + Style.BRIGHT}Please enter either 1 or 2.{Style.RESET_ALL}")
160 | except ValueError:
161 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number (1 or 2).{Style.RESET_ALL}")
162 |
163 | rotate_proxy = False
164 | if proxy_choice == 1:
165 | while True:
166 | rotate_proxy = input(f"{Fore.BLUE + Style.BRIGHT}Rotate Invalid Proxy? [y/n] -> {Style.RESET_ALL}").strip()
167 | if rotate_proxy in ["y", "n"]:
168 | rotate_proxy = rotate_proxy == "y"
169 | break
170 | else:
171 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter 'y' or 'n'.{Style.RESET_ALL}")
172 |
173 | return proxy_choice, rotate_proxy
174 |
175 | async def check_connection(self, email: str, proxy_url=None):
176 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
177 | try:
178 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=10)) as session:
179 | async with session.get(url="https://api.ipify.org?format=json", proxy=proxy, proxy_auth=proxy_auth) as response:
180 | response.raise_for_status()
181 | return True
182 | except (Exception, ClientResponseError) as e:
183 | self.print_message(email, proxy, Fore.RED, f"Connection Not 200 OK: {Fore.YELLOW+Style.BRIGHT}{str(e)}")
184 | return None
185 |
186 | async def user_point(self, email: str, proxy_url=None, retries=5):
187 | url = f"{self.BASE_API}/point?user_id={self.user_ids[email]}"
188 | headers = {
189 | **self.HEADERS[email],
190 | "Authorization": f"Bearer {self.session_tokens[email]}"
191 | }
192 |
193 | for attempt in range(retries):
194 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
195 | try:
196 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
197 | async with session.get(url=url, headers=headers, proxy=proxy, proxy_auth=proxy_auth) as response:
198 | if response.status == 401:
199 | self.print_message(email, proxy, Fore.RED, f"GET Earning Failed: {Fore.YELLOW+Style.BRIGHT}Token Already Expired")
200 | return None
201 | response.raise_for_status()
202 | return await response.json()
203 | except (Exception, ClientResponseError) as e:
204 | if attempt < retries - 1:
205 | await asyncio.sleep(5)
206 | continue
207 | self.print_message(email, proxy, Fore.RED, f"GET Earning Failed: {Fore.YELLOW+Style.BRIGHT}{str(e)}")
208 |
209 | return None
210 |
211 | async def extension_ping(self, email: str, timestamp: str, proxy_url=None, retries=5):
212 | url = f"{self.BASE_API}/ping?role=extension"
213 | data = json.dumps({
214 | "user_id": self.user_ids[email],
215 | "extension_id": "fpdkjdnhkakefebpekbdhillbhonfjjp",
216 | "timestamp": timestamp
217 | })
218 | headers = {
219 | **self.HEADERS[email],
220 | "Authorization": f"Bearer {self.session_tokens[email]}",
221 | "Content-Length": str(len(data)),
222 | "Content-Type": "application/json"
223 | }
224 | for attempt in range(retries):
225 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
226 | try:
227 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
228 | async with session.post(url=url, headers=headers, data=data, proxy=proxy, proxy_auth=proxy_auth) as response:
229 | if response.status == 401:
230 | self.print_message(email, proxy, Fore.RED, f"PING Failed: {Fore.YELLOW+Style.BRIGHT}Token Already Expired")
231 | return None
232 | elif response.status == 429:
233 | self.print_message(email, proxy, Fore.RED, f"PING Failed: {Fore.YELLOW+Style.BRIGHT}Too Many Request")
234 | return None
235 | response.raise_for_status()
236 | return await response.json()
237 | except (Exception, ClientResponseError) as e:
238 | if attempt < retries - 1:
239 | await asyncio.sleep(5)
240 | continue
241 | self.print_message(email, proxy, Fore.RED, f"PING Failed: {Fore.YELLOW+Style.BRIGHT}{str(e)}")
242 |
243 | return None
244 |
245 | async def process_check_connection(self, email: str, use_proxy: bool, rotate_proxy: bool):
246 | while True:
247 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None
248 |
249 | is_valid = await self.check_connection(email, proxy)
250 | if is_valid: return True
251 |
252 | if rotate_proxy:
253 | proxy = self.rotate_proxy_for_account(email)
254 |
255 | await asyncio.sleep(1)
256 |
257 | async def process_user_earning(self, email: str, use_proxy: bool):
258 | while True:
259 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None
260 |
261 | user = await self.user_point(email, proxy)
262 | if user:
263 | node_points = user.get("points", 0)
264 | referral_points = user.get("referral_points", 0)
265 | total_points = node_points + referral_points
266 |
267 | self.print_message(email, proxy, Fore.WHITE, f"Earning {total_points} PTS")
268 |
269 | await asyncio.sleep(5 * 60)
270 |
271 | async def process_send_keepalive(self, email: str, use_proxy: bool):
272 | while True:
273 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None
274 |
275 | await asyncio.sleep(3)
276 |
277 | print(
278 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
279 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}"
280 | f"{Fore.BLUE + Style.BRIGHT}Wait For 10 Minutes For Sent Ping...{Style.RESET_ALL}",
281 | end="\r",
282 | flush=True
283 | )
284 |
285 | await asyncio.sleep(10 * 60)
286 |
287 | timestamp = datetime.now(timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z")
288 |
289 | keepalive = await self.extension_ping(email, timestamp, proxy)
290 | if keepalive:
291 | message = keepalive.get("message")
292 |
293 | self.print_message(email, proxy, Fore.GREEN, "PING Success "
294 | f"{Fore.MAGENTA + Style.BRIGHT}-{Style.RESET_ALL}"
295 | f"{Fore.CYAN + Style.BRIGHT} Message: {Style.RESET_ALL}"
296 | f"{Fore.BLUE + Style.BRIGHT}{message}{Style.RESET_ALL}"
297 | )
298 |
299 | async def process_accounts(self, email: str, use_proxy: bool, rotate_proxy: bool):
300 | is_valid = await self.process_check_connection(email, use_proxy, rotate_proxy)
301 | if is_valid:
302 | tasks = [
303 | asyncio.create_task(self.process_user_earning(email, use_proxy)),
304 | asyncio.create_task(self.process_send_keepalive(email, use_proxy))
305 | ]
306 | await asyncio.gather(*tasks)
307 |
308 | async def main(self):
309 | try:
310 | accounts = self.load_accounts()
311 | if not accounts:
312 | self.log(f"{Fore.RED + Style.BRIGHT}No Accounts Loaded.{Style.RESET_ALL}")
313 | return
314 |
315 | proxy_choice, rotate_proxy = self.print_question()
316 |
317 | self.clear_terminal()
318 | self.welcome()
319 | self.log(
320 | f"{Fore.GREEN + Style.BRIGHT}Account's Total: {Style.RESET_ALL}"
321 | f"{Fore.WHITE + Style.BRIGHT}{len(accounts)}{Style.RESET_ALL}"
322 | )
323 |
324 | use_proxy = True if proxy_choice == 1 else False
325 | if use_proxy:
326 | await self.load_proxies()
327 |
328 | self.log(f"{Fore.CYAN + Style.BRIGHT}={Style.RESET_ALL}"*75)
329 |
330 | tasks = []
331 | for idx, account in enumerate(accounts, start=1):
332 | if account:
333 | email = account["email"]
334 | user_id = account["userId"]
335 | session_token = account["sessionToken"]
336 |
337 | if not "@" in email or not user_id or not session_token:
338 | self.log(
339 | f"{Fore.CYAN + Style.BRIGHT}[ Account: {Style.RESET_ALL}"
340 | f"{Fore.WHITE + Style.BRIGHT}{idx}{Style.RESET_ALL}"
341 | f"{Fore.MAGENTA + Style.BRIGHT} - {Style.RESET_ALL}"
342 | f"{Fore.CYAN + Style.BRIGHT}Status:{Style.RESET_ALL}"
343 | f"{Fore.RED + Style.BRIGHT} Invalid Account Data {Style.RESET_ALL}"
344 | f"{Fore.CYAN + Style.BRIGHT}]{Style.RESET_ALL}"
345 | )
346 | continue
347 |
348 | self.HEADERS[email] = {
349 | "Accept": "*/*",
350 | "Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
351 | "Origin": "chrome-extension://fpdkjdnhkakefebpekbdhillbhonfjjp",
352 | "Sec-Fetch-Dest": "empty",
353 | "Sec-Fetch-Mode": "cors",
354 | "Sec-Fetch-Site": "cross-site",
355 | "User-Agent": FakeUserAgent().random
356 | }
357 |
358 | self.user_ids[email] = user_id
359 | self.session_tokens[email] = session_token
360 |
361 | tasks.append(asyncio.create_task(self.process_accounts(email, use_proxy, rotate_proxy)))
362 |
363 | await asyncio.gather(*tasks)
364 |
365 | except Exception as e:
366 | self.log(f"{Fore.RED+Style.BRIGHT}Error: {e}{Style.RESET_ALL}")
367 | raise e
368 |
369 | if __name__ == "__main__":
370 | try:
371 | bot = Dawn()
372 | asyncio.run(bot.main())
373 | except KeyboardInterrupt:
374 | print(
375 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
376 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}"
377 | f"{Fore.RED + Style.BRIGHT}[ EXIT ] Dawn - BOT{Style.RESET_ALL} ",
378 | )
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from aiohttp import ClientResponseError, ClientSession, ClientTimeout, BasicAuth
2 | from aiohttp_socks import ProxyConnector
3 | from fake_useragent import FakeUserAgent
4 | from datetime import datetime
5 | from colorama import *
6 | import asyncio, uuid, json, pytz, re, os
7 |
8 | wib = pytz.timezone('Asia/Jakarta')
9 |
10 | class Dawn:
11 | def __init__(self) -> None:
12 | self.BASE_API = "https://api.dawninternet.com"
13 | self.PRIVY_API = "https://auth.privy.io/api/v1"
14 | self.REF_CODE = "02lt4r" # U can change it with yours
15 | self.BASE_HEADERS = {}
16 | self.PRIVY_HEADERS = {}
17 | self.proxies = []
18 | self.proxy_index = 0
19 | self.account_proxies = {}
20 |
21 | def clear_terminal(self):
22 | os.system('cls' if os.name == 'nt' else 'clear')
23 |
24 | def log(self, message):
25 | print(
26 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
27 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}{message}",
28 | flush=True
29 | )
30 |
31 | def log_status(self, action, status, message="", error=None):
32 | if status == "success":
33 | self.log(
34 | f"{Fore.CYAN+Style.BRIGHT}Action :{Style.RESET_ALL}"
35 | f"{Fore.WHITE+Style.BRIGHT} {action} {Style.RESET_ALL}"
36 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}"
37 | f"{Fore.GREEN+Style.BRIGHT} Success {Style.RESET_ALL}"
38 | f"{(Fore.MAGENTA+Style.BRIGHT + '- ' + Style.RESET_ALL + Fore.WHITE+Style.BRIGHT + message + Style.RESET_ALL) if message else ''}"
39 | )
40 | elif status == "failed":
41 | self.log(
42 | f"{Fore.CYAN+Style.BRIGHT}Action :{Style.RESET_ALL}"
43 | f"{Fore.WHITE+Style.BRIGHT} {action} {Style.RESET_ALL}"
44 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}"
45 | f"{Fore.RED+Style.BRIGHT} Failed {Style.RESET_ALL}"
46 | f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
47 | f"{Fore.YELLOW+Style.BRIGHT} {str(error)} {Style.RESET_ALL}"
48 | )
49 | elif status == "retry":
50 | self.log(
51 | f"{Fore.CYAN+Style.BRIGHT}Action :{Style.RESET_ALL}"
52 | f"{Fore.WHITE+Style.BRIGHT} {action} {Style.RESET_ALL}"
53 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}"
54 | f"{Fore.YELLOW+Style.BRIGHT} Retrying {Style.RESET_ALL}"
55 | f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
56 | f"{Fore.WHITE+Style.BRIGHT} {message} {Style.RESET_ALL}"
57 | )
58 |
59 | def welcome(self):
60 | print(
61 | f"""
62 | {Fore.GREEN + Style.BRIGHT}Dawn {Fore.BLUE + Style.BRIGHT}Auto BOT
63 | """
64 | f"""
65 | {Fore.GREEN + Style.BRIGHT}Rey? {Fore.YELLOW + Style.BRIGHT}
66 | """
67 | )
68 |
69 | def format_seconds(self, seconds):
70 | hours, remainder = divmod(seconds, 3600)
71 | minutes, seconds = divmod(remainder, 60)
72 | return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}"
73 |
74 | def save_tokens(self, new_accounts):
75 | filename = "tokens.json"
76 | try:
77 | if os.path.exists(filename) and os.path.getsize(filename) > 0:
78 | with open(filename, 'r') as file:
79 | existing_accounts = json.load(file)
80 | else:
81 | existing_accounts = []
82 |
83 | account_dict = {acc["email"]: acc for acc in existing_accounts}
84 |
85 | for new_acc in new_accounts:
86 | account_dict[new_acc["email"]] = new_acc
87 |
88 | updated_accounts = list(account_dict.values())
89 |
90 | with open(filename, 'w') as file:
91 | json.dump(updated_accounts, file, indent=4)
92 |
93 | self.log_status("Save Tokens", "success", "Tokens saved to file")
94 |
95 | except Exception as e:
96 | self.log_status("Save Tokens", "failed", error=e)
97 | return []
98 |
99 | async def load_proxies(self):
100 | filename = "proxy.txt"
101 | try:
102 | if not os.path.exists(filename):
103 | self.log(f"{Fore.RED + Style.BRIGHT}File {filename} Not Found.{Style.RESET_ALL}")
104 | return
105 | with open(filename, 'r') as f:
106 | self.proxies = [line.strip() for line in f.read().splitlines() if line.strip()]
107 |
108 | if not self.proxies:
109 | self.log(f"{Fore.RED + Style.BRIGHT}No Proxies Found.{Style.RESET_ALL}")
110 | return
111 |
112 | self.log(
113 | f"{Fore.GREEN + Style.BRIGHT}Proxies Total : {Style.RESET_ALL}"
114 | f"{Fore.WHITE + Style.BRIGHT}{len(self.proxies)}{Style.RESET_ALL}"
115 | )
116 |
117 | except Exception as e:
118 | self.log(f"{Fore.RED + Style.BRIGHT}Failed To Load Proxies: {e}{Style.RESET_ALL}")
119 | self.proxies = []
120 |
121 | def check_proxy_schemes(self, proxies):
122 | schemes = ["http://", "https://", "socks4://", "socks5://"]
123 | if any(proxies.startswith(scheme) for scheme in schemes):
124 | return proxies
125 | return f"http://{proxies}"
126 |
127 | def get_next_proxy_for_account(self, account):
128 | if account not in self.account_proxies:
129 | if not self.proxies:
130 | return None
131 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index])
132 | self.account_proxies[account] = proxy
133 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies)
134 | return self.account_proxies[account]
135 |
136 | def rotate_proxy_for_account(self, account):
137 | if not self.proxies:
138 | return None
139 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index])
140 | self.account_proxies[account] = proxy
141 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies)
142 | return proxy
143 |
144 | def build_proxy_config(self, proxy=None):
145 | if not proxy:
146 | return None, None, None
147 |
148 | if proxy.startswith("socks"):
149 | connector = ProxyConnector.from_url(proxy)
150 | return connector, None, None
151 |
152 | elif proxy.startswith("http"):
153 | match = re.match(r"http://(.*?):(.*?)@(.*)", proxy)
154 | if match:
155 | username, password, host_port = match.groups()
156 | clean_url = f"http://{host_port}"
157 | auth = BasicAuth(username, password)
158 | return None, clean_url, auth
159 | else:
160 | return None, proxy, None
161 |
162 | raise Exception("Unsupported Proxy Type.")
163 |
164 | def mask_account(self, account):
165 | if "@" in account:
166 | local, domain = account.split('@', 1)
167 | mask_account = local[:3] + '*' * 3 + local[-3:]
168 | return f"{mask_account}@{domain}"
169 |
170 | def print_question(self):
171 | while True:
172 | try:
173 | print(f"{Fore.WHITE + Style.BRIGHT}1. Run With Proxy{Style.RESET_ALL}")
174 | print(f"{Fore.WHITE + Style.BRIGHT}2. Run Without Proxy{Style.RESET_ALL}")
175 | proxy_choice = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2] -> {Style.RESET_ALL}").strip())
176 |
177 | if proxy_choice in [1, 2]:
178 | proxy_type = (
179 | "With" if proxy_choice == 1 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 or 2.{Style.RESET_ALL}")
186 | except ValueError:
187 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number (1 or 2).{Style.RESET_ALL}")
188 |
189 | rotate_proxy = False
190 | if proxy_choice == 1:
191 | while True:
192 | rotate_proxy = input(f"{Fore.BLUE + Style.BRIGHT}Rotate Invalid Proxy? [y/n] -> {Style.RESET_ALL}").strip()
193 | if rotate_proxy in ["y", "n"]:
194 | rotate_proxy = rotate_proxy == "y"
195 | break
196 | else:
197 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter 'y' or 'n'.{Style.RESET_ALL}")
198 |
199 | return proxy_choice, rotate_proxy
200 |
201 | async def check_connection(self, proxy_url=None):
202 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
203 | try:
204 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=10)) as session:
205 | async with session.get(url="https://api.ipify.org?format=json", proxy=proxy, proxy_auth=proxy_auth) as response:
206 | response.raise_for_status()
207 | self.log_status("Check Connection", "success", "Connection OK")
208 | return True
209 | except (Exception, ClientResponseError) as e:
210 | self.log_status("Check Connection", "failed", error=e)
211 | return None
212 |
213 | async def request_otp(self, email: str, proxy_url=None, retries=5):
214 | url = f"{self.PRIVY_API}/passwordless/init"
215 | data = json.dumps({"email": email})
216 | headers = {
217 | **self.PRIVY_HEADERS[email],
218 | "Content-Length": str(len(data)),
219 | "Content-Type": "application/json"
220 | }
221 |
222 | for attempt in range(retries):
223 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
224 | try:
225 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
226 | async with session.post(url=url, headers=headers, data=data, proxy=proxy, proxy_auth=proxy_auth) as response:
227 | response.raise_for_status()
228 | result = await response.json()
229 | self.log_status("Request OTP", "success", "OTP request sent")
230 | return result
231 | except (Exception, ClientResponseError) as e:
232 | if attempt < retries - 1:
233 | self.log_status("Request OTP", "retry", f"Attempt {attempt + 1}/{retries}")
234 | await asyncio.sleep(5)
235 | continue
236 | else:
237 | self.log_status("Request OTP", "failed", error=e)
238 | return None
239 |
240 | async def authenticate_otp(self, email: str, otp_code: str, proxy_url=None, retries=5):
241 | url = f"{self.PRIVY_API}/passwordless/authenticate"
242 | data = json.dumps({"email": email, "code": otp_code, "mode": "login-or-sign-up"})
243 | headers = {
244 | **self.PRIVY_HEADERS[email],
245 | "Content-Length": str(len(data)),
246 | "Content-Type": "application/json"
247 | }
248 |
249 | for attempt in range(retries):
250 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
251 | try:
252 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
253 | async with session.post(url=url, headers=headers, data=data, proxy=proxy, proxy_auth=proxy_auth) as response:
254 | response.raise_for_status()
255 | result = await response.json()
256 | self.log_status("Authenticate OTP", "success", "OTP verified successfully")
257 | return result
258 | except (Exception, ClientResponseError) as e:
259 | if attempt < retries - 1:
260 | self.log_status("Authenticate OTP", "retry", f"Attempt {attempt + 1}/{retries}")
261 | await asyncio.sleep(5)
262 | continue
263 | else:
264 | self.log_status("Authenticate OTP", "failed", error=e)
265 | return None
266 |
267 | async def auth_jwt(self, email: str, privy_token: str, proxy_url=None, retries=5):
268 | url = f"{self.BASE_API}/auth?jwt=true&role=extension"
269 | headers = {
270 | **self.BASE_HEADERS[email],
271 | "X-Privy-Token": privy_token
272 | }
273 |
274 | for attempt in range(retries):
275 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
276 | try:
277 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
278 | async with session.get(url=url, headers=headers, proxy=proxy, proxy_auth=proxy_auth) as response:
279 | response.raise_for_status()
280 | result = await response.json()
281 | self.log_status("JWT Authentication", "success", "JWT token obtained")
282 | return result
283 | except (Exception, ClientResponseError) as e:
284 | if attempt < retries - 1:
285 | self.log_status("JWT Authentication", "retry", f"Attempt {attempt + 1}/{retries}")
286 | await asyncio.sleep(5)
287 | continue
288 | else:
289 | self.log_status("JWT Authentication", "failed", error=e)
290 | return None
291 |
292 | async def use_referral(self, email: str, session_token: str, proxy_url=None, retries=5):
293 | url = f"{self.BASE_API}/referral/use"
294 | data = json.dumps({"referralCode":self.REF_CODE})
295 | headers = {
296 | **self.BASE_HEADERS[email],
297 | "Authorization": f"Bearer {session_token}",
298 | "Content-Length": str(len(data)),
299 | "Content-Type": "application/json"
300 | }
301 |
302 | for attempt in range(retries):
303 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
304 | try:
305 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
306 | async with session.post(url=url, headers=headers, data=data, proxy=proxy, proxy_auth=proxy_auth) as response:
307 | if response.status == 400: return None
308 | response.raise_for_status()
309 | result = await response.json()
310 | return result
311 | except (Exception, ClientResponseError) as e:
312 | if attempt < retries - 1:
313 | await asyncio.sleep(5)
314 | continue
315 | else:
316 | return None
317 |
318 | async def process_check_connection(self, email: str, use_proxy: bool, rotate_proxy: bool):
319 | while True:
320 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None
321 | self.log(
322 | f"{Fore.CYAN+Style.BRIGHT}Proxy :{Style.RESET_ALL}"
323 | f"{Fore.WHITE+Style.BRIGHT} {proxy if proxy else 'No Proxy'} {Style.RESET_ALL}"
324 | )
325 |
326 | is_valid = await self.check_connection(proxy)
327 | if is_valid: return True
328 |
329 | if rotate_proxy:
330 | proxy = self.rotate_proxy_for_account(email)
331 | await asyncio.sleep(1)
332 | continue
333 |
334 | return False
335 |
336 | async def process_accounts(self, email: str, use_proxy: bool, rotate_proxy: bool):
337 | is_valid = await self.process_check_connection(email, use_proxy, rotate_proxy)
338 | if not is_valid:
339 | self.log_status("Process Account", "failed", error="Connection check failed")
340 | return
341 |
342 | proxy = self.get_next_proxy_for_account(email) if use_proxy else None
343 |
344 | request = await self.request_otp(email, proxy)
345 | if not request: return
346 |
347 | timestamp = (
348 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
349 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}"
350 | f"{Fore.CYAN + Style.BRIGHT}Action :{Style.RESET_ALL}"
351 | )
352 | otp_code = input(f"{timestamp}{Fore.BLUE + Style.BRIGHT} Enter OTP Code -> {Style.RESET_ALL}")
353 |
354 | authenticate = await self.authenticate_otp(email, otp_code, proxy)
355 | if not authenticate: return
356 |
357 | privy_token = authenticate.get("token")
358 | if not privy_token:
359 | self.log_status("Process Account", "failed", error="No token received from authentication")
360 | return
361 |
362 | auth_jwt = await self.auth_jwt(email, privy_token, proxy)
363 | if not auth_jwt: return
364 |
365 | user_id = auth_jwt.get("user", {}).get("id")
366 | session_token = auth_jwt.get("session_token")
367 |
368 | if user_id and session_token:
369 | await self.use_referral(email, session_token, proxy)
370 | account_data = [{"email": email, "userId": user_id, "sessionToken": session_token}]
371 | self.save_tokens(account_data)
372 | self.log_status("Process Account", "success", f"Account {self.mask_account(email)} processed successfully")
373 | else:
374 | self.log_status("Process Account", "failed", error="Invalid response data")
375 |
376 | async def main(self):
377 | try:
378 | with open('emails.txt', 'r') as file:
379 | emails = [line.strip() for line in file if line.strip()]
380 |
381 | proxy_choice, rotate_proxy = self.print_question()
382 |
383 | self.clear_terminal()
384 | self.welcome()
385 |
386 | use_proxy = True if proxy_choice == 1 else False
387 | if use_proxy:
388 | await self.load_proxies()
389 |
390 | separator = "=" * 27
391 | for idx, email in enumerate(emails, start=1):
392 | if "@" not in email:
393 | self.log_status("Email Validation", "failed", error="Invalid email format")
394 | continue
395 |
396 | self.log(
397 | f"{Fore.CYAN + Style.BRIGHT}{separator}[{Style.RESET_ALL}"
398 | f"{Fore.WHITE + Style.BRIGHT} {idx} {Style.RESET_ALL}"
399 | f"{Fore.CYAN + Style.BRIGHT}Of{Style.RESET_ALL}"
400 | f"{Fore.WHITE + Style.BRIGHT} {len(emails)} {Style.RESET_ALL}"
401 | f"{Fore.CYAN + Style.BRIGHT}]{separator}{Style.RESET_ALL}"
402 | )
403 |
404 | user_agent = FakeUserAgent().random
405 |
406 | self.BASE_HEADERS[email] = {
407 | "Accept": "*/*",
408 | "Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
409 | "Origin": "chrome-extension://fpdkjdnhkakefebpekbdhillbhonfjjp",
410 | "Sec-Fetch-Dest": "empty",
411 | "Sec-Fetch-Mode": "cors",
412 | "Sec-Fetch-Site": "cross-site",
413 | "User-Agent": user_agent
414 | }
415 |
416 | self.PRIVY_HEADERS[email] = {
417 | "Accept": "application/json",
418 | "Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
419 | "Origin": "chrome-extension://fpdkjdnhkakefebpekbdhillbhonfjjp",
420 | "Privy-App-Id": "cmfb724md0057la0bs4tg0vf1",
421 | "Privy-Ca-Id": str(uuid.uuid4()),
422 | "Privy-Client": "react-auth:2.24.0",
423 | "Privy-Ui": "t",
424 | "Sec-Fetch-Dest": "empty",
425 | "Sec-Fetch-Mode": "cors",
426 | "Sec-Fetch-Site": "none",
427 | "Sec-Fetch-Storage-Access": "active",
428 | "User-Agent": user_agent
429 | }
430 |
431 | self.log(
432 | f"{Fore.CYAN+Style.BRIGHT}Email :{Style.RESET_ALL}"
433 | f"{Fore.WHITE+Style.BRIGHT} {self.mask_account(email)} {Style.RESET_ALL}"
434 | )
435 |
436 | await self.process_accounts(email, use_proxy, rotate_proxy)
437 | await asyncio.sleep(3)
438 |
439 | except FileNotFoundError:
440 | self.log_status("File Loading", "failed", error="File 'emails.txt' not found")
441 | return
442 | except Exception as e:
443 | self.log_status("Main Process", "failed", error=e)
444 | raise e
445 |
446 | if __name__ == "__main__":
447 | try:
448 | bot = Dawn()
449 | asyncio.run(bot.main())
450 | except KeyboardInterrupt:
451 | print(
452 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
453 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}"
454 | f"{Fore.RED + Style.BRIGHT}[ EXIT ] Dawn - BOT{Style.RESET_ALL} ",
455 | )
--------------------------------------------------------------------------------