|
| 1 | +import aiohttp |
| 2 | +import asyncio |
| 3 | +import aiofiles |
| 4 | +import logging |
| 5 | +import time |
| 6 | + |
| 7 | +logging.basicConfig(level=logging.INFO) |
| 8 | +logger = logging.getLogger(__name__) |
| 9 | + |
| 10 | +# 设置默认请求头 |
| 11 | +headers = { |
| 12 | + 'Content-Type': 'application/json', |
| 13 | +} |
| 14 | + |
| 15 | +# coday 函数 |
| 16 | +async def coday(url, method, headers, payload_data=None, proxy=None): |
| 17 | + try: |
| 18 | + async with aiohttp.ClientSession() as session: |
| 19 | + async with session.request(method, url, headers=headers, json=payload_data, proxy=proxy) as response: |
| 20 | + try: |
| 21 | + json_data = await response.json() |
| 22 | + except aiohttp.ContentTypeError: |
| 23 | + json_data = {} |
| 24 | + if not response.ok: |
| 25 | + return {'error': True, 'status': response.status, 'data': json_data} |
| 26 | + return json_data |
| 27 | + except Exception as e: |
| 28 | + logger.error(f"Error in coday: {e}") |
| 29 | + return {'error': True, 'message': str(e)} |
| 30 | + |
| 31 | +# 读取令牌、唯一 ID 和代理 |
| 32 | +async def read_tokens_ids_and_proxies(): |
| 33 | + try: |
| 34 | + # 读取 token 文件 |
| 35 | + async with aiofiles.open('token.txt', 'r') as f: |
| 36 | + token_data = await f.read() |
| 37 | + tokens = [line.strip() for line in token_data.split('\n') if line.strip()] |
| 38 | + |
| 39 | + # 读取唯一 ID 文件 |
| 40 | + async with aiofiles.open('unique_id.txt', 'r') as f: |
| 41 | + ids_data = await f.read() |
| 42 | + unique_ids = [line.strip() for line in ids_data.split('\n') if line.strip()] |
| 43 | + |
| 44 | + # 询问用户是否使用代理 |
| 45 | + use_proxy = input("是否使用代理?(y/n): ").strip().lower() == 'y' |
| 46 | + |
| 47 | + proxies = [] |
| 48 | + if use_proxy: |
| 49 | + # 读取代理文件 |
| 50 | + async with aiofiles.open('proxy.txt', 'r') as f: |
| 51 | + proxy_data = await f.read() |
| 52 | + proxies = [line.strip() for line in proxy_data.split('\n') if line.strip()] |
| 53 | + |
| 54 | + # 检查 token、唯一 ID 和代理的行数是否匹配 |
| 55 | + if len(tokens) != len(unique_ids) or len(tokens) != len(proxies): |
| 56 | + logger.error("Token、唯一 ID 和代理的行数不匹配。") |
| 57 | + return [] |
| 58 | + |
| 59 | + # 组合账户信息 |
| 60 | + accounts = [] |
| 61 | + for i in range(len(tokens)): |
| 62 | + access_token, refresh_token = map(str.strip, tokens[i].split('|')) |
| 63 | + ids = list(map(str.strip, unique_ids[i].split('|'))) |
| 64 | + proxy = proxies[i] if use_proxy else None |
| 65 | + proxy_type = 'socks5' if proxy and proxy.startswith('socks5://') else 'http' |
| 66 | + accounts.append({'access_token': access_token, 'refresh_token': refresh_token, 'unique_ids': ids, 'proxy': f"{proxy_type}://{proxy}" if proxy else None}) |
| 67 | + |
| 68 | + return accounts |
| 69 | + except Exception as e: |
| 70 | + logger.error(f"读取 token、唯一 ID 或代理文件失败: {e}") |
| 71 | + return [] |
| 72 | +# 刷新令牌功能 |
| 73 | +async def refresh_token(refresh_token, account_index, proxy): |
| 74 | + logger.info(f"正在刷新账户 {account_index + 1} 的访问令牌...") |
| 75 | + payload_data = {'refresh_token': refresh_token} |
| 76 | + response = await coday("https://api.meshchain.ai/meshmain/auth/refresh-token", 'POST', headers, payload_data, proxy=proxy) |
| 77 | + |
| 78 | + if response and response.get('access_token'): |
| 79 | + # 更新 token 文件 |
| 80 | + async with aiofiles.open('token.txt', 'r') as f: |
| 81 | + token_lines = (await f.read()).split('\n') |
| 82 | + token_lines[account_index] = f"{response['access_token']}|{response['refresh_token']}" |
| 83 | + async with aiofiles.open('token.txt', 'w') as f: |
| 84 | + await f.write('\n'.join(token_lines)) |
| 85 | + logger.info(f"账户 {account_index + 1} 的令牌刷新成功") |
| 86 | + return response['access_token'] |
| 87 | + logger.error(f"账户 {account_index + 1} 的令牌刷新失败") |
| 88 | + return None |
| 89 | + |
| 90 | +# info 函数 |
| 91 | +async def info(unique_id, headers, proxy): |
| 92 | + url = 'https://api.meshchain.ai/meshmain/nodes/status' |
| 93 | + return await coday(url, 'POST', headers, {'unique_id': unique_id}, proxy=proxy) |
| 94 | + |
| 95 | +# estimate 函数 |
| 96 | +async def estimate(unique_id, headers, proxy): |
| 97 | + url = 'https://api.meshchain.ai/meshmain/rewards/estimate' |
| 98 | + return await coday(url, 'POST', headers, {'unique_id': unique_id}, proxy=proxy) |
| 99 | + |
| 100 | +# claim 函数 |
| 101 | +async def claim(unique_id, headers, proxy): |
| 102 | + url = 'https://api.meshchain.ai/meshmain/rewards/claim' |
| 103 | + result = await coday(url, 'POST', headers, {'unique_id': unique_id}, proxy=proxy) |
| 104 | + return result.get('total_reward', None) |
| 105 | + |
| 106 | +# start 函数 |
| 107 | +async def start(unique_id, headers, proxy): |
| 108 | + url = 'https://api.meshchain.ai/meshmain/rewards/start' |
| 109 | + return await coday(url, 'POST', headers, {'unique_id': unique_id}, proxy=proxy) |
| 110 | + |
| 111 | +# 单个账户的主要处理流程 |
| 112 | +async def process_account(account, account_index): |
| 113 | + global headers |
| 114 | + headers['Authorization'] = f"Bearer {account['access_token']}" |
| 115 | + |
| 116 | + for unique_id in account['unique_ids']: |
| 117 | + proxy = account['proxy'] |
| 118 | + |
| 119 | + # 获取用户信息 |
| 120 | + profile = await info(unique_id, headers, proxy) |
| 121 | + |
| 122 | + if profile.get('error'): |
| 123 | + logger.error(f"账户 {account_index + 1} | {unique_id}: 获取用户信息失败,尝试刷新令牌...") |
| 124 | + new_access_token = await refresh_token(account['refresh_token'], account_index, proxy) |
| 125 | + if not new_access_token: |
| 126 | + return |
| 127 | + headers['Authorization'] = f"Bearer {new_access_token}" |
| 128 | + else: |
| 129 | + name = profile.get('name') |
| 130 | + total_reward = profile.get('total_reward') |
| 131 | + logger.info(f"账户 {account_index + 1} | {unique_id}: {name} | 余额: {total_reward}") |
| 132 | + |
| 133 | + # 获取奖励估算 |
| 134 | + filled = await estimate(unique_id, headers, proxy) |
| 135 | + if not filled: |
| 136 | + logger.error(f"账户 {account_index + 1} | {unique_id}: 获取估算值失败。") |
| 137 | + continue |
| 138 | + |
| 139 | + if filled.get('value', 0) > 10: |
| 140 | + logger.info(f"账户 {account_index + 1} | {unique_id}: 尝试领取奖励...") |
| 141 | + reward = await claim(unique_id, headers, proxy) |
| 142 | + if reward: |
| 143 | + logger.info(f"账户 {account_index + 1} | {unique_id}: 奖励领取成功!新余额: {reward}") |
| 144 | + await start(unique_id, headers, proxy) |
| 145 | + logger.info(f"账户 {account_index + 1} | {unique_id}: 重新开始挖矿。") |
| 146 | + else: |
| 147 | + logger.error(f"账户 {account_index + 1} | {unique_id}: 领取奖励失败。") |
| 148 | + else: |
| 149 | + logger.info(f"账户 {account_index + 1} | {unique_id}: 已经在挖矿中,当前值: {filled.get('value', 0)}") |
| 150 | + |
| 151 | +# 主流程处理所有账户 |
| 152 | +async def main(): |
| 153 | + banner = "Your Banner Here" |
| 154 | + logger.debug(banner) |
| 155 | + |
| 156 | + while True: |
| 157 | + accounts = await read_tokens_ids_and_proxies() |
| 158 | + |
| 159 | + if not accounts: |
| 160 | + logger.error("没有账户可处理。") |
| 161 | + return |
| 162 | + |
| 163 | + for i, account in enumerate(accounts): |
| 164 | + logger.info(f"正在处理账户 {i + 1}...") |
| 165 | + await process_account(account, i) |
| 166 | + |
| 167 | + await asyncio.sleep(60) # 每 60 秒运行一次 |
| 168 | + |
| 169 | +# 运行主流程 |
| 170 | +if __name__ == "__main__": |
| 171 | + asyncio.run(main()) |
0 commit comments