├── proxy.txt ├── wallet.txt ├── successful_wallets.txt ├── requirements.txt ├── README.md └── main.py /proxy.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wallet.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /successful_wallets.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | fake_useragent 3 | 2captcha-python 4 | loguru 5 | python-dotenv -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 Auto Get Sonic Faucet 2 | 3 | Python script to automate the process of getting Sonic Faucet using multiple wallets. This script is designed to handle CAPTCHA solving, proxy usage, and logging. 4 | 5 | ## ✨ Features 6 | - 🤖 Solve CAPTCHA automatically using 2Captcha 7 | - 🌐 Support for proxy usage (HTTP only) 8 | - 📂 Handle multiple wallets from a file 9 | - 💾 Save successful wallet signatures to a file 10 | 11 | ## 📋 Requirements 12 | - 🐍 Python3 13 | - 🤖 2Captcha APIKEY (minimum deposit $2) 14 | - 🌐 Proxy (optional) 15 | 16 | ## 🛠️ Installation 17 | 1. Clone the repository: 18 | ```bash 19 | git clone https://github.com/Tnodes/auto-get-sonic-faucet.git 20 | ``` 21 | 2. Navigate to the cloned directory: 22 | ```bash 23 | cd auto-get-sonic-faucet 24 | ``` 25 | 3. Install the required dependencies: 26 | ```bash 27 | pip install -r requirements.txt 28 | ``` 29 | 30 | ## ⚙️ Setup 31 | 1. Create a `.env` file in the same directory with the following content: 32 | ``` 33 | API_KEY=your_2captcha_api_key 34 | ``` 35 | 2. Prepare your `proxy.txt` (optional) and `wallet.txt` files in the same directory. 36 | - `proxy.txt` should contain one proxy per line in the format `username:password@ip:port` for authenticated proxies or `ip:port` for non-authenticated proxies. 37 | - **Note:** Only HTTP proxies are supported. 38 | - `wallet.txt` should contain one wallet address per line. 39 | 40 | ## 🚀 Usage 41 | Run the script with the following command: 42 | ```bash 43 | python main.py 44 | ``` 45 | 46 | ## 📄 Notes 47 | - Ensure you have a valid 2Captcha API key and update it in the `.env` file. 48 | - Successful wallet signatures are saved to `successful_wallets.txt`. 49 | 50 | ## 🔔 Telegram 51 | Join to my telegram channel: 52 | https://t.me/tdropid 53 | 54 | ## 💖 Support Our Work 55 | 🌟 If you have found this script helpful, we invite you to support its development by making a donation. Your generosity enables us to continue improving and expanding our work. Below are the wallet addresses where you can contribute: 56 | 57 | ``` 58 | EVM: 0xC76AE3B69478Eab1a093642548c0656e83c18623 59 | SOL: 7xDtSzUS8Mrbfqa79ThyQHbcDsFK9h4143A1fqTsxJwt 60 | BTC: bc1q7ulh39d644law0vfst4kl8shkd4k58qyjtlsyu 61 | ``` 62 | 63 | Thank you for your support! 🙏 -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import random 3 | import time 4 | import re 5 | import sys 6 | from fake_useragent import UserAgent 7 | from twocaptcha import TwoCaptcha, ApiException, ValidationException, NetworkException, TimeoutException 8 | from typing import List, Optional 9 | from loguru import logger 10 | from dotenv import load_dotenv 11 | import os 12 | 13 | load_dotenv() 14 | logger.remove(0) 15 | logger.add(sys.stderr, level='DEBUG', colorize=True, format="{time:HH:mm:ss} | {level: <7} | {message}") 16 | 17 | def load_lines(file_path: str) -> List[str]: 18 | try: 19 | with open(file_path, 'r') as file: 20 | return [line.strip() for line in file if line.strip()] 21 | except FileNotFoundError: 22 | logger.warning(f"{file_path} not found, continuing without it") 23 | return [] 24 | 25 | def generate_fake_user_agent() -> str: 26 | return UserAgent().random 27 | 28 | def solve_captcha(solver: TwoCaptcha, sitekey: str, url: str, useragent: str, max_attempts: int = 3) -> Optional[str]: 29 | for attempt in range(max_attempts): 30 | try: 31 | logger.info("Solving CAPTCHA...") 32 | result = solver.turnstile(sitekey=sitekey, url=url, useragent=useragent) 33 | logger.info("CAPTCHA solved") 34 | return result['code'] 35 | except (ValidationException, NetworkException, TimeoutException, ApiException) as e: 36 | logger.error(f"Error solving CAPTCHA: {e}") 37 | if attempt < max_attempts - 1: 38 | backoff_time = 2 ** (attempt + 1) 39 | logger.info(f"Retrying in {backoff_time} seconds...") 40 | time.sleep(backoff_time) 41 | logger.error("Failed to solve CAPTCHA after maximum attempts") 42 | return None 43 | 44 | def make_api_request(api_url: str, captcha_code: str, proxy: Optional[str], max_attempts: int = 3) -> Optional[str]: 45 | headers = generate_headers() 46 | api_url_with_captcha = api_url.format(captcha_code=captcha_code) 47 | proxies = {'http': proxy} if proxy else None 48 | log_message = 'with' if proxy else 'without' 49 | logger.info(f'Making request to API {log_message} proxy...') 50 | 51 | for attempt in range(max_attempts): 52 | try: 53 | response = requests.get(api_url_with_captcha, headers=headers, proxies=proxies) 54 | return handle_response(response) 55 | except requests.RequestException as e: 56 | logger.error(f"Request failed: {e}") 57 | if attempt < max_attempts - 1: 58 | backoff_time = 2 ** (attempt + 1) 59 | logger.info(f"Retrying in {backoff_time} seconds...") 60 | time.sleep(backoff_time) 61 | logger.error("Failed to make API request after maximum attempts") 62 | return None 63 | 64 | def generate_headers() -> dict: 65 | user_agent = generate_fake_user_agent() 66 | platform_match = re.search(r'\([^;]+', user_agent) 67 | system_platform = platform_match.group(0)[1:] if platform_match else "Unknown" 68 | return { 69 | "path": "/airdrop/{captcha_code}", 70 | "Accept": "application/json, text/plain, */*", 71 | "Content-Type": "application/json", 72 | "Accept-Language": "en-US,en;q=0.9,id;q=0.8", 73 | "Dnt": "1", 74 | "Origin": "https://faucet.sonic.game", 75 | "Priority": "u=1, i", 76 | "Referer": "https://faucet.sonic.game/", 77 | "User-Agent": user_agent, 78 | "sec-ch-ua-mobile": "?0", 79 | "sec-ch-ua-platform": f'"{system_platform}"' 80 | } 81 | 82 | def handle_response(response: requests.Response) -> Optional[str]: 83 | if response.status_code == 200: 84 | try: 85 | data = response.json() 86 | if data['status'] == 'ok': 87 | logger.info(f"Response Status: {data['status']}") 88 | return data['data']['data'].strip() 89 | else: 90 | logger.error(f"Error in API response: {data}") 91 | except ValueError: 92 | logger.error("Error: Received invalid JSON") 93 | logger.error(f"Response content: {response.content}") 94 | elif response.status_code == 429: 95 | logger.warning("Received 429 Too Many Requests, skipping to next wallet") 96 | return "too_many_requests" 97 | elif response.status_code == 401: 98 | logger.warning("Received 401 You might be a robot, skipping to next wallet") 99 | return "might_be_a_robot" 100 | else: 101 | logger.error(f"Error: {response.status_code}, Response content: {response.content}") 102 | return None 103 | 104 | def save_wallet_signature(wallet: str, signature: str) -> None: 105 | with open('successful_wallets.txt', 'a') as file: 106 | file.write(f'{wallet},{signature}\n') 107 | 108 | def banner() -> None: 109 | art = """ 110 | _________________________________________ 111 | | AUTO GET SONIC FAUCET | 112 | | GITHUB: https://github.com/Tnodes | 113 | | TELEGRAM: https://t.me/tdropid | 114 | |_________________________________________| 115 | """ 116 | print(art) 117 | 118 | def choose_network() -> str: 119 | while True: 120 | print("\nChoose the network:") 121 | print("1. Devnet") 122 | print("2. Testnet") 123 | choice = input("Enter your choice (1 or 2): ") 124 | if choice == '1': 125 | return "devnet" 126 | elif choice == '2': 127 | return "testnet" 128 | else: 129 | print("Invalid choice. Please enter 1 or 2.") 130 | 131 | def main() -> None: 132 | banner() 133 | 134 | api_key = os.getenv("API_KEY") 135 | if not api_key: 136 | logger.error("API key not found in environment variables") 137 | return 138 | 139 | network = choose_network() 140 | 141 | sitekey = '0x4AAAAAAAc6HG1RMG_8EHSC' 142 | url = 'https://faucet.sonic.game/' 143 | 144 | if network == "devnet": 145 | api_base_url = "https://faucet-api.sonic.game/airdrop/" 146 | else: # testnet 147 | api_base_url = "https://faucet-api-grid-1.sonic.game/airdrop/" 148 | 149 | proxies = load_lines('proxy.txt') 150 | wallets = load_lines('wallet.txt') 151 | 152 | if not wallets: 153 | logger.error("No wallets to process.") 154 | return 155 | 156 | solver = TwoCaptcha(api_key) 157 | 158 | for wallet in wallets: 159 | logger.info(f"Processing wallet: {wallet}") 160 | api_url = f"{api_base_url}{wallet}/0.5/{{captcha_code}}" 161 | proxy = random.choice(proxies) if proxies else None 162 | captcha_code = solve_captcha(solver, sitekey, url, generate_fake_user_agent()) 163 | 164 | if not captcha_code: 165 | logger.error(f"Unable to solve CAPTCHA after multiple attempts for wallet {wallet}, skipping request") 166 | continue 167 | 168 | signature = make_api_request(api_url, captcha_code, proxy) 169 | if signature and signature not in ["too_many_requests", "might_be_a_robot"]: 170 | logger.info(f"Successfully received signature for wallet {wallet}, {signature}") 171 | save_wallet_signature(wallet, signature) 172 | 173 | time.sleep(20) 174 | 175 | if __name__ == "__main__": 176 | main() --------------------------------------------------------------------------------