├── README.md └── nyan.py /README.md: -------------------------------------------------------------------------------- 1 | # NyanHeroes 2 | nyanheroes项目批量刷邀请+自动完成任务 3 | 4 | 用法: 5 | 修改nyan.py中的邀请码,将tw_token.txt放在脚本同目录,一行一个token。 6 | 7 | python3 nyan.py 8 | -------------------------------------------------------------------------------- /nyan.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import sys 3 | import time 4 | from datetime import datetime 5 | import base58 6 | import httpx 7 | from loguru import logger 8 | from urllib.parse import urlparse, parse_qs 9 | from solathon import Keypair 10 | 11 | g_success, g_fail = 0, 0 12 | 13 | logger.remove() 14 | logger.add(sys.stdout, colorize=True, 15 | format="{time:HH:mm:ss:SSS} | {extra[fail]}-{extra[success]} | {message}") 16 | logger = logger.patch(lambda record: record["extra"].update(fail=g_fail, success=g_success)) 17 | 18 | 19 | proxies = { 20 | 'http://': 'http://127.0.0.1:7890', 21 | 'https://': 'http://127.0.0.1:7890', 22 | } 23 | 24 | 25 | class Nyan: 26 | def __init__(self, auth_token, referral): 27 | self.http = httpx.AsyncClient(proxies=proxies, verify=False) 28 | self.http.headers = { 29 | 'Accept-Language': 'en-US,en;q=0.8', 30 | 'Authority': 'twitter.com', 31 | 'Origin': 'https://twitter.com', 32 | 'Referer': 'https://twitter.com/', 33 | 'Sec-Ch-Ua': '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', 34 | 'Sec-Ch-Ua-Mobile': '?0', 35 | 'Sec-Ch-Ua-Platform': "Windows", 36 | 'Sec-Fetch-Dest': 'empty', 37 | 'Sec-Fetch-Mode': 'cors', 38 | 'Sec-Fetch-Site': 'same-origin', 39 | 'Sec-Gpc': '1', 40 | 'User-Agent': 'Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/' 41 | } 42 | 43 | self.Twitter = httpx.AsyncClient(proxies=proxies, verify=False) 44 | self.Twitter.headers = { 45 | 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 46 | 'Accept': 'application/json, text/plain, */*', 47 | 'Origin': 'https://missions.nyanheroes.com', 48 | 'Sec-Fetch-Dest': 'empty', 49 | 'Sec-Fetch-Mode': 'cors', 50 | 'Sec-Fetch-Site': 'same-origin', 51 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:123.0) Gecko/20100101 Firefox/123.0' 52 | } 53 | self.Twitter.cookies.update({'auth_token': auth_token}) 54 | self.oauth_token, self.authenticity_token, self.oauth_verifier, self.token = None, None, None, None 55 | self.referral = referral 56 | self.auth_token = auth_token 57 | 58 | async def get_twitter(self): 59 | try: 60 | response = await self.http.get( 61 | 'https://api.nyanheroes.com/Login/Authorize?callbackUrl=https://missions.nyanheroes.com/') 62 | if 'oauth_token' in response.text: 63 | parsed_url = urlparse(response.text) 64 | query_params = parse_qs(parsed_url.query) 65 | self.oauth_token = query_params.get('oauth_token', [None])[0] 66 | return True 67 | logger.error(f'{self.auth_token} 获取oauth_token失败') 68 | return False 69 | except Exception as e: 70 | logger.error(e) 71 | return False 72 | 73 | async def get_twitter_token(self): 74 | try: 75 | if not await self.get_twitter(): 76 | return False 77 | response = await self.Twitter.get(f'https://api.twitter.com/oauth/authorize?oauth_token={self.oauth_token}') 78 | if 'authenticity_token' in response.text: 79 | self.authenticity_token = response.text.split('authenticity_token" value="')[1].split('"')[0] 80 | return True 81 | logger.error(f'{self.auth_token} 获取authenticity_token失败') 82 | return False 83 | except Exception as e: 84 | logger.error(e) 85 | return False 86 | 87 | async def twitter_authorize(self): 88 | try: 89 | if not await self.get_twitter_token(): 90 | return False 91 | data = { 92 | 'authenticity_token': self.authenticity_token, 93 | 'redirect_after_login': f'https://api.twitter.com/oauth/authorize?oauth_token={self.oauth_token}', 94 | 'oauth_token': self.oauth_token 95 | } 96 | response = await self.Twitter.post('https://api.twitter.com/oauth/authorize', data=data) 97 | if 'oauth_verifier' in response.text: 98 | self.oauth_verifier = response.text.split('oauth_verifier=')[1].split('"')[0] 99 | return True 100 | logger.error(f'{self.auth_token} 获取oauth_verifier失败') 101 | return False 102 | except Exception as e: 103 | logger.error(e) 104 | return False 105 | 106 | async def twitter_login(self): 107 | try: 108 | if not await self.twitter_authorize(): 109 | return False 110 | data = { 111 | 'oauthToken': self.oauth_token, 112 | 'callbackUrl': 'https://missions.nyanheroes.com/', 113 | 'oauthVerifier': self.oauth_verifier 114 | } 115 | response = await self.http.get(f'https://api.nyanheroes.com/Login/Authorize', params=data) 116 | if response.json()['user']['twitterUsername'] is not None: 117 | self.token = response.json()['token'] 118 | self.http.headers['Authorization'] = 'Bearer ' + self.token 119 | return True 120 | logger.error(f'{self.auth_token} 登录失败') 121 | return False 122 | except Exception as e: 123 | logger.error(e) 124 | return False 125 | 126 | async def set_referral(self): 127 | try: 128 | response = await self.http.post('https://api.nyanheroes.com/User/addReferral?referralCode=' + self.referral) 129 | if response.json()['result']: 130 | return True 131 | logger.error(f'{self.auth_token} 设置邀请人失败') 132 | return False 133 | except Exception as e: 134 | logger.error(e) 135 | return False 136 | 137 | async def compete_task(self,sol_wallet): 138 | try: 139 | task_id = [5, 6, 7, 8, 3, 31, 1, 4, 32, 65, 2] 140 | for i in task_id: 141 | time.sleep(1) 142 | try: 143 | if i != 2: 144 | response = await self.http.post('https://api.nyanheroes.com/Quest/setQuest', json={'Id': i}) 145 | if not response.json()['result']: 146 | logger.error(f'{self.auth_token} 完成任务{i}失败') 147 | continue 148 | else: 149 | now = datetime.utcnow() 150 | iso_format_time = now.strftime("%Y-%m-%dT%H:%M:%S.%fZ")[:23] + 'Z' 151 | message = f'Please sign in to prove the ownership : {str(sol_wallet.public_key)} , Timestamp: {iso_format_time}' 152 | signature = sol_wallet.sign(message)[:64] 153 | signature = base58.b58encode(signature).decode('utf-8') 154 | data = { 155 | 'QuestId': 2, 156 | 'WalletAddress': str(sol_wallet.public_key), 157 | 'Signature':signature, 158 | 'Message':message, 159 | } 160 | response = await self.http.post('https://api.nyanheroes.com/Quest/verifyMessage', json=data) 161 | if not response.json()['result']: 162 | logger.error(f'{self.auth_token} 完成任务{i}失败') 163 | continue 164 | except Exception as e: 165 | logger.error(e) 166 | continue 167 | return True 168 | except Exception as e: 169 | logger.error(e) 170 | return False 171 | 172 | 173 | async def main(referral_code, file_name,task=False): 174 | global g_fail, g_success 175 | with open(file_name, 'r', encoding='UTF-8') as f, open('nyan-success.txt', 'a') as s, open('nyan-error.txt', 176 | 'a') as e: # eth----auth_token 177 | lines = f.readlines() 178 | for k, v in enumerate(lines): 179 | try: 180 | auth_token = v.strip() 181 | mini = Nyan(auth_token, referral_code) 182 | if await mini.twitter_login() and await mini.set_referral(): 183 | sol_private = '' 184 | if task: 185 | sol_wallet = Keypair() 186 | sol_private = str(sol_wallet.private_key) 187 | await mini.compete_task(sol_wallet) 188 | g_success += 1 189 | logger.success(f'{auth_token} 成功') 190 | s.write(f'{auth_token}----{sol_private}\n') 191 | else: 192 | g_fail += 1 193 | logger.error(f'{auth_token} 失败') 194 | e.write(f'{auth_token}----{sol_private}\n') 195 | except Exception as ex: 196 | g_fail += 1 197 | logger.error(f'{auth_token} 失败') 198 | e.write(f'{auth_token}----{auth_token}\n') 199 | continue 200 | 201 | 202 | if __name__ == '__main__': 203 | rel_code = '' #替换为你的邀请码 204 | file_name = 'tw_token.txt' 205 | asyncio.run(main(rel_code, file_name,task=True)) 206 | --------------------------------------------------------------------------------